@@ -15,6 +15,7 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include "json_object_private.h"
#include "json_pointer.h"
#include "json_pointer.h"
#include "strdup_compat.h"
#include "strdup_compat.h"
#include "vasprintf_compat.h"
#include "vasprintf_compat.h"
@@ -88,14 +89,13 @@ check_oob:
}
}
static int json_pointer_get_single_path(struct json_object *obj, char *path,
static int json_pointer_get_single_path(struct json_object *obj, char *path,
struct json_object **value)
struct json_object **value, size_t *idx )
{
{
if (json_object_is_type(obj, json_type_array))
if (json_object_is_type(obj, json_type_array))
{
{
size_t idx;
if (!is_valid_index(obj, path, &idx))
if (!is_valid_index(obj, path, idx))
return -1;
return -1;
obj = json_object_array_get_idx(obj, idx);
obj = json_object_array_get_idx(obj, * idx);
if (obj)
if (obj)
{
{
if (value)
if (value)
@@ -147,9 +147,11 @@ static int json_pointer_set_single_path(struct json_object *parent, const char *
return -1;
return -1;
}
}
static int json_pointer_get_recursive(struct json_object *obj, char *path,
struct json_object **value )
static int json_pointer_result_ get_recursive(struct json_object *obj, char *path,
struct json_pointer_get_result *res )
{
{
struct json_object *parent_obj = obj;
size_t idx;
char *endp;
char *endp;
int rc;
int rc;
@@ -166,24 +168,47 @@ static int json_pointer_get_recursive(struct json_object *obj, char *path,
*endp = '\0';
*endp = '\0';
/* If we err-ed here, return here */
/* If we err-ed here, return here */
if ((rc = json_pointer_get_single_path(obj, path, &obj)))
if ((rc = json_pointer_get_single_path(obj, path, &obj, &idx )))
return rc;
return rc;
if (endp)
if (endp)
{
{
/* Put the slash back, so that the sanity check passes on next recursion level */
/* Put the slash back, so that the sanity check passes on next recursion level */
*endp = '/';
*endp = '/';
return json_pointer_get_recursive(obj, endp, value );
return json_pointer_result_get_recursive(obj, endp, res );
}
}
/* We should be at the end of the recursion here */
/* We should be at the end of the recursion here */
if (res) {
res->parent = parent_obj;
res->obj = obj;
if (json_object_is_type(res->parent, json_type_array))
res->id.index = idx;
else
res->id.key = path;
}
return 0;
}
static int json_pointer_object_get_recursive(struct json_object *obj, char *path,
struct json_object **value)
{
struct json_pointer_get_result res;
int rc;
rc = json_pointer_result_get_recursive(obj, path, &res);
if (rc)
return rc;
if (value)
if (value)
*value = obj;
*value = res. obj;
return 0;
return 0;
}
}
int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res)
int json_pointer_get_internal(struct json_object *obj, const char *path,
struct json_pointer_get_result *res)
{
{
char *path_copy = NULL;
char *path_copy = NULL;
int rc;
int rc;
@@ -196,8 +221,11 @@ int json_pointer_get(struct json_object *obj, const char *path, struct json_obje
if (path[0] == '\0')
if (path[0] == '\0')
{
{
if (res)
*res = obj;
if (res) {
res->parent = NULL;
res->obj = obj;
}
res->id.key = NULL;
return 0;
return 0;
}
}
@@ -207,12 +235,30 @@ int json_pointer_get(struct json_object *obj, const char *path, struct json_obje
errno = ENOMEM;
errno = ENOMEM;
return -1;
return -1;
}
}
rc = json_pointer_get_recursive(obj, path_copy, res);
rc = json_pointer_result_get_recursive(obj, path_copy, res);
/* re-map the path string to the const-path string */
if (rc == 0 && res->id.key && !json_object_is_type(res->parent, json_type_array))
res->id.key = path + (res->id.key - path_copy);
free(path_copy);
free(path_copy);
return rc;
return rc;
}
}
int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res)
{
struct json_pointer_get_result jpres;
int rc;
rc = json_pointer_get_internal(obj, path, &jpres);
if (rc)
return rc;
if (res)
*res = jpres.obj;
return 0;
}
int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...)
int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...)
{
{
char *path_copy = NULL;
char *path_copy = NULL;
@@ -239,7 +285,7 @@ int json_pointer_getf(struct json_object *obj, struct json_object **res, const c
goto out;
goto out;
}
}
rc = json_pointer_get_recursive(obj, path_copy, res);
rc = json_pointer_object_ get_recursive(obj, path_copy, res);
out:
out:
free(path_copy);
free(path_copy);
@@ -286,7 +332,7 @@ int json_pointer_set(struct json_object **obj, const char *path, struct json_obj
return -1;
return -1;
}
}
path_copy[endp - path] = '\0';
path_copy[endp - path] = '\0';
rc = json_pointer_get_recursive(*obj, path_copy, &set);
rc = json_pointer_object_ get_recursive(*obj, path_copy, &set);
free(path_copy);
free(path_copy);
if (rc)
if (rc)
@@ -341,7 +387,7 @@ int json_pointer_setf(struct json_object **obj, struct json_object *value, const
}
}
*endp = '\0';
*endp = '\0';
rc = json_pointer_get_recursive(*obj, path_copy, &set);
rc = json_pointer_object_ get_recursive(*obj, path_copy, &set);
if (rc)
if (rc)
goto out;
goto out;