From: Bert Vermeulen Date: Mon, 25 Mar 2013 14:38:44 +0000 (+0100) Subject: Use GVariant for sr_config_*() functions X-Git-Tag: dsupstream~218 X-Git-Url: http://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=bc1c2f001a3b8499052348ec45155313153b2194 Use GVariant for sr_config_*() functions sr_config_get() provides a GVariant owned by the caller, so it must be released with g_variant_unref() when done. sr_config_set() takes a GVariant from the caller which may be floating; it will be properly sunk and release after use by this function. Thus the output of g_variant_new_*() may be used as an argument. sr_config_list() also provides a GVariant owned by the caller, to be unreferenced when done. sr_config_make() can take a floating reference. --- diff --git a/hwdriver.c b/hwdriver.c index 1d0aa46c..4635f3c4 100644 --- a/hwdriver.c +++ b/hwdriver.c @@ -355,14 +355,15 @@ SR_PRIV void sr_hw_cleanup_all(void) } } -SR_PRIV struct sr_config *sr_config_new(int key, const void *value) +/** A floating reference can be passed in for data. */ +SR_PRIV struct sr_config *sr_config_new(int key, GVariant *data) { struct sr_config *src; if (!(src = g_try_malloc(sizeof(struct sr_config)))) return NULL; src->key = key; - src->value = value; + src->data = g_variant_ref_sink(data); return src; } @@ -372,9 +373,14 @@ SR_PRIV struct sr_config *sr_config_new(int key, const void *value) * * @param driver The sr_dev_driver struct to query. * @param key The configuration key (SR_CONF_*). - * @param data Pointer where the value will be stored. Must not be NULL. - * @param sdi If the key is specific to a device, this must contain a - * pointer to the struct sr_dev_inst to be checked. + * @param data Pointer to a GVariant where the value will be stored. Must + * not be NULL. The caller is given ownership of the GVariant + * and must thus decrease the refcount after use. However if + * this function returns an error code, the field should be + * considered unused, and should not be unreferenced. + * @param sdi (optional) If the key is specific to a device, this must + * contain a pointer to the struct sr_dev_inst to be checked. + * Otherwise it must be NULL. * * @return SR_OK upon success or SR_ERR in case of error. Note SR_ERR_ARG * may be returned by the driver indicating it doesn't know that key, @@ -382,14 +388,18 @@ SR_PRIV struct sr_config *sr_config_new(int key, const void *value) * as an indication that it's not applicable. */ SR_API int sr_config_get(const struct sr_dev_driver *driver, int key, - const void **data, const struct sr_dev_inst *sdi) + GVariant **data, const struct sr_dev_inst *sdi) { int ret; if (!driver || !data) return SR_ERR; - ret = driver->config_get(key, data, sdi); + if ((ret = driver->config_get(key, data, sdi)) == SR_OK) { + /* Got a floating reference from the driver. Sink it here, + * caller will need to unref when done with it. */ + g_variant_ref_sink(*data); + } return ret; } @@ -399,26 +409,29 @@ SR_API int sr_config_get(const struct sr_dev_driver *driver, int key, * * @param sdi The device instance. * @param key The configuration key (SR_CONF_*). - * @param value The new value for the key, as a pointer to whatever type - * is appropriate for that key. + * @param data The new value for the key, as a GVariant with GVariantType + * appropriate to that key. A floating reference can be passed + * in; its refcount will be sunk and unreferenced after use. * * @return SR_OK upon success or SR_ERR in case of error. Note SR_ERR_ARG * may be returned by the driver indicating it doesn't know that key, * but this is not to be flagged as an error by the caller; merely * as an indication that it's not applicable. */ -SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, - const void *value) +SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, GVariant *data) { int ret; - if (!sdi || !sdi->driver || !value) - return SR_ERR; + g_variant_ref_sink(data); - if (!sdi->driver->config_set) - return SR_ERR_ARG; + if (!sdi || !sdi->driver || !data) + ret = SR_ERR; + else if (!sdi->driver->config_set) + ret = SR_ERR_ARG; + else + ret = sdi->driver->config_set(key, data, sdi); - ret = sdi->driver->config_set(key, value, sdi); + g_variant_unref(data); return ret; } @@ -428,10 +441,13 @@ SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, * * @param driver The sr_dev_driver struct to query. * @param key The configuration key (SR_CONF_*). - * @param data A pointer to a list of values, in whatever format is - * appropriate for that key. - * @param sdi If the key is specific to a device, this must contain a - * pointer to the struct sr_dev_inst to be checked. + * @param data A pointer to a GVariant where the list will be stored. The + * caller is given ownership of the GVariant and must thus + * unref the GVariant after use. However if this function + * returns an error code, the field should be considered + * unused, and should not be unreferenced. + * @param sdi (optional) If the key is specific to a device, this must + * contain a pointer to the struct sr_dev_inst to be checked. * * @return SR_OK upon success or SR_ERR in case of error. Note SR_ERR_ARG * may be returned by the driver indicating it doesn't know that key, @@ -439,14 +455,14 @@ SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, * as an indication that it's not applicable. */ SR_API int sr_config_list(const struct sr_dev_driver *driver, int key, - const void **data, const struct sr_dev_inst *sdi) + GVariant **data, const struct sr_dev_inst *sdi) { int ret; - if (!driver || !data) - return SR_ERR; - - ret = driver->config_list(key, data, sdi); + if (!driver || !data || !driver->config_list) + ret = SR_ERR; + else if ((ret = driver->config_list(key, data, sdi)) == SR_OK) + g_variant_ref_sink(*data); return ret; } diff --git a/libsigrok-internal.h b/libsigrok-internal.h index ff6223c6..649a0a31 100644 --- a/libsigrok-internal.h +++ b/libsigrok-internal.h @@ -113,7 +113,7 @@ SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial); /*--- hwdriver.c ------------------------------------------------------------*/ SR_PRIV void sr_hw_cleanup_all(void); -SR_PRIV struct sr_config *sr_config_new(int key, const void *value); +SR_PRIV struct sr_config *sr_config_new(int key, GVariant *data); SR_PRIV int sr_source_remove(int fd); SR_PRIV int sr_source_add(int fd, int events, int timeout, sr_receive_data_callback_t cb, void *cb_data); diff --git a/libsigrok.h b/libsigrok.h index 6f6163b6..351bc0a4 100644 --- a/libsigrok.h +++ b/libsigrok.h @@ -522,7 +522,7 @@ struct sr_probe { struct sr_config { int key; - const void *value; + GVariant *data; }; struct sr_config_info { @@ -744,11 +744,11 @@ struct sr_dev_driver { GSList *(*scan) (GSList *options); GSList *(*dev_list) (void); int (*dev_clear) (void); - int (*config_get) (int id, const void **value, + int (*config_get) (int id, GVariant **data, const struct sr_dev_inst *sdi); - int (*config_set) (int id, const void *value, + int (*config_set) (int id, GVariant *data, const struct sr_dev_inst *sdi); - int (*config_list) (int info_id, const void **data, + int (*config_list) (int info_id, GVariant **data, const struct sr_dev_inst *sdi); /* Device-specific */ diff --git a/proto.h b/proto.h index ed72d4b3..f993d605 100644 --- a/proto.h +++ b/proto.h @@ -69,11 +69,11 @@ SR_API int sr_driver_init(struct sr_context *ctx, struct sr_dev_driver *driver); SR_API GSList *sr_driver_scan(struct sr_dev_driver *driver, GSList *options); SR_API int sr_config_get(const struct sr_dev_driver *driver, int key, - const void **data, const struct sr_dev_inst *sdi); + GVariant **data, const struct sr_dev_inst *sdi); SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, - const void *value); + GVariant *data); SR_API int sr_config_list(const struct sr_dev_driver *driver, int key, - const void **data, const struct sr_dev_inst *sdi); + GVariant **data, const struct sr_dev_inst *sdi); SR_API const struct sr_config_info *sr_config_info_get(int key); SR_API const struct sr_config_info *sr_config_info_name_get(const char *optname);