#include <stdlib.h>
#include <string.h>
+#include "json_object_private.h"
#include "json_pointer.h"
#include "strdup_compat.h"
#include "vasprintf_compat.h"
}
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))
{
- size_t idx;
- if (!is_valid_index(obj, path, &idx))
+ if (!is_valid_index(obj, path, idx))
return -1;
- obj = json_object_array_get_idx(obj, idx);
+ obj = json_object_array_get_idx(obj, *idx);
if (obj)
{
if (value)
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;
int rc;
*endp = '\0';
/* 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;
if (endp)
{
/* Put the slash back, so that the sanity check passes on next recursion level */
*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 */
+ 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)
- *value = obj;
+ *value = res.obj;
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;
int rc;
if (path[0] == '\0')
{
- if (res)
- *res = obj;
+ if (res) {
+ res->parent = NULL;
+ res->obj = obj;
+ }
+ res->id.key = NULL;
return 0;
}
errno = ENOMEM;
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);
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, ...)
{
char *path_copy = NULL;
goto out;
}
- rc = json_pointer_get_recursive(obj, path_copy, res);
+ rc = json_pointer_object_get_recursive(obj, path_copy, res);
out:
free(path_copy);
return -1;
}
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);
if (rc)
}
*endp = '\0';
- rc = json_pointer_get_recursive(*obj, path_copy, &set);
+ rc = json_pointer_object_get_recursive(*obj, path_copy, &set);
if (rc)
goto out;