예제 #1
0
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;
}
예제 #2
0
파일: json_get.c 프로젝트: tidatida/gretl
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;
    double x;
    int err = 0;

    *n_objects = 0;

    node = json_parser_get_root(parser);
    path = json_path_new();

    if (!json_path_compile(path, pathstr, &gerr)) {
        if (gerr != NULL) {
            gretl_errmsg_sprintf("Failed to compile JsonPath: %s",
                                 gerr->message);
            g_error_free(gerr);
        } else {
            gretl_errmsg_set("Failed to compile JsonPath");
        }
        g_object_unref(path);
        return E_DATA;
    }

    match = json_path_match(path, node);
    if (match == NULL) {
        /* 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;

        array = json_node_get_array(match);
        node = json_array_get_element(array, 0);

repeat:

        if (node == NULL) {
            gretl_errmsg_set("Failed to match JsonPath");
            ntype = 0;
        } else {
            ntype = json_node_get_value_type(node);
        }

        if (!handled_type(ntype)) {
            if (JSON_NODE_HOLDS_ARRAY(node)) {
                array = json_node_get_array(node);
                node = json_array_get_element(array, 0);
                goto repeat;
            } else {
                gretl_errmsg_sprintf("Unhandled array type '%s'",
                                     g_type_name(ntype));
                err = E_DATA;
            }
        } else {
            int i, n = json_array_get_length(array);

            for (i=0; i<n; i++) {
                node = json_array_get_element(array, i);
                if (ntype == G_TYPE_STRING) {
                    pputs(prn, json_node_get_string(node));
                } else {
                    x = json_node_get_double(node);
                    pprintf(prn, "%.15g", x);
                }
                if (n > 1) {
                    pputc(prn, '\n');
                }
            }
            *n_objects = n;
        }
    } else {
        ntype = json_node_get_value_type(match);
        if (!handled_type(ntype)) {
            gretl_errmsg_sprintf("Unhandled object type '%s'",
                                 g_type_name(ntype));
            err = E_DATA;
        } else {
            if (ntype == G_TYPE_STRING) {
                pputs(prn, json_node_get_string(match));
            } else {
                x = json_node_get_double(match);
                pprintf(prn, "%.15g", x);
            }
            *n_objects = 1;
        }
    }

    gretl_pop_c_numeric_locale();

    json_node_free(match);
    g_object_unref(path);

    return err;
}