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.
This commit is contained in:
Bert Vermeulen 2013-03-25 15:38:44 +01:00
parent 13d8e03c4f
commit bc1c2f001a
4 changed files with 49 additions and 33 deletions

View File

@ -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; struct sr_config *src;
if (!(src = g_try_malloc(sizeof(struct sr_config)))) if (!(src = g_try_malloc(sizeof(struct sr_config))))
return NULL; return NULL;
src->key = key; src->key = key;
src->value = value; src->data = g_variant_ref_sink(data);
return src; 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 driver The sr_dev_driver struct to query.
* @param key The configuration key (SR_CONF_*). * @param key The configuration key (SR_CONF_*).
* @param data Pointer where the value will be stored. Must not be NULL. * @param data Pointer to a GVariant where the value will be stored. Must
* @param sdi If the key is specific to a device, this must contain a * not be NULL. The caller is given ownership of the GVariant
* pointer to the struct sr_dev_inst to be checked. * 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 * @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, * 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. * as an indication that it's not applicable.
*/ */
SR_API int sr_config_get(const struct sr_dev_driver *driver, int key, 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; int ret;
if (!driver || !data) if (!driver || !data)
return SR_ERR; 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; 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 sdi The device instance.
* @param key The configuration key (SR_CONF_*). * @param key The configuration key (SR_CONF_*).
* @param value The new value for the key, as a pointer to whatever type * @param data The new value for the key, as a GVariant with GVariantType
* is appropriate for that key. * 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 * @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, * 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 * but this is not to be flagged as an error by the caller; merely
* as an indication that it's not applicable. * as an indication that it's not applicable.
*/ */
SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, SR_API int sr_config_set(const struct sr_dev_inst *sdi, int key, GVariant *data)
const void *value)
{ {
int ret; int ret;
if (!sdi || !sdi->driver || !value) g_variant_ref_sink(data);
return SR_ERR;
if (!sdi->driver->config_set) if (!sdi || !sdi->driver || !data)
return SR_ERR_ARG; 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; 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 driver The sr_dev_driver struct to query.
* @param key The configuration key (SR_CONF_*). * @param key The configuration key (SR_CONF_*).
* @param data A pointer to a list of values, in whatever format is * @param data A pointer to a GVariant where the list will be stored. The
* appropriate for that key. * caller is given ownership of the GVariant and must thus
* @param sdi If the key is specific to a device, this must contain a * unref the GVariant after use. However if this function
* pointer to the struct sr_dev_inst to be checked. * 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 * @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, * 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. * as an indication that it's not applicable.
*/ */
SR_API int sr_config_list(const struct sr_dev_driver *driver, int key, 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; int ret;
if (!driver || !data) if (!driver || !data || !driver->config_list)
return SR_ERR; ret = SR_ERR;
else if ((ret = driver->config_list(key, data, sdi)) == SR_OK)
ret = driver->config_list(key, data, sdi); g_variant_ref_sink(*data);
return ret; return ret;
} }

View File

@ -113,7 +113,7 @@ SR_PRIV void sr_serial_dev_inst_free(struct sr_serial_dev_inst *serial);
/*--- hwdriver.c ------------------------------------------------------------*/ /*--- hwdriver.c ------------------------------------------------------------*/
SR_PRIV void sr_hw_cleanup_all(void); 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_remove(int fd);
SR_PRIV int sr_source_add(int fd, int events, int timeout, SR_PRIV int sr_source_add(int fd, int events, int timeout,
sr_receive_data_callback_t cb, void *cb_data); sr_receive_data_callback_t cb, void *cb_data);

View File

@ -522,7 +522,7 @@ struct sr_probe {
struct sr_config { struct sr_config {
int key; int key;
const void *value; GVariant *data;
}; };
struct sr_config_info { struct sr_config_info {
@ -744,11 +744,11 @@ struct sr_dev_driver {
GSList *(*scan) (GSList *options); GSList *(*scan) (GSList *options);
GSList *(*dev_list) (void); GSList *(*dev_list) (void);
int (*dev_clear) (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); 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); 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); const struct sr_dev_inst *sdi);
/* Device-specific */ /* Device-specific */

View File

@ -69,11 +69,11 @@ SR_API int sr_driver_init(struct sr_context *ctx,
struct sr_dev_driver *driver); struct sr_dev_driver *driver);
SR_API GSList *sr_driver_scan(struct sr_dev_driver *driver, GSList *options); 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, 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, 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, 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_get(int key);
SR_API const struct sr_config_info *sr_config_info_name_get(const char *optname); SR_API const struct sr_config_info *sr_config_info_name_get(const char *optname);