diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2017-11-14 17:16:40 +0000 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2017-11-14 17:16:40 +0000 |
commit | 5b816ff8df9e563c1e9c3ae05ee97d46924f9b40 (patch) | |
tree | a55205f1519a5f563f70df6ae276b5510acffe4e /json-glib/json-object.c | |
parent | ce0f83a46317482255e5e6afe9b9d57422c6bffb (diff) | |
download | json-glib-5b816ff8df9e563c1e9c3ae05ee97d46924f9b40.tar.gz |
Add with_default() variant for JsonObject getters
When using the typed getters for JsonObject, the existing API will
automatically fail if the member requested is not present. This is
generally good practice, because JSON data typically does not have a
schema, and thus is has to be validated "on the go"; a JSON object
member that contains `null`, or `0`, or `false`, is indistinguishable
from a JSON object member that does not exist, so we cannot simply
return a scalar value and be done with it.
We can provide an escape hatch, though, for the crowd writing parsers
for JSON data; by using Python as the model, we can add methods that
take a default value as a parameter, and return it as a fallback value
if the requested object member does not exist, or if it's set to `null`.
Diffstat (limited to 'json-glib/json-object.c')
-rw-r--r-- | json-glib/json-object.c | 205 |
1 files changed, 131 insertions, 74 deletions
diff --git a/json-glib/json-object.c b/json-glib/json-object.c index 29b9401..bb33ec0 100644 --- a/json-glib/json-object.c +++ b/json-glib/json-object.c @@ -579,10 +579,50 @@ json_object_get_member (JsonObject *object, return object_get_member_internal (object, member_name); } +#define JSON_OBJECT_GET(ret_type,type_name) \ +ret_type \ +json_object_get_ ##type_name## _member (JsonObject *object, \ + const char *member_name) \ +{ \ + g_return_val_if_fail (object != NULL, (ret_type) 0); \ + g_return_val_if_fail (member_name != NULL, (ret_type) 0); \ +\ + JsonNode *node = object_get_member_internal (object, member_name); \ + g_return_val_if_fail (node != NULL, (ret_type) 0); \ +\ + if (JSON_NODE_HOLDS_NULL (node)) \ + return (ret_type) 0; \ +\ + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, (ret_type) 0); \ +\ + return json_node_get_ ##type_name (node); \ +} + +#define JSON_OBJECT_GET_DEFAULT(ret_type,type_name) \ +ret_type \ +json_object_get_ ##type_name## _member_with_default (JsonObject *object, \ + const char *member_name, \ + ret_type default_value) \ +{ \ + g_return_val_if_fail (object != NULL, default_value); \ + g_return_val_if_fail (member_name != NULL, default_value); \ +\ + JsonNode *node = object_get_member_internal (object, member_name); \ + if (node == NULL) \ + return default_value; \ +\ + if (JSON_NODE_HOLDS_NULL (node)) \ + return default_value; \ +\ + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, default_value); \ +\ + return json_node_get_ ##type_name (node); \ +} + /** * json_object_get_int_member: * @object: a #JsonObject - * @member_name: the name of the member + * @member_name: the name of the @object member * * Convenience function that retrieves the integer value * stored in @member_name of @object @@ -593,21 +633,26 @@ json_object_get_member (JsonObject *object, * * Since: 0.8 */ -gint64 -json_object_get_int_member (JsonObject *object, - const gchar *member_name) -{ - JsonNode *node; - - g_return_val_if_fail (object != NULL, 0); - g_return_val_if_fail (member_name != NULL, 0); +JSON_OBJECT_GET (gint64, int) - node = object_get_member_internal (object, member_name); - g_return_val_if_fail (node != NULL, 0); - g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0); - - return json_node_get_int (node); -} +/** + * json_object_get_int_member_with_default: + * @object: a #JsonObject + * @member_name: the name of the @object member + * @default_value: the value to return if @member_name is not valid + * + * Convenience function that retrieves the integer value + * stored in @member_name of @object. + * + * If @member_name does not exist, does not contain a scalar value, + * or contains `null`, then @default_value is returned instead. + * + * Returns: the integer value of the object's member, or the + * given default + * + * Since: 1.6 + */ +JSON_OBJECT_GET_DEFAULT (gint64, int) /** * json_object_get_double_member: @@ -623,21 +668,26 @@ json_object_get_int_member (JsonObject *object, * * Since: 0.8 */ -gdouble -json_object_get_double_member (JsonObject *object, - const gchar *member_name) -{ - JsonNode *node; - - g_return_val_if_fail (object != NULL, 0.0); - g_return_val_if_fail (member_name != NULL, 0.0); - - node = object_get_member_internal (object, member_name); - g_return_val_if_fail (node != NULL, 0.0); - g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0); +JSON_OBJECT_GET (gdouble, double) - return json_node_get_double (node); -} +/** + * json_object_get_double_member_with_default: + * @object: a #JsonObject + * @member_name: the name of the @object member + * @default_value: the value to return if @member_name is not valid + * + * Convenience function that retrieves the floating point value + * stored in @member_name of @object. + * + * If @member_name does not exist, does not contain a scalar value, + * or contains `null`, then @default_value is returned instead. + * + * Returns: the floating point value of the object's member, or the + * given default + * + * Since: 1.6 + */ +JSON_OBJECT_GET_DEFAULT (double, double) /** * json_object_get_boolean_member: @@ -653,21 +703,61 @@ json_object_get_double_member (JsonObject *object, * * Since: 0.8 */ -gboolean -json_object_get_boolean_member (JsonObject *object, - const gchar *member_name) -{ - JsonNode *node; +JSON_OBJECT_GET (gboolean, boolean) - g_return_val_if_fail (object != NULL, FALSE); - g_return_val_if_fail (member_name != NULL, FALSE); +/** + * json_object_get_boolean_member_with_default: + * @object: a #JsonObject + * @member_name: the name of the @object member + * @default_value: the value to return if @member_name is not valid + * + * Convenience function that retrieves the boolean value + * stored in @member_name of @object. + * + * If @member_name does not exist, does not contain a scalar value, + * or contains `null`, then @default_value is returned instead. + * + * Returns: the boolean value of the object's member, or the + * given default + * + * Since: 1.6 + */ +JSON_OBJECT_GET_DEFAULT (gboolean, boolean) - node = object_get_member_internal (object, member_name); - g_return_val_if_fail (node != NULL, FALSE); - g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE); +/** + * json_object_get_string_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the string value + * stored in @member_name of @object + * + * See also: json_object_get_member() + * + * Return value: the string value of the object's member + * + * Since: 0.8 + */ +JSON_OBJECT_GET (const gchar *, string) - return json_node_get_boolean (node); -} +/** + * json_object_get_string_member_with_default: + * @object: a #JsonObject + * @member_name: the name of the @object member + * @default_value: the value to return if @member_name is not valid + * + * Convenience function that retrieves the string value + * stored in @member_name of @object. + * + * If @member_name does not exist, does not contain a scalar value, + * or contains `null`, then @default_value is returned instead. + * + * Returns: the string value of the object's member, or the + * given default + * + * Since: 1.6 + */ +JSON_OBJECT_GET_DEFAULT (const char *, string) /** * json_object_get_null_member: @@ -708,39 +798,6 @@ json_object_get_null_member (JsonObject *object, } /** - * json_object_get_string_member: - * @object: a #JsonObject - * @member_name: the name of the member - * - * Convenience function that retrieves the string value - * stored in @member_name of @object - * - * See also: json_object_get_member() - * - * Return value: the string value of the object's member - * - * Since: 0.8 - */ -const gchar * -json_object_get_string_member (JsonObject *object, - const gchar *member_name) -{ - JsonNode *node; - - g_return_val_if_fail (object != NULL, NULL); - g_return_val_if_fail (member_name != NULL, NULL); - - node = object_get_member_internal (object, member_name); - g_return_val_if_fail (node != NULL, NULL); - g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL); - - if (JSON_NODE_HOLDS_NULL (node)) - return NULL; - - return json_node_get_string (node); -} - -/** * json_object_get_array_member: * @object: a #JsonObject * @member_name: the name of the member |