Files
json-c/json_object_private.h
Alexandru Ardelean e4d9fbd52a json_pointer: split json_pointer_set_with_array_cb()
JSON patch is a bit more clear on how some array operations should be
handled. Unfortunately, handling them on a case-by-case is a bit tricky
because it's difficult to satisfy properly an 'add' operating with a 'move'
operation and the basic json_pointer_set().

With json_pointer_set{f}() we use json_object_array_put_idx() to insert a
value at a certain index.

With JSON patch:
* for the 'add' operation, we need to insert a value at a given index,
  which means shifting existing values by one to the right
  - also, we cannot allow values to be inserted/added outside the bounds of
    the array
* a 'move' operation, is described as a 'remove' and then an 'add';
  for arrays this complicates things, because when we want to a move a
  value within the array, we have to remove it first (during which the size
  of the array is reduced by one); when the size of the array is reduced by
  one, we can't add it to the last position in the array (before the
  remove)

The only sane method to handle this (after a few considerations) is to
provide a callback to the function that does the final put/insert into
the array. That way, we can do some final checks where these are needed to
handle each corner-case.

Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
2023-07-31 22:17:30 -04:00

127 lines
2.8 KiB
C

/*
* $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
*
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
* Michael Clark <michael@metaparadigm.com>
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See COPYING for details.
*
*/
/**
* @file
* @brief Do not use, json-c internal, may be changed or removed at any time.
*/
#ifndef _json_object_private_h_
#define _json_object_private_h_
#ifdef __cplusplus
extern "C" {
#endif
struct json_object;
#include "json_inttypes.h"
#include "json_types.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef _MSC_VER
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif
/* json object int type, support extension*/
typedef enum json_object_int_type
{
json_object_int_type_int64,
json_object_int_type_uint64
} json_object_int_type;
struct json_object
{
enum json_type o_type;
uint32_t _ref_count;
json_object_to_json_string_fn *_to_json_string;
struct printbuf *_pb;
json_object_delete_fn *_user_delete;
void *_userdata;
// Actually longer, always malloc'd as some more-specific type.
// The rest of a struct json_object_${o_type} follows
};
struct json_object_object
{
struct json_object base;
struct lh_table *c_object;
};
struct json_object_array
{
struct json_object base;
struct array_list *c_array;
};
struct json_object_boolean
{
struct json_object base;
json_bool c_boolean;
};
struct json_object_double
{
struct json_object base;
double c_double;
};
struct json_object_int
{
struct json_object base;
enum json_object_int_type cint_type;
union
{
int64_t c_int64;
uint64_t c_uint64;
} cint;
};
struct json_object_string
{
struct json_object base;
ssize_t len; // Signed b/c negative lengths indicate data is a pointer
// Consider adding an "alloc" field here, if json_object_set_string calls
// to expand the length of a string are common operations to perform.
union
{
char idata[1]; // Immediate data. Actually longer
char *pdata; // Only when len < 0
} c_string;
};
void _json_c_set_last_err(const char *err_fmt, ...);
extern const char *json_hex_chars;
struct json_pointer_get_result {
struct json_object *parent;
struct json_object *obj;
union {
const char *key;
uint32_t index;
} id;
};
int json_pointer_get_internal(struct json_object *obj, const char *path,
struct json_pointer_get_result *res);
typedef int(*json_pointer_array_set_cb)(json_object *parent, size_t idx,
json_object *value, void *priv);
int json_pointer_set_with_array_cb(struct json_object **obj, const char *path,
struct json_object *value,
json_pointer_array_set_cb array_set_cb, void *priv);
#ifdef __cplusplus
}
#endif
#endif