m_config: add function to copy subopt-struct

This commit is contained in:
wm4 2014-06-09 23:46:53 +02:00
parent e033f3c8bc
commit 98c0930f9b
2 changed files with 43 additions and 0 deletions

View File

@ -874,6 +874,43 @@ void *m_config_alloc_struct(void *talloc_ctx,
return substruct;
}
struct dtor_info {
const struct m_sub_options *opts;
void *ptr;
};
static void free_substruct(void *ptr)
{
struct dtor_info *d = ptr;
for (int n = 0; d->opts->opts && d->opts->opts[n].type; n++) {
const struct m_option *opt = &d->opts->opts[n];
void *dst = (char *)d->ptr + opt->offset;
m_option_free(opt, dst);
}
}
void *m_sub_options_copy(void *talloc_ctx, const struct m_sub_options *opts,
const void *ptr)
{
void *new = talloc_zero_size(talloc_ctx, opts->size);
struct dtor_info *dtor = talloc_ptrtype(new, dtor);
*dtor = (struct dtor_info){opts, new};
talloc_set_destructor(dtor, free_substruct);
// also fill/initialize members not described by opts
if (opts->defaults)
memcpy(new, opts->defaults, opts->size);
for (int n = 0; opts->opts && opts->opts[n].type; n++) {
const struct m_option *opt = &opts->opts[n];
// not implemented, because it adds lots of complexity
assert(!(opt->type->flags & M_OPT_TYPE_HAS_CHILD));
void *src = (char *)ptr + opt->offset;
void *dst = (char *)new + opt->offset;
memset(dst, 0, opt->type->size);
m_option_copy(opt, dst, src);
}
return new;
}
// This is used for printing error messages on unknown options.
static const char *replaced_opts =
"|a52drc#--ad-lavc-ac3drc=level"

View File

@ -237,4 +237,10 @@ void m_config_set_profile(struct m_config *config, struct m_profile *p,
void *m_config_alloc_struct(void *talloc_ctx,
const struct m_sub_options *subopts);
// Create a copy of the struct ptr, described by opts.
// "opts" must live until the struct is free'd.
// Freeing the struct frees all members.
void *m_sub_options_copy(void *talloc_ctx, const struct m_sub_options *opts,
const void *ptr);
#endif /* MPLAYER_M_CONFIG_H */