/* FIXME: an error exit at field i leaves fields [0..i) modified. */ bool format_from_json( void *dest, JsonObject *obj, const struct field_desc *fields, size_t num_fields, GError **err_p) { for(size_t i=0; i < num_fields; i++) { const char *name = fields[i].name; JsonNode *node = json_object_get_member(obj, name); if(node == NULL) { /* not present. skip. */ continue; } bool null_ok = islower(fields[i].type), is_null = json_node_is_null(node); if(!null_ok && is_null) { g_set_error(err_p, 0, 0, "%s: field `%s' is null, but not allowed to", __func__, name); return false; } void *ptr = dest + fields[i].offset; switch(tolower(fields[i].type)) { case 'i': *(uint64_t *)ptr = is_null ? 0 : json_object_get_int_member(obj, name); break; case 'b': *(bool *)ptr = is_null ? false : json_object_get_boolean_member(obj, name); break; case 's': g_free(*(char **)ptr); *(char **)ptr = is_null ? NULL : g_strdup(json_object_get_string_member(obj, name)); break; case 't': { GDateTime **dt_p = ptr; if(*dt_p != NULL) { g_date_time_unref(*dt_p); *dt_p = NULL; } *dt_p = parse_datetime(json_object_get_string_member(obj, name)); break; } default: assert(false); } } return true; }
gboolean Settings::getNull(const char* path){ JsonNode* node = getNode(path); return json_node_is_null(node); }
bool GobjectImplScalar::isNull() const { if (json_node_is_null(mNode)) { return true; } return false; }
static int null_node (JsonNode *node) { return node == NULL || json_node_is_null(node); }
static int real_json_get (JsonParser *parser, const char *pathstr, int *n_objects, PRN *prn) { GError *gerr = NULL; JsonNode *match, *node; JsonPath *path; GType ntype; int err = 0; *n_objects = 0; node = json_parser_get_root(parser); if (node == NULL || json_node_is_null(node)) { gretl_errmsg_set("jsonget: got null root node"); return E_DATA; } path = json_path_new(); if (!json_path_compile(path, pathstr, &gerr)) { if (gerr != NULL) { gretl_errmsg_sprintf("jsonget: failed to compile JsonPath: %s", gerr->message); g_error_free(gerr); } else { gretl_errmsg_set("jsonget: failed to compile JsonPath"); } g_object_unref(path); return E_DATA; } match = json_path_match(path, node); if (null_node(match)) { /* FIXME : maybe return empty string? */ g_object_unref(path); return E_DATA; } /* in case we get floating-point output */ gretl_push_c_numeric_locale(); if (JSON_NODE_HOLDS_ARRAY(match)) { JsonArray *array = json_node_get_array(match); int len = 0, index = 0; if (non_empty_array(array)) { len = json_array_get_length(array); node = json_array_get_element(array, index); } else { node = NULL; } repeat: if (null_node(node)) { gretl_errmsg_set("jsonget: failed to match JsonPath"); ntype = 0; err = E_DATA; goto bailout; } else { ntype = json_node_get_value_type(node); } if (node != NULL && !handled_type(ntype)) { if (JSON_NODE_HOLDS_ARRAY(node)) { /* recurse on array type */ array = json_node_get_array(node); if (non_empty_array(array)) { node = json_array_get_element(array, 0); goto repeat; } } else if (json_node_get_node_type(node) == JSON_NODE_OBJECT) { err = excavate_json_object(node, n_objects, prn); if (!err) { if (index < len - 1) { node = json_array_get_element(array, ++index); goto repeat; } } } else { gretl_errmsg_sprintf("jsonget: unhandled array type '%s'", g_type_name(ntype)); err = E_DATA; } } else if (array != NULL) { int i, n = json_array_get_length(array); for (i=0; i<n && !err; i++) { node = json_array_get_element(array, i); err = output_json_node_value(node, prn); if (!err) { *n_objects += 1; if (n > 1) { pputc(prn, '\n'); } } } } } else { /* not an array-holding node */ err = output_json_node_value(match, prn); if (!err) { *n_objects += 1; } } bailout: gretl_pop_c_numeric_locale(); json_node_free(match); g_object_unref(path); return err; }