Merge branch 'master' into fix-issue281
This commit is contained in:
@@ -55,7 +55,7 @@ typedef struct hashtable {
|
||||
*
|
||||
* Returns 0 on success, -1 on error (out of memory).
|
||||
*/
|
||||
int hashtable_init(hashtable_t *hashtable) JANSSON_ATTRS(warn_unused_result);
|
||||
int hashtable_init(hashtable_t *hashtable) JANSSON_ATTRS((warn_unused_result));
|
||||
|
||||
/**
|
||||
* hashtable_close - Release all resources used by a hashtable object
|
||||
|
||||
@@ -41,6 +41,7 @@ EXPORTS
|
||||
json_object_update
|
||||
json_object_update_existing
|
||||
json_object_update_missing
|
||||
json_object_update_recursive
|
||||
json_object_iter
|
||||
json_object_iter_at
|
||||
json_object_iter_next
|
||||
|
||||
@@ -40,9 +40,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define JANSSON_ATTRS(...) __attribute__((__VA_ARGS__))
|
||||
#define JANSSON_ATTRS(x) __attribute__(x)
|
||||
#else
|
||||
#define JANSSON_ATTRS(...)
|
||||
#define JANSSON_ATTRS(x)
|
||||
#endif
|
||||
|
||||
/* types */
|
||||
@@ -191,7 +191,7 @@ static JSON_INLINE enum json_error_code json_error_code(const json_error_t *e) {
|
||||
|
||||
void json_object_seed(size_t seed);
|
||||
size_t json_object_size(const json_t *object);
|
||||
json_t *json_object_get(const json_t *object, const char *key) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_object_get(const json_t *object, const char *key) JANSSON_ATTRS((warn_unused_result));
|
||||
int json_object_set_new(json_t *object, const char *key, json_t *value);
|
||||
int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
|
||||
int json_object_del(json_t *object, const char *key);
|
||||
@@ -199,6 +199,7 @@ int json_object_clear(json_t *object);
|
||||
int json_object_update(json_t *object, json_t *other);
|
||||
int json_object_update_existing(json_t *object, json_t *other);
|
||||
int json_object_update_missing(json_t *object, json_t *other);
|
||||
int json_object_update_recursive(json_t *object, json_t *other);
|
||||
void *json_object_iter(json_t *object);
|
||||
void *json_object_iter_at(json_t *object, const char *key);
|
||||
void *json_object_key_to_iter(const char *key);
|
||||
@@ -267,7 +268,7 @@ int json_object_update_missing_new(json_t *object, json_t *other)
|
||||
}
|
||||
|
||||
size_t json_array_size(const json_t *array);
|
||||
json_t *json_array_get(const json_t *array, size_t index) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_array_get(const json_t *array, size_t index) JANSSON_ATTRS((warn_unused_result));
|
||||
int json_array_set_new(json_t *array, size_t index, json_t *value);
|
||||
int json_array_append_new(json_t *array, json_t *value);
|
||||
int json_array_insert_new(json_t *array, size_t index, json_t *value);
|
||||
@@ -308,9 +309,9 @@ int json_real_set(json_t *real, double value);
|
||||
|
||||
/* pack, unpack */
|
||||
|
||||
json_t *json_pack(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_pack(const char *fmt, ...) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap) JANSSON_ATTRS((warn_unused_result));
|
||||
|
||||
#define JSON_VALIDATE_ONLY 0x1
|
||||
#define JSON_STRICT 0x2
|
||||
@@ -321,8 +322,8 @@ int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char
|
||||
|
||||
/* sprintf */
|
||||
|
||||
json_t *json_sprintf(const char *fmt, ...) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 2));
|
||||
json_t *json_vsprintf(const char *fmt, va_list ap) JANSSON_ATTRS(warn_unused_result, format(printf, 1, 0));
|
||||
json_t *json_sprintf(const char *fmt, ...) JANSSON_ATTRS((warn_unused_result, format(printf, 1, 2)));
|
||||
json_t *json_vsprintf(const char *fmt, va_list ap) JANSSON_ATTRS((warn_unused_result, format(printf, 1, 0)));
|
||||
|
||||
|
||||
/* equality */
|
||||
@@ -332,8 +333,8 @@ int json_equal(const json_t *value1, const json_t *value2);
|
||||
|
||||
/* copying */
|
||||
|
||||
json_t *json_copy(json_t *value) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_deep_copy(const json_t *value) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_copy(json_t *value) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_deep_copy(const json_t *value) JANSSON_ATTRS((warn_unused_result));
|
||||
|
||||
|
||||
/* decoding */
|
||||
@@ -346,12 +347,12 @@ json_t *json_deep_copy(const json_t *value) JANSSON_ATTRS(warn_unused_result);
|
||||
|
||||
typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
|
||||
|
||||
json_t *json_loads(const char *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loadfd(int input, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_load_file(const char *path, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error) JANSSON_ATTRS(warn_unused_result);
|
||||
json_t *json_loads(const char *input, size_t flags, json_error_t *error) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_loadf(FILE *input, size_t flags, json_error_t *error) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_loadfd(int input, size_t flags, json_error_t *error) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_load_file(const char *path, size_t flags, json_error_t *error) JANSSON_ATTRS((warn_unused_result));
|
||||
json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error) JANSSON_ATTRS((warn_unused_result));
|
||||
|
||||
|
||||
/* encoding */
|
||||
@@ -369,7 +370,7 @@ json_t *json_load_callback(json_load_callback_t callback, void *data, size_t fla
|
||||
|
||||
typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
|
||||
|
||||
char *json_dumps(const json_t *json, size_t flags) JANSSON_ATTRS(warn_unused_result);
|
||||
char *json_dumps(const json_t *json, size_t flags) JANSSON_ATTRS((warn_unused_result));
|
||||
size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);
|
||||
int json_dumpf(const json_t *json, FILE *output, size_t flags);
|
||||
int json_dumpfd(const json_t *json, int output, size_t flags);
|
||||
|
||||
@@ -84,11 +84,11 @@ int jsonp_strtod(strbuffer_t *strbuffer, double *out);
|
||||
int jsonp_dtostr(char *buffer, size_t size, double value, int prec);
|
||||
|
||||
/* Wrappers for custom memory functions */
|
||||
void* jsonp_malloc(size_t size) JANSSON_ATTRS(warn_unused_result);
|
||||
void* jsonp_malloc(size_t size) JANSSON_ATTRS((warn_unused_result));
|
||||
void jsonp_free(void *ptr);
|
||||
char *jsonp_strndup(const char *str, size_t length) JANSSON_ATTRS(warn_unused_result);
|
||||
char *jsonp_strdup(const char *str) JANSSON_ATTRS(warn_unused_result);
|
||||
char *jsonp_strndup(const char *str, size_t len) JANSSON_ATTRS(warn_unused_result);
|
||||
char *jsonp_strndup(const char *str, size_t length) JANSSON_ATTRS((warn_unused_result));
|
||||
char *jsonp_strdup(const char *str) JANSSON_ATTRS((warn_unused_result));
|
||||
char *jsonp_strndup(const char *str, size_t len) JANSSON_ATTRS((warn_unused_result));
|
||||
|
||||
/* Circular reference check*/
|
||||
/* Space for "0x", double the sizeof a pointer for the hex and a terminator. */
|
||||
|
||||
@@ -243,7 +243,7 @@ static uint32_t hashlittle(const void *key, size_t length, uint32_t initval)
|
||||
* rest of the string. Every machine with memory protection I've seen
|
||||
* does it on word boundaries, so is OK with this. But VALGRIND will
|
||||
* still catch it and complain. The masking trick does make the hash
|
||||
* noticably faster for short strings (like English words).
|
||||
* noticeably faster for short strings (like English words).
|
||||
*/
|
||||
#ifndef NO_MASKING_TRICK
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ typedef struct {
|
||||
size_t size; /* bytes allocated */
|
||||
} strbuffer_t;
|
||||
|
||||
int strbuffer_init(strbuffer_t *strbuff) JANSSON_ATTRS(warn_unused_result);
|
||||
int strbuffer_init(strbuffer_t *strbuff) JANSSON_ATTRS((warn_unused_result));
|
||||
void strbuffer_close(strbuffer_t *strbuff);
|
||||
|
||||
void strbuffer_clear(strbuffer_t *strbuff);
|
||||
|
||||
62
src/value.c
62
src/value.c
@@ -37,7 +37,7 @@ static JSON_INLINE int isnan(double x) { return x != x; }
|
||||
static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
|
||||
#endif
|
||||
|
||||
json_t *do_deep_copy(const json_t *, hashtable_t *);
|
||||
json_t *do_deep_copy(const json_t *json, hashtable_t *parents);
|
||||
|
||||
static JSON_INLINE void json_init(json_t *json, json_type type)
|
||||
{
|
||||
@@ -214,6 +214,58 @@ int json_object_update_missing(json_t *object, json_t *other)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_object_update_recursive(json_t *object, json_t *other, hashtable_t *parents)
|
||||
{
|
||||
const char *key;
|
||||
json_t *value;
|
||||
char loop_key[LOOP_KEY_LEN];
|
||||
int res = 0;
|
||||
|
||||
if(!json_is_object(object) || !json_is_object(other))
|
||||
return -1;
|
||||
|
||||
if(jsonp_loop_check(parents, other, loop_key, sizeof(loop_key)))
|
||||
return -1;
|
||||
|
||||
json_object_foreach(other, key, value) {
|
||||
json_t *v = json_object_get(object, key);
|
||||
|
||||
if(json_is_object(v) && json_is_object(value))
|
||||
{
|
||||
if(do_object_update_recursive(v, value, parents))
|
||||
{
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(json_object_set_nocheck(object, key, value))
|
||||
{
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hashtable_del(parents, loop_key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int json_object_update_recursive(json_t *object, json_t *other)
|
||||
{
|
||||
int res;
|
||||
hashtable_t parents_set;
|
||||
|
||||
if (hashtable_init(&parents_set))
|
||||
return -1;
|
||||
res = do_object_update_recursive(object, other, &parents_set);
|
||||
hashtable_close(&parents_set);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void *json_object_iter(json_t *json)
|
||||
{
|
||||
json_object_t *object;
|
||||
@@ -329,7 +381,7 @@ static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents)
|
||||
|
||||
result = json_object();
|
||||
if(!result)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
/* Cannot use json_object_foreach because object has to be cast
|
||||
non-const */
|
||||
@@ -348,6 +400,8 @@ static json_t *json_object_deep_copy(const json_t *object, hashtable_t *parents)
|
||||
}
|
||||
iter = json_object_iter_next((json_t *)object, iter);
|
||||
}
|
||||
|
||||
out:
|
||||
hashtable_del(parents, loop_key);
|
||||
|
||||
return result;
|
||||
@@ -648,7 +702,7 @@ static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents)
|
||||
|
||||
result = json_array();
|
||||
if(!result)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
for(i = 0; i < json_array_size(array); i++)
|
||||
{
|
||||
@@ -659,6 +713,8 @@ static json_t *json_array_deep_copy(const json_t *array, hashtable_t *parents)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
hashtable_del(parents, loop_key);
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user