From 98c0930f9b69122996cc725a08336ee6bd9abc7e Mon Sep 17 00:00:00 2001 From: wm4 Date: Mon, 9 Jun 2014 23:46:53 +0200 Subject: m_config: add function to copy subopt-struct --- options/m_config.c | 37 +++++++++++++++++++++++++++++++++++++ options/m_config.h | 6 ++++++ 2 files changed, 43 insertions(+) diff --git a/options/m_config.c b/options/m_config.c index 857d6591b7..b0b06bc271 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -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" diff --git a/options/m_config.h b/options/m_config.h index 5a6274b945..e20a99853f 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -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 */ -- cgit v1.2.3