mirror of
https://github.com/json-c/json-c.git
synced 2026-04-12 00:39:06 +08:00
clang-format the files
This commit is contained in:
66
arraylist.c
66
arraylist.c
@@ -36,37 +36,38 @@
|
|||||||
|
|
||||||
#include "arraylist.h"
|
#include "arraylist.h"
|
||||||
|
|
||||||
struct array_list*
|
struct array_list *array_list_new(array_list_free_fn *free_fn)
|
||||||
array_list_new(array_list_free_fn *free_fn)
|
|
||||||
{
|
{
|
||||||
struct array_list *arr;
|
struct array_list *arr;
|
||||||
|
|
||||||
arr = (struct array_list *)calloc(1, sizeof(struct array_list));
|
arr = (struct array_list *)calloc(1, sizeof(struct array_list));
|
||||||
if(!arr) return NULL;
|
if (!arr)
|
||||||
|
return NULL;
|
||||||
arr->size = ARRAY_LIST_DEFAULT_SIZE;
|
arr->size = ARRAY_LIST_DEFAULT_SIZE;
|
||||||
arr->length = 0;
|
arr->length = 0;
|
||||||
arr->free_fn = free_fn;
|
arr->free_fn = free_fn;
|
||||||
if(!(arr->array = (void**)calloc(arr->size, sizeof(void*)))) {
|
if (!(arr->array = (void **)calloc(arr->size, sizeof(void *))))
|
||||||
|
{
|
||||||
free(arr);
|
free(arr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void
|
extern void array_list_free(struct array_list *arr)
|
||||||
array_list_free(struct array_list *arr)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
for (i = 0; i < arr->length; i++)
|
for (i = 0; i < arr->length; i++)
|
||||||
if(arr->array[i]) arr->free_fn(arr->array[i]);
|
if (arr->array[i])
|
||||||
|
arr->free_fn(arr->array[i]);
|
||||||
free(arr->array);
|
free(arr->array);
|
||||||
free(arr);
|
free(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void *array_list_get_idx(struct array_list *arr, size_t i)
|
||||||
array_list_get_idx(struct array_list *arr, size_t i)
|
|
||||||
{
|
{
|
||||||
if(i >= arr->length) return NULL;
|
if (i >= arr->length)
|
||||||
|
return NULL;
|
||||||
return arr->array[i];
|
return arr->array[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +76,8 @@ static int array_list_expand_internal(struct array_list *arr, size_t max)
|
|||||||
void *t;
|
void *t;
|
||||||
size_t new_size;
|
size_t new_size;
|
||||||
|
|
||||||
if(max < arr->size) return 0;
|
if (max < arr->size)
|
||||||
|
return 0;
|
||||||
/* Avoid undefined behaviour on size_t overflow */
|
/* Avoid undefined behaviour on size_t overflow */
|
||||||
if (arr->size >= SIZE_T_MAX / 2)
|
if (arr->size >= SIZE_T_MAX / 2)
|
||||||
new_size = max;
|
new_size = max;
|
||||||
@@ -85,34 +87,36 @@ static int array_list_expand_internal(struct array_list *arr, size_t max)
|
|||||||
if (new_size < max)
|
if (new_size < max)
|
||||||
new_size = max;
|
new_size = max;
|
||||||
}
|
}
|
||||||
if (new_size > (~((size_t)0)) / sizeof(void*)) return -1;
|
if (new_size > (~((size_t)0)) / sizeof(void *))
|
||||||
if (!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
|
return -1;
|
||||||
|
if (!(t = realloc(arr->array, new_size * sizeof(void *))))
|
||||||
|
return -1;
|
||||||
arr->array = (void **)t;
|
arr->array = (void **)t;
|
||||||
(void)memset(arr->array + arr->size, 0, (new_size - arr->size) * sizeof(void *));
|
(void)memset(arr->array + arr->size, 0, (new_size - arr->size) * sizeof(void *));
|
||||||
arr->size = new_size;
|
arr->size = new_size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int array_list_put_idx(struct array_list *arr, size_t idx, void *data)
|
||||||
array_list_put_idx(struct array_list *arr, size_t idx, void *data)
|
|
||||||
{
|
{
|
||||||
if (idx > SIZE_T_MAX - 1 ) return -1;
|
if (idx > SIZE_T_MAX - 1)
|
||||||
if(array_list_expand_internal(arr, idx+1)) return -1;
|
return -1;
|
||||||
|
if (array_list_expand_internal(arr, idx + 1))
|
||||||
|
return -1;
|
||||||
if (idx < arr->length && arr->array[idx])
|
if (idx < arr->length && arr->array[idx])
|
||||||
arr->free_fn(arr->array[idx]);
|
arr->free_fn(arr->array[idx]);
|
||||||
arr->array[idx] = data;
|
arr->array[idx] = data;
|
||||||
if(arr->length <= idx) arr->length = idx + 1;
|
if (arr->length <= idx)
|
||||||
|
arr->length = idx + 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int array_list_add(struct array_list *arr, void *data)
|
||||||
array_list_add(struct array_list *arr, void *data)
|
|
||||||
{
|
{
|
||||||
return array_list_put_idx(arr, arr->length, data);
|
return array_list_put_idx(arr, arr->length, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *))
|
||||||
array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *))
|
|
||||||
{
|
{
|
||||||
qsort(arr->array, arr->length, sizeof(arr->array[0]), compar);
|
qsort(arr->array, arr->length, sizeof(arr->array[0]), compar);
|
||||||
}
|
}
|
||||||
@@ -120,25 +124,25 @@ array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *)
|
|||||||
void *array_list_bsearch(const void **key, struct array_list *arr,
|
void *array_list_bsearch(const void **key, struct array_list *arr,
|
||||||
int (*compar)(const void *, const void *))
|
int (*compar)(const void *, const void *))
|
||||||
{
|
{
|
||||||
return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]),
|
return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), compar);
|
||||||
compar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t array_list_length(struct array_list *arr)
|
||||||
array_list_length(struct array_list *arr)
|
|
||||||
{
|
{
|
||||||
return arr->length;
|
return arr->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int array_list_del_idx(struct array_list *arr, size_t idx, size_t count)
|
||||||
array_list_del_idx( struct array_list *arr, size_t idx, size_t count )
|
|
||||||
{
|
{
|
||||||
size_t i, stop;
|
size_t i, stop;
|
||||||
|
|
||||||
stop = idx + count;
|
stop = idx + count;
|
||||||
if ( idx >= arr->length || stop > arr->length ) return -1;
|
if (idx >= arr->length || stop > arr->length)
|
||||||
for ( i = idx; i < stop; ++i ) {
|
return -1;
|
||||||
if ( arr->array[i] ) arr->free_fn( arr->array[i] );
|
for (i = idx; i < stop; ++i)
|
||||||
|
{
|
||||||
|
if (arr->array[i])
|
||||||
|
arr->free_fn(arr->array[i]);
|
||||||
}
|
}
|
||||||
memmove(arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void *));
|
memmove(arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void *));
|
||||||
arr->length -= count;
|
arr->length -= count;
|
||||||
|
|||||||
27
arraylist.h
27
arraylist.h
@@ -35,33 +35,24 @@ struct array_list
|
|||||||
};
|
};
|
||||||
typedef struct array_list array_list;
|
typedef struct array_list array_list;
|
||||||
|
|
||||||
extern struct array_list*
|
extern struct array_list *array_list_new(array_list_free_fn *free_fn);
|
||||||
array_list_new(array_list_free_fn *free_fn);
|
|
||||||
|
|
||||||
extern void
|
extern void array_list_free(struct array_list *al);
|
||||||
array_list_free(struct array_list *al);
|
|
||||||
|
|
||||||
extern void*
|
extern void *array_list_get_idx(struct array_list *al, size_t i);
|
||||||
array_list_get_idx(struct array_list *al, size_t i);
|
|
||||||
|
|
||||||
extern int
|
extern int array_list_put_idx(struct array_list *al, size_t i, void *data);
|
||||||
array_list_put_idx(struct array_list *al, size_t i, void *data);
|
|
||||||
|
|
||||||
extern int
|
extern int array_list_add(struct array_list *al, void *data);
|
||||||
array_list_add(struct array_list *al, void *data);
|
|
||||||
|
|
||||||
extern size_t
|
extern size_t array_list_length(struct array_list *al);
|
||||||
array_list_length(struct array_list *al);
|
|
||||||
|
|
||||||
extern void
|
extern void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *));
|
||||||
array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *));
|
|
||||||
|
|
||||||
extern void*
|
extern void *array_list_bsearch(const void **key, struct array_list *arr,
|
||||||
array_list_bsearch(const void **key, struct array_list *arr,
|
|
||||||
int (*compar)(const void *, const void *));
|
int (*compar)(const void *, const void *));
|
||||||
|
|
||||||
extern int
|
extern int array_list_del_idx(struct array_list *arr, size_t idx, size_t count);
|
||||||
array_list_del_idx(struct array_list *arr, size_t idx, size_t count);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
33
debug.c
33
debug.c
@@ -11,10 +11,10 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#if HAVE_SYSLOG_H
|
#if HAVE_SYSLOG_H
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
@@ -33,8 +33,14 @@
|
|||||||
static int _syslog = 0;
|
static int _syslog = 0;
|
||||||
static int _debug = 0;
|
static int _debug = 0;
|
||||||
|
|
||||||
void mc_set_debug(int debug) { _debug = debug; }
|
void mc_set_debug(int debug)
|
||||||
int mc_get_debug(void) { return _debug; }
|
{
|
||||||
|
_debug = debug;
|
||||||
|
}
|
||||||
|
int mc_get_debug(void)
|
||||||
|
{
|
||||||
|
return _debug;
|
||||||
|
}
|
||||||
|
|
||||||
extern void mc_set_syslog(int syslog)
|
extern void mc_set_syslog(int syslog)
|
||||||
{
|
{
|
||||||
@@ -44,12 +50,15 @@ extern void mc_set_syslog(int syslog)
|
|||||||
void mc_debug(const char *msg, ...)
|
void mc_debug(const char *msg, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
if(_debug) {
|
if (_debug)
|
||||||
|
{
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
#if HAVE_VSYSLOG
|
#if HAVE_VSYSLOG
|
||||||
if(_syslog) {
|
if (_syslog)
|
||||||
|
{
|
||||||
vsyslog(LOG_DEBUG, msg, ap);
|
vsyslog(LOG_DEBUG, msg, ap);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
vprintf(msg, ap);
|
vprintf(msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@@ -61,9 +70,11 @@ void mc_error(const char *msg, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
#if HAVE_VSYSLOG
|
#if HAVE_VSYSLOG
|
||||||
if(_syslog) {
|
if (_syslog)
|
||||||
|
{
|
||||||
vsyslog(LOG_ERR, msg, ap);
|
vsyslog(LOG_ERR, msg, ap);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
vfprintf(stderr, msg, ap);
|
vfprintf(stderr, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@@ -74,9 +85,11 @@ void mc_info(const char *msg, ...)
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
#if HAVE_VSYSLOG
|
#if HAVE_VSYSLOG
|
||||||
if(_syslog) {
|
if (_syslog)
|
||||||
|
{
|
||||||
vsyslog(LOG_INFO, msg, ap);
|
vsyslog(LOG_INFO, msg, ap);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
vfprintf(stderr, msg, ap);
|
vfprintf(stderr, msg, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|||||||
31
debug.h
31
debug.h
@@ -46,13 +46,20 @@ JSON_EXPORT void mc_info(const char *msg, ...);
|
|||||||
|
|
||||||
#ifndef PARSER_BROKEN_FIXED
|
#ifndef PARSER_BROKEN_FIXED
|
||||||
|
|
||||||
#define JASSERT(cond) do {} while(0)
|
#define JASSERT(cond) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define JASSERT(cond) do { \
|
#define JASSERT(cond) \
|
||||||
if (!(cond)) { \
|
do \
|
||||||
mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \
|
{ \
|
||||||
|
if (!(cond)) \
|
||||||
|
{ \
|
||||||
|
mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
*(int *)0 = 1; \
|
*(int *)0 = 1; \
|
||||||
abort(); \
|
abort(); \
|
||||||
} \
|
} \
|
||||||
@@ -69,11 +76,19 @@ JSON_EXPORT void mc_info(const char *msg, ...);
|
|||||||
#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
|
#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
|
||||||
#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
|
#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
|
#define MC_SET_DEBUG(x) \
|
||||||
|
if (0) \
|
||||||
|
mc_set_debug(x)
|
||||||
#define MC_GET_DEBUG() (0)
|
#define MC_GET_DEBUG() (0)
|
||||||
#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
|
#define MC_SET_SYSLOG(x) \
|
||||||
#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
|
if (0) \
|
||||||
#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
|
mc_set_syslog(x)
|
||||||
|
#define MC_DEBUG(x, ...) \
|
||||||
|
if (0) \
|
||||||
|
mc_debug(x, ##__VA_ARGS__)
|
||||||
|
#define MC_INFO(x, ...) \
|
||||||
|
if (0) \
|
||||||
|
mc_info(x, ##__VA_ARGS__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
#include <json.h>
|
#include <json.h>
|
||||||
|
|
||||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||||
|
{
|
||||||
const char *data1 = reinterpret_cast<const char *>(data);
|
const char *data1 = reinterpret_cast<const char *>(data);
|
||||||
json_tokener *tok = json_tokener_new();
|
json_tokener *tok = json_tokener_new();
|
||||||
json_object *obj = json_tokener_parse_ex(tok, data1, size);
|
json_object *obj = json_tokener_parse_ex(tok, data1, size);
|
||||||
|
|||||||
10
json.h
10
json.h
@@ -21,15 +21,15 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "linkhash.h"
|
|
||||||
#include "arraylist.h"
|
#include "arraylist.h"
|
||||||
#include "json_util.h"
|
#include "debug.h"
|
||||||
|
#include "json_c_version.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
|
#include "json_object_iterator.h"
|
||||||
#include "json_pointer.h"
|
#include "json_pointer.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
#include "json_object_iterator.h"
|
#include "json_util.h"
|
||||||
#include "json_c_version.h"
|
#include "linkhash.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,4 +17,3 @@ int json_c_version_num(void)
|
|||||||
{
|
{
|
||||||
return JSON_C_VERSION_NUM;
|
return JSON_C_VERSION_NUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,8 @@
|
|||||||
#define JSON_C_MAJOR_VERSION 0
|
#define JSON_C_MAJOR_VERSION 0
|
||||||
#define JSON_C_MINOR_VERSION 13
|
#define JSON_C_MINOR_VERSION 13
|
||||||
#define JSON_C_MICRO_VERSION 99
|
#define JSON_C_MICRO_VERSION 99
|
||||||
#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
|
#define JSON_C_VERSION_NUM \
|
||||||
(JSON_C_MINOR_VERSION << 8) | \
|
((JSON_C_MAJOR_VERSION << 16) | (JSON_C_MINOR_VERSION << 8) | JSON_C_MICRO_VERSION)
|
||||||
JSON_C_MICRO_VERSION)
|
|
||||||
#define JSON_C_VERSION "0.13.99"
|
#define JSON_C_VERSION "0.13.99"
|
||||||
|
|
||||||
#ifndef JSON_EXPORT
|
#ifndef JSON_EXPORT
|
||||||
|
|||||||
570
json_object.c
570
json_object.c
File diff suppressed because it is too large
Load Diff
@@ -41,9 +41,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "printbuf.h"
|
#include "printbuf.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -163,14 +163,13 @@ typedef void (json_object_delete_fn)(struct json_object *jso, void *userdata);
|
|||||||
/**
|
/**
|
||||||
* Type of a custom serialization function. See json_object_set_serializer.
|
* Type of a custom serialization function. See json_object_set_serializer.
|
||||||
*/
|
*/
|
||||||
typedef int (json_object_to_json_string_fn)(struct json_object *jso,
|
typedef int(json_object_to_json_string_fn)(struct json_object *jso, struct printbuf *pb, int level,
|
||||||
struct printbuf *pb,
|
|
||||||
int level,
|
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
/* supported object types */
|
/* supported object types */
|
||||||
|
|
||||||
typedef enum json_type {
|
typedef enum json_type
|
||||||
|
{
|
||||||
/* If you change this, be sure to update json_type_to_name() too */
|
/* If you change this, be sure to update json_type_to_name() too */
|
||||||
json_type_null,
|
json_type_null,
|
||||||
json_type_boolean,
|
json_type_boolean,
|
||||||
@@ -232,7 +231,6 @@ JSON_EXPORT int json_object_is_type(const struct json_object *obj, enum json_typ
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj);
|
JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj);
|
||||||
|
|
||||||
|
|
||||||
/** Stringify object to json format.
|
/** Stringify object to json format.
|
||||||
* Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
|
* Equivalent to json_object_to_json_string_ext(obj, JSON_C_TO_STRING_SPACED)
|
||||||
* The pointer you get is an internal of your json object. You don't
|
* The pointer you get is an internal of your json object. You don't
|
||||||
@@ -250,8 +248,7 @@ JSON_EXPORT const char* json_object_to_json_string(struct json_object *obj);
|
|||||||
* @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants
|
* @param flags formatting options, see JSON_C_TO_STRING_PRETTY and other constants
|
||||||
* @returns a string in JSON format
|
* @returns a string in JSON format
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT const char* json_object_to_json_string_ext(struct json_object *obj, int
|
JSON_EXPORT const char *json_object_to_json_string_ext(struct json_object *obj, int flags);
|
||||||
flags);
|
|
||||||
|
|
||||||
/** Stringify object to json format
|
/** Stringify object to json format
|
||||||
* @see json_object_to_json_string() for details on how to free string.
|
* @see json_object_to_json_string() for details on how to free string.
|
||||||
@@ -260,8 +257,8 @@ flags);
|
|||||||
* @param length a pointer where, if not NULL, the length (without null) is stored
|
* @param length a pointer where, if not NULL, the length (without null) is stored
|
||||||
* @returns a string in JSON format and the length if not NULL
|
* @returns a string in JSON format and the length if not NULL
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT const char* json_object_to_json_string_length(struct json_object *obj, int
|
JSON_EXPORT const char *json_object_to_json_string_length(struct json_object *obj, int flags,
|
||||||
flags, size_t *length);
|
size_t *length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the userdata set by json_object_set_userdata() or
|
* Returns the userdata set by json_object_set_userdata() or
|
||||||
@@ -331,8 +328,7 @@ JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata,
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT void json_object_set_serializer(json_object *jso,
|
JSON_EXPORT void json_object_set_serializer(json_object *jso,
|
||||||
json_object_to_json_string_fn *to_string_func,
|
json_object_to_json_string_fn *to_string_func,
|
||||||
void *userdata,
|
void *userdata, json_object_delete_fn *user_delete);
|
||||||
json_object_delete_fn *user_delete);
|
|
||||||
|
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
/*
|
/*
|
||||||
@@ -369,7 +365,6 @@ JSON_EXPORT json_object_to_json_string_fn json_object_userdata_to_json_string;
|
|||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* object type methods */
|
/* object type methods */
|
||||||
|
|
||||||
/** Create a new empty object with a reference count of 1. The caller of
|
/** Create a new empty object with a reference count of 1. The caller of
|
||||||
@@ -435,10 +430,8 @@ JSON_EXPORT int json_object_object_add(struct json_object* obj, const char *key,
|
|||||||
* @param opts process-modifying options. To specify multiple options, use
|
* @param opts process-modifying options. To specify multiple options, use
|
||||||
* arithmetic or (OPT1|OPT2)
|
* arithmetic or (OPT1|OPT2)
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_object_add_ex(struct json_object* obj,
|
JSON_EXPORT int json_object_object_add_ex(struct json_object *obj, const char *const key,
|
||||||
const char *const key,
|
struct json_object *const val, const unsigned opts);
|
||||||
struct json_object *const val,
|
|
||||||
const unsigned opts);
|
|
||||||
|
|
||||||
/** Get the json_object associate with a given object field.
|
/** Get the json_object associate with a given object field.
|
||||||
* Deprecated/discouraged: used json_object_object_get_ex instead.
|
* Deprecated/discouraged: used json_object_object_get_ex instead.
|
||||||
@@ -482,8 +475,7 @@ JSON_EXPORT struct json_object* json_object_object_get(const struct json_object*
|
|||||||
* It is safe to pass a NULL value.
|
* It is safe to pass a NULL value.
|
||||||
* @returns whether or not the key exists
|
* @returns whether or not the key exists
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object* obj,
|
JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, const char *key,
|
||||||
const char *key,
|
|
||||||
struct json_object **value);
|
struct json_object **value);
|
||||||
|
|
||||||
/** Delete the given json_object field
|
/** Delete the given json_object field
|
||||||
@@ -515,12 +507,17 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key
|
|||||||
#define json_object_object_foreach(obj, key, val) \
|
#define json_object_object_foreach(obj, key, val) \
|
||||||
char *key = NULL; \
|
char *key = NULL; \
|
||||||
struct json_object *val __attribute__((__unused__)) = NULL; \
|
struct json_object *val __attribute__((__unused__)) = NULL; \
|
||||||
for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
|
for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \
|
||||||
({ if(entry ## key) { \
|
*entry_next##key = NULL; \
|
||||||
|
({ \
|
||||||
|
if (entry##key) \
|
||||||
|
{ \
|
||||||
key = (char *)lh_entry_k(entry##key); \
|
key = (char *)lh_entry_k(entry##key); \
|
||||||
val = (struct json_object *)lh_entry_v(entry##key); \
|
val = (struct json_object *)lh_entry_v(entry##key); \
|
||||||
entry_next##key = entry##key->next; \
|
entry_next##key = entry##key->next; \
|
||||||
} ; entry ## key; }); \
|
}; \
|
||||||
|
entry##key; \
|
||||||
|
}); \
|
||||||
entry##key = entry_next##key)
|
entry##key = entry_next##key)
|
||||||
|
|
||||||
#else /* ANSI C or MSC */
|
#else /* ANSI C or MSC */
|
||||||
@@ -531,11 +528,10 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key
|
|||||||
struct lh_entry *entry##key; \
|
struct lh_entry *entry##key; \
|
||||||
struct lh_entry *entry_next##key = NULL; \
|
struct lh_entry *entry_next##key = NULL; \
|
||||||
for (entry##key = json_object_get_object(obj)->head; \
|
for (entry##key = json_object_get_object(obj)->head; \
|
||||||
(entry ## key ? ( \
|
(entry##key ? (key = (char *)lh_entry_k(entry##key), \
|
||||||
key = (char*)lh_entry_k(entry ## key), \
|
|
||||||
val = (struct json_object *)lh_entry_v(entry##key), \
|
val = (struct json_object *)lh_entry_v(entry##key), \
|
||||||
entry_next ## key = entry ## key->next, \
|
entry_next##key = entry##key->next, entry##key) \
|
||||||
entry ## key) : 0); \
|
: 0); \
|
||||||
entry##key = entry_next##key)
|
entry##key = entry_next##key)
|
||||||
|
|
||||||
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */
|
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */
|
||||||
@@ -546,7 +542,9 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key
|
|||||||
*/
|
*/
|
||||||
#define json_object_object_foreachC(obj, iter) \
|
#define json_object_object_foreachC(obj, iter) \
|
||||||
for (iter.entry = json_object_get_object(obj)->head; \
|
for (iter.entry = json_object_get_object(obj)->head; \
|
||||||
(iter.entry ? (iter.key = (char*)lh_entry_k(iter.entry), iter.val = (struct json_object*)lh_entry_v(iter.entry), iter.entry) : 0); \
|
(iter.entry ? (iter.key = (char *)lh_entry_k(iter.entry), \
|
||||||
|
iter.val = (struct json_object *)lh_entry_v(iter.entry), iter.entry) \
|
||||||
|
: 0); \
|
||||||
iter.entry = iter.entry->next)
|
iter.entry = iter.entry->next)
|
||||||
|
|
||||||
/* Array type methods */
|
/* Array type methods */
|
||||||
@@ -576,7 +574,8 @@ JSON_EXPORT size_t json_object_array_length(const struct json_object *obj);
|
|||||||
* @param jso the json_object instance
|
* @param jso the json_object instance
|
||||||
* @param sort_fn a sorting function
|
* @param sort_fn a sorting function
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *));
|
JSON_EXPORT void json_object_array_sort(struct json_object *jso,
|
||||||
|
int (*sort_fn)(const void *, const void *));
|
||||||
|
|
||||||
/** Binary search a sorted array for a specified key object.
|
/** Binary search a sorted array for a specified key object.
|
||||||
*
|
*
|
||||||
@@ -592,9 +591,8 @@ JSON_EXPORT void json_object_array_sort(struct json_object *jso, int(*sort_fn)(c
|
|||||||
*
|
*
|
||||||
* @return the wanted json_object instance
|
* @return the wanted json_object instance
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object* json_object_array_bsearch(
|
JSON_EXPORT struct json_object *
|
||||||
const struct json_object *key,
|
json_object_array_bsearch(const struct json_object *key, const struct json_object *jso,
|
||||||
const struct json_object *jso,
|
|
||||||
int (*sort_fn)(const void *, const void *));
|
int (*sort_fn)(const void *, const void *));
|
||||||
|
|
||||||
/** Add an element to the end of a json_object of type json_type_array
|
/** Add an element to the end of a json_object of type json_type_array
|
||||||
@@ -606,8 +604,7 @@ JSON_EXPORT struct json_object* json_object_array_bsearch(
|
|||||||
* @param obj the json_object instance
|
* @param obj the json_object instance
|
||||||
* @param val the json_object to be added
|
* @param val the json_object to be added
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_array_add(struct json_object *obj,
|
JSON_EXPORT int json_object_array_add(struct json_object *obj, struct json_object *val);
|
||||||
struct json_object *val);
|
|
||||||
|
|
||||||
/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array)
|
/** Insert or replace an element at a specified index in an array (a json_object of type json_type_array)
|
||||||
*
|
*
|
||||||
@@ -669,7 +666,6 @@ JSON_EXPORT struct json_object* json_object_new_boolean(json_bool b);
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj);
|
JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj);
|
||||||
|
|
||||||
|
|
||||||
/** Set the json_bool value of a json_object
|
/** Set the json_bool value of a json_object
|
||||||
*
|
*
|
||||||
* The type of obj is checked to be a json_type_boolean and 0 is returned
|
* The type of obj is checked to be a json_type_boolean and 0 is returned
|
||||||
@@ -682,7 +678,6 @@ JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj);
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_set_boolean(struct json_object *obj, json_bool new_value);
|
JSON_EXPORT int json_object_set_boolean(struct json_object *obj, json_bool new_value);
|
||||||
|
|
||||||
|
|
||||||
/* int type methods */
|
/* int type methods */
|
||||||
|
|
||||||
/** Create a new empty json_object of type json_type_int
|
/** Create a new empty json_object of type json_type_int
|
||||||
@@ -693,21 +688,18 @@ JSON_EXPORT int json_object_set_boolean(struct json_object *obj,json_bool new_va
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object *json_object_new_int(int32_t i);
|
JSON_EXPORT struct json_object *json_object_new_int(int32_t i);
|
||||||
|
|
||||||
|
|
||||||
/** Create a new empty json_object of type json_type_int
|
/** Create a new empty json_object of type json_type_int
|
||||||
* @param i the integer
|
* @param i the integer
|
||||||
* @returns a json_object of type json_type_int
|
* @returns a json_object of type json_type_int
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object *json_object_new_int64(int64_t i);
|
JSON_EXPORT struct json_object *json_object_new_int64(int64_t i);
|
||||||
|
|
||||||
|
|
||||||
/** Create a new empty json_object of type json_type_uint
|
/** Create a new empty json_object of type json_type_uint
|
||||||
* @param i the integer
|
* @param i the integer
|
||||||
* @returns a json_object of type json_type_uint
|
* @returns a json_object of type json_type_uint
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object *json_object_new_uint64(uint64_t i);
|
JSON_EXPORT struct json_object *json_object_new_uint64(uint64_t i);
|
||||||
|
|
||||||
|
|
||||||
/** Get the int value of a json_object
|
/** Get the int value of a json_object
|
||||||
*
|
*
|
||||||
* The type is coerced to a int if the passed object is not a int.
|
* The type is coerced to a int if the passed object is not a int.
|
||||||
@@ -858,9 +850,8 @@ JSON_EXPORT struct json_object* json_object_new_double_s(double d, const char *d
|
|||||||
*
|
*
|
||||||
* @return -1 on errors, 0 on success.
|
* @return -1 on errors, 0 on success.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format, int global_or_thread);
|
JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format,
|
||||||
|
int global_or_thread);
|
||||||
|
|
||||||
|
|
||||||
/** Serialize a json_object of type json_type_double to a string.
|
/** Serialize a json_object of type json_type_double to a string.
|
||||||
*
|
*
|
||||||
@@ -881,10 +872,8 @@ JSON_EXPORT int json_c_set_serialization_double_format(const char *double_format
|
|||||||
* @param level Ignored.
|
* @param level Ignored.
|
||||||
* @param flags Ignored.
|
* @param flags Ignored.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_double_to_json_string(struct json_object* jso,
|
JSON_EXPORT int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb,
|
||||||
struct printbuf *pb,
|
int level, int flags);
|
||||||
int level,
|
|
||||||
int flags);
|
|
||||||
|
|
||||||
/** Get the double floating point value of a json_object
|
/** Get the double floating point value of a json_object
|
||||||
*
|
*
|
||||||
@@ -911,7 +900,6 @@ JSON_EXPORT int json_object_double_to_json_string(struct json_object* jso,
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT double json_object_get_double(const struct json_object *obj);
|
JSON_EXPORT double json_object_get_double(const struct json_object *obj);
|
||||||
|
|
||||||
|
|
||||||
/** Set the double value of a json_object
|
/** Set the double value of a json_object
|
||||||
*
|
*
|
||||||
* The type of obj is checked to be a json_type_double and 0 is returned
|
* The type of obj is checked to be a json_type_double and 0 is returned
|
||||||
@@ -927,8 +915,6 @@ JSON_EXPORT double json_object_get_double(const struct json_object *obj);
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_set_double(struct json_object *obj, double new_value);
|
JSON_EXPORT int json_object_set_double(struct json_object *obj, double new_value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* string type methods */
|
/* string type methods */
|
||||||
|
|
||||||
/** Create a new empty json_object of type json_type_string
|
/** Create a new empty json_object of type json_type_string
|
||||||
@@ -981,7 +967,6 @@ JSON_EXPORT const char* json_object_get_string(struct json_object *obj);
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_get_string_len(const struct json_object *obj);
|
JSON_EXPORT int json_object_get_string_len(const struct json_object *obj);
|
||||||
|
|
||||||
|
|
||||||
/** Set the string value of a json_object with zero terminated strings
|
/** Set the string value of a json_object with zero terminated strings
|
||||||
* equivalent to json_object_set_string_len (obj, new_value, strlen(new_value))
|
* equivalent to json_object_set_string_len (obj, new_value, strlen(new_value))
|
||||||
* @returns 1 if value is set correctly, 0 otherwise
|
* @returns 1 if value is set correctly, 0 otherwise
|
||||||
@@ -1024,8 +1009,7 @@ JSON_EXPORT struct json_object* json_object_new_null();
|
|||||||
* @param obj2 the second json_object instance
|
* @param obj2 the second json_object instance
|
||||||
* @returns whether both objects are equal or not
|
* @returns whether both objects are equal or not
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_object_equal(struct json_object *obj1,
|
JSON_EXPORT int json_object_equal(struct json_object *obj1, struct json_object *obj2);
|
||||||
struct json_object *obj2);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a shallow copy of src into *dst as part of an overall json_object_deep_copy().
|
* Perform a shallow copy of src into *dst as part of an overall json_object_deep_copy().
|
||||||
@@ -1041,7 +1025,8 @@ JSON_EXPORT int json_object_equal(struct json_object *obj1,
|
|||||||
*
|
*
|
||||||
* @return On success 1 or 2, -1 on errors
|
* @return On success 1 or 2, -1 on errors
|
||||||
*/
|
*/
|
||||||
typedef int (json_c_shallow_copy_fn)(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst);
|
typedef int(json_c_shallow_copy_fn)(json_object *src, json_object *parent, const char *key,
|
||||||
|
size_t index, json_object **dst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default shallow copy implementation for use with json_object_deep_copy().
|
* The default shallow copy implementation for use with json_object_deep_copy().
|
||||||
@@ -1076,7 +1061,8 @@ JSON_EXPORT json_c_shallow_copy_fn json_c_shallow_copy_default;
|
|||||||
* or if the destination pointer is non-NULL
|
* or if the destination pointer is non-NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst, json_c_shallow_copy_fn *shallow_copy);
|
JSON_EXPORT int json_object_deep_copy(struct json_object *src, struct json_object **dst,
|
||||||
|
json_c_shallow_copy_fn *shallow_copy);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ static const void* kObjectEndIterValue = NULL;
|
|||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
struct json_object_iterator
|
struct json_object_iterator json_object_iter_begin(struct json_object *obj)
|
||||||
json_object_iter_begin(struct json_object* obj)
|
|
||||||
{
|
{
|
||||||
struct json_object_iterator iter;
|
struct json_object_iterator iter;
|
||||||
struct lh_table *pTable;
|
struct lh_table *pTable;
|
||||||
@@ -78,8 +77,7 @@ json_object_iter_begin(struct json_object* obj)
|
|||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
struct json_object_iterator
|
struct json_object_iterator json_object_iter_end(const struct json_object *obj)
|
||||||
json_object_iter_end(const struct json_object* obj)
|
|
||||||
{
|
{
|
||||||
struct json_object_iterator iter;
|
struct json_object_iterator iter;
|
||||||
|
|
||||||
@@ -94,8 +92,7 @@ json_object_iter_end(const struct json_object* obj)
|
|||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
void
|
void json_object_iter_next(struct json_object_iterator *iter)
|
||||||
json_object_iter_next(struct json_object_iterator* iter)
|
|
||||||
{
|
{
|
||||||
JASSERT(NULL != iter);
|
JASSERT(NULL != iter);
|
||||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
@@ -103,12 +100,10 @@ json_object_iter_next(struct json_object_iterator* iter)
|
|||||||
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
|
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
const char*
|
const char *json_object_iter_peek_name(const struct json_object_iterator *iter)
|
||||||
json_object_iter_peek_name(const struct json_object_iterator* iter)
|
|
||||||
{
|
{
|
||||||
JASSERT(NULL != iter);
|
JASSERT(NULL != iter);
|
||||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
@@ -116,12 +111,10 @@ json_object_iter_peek_name(const struct json_object_iterator* iter)
|
|||||||
return (const char *)(((const struct lh_entry *)iter->opaque_)->k);
|
return (const char *)(((const struct lh_entry *)iter->opaque_)->k);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
struct json_object*
|
struct json_object *json_object_iter_peek_value(const struct json_object_iterator *iter)
|
||||||
json_object_iter_peek_value(const struct json_object_iterator* iter)
|
|
||||||
{
|
{
|
||||||
JASSERT(NULL != iter);
|
JASSERT(NULL != iter);
|
||||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||||
@@ -129,12 +122,10 @@ json_object_iter_peek_value(const struct json_object_iterator* iter)
|
|||||||
return (struct json_object *)lh_entry_v((const struct lh_entry *)iter->opaque_);
|
return (struct json_object *)lh_entry_v((const struct lh_entry *)iter->opaque_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
json_bool
|
json_bool json_object_iter_equal(const struct json_object_iterator *iter1,
|
||||||
json_object_iter_equal(const struct json_object_iterator* iter1,
|
|
||||||
const struct json_object_iterator *iter2)
|
const struct json_object_iterator *iter2)
|
||||||
{
|
{
|
||||||
JASSERT(NULL != iter1);
|
JASSERT(NULL != iter1);
|
||||||
@@ -143,12 +134,10 @@ json_object_iter_equal(const struct json_object_iterator* iter1,
|
|||||||
return (iter1->opaque_ == iter2->opaque_);
|
return (iter1->opaque_ == iter2->opaque_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ****************************************************************************
|
* ****************************************************************************
|
||||||
*/
|
*/
|
||||||
struct json_object_iterator
|
struct json_object_iterator json_object_iter_init_default(void)
|
||||||
json_object_iter_init_default(void)
|
|
||||||
{
|
{
|
||||||
struct json_object_iterator iter;
|
struct json_object_iterator iter;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef JSON_OBJECT_ITERATOR_H
|
#ifndef JSON_OBJECT_ITERATOR_H
|
||||||
#define JSON_OBJECT_ITERATOR_H
|
#define JSON_OBJECT_ITERATOR_H
|
||||||
|
|
||||||
@@ -47,17 +46,16 @@ struct json_object_iter_info_;
|
|||||||
* The opaque iterator that references a name/value pair within
|
* The opaque iterator that references a name/value pair within
|
||||||
* a JSON Object instance or the "end" iterator value.
|
* a JSON Object instance or the "end" iterator value.
|
||||||
*/
|
*/
|
||||||
struct json_object_iterator {
|
struct json_object_iterator
|
||||||
|
{
|
||||||
const void *opaque_;
|
const void *opaque_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* forward declaration of json-c's JSON value instance structure
|
* forward declaration of json-c's JSON value instance structure
|
||||||
*/
|
*/
|
||||||
struct json_object;
|
struct json_object;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an iterator structure to a "default" value that
|
* Initializes an iterator structure to a "default" value that
|
||||||
* is convenient for initializing an iterator variable to a
|
* is convenient for initializing an iterator variable to a
|
||||||
@@ -80,8 +78,7 @@ struct json_object;
|
|||||||
*
|
*
|
||||||
* @return json_object_iterator
|
* @return json_object_iterator
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object_iterator
|
JSON_EXPORT struct json_object_iterator json_object_iter_init_default(void);
|
||||||
json_object_iter_init_default(void);
|
|
||||||
|
|
||||||
/** Retrieves an iterator to the first pair of the JSON Object.
|
/** Retrieves an iterator to the first pair of the JSON Object.
|
||||||
*
|
*
|
||||||
@@ -114,8 +111,7 @@ json_object_iter_init_default(void);
|
|||||||
*
|
*
|
||||||
* @endcode
|
* @endcode
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object_iterator
|
JSON_EXPORT struct json_object_iterator json_object_iter_begin(struct json_object *obj);
|
||||||
json_object_iter_begin(struct json_object* obj);
|
|
||||||
|
|
||||||
/** Retrieves the iterator that represents the position beyond the
|
/** Retrieves the iterator that represents the position beyond the
|
||||||
* last pair of the given JSON Object instance.
|
* last pair of the given JSON Object instance.
|
||||||
@@ -145,8 +141,7 @@ json_object_iter_begin(struct json_object* obj);
|
|||||||
* (i.e., NOT the last pair, but "beyond the last
|
* (i.e., NOT the last pair, but "beyond the last
|
||||||
* pair" value)
|
* pair" value)
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object_iterator
|
JSON_EXPORT struct json_object_iterator json_object_iter_end(const struct json_object *obj);
|
||||||
json_object_iter_end(const struct json_object* obj);
|
|
||||||
|
|
||||||
/** Returns an iterator to the next pair, if any
|
/** Returns an iterator to the next pair, if any
|
||||||
*
|
*
|
||||||
@@ -163,9 +158,7 @@ json_object_iter_end(const struct json_object* obj);
|
|||||||
* of json_object_iter_end() for the same JSON Object
|
* of json_object_iter_end() for the same JSON Object
|
||||||
* instance.
|
* instance.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT void
|
JSON_EXPORT void json_object_iter_next(struct json_object_iterator *iter);
|
||||||
json_object_iter_next(struct json_object_iterator* iter);
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns a const pointer to the name of the pair referenced
|
/** Returns a const pointer to the name of the pair referenced
|
||||||
* by the given iterator.
|
* by the given iterator.
|
||||||
@@ -182,9 +175,7 @@ json_object_iter_next(struct json_object_iterator* iter);
|
|||||||
* deleted or modified, and MUST NOT be modified or
|
* deleted or modified, and MUST NOT be modified or
|
||||||
* freed by the user.
|
* freed by the user.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT const char*
|
JSON_EXPORT const char *json_object_iter_peek_name(const struct json_object_iterator *iter);
|
||||||
json_object_iter_peek_name(const struct json_object_iterator* iter);
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns a pointer to the json-c instance representing the
|
/** Returns a pointer to the json-c instance representing the
|
||||||
* value of the referenced name/value pair, without altering
|
* value of the referenced name/value pair, without altering
|
||||||
@@ -208,7 +199,6 @@ json_object_iter_peek_name(const struct json_object_iterator* iter);
|
|||||||
JSON_EXPORT struct json_object *
|
JSON_EXPORT struct json_object *
|
||||||
json_object_iter_peek_value(const struct json_object_iterator *iter);
|
json_object_iter_peek_value(const struct json_object_iterator *iter);
|
||||||
|
|
||||||
|
|
||||||
/** Tests two iterators for equality. Typically used to test
|
/** Tests two iterators for equality. Typically used to test
|
||||||
* for end of iteration by comparing an iterator to the
|
* for end of iteration by comparing an iterator to the
|
||||||
* corresponding "end" iterator (that was derived from the same
|
* corresponding "end" iterator (that was derived from the same
|
||||||
@@ -235,14 +225,11 @@ json_object_iter_peek_value(const struct json_object_iterator* iter);
|
|||||||
* reference the same name/value pair or are both at
|
* reference the same name/value pair or are both at
|
||||||
* "end"); zero if they are not equal.
|
* "end"); zero if they are not equal.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT json_bool
|
JSON_EXPORT json_bool json_object_iter_equal(const struct json_object_iterator *iter1,
|
||||||
json_object_iter_equal(const struct json_object_iterator* iter1,
|
|
||||||
const struct json_object_iterator *iter2);
|
const struct json_object_iterator *iter2);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* JSON_OBJECT_ITERATOR_H */
|
#endif /* JSON_OBJECT_ITERATOR_H */
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ extern "C" {
|
|||||||
typedef void(json_object_private_delete_fn)(struct json_object *o);
|
typedef void(json_object_private_delete_fn)(struct json_object *o);
|
||||||
|
|
||||||
/* json object int type, support extension*/
|
/* json object int type, support extension*/
|
||||||
typedef enum json_object_int_type {
|
typedef enum json_object_int_type
|
||||||
|
{
|
||||||
json_object_int_type_int64,
|
json_object_int_type_int64,
|
||||||
json_object_int_type_uint64
|
json_object_int_type_uint64
|
||||||
} json_object_int_type;
|
} json_object_int_type;
|
||||||
@@ -38,11 +39,14 @@ struct json_object
|
|||||||
json_object_private_delete_fn *_delete;
|
json_object_private_delete_fn *_delete;
|
||||||
json_object_to_json_string_fn *_to_json_string;
|
json_object_to_json_string_fn *_to_json_string;
|
||||||
struct printbuf *_pb;
|
struct printbuf *_pb;
|
||||||
union data {
|
union data
|
||||||
|
{
|
||||||
json_bool c_boolean;
|
json_bool c_boolean;
|
||||||
double c_double;
|
double c_double;
|
||||||
struct {
|
struct
|
||||||
union {
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
int64_t c_int64;
|
int64_t c_int64;
|
||||||
uint64_t c_uint64;
|
uint64_t c_uint64;
|
||||||
} cint;
|
} cint;
|
||||||
@@ -50,8 +54,10 @@ struct json_object
|
|||||||
} c_int;
|
} c_int;
|
||||||
struct lh_table *c_object;
|
struct lh_table *c_object;
|
||||||
struct array_list *c_array;
|
struct array_list *c_array;
|
||||||
struct {
|
struct
|
||||||
union {
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
/* optimize: if we have small strings, we can store them
|
/* optimize: if we have small strings, we can store them
|
||||||
* directly. This saves considerable CPU cycles AND memory.
|
* directly. This saves considerable CPU cycles AND memory.
|
||||||
*/
|
*/
|
||||||
|
|||||||
101
json_pointer.c
101
json_pointer.c
@@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
#include "strerror_override.h"
|
#include "strerror_override.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include "json_pointer.h"
|
#include "json_pointer.h"
|
||||||
#include "strdup_compat.h"
|
#include "strdup_compat.h"
|
||||||
@@ -30,7 +30,8 @@ static void string_replace_all_occurrences_with_char(char *s, const char *occur,
|
|||||||
int slen = strlen(s);
|
int slen = strlen(s);
|
||||||
int skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */
|
int skip = strlen(occur) - 1; /* length of the occurrence, minus the char we're replacing */
|
||||||
char *p = s;
|
char *p = s;
|
||||||
while ((p = strstr(p, occur))) {
|
while ((p = strstr(p, occur)))
|
||||||
|
{
|
||||||
*p = repl_char;
|
*p = repl_char;
|
||||||
p++;
|
p++;
|
||||||
slen -= skip;
|
slen -= skip;
|
||||||
@@ -44,8 +45,10 @@ static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx
|
|||||||
/* this code-path optimizes a bit, for when we reference the 0-9 index range
|
/* this code-path optimizes a bit, for when we reference the 0-9 index range
|
||||||
* in a JSON array and because leading zeros not allowed
|
* in a JSON array and because leading zeros not allowed
|
||||||
*/
|
*/
|
||||||
if (len == 1) {
|
if (len == 1)
|
||||||
if (isdigit((unsigned char)path[0])) {
|
{
|
||||||
|
if (isdigit((unsigned char)path[0]))
|
||||||
|
{
|
||||||
*idx = (path[0] - '0');
|
*idx = (path[0] - '0');
|
||||||
goto check_oob;
|
goto check_oob;
|
||||||
}
|
}
|
||||||
@@ -53,26 +56,31 @@ static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* leading zeros not allowed per RFC */
|
/* leading zeros not allowed per RFC */
|
||||||
if (path[0] == '0') {
|
if (path[0] == '0')
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* RFC states base-10 decimals */
|
/* RFC states base-10 decimals */
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++)
|
||||||
if (!isdigit((unsigned char)path[i])) {
|
{
|
||||||
|
if (!isdigit((unsigned char)path[i]))
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*idx = strtol(path, NULL, 10);
|
*idx = strtol(path, NULL, 10);
|
||||||
if (*idx < 0) {
|
if (*idx < 0)
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
check_oob:
|
check_oob:
|
||||||
len = json_object_array_length(jo);
|
len = json_object_array_length(jo);
|
||||||
if (*idx >= len) {
|
if (*idx >= len)
|
||||||
|
{
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -80,14 +88,17 @@ check_oob:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int json_pointer_get_single_path(struct json_object *obj, char *path, struct json_object **value)
|
static int json_pointer_get_single_path(struct json_object *obj, char *path,
|
||||||
|
struct json_object **value)
|
||||||
|
{
|
||||||
|
if (json_object_is_type(obj, json_type_array))
|
||||||
{
|
{
|
||||||
if (json_object_is_type(obj, json_type_array)) {
|
|
||||||
int32_t idx;
|
int32_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)
|
||||||
*value = obj;
|
*value = obj;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -101,7 +112,8 @@ static int json_pointer_get_single_path(struct json_object *obj, char *path, str
|
|||||||
string_replace_all_occurrences_with_char(path, "~1", '/');
|
string_replace_all_occurrences_with_char(path, "~1", '/');
|
||||||
string_replace_all_occurrences_with_char(path, "~0", '~');
|
string_replace_all_occurrences_with_char(path, "~0", '~');
|
||||||
|
|
||||||
if (!json_object_object_get_ex(obj, path, value)) {
|
if (!json_object_object_get_ex(obj, path, value))
|
||||||
|
{
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -109,12 +121,11 @@ static int json_pointer_get_single_path(struct json_object *obj, char *path, str
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int json_pointer_set_single_path(
|
static int json_pointer_set_single_path(struct json_object *parent, const char *path,
|
||||||
struct json_object *parent,
|
|
||||||
const char *path,
|
|
||||||
struct json_object *value)
|
struct json_object *value)
|
||||||
{
|
{
|
||||||
if (json_object_is_type(parent, json_type_array)) {
|
if (json_object_is_type(parent, json_type_array))
|
||||||
|
{
|
||||||
int32_t idx;
|
int32_t idx;
|
||||||
/* RFC (Chapter 4) states that '-' may be used to add new elements to an array */
|
/* RFC (Chapter 4) states that '-' may be used to add new elements to an array */
|
||||||
if (path[0] == '-' && path[1] == '\0')
|
if (path[0] == '-' && path[1] == '\0')
|
||||||
@@ -137,16 +148,15 @@ static int json_pointer_set_single_path(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int json_pointer_get_recursive(
|
static int json_pointer_get_recursive(struct json_object *obj, char *path,
|
||||||
struct json_object *obj,
|
|
||||||
char *path,
|
|
||||||
struct json_object **value)
|
struct json_object **value)
|
||||||
{
|
{
|
||||||
char *endp;
|
char *endp;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* All paths (on each recursion level must have a leading '/' */
|
/* All paths (on each recursion level must have a leading '/' */
|
||||||
if (path[0] != '/') {
|
if (path[0] != '/')
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -160,7 +170,8 @@ static int json_pointer_get_recursive(
|
|||||||
if ((rc = json_pointer_get_single_path(obj, path, &obj)))
|
if ((rc = json_pointer_get_single_path(obj, path, &obj)))
|
||||||
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_get_recursive(obj, endp, value);
|
||||||
@@ -178,19 +189,22 @@ int json_pointer_get(struct json_object *obj, const char *path, struct json_obje
|
|||||||
char *path_copy = NULL;
|
char *path_copy = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!obj || !path) {
|
if (!obj || !path)
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path[0] == '\0') {
|
if (path[0] == '\0')
|
||||||
|
{
|
||||||
if (res)
|
if (res)
|
||||||
*res = obj;
|
*res = obj;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass a working copy to the recursive call */
|
/* pass a working copy to the recursive call */
|
||||||
if (!(path_copy = strdup(path))) {
|
if (!(path_copy = strdup(path)))
|
||||||
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -206,7 +220,8 @@ int json_pointer_getf(struct json_object *obj, struct json_object **res, const c
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
if (!obj || !path_fmt) {
|
if (!obj || !path_fmt)
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -218,7 +233,8 @@ int json_pointer_getf(struct json_object *obj, struct json_object **res, const c
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (path_copy[0] == '\0') {
|
if (path_copy[0] == '\0')
|
||||||
|
{
|
||||||
if (res)
|
if (res)
|
||||||
*res = obj;
|
*res = obj;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -238,30 +254,35 @@ int json_pointer_set(struct json_object **obj, const char *path, struct json_obj
|
|||||||
struct json_object *set = NULL;
|
struct json_object *set = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (!obj || !path) {
|
if (!obj || !path)
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path[0] == '\0') {
|
if (path[0] == '\0')
|
||||||
|
{
|
||||||
json_object_put(*obj);
|
json_object_put(*obj);
|
||||||
*obj = value;
|
*obj = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path[0] != '/') {
|
if (path[0] != '/')
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there's only 1 level to set, stop here */
|
/* If there's only 1 level to set, stop here */
|
||||||
if ((endp = strrchr(path, '/')) == path) {
|
if ((endp = strrchr(path, '/')) == path)
|
||||||
|
{
|
||||||
path++;
|
path++;
|
||||||
return json_pointer_set_single_path(*obj, path, value);
|
return json_pointer_set_single_path(*obj, path, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pass a working copy to the recursive call */
|
/* pass a working copy to the recursive call */
|
||||||
if (!(path_copy = strdup(path))) {
|
if (!(path_copy = strdup(path)))
|
||||||
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -276,7 +297,8 @@ int json_pointer_set(struct json_object **obj, const char *path, struct json_obj
|
|||||||
return json_pointer_set_single_path(set, endp, value);
|
return json_pointer_set_single_path(set, endp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...)
|
int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt,
|
||||||
|
...)
|
||||||
{
|
{
|
||||||
char *endp;
|
char *endp;
|
||||||
char *path_copy = NULL;
|
char *path_copy = NULL;
|
||||||
@@ -284,7 +306,8 @@ int json_pointer_setf(struct json_object **obj, struct json_object *value, const
|
|||||||
va_list args;
|
va_list args;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
if (!obj || !path_fmt) {
|
if (!obj || !path_fmt)
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -297,20 +320,23 @@ int json_pointer_setf(struct json_object **obj, struct json_object *value, const
|
|||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (path_copy[0] == '\0') {
|
if (path_copy[0] == '\0')
|
||||||
|
{
|
||||||
json_object_put(*obj);
|
json_object_put(*obj);
|
||||||
*obj = value;
|
*obj = value;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path_copy[0] != '/') {
|
if (path_copy[0] != '/')
|
||||||
|
{
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
rc = -1;
|
rc = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there's only 1 level to set, stop here */
|
/* If there's only 1 level to set, stop here */
|
||||||
if ((endp = strrchr(path_copy, '/')) == path_copy) {
|
if ((endp = strrchr(path_copy, '/')) == path_copy)
|
||||||
|
{
|
||||||
set = *obj;
|
set = *obj;
|
||||||
goto set_single_path;
|
goto set_single_path;
|
||||||
}
|
}
|
||||||
@@ -328,4 +354,3 @@ out:
|
|||||||
free(path_copy);
|
free(path_copy);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @return negative if an error (or not found), or 0 if succeeded
|
* @return negative if an error (or not found), or 0 if succeeded
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res);
|
JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path,
|
||||||
|
struct json_object **res);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a variant of 'json_pointer_get()' that supports printf() style arguments.
|
* This is a variant of 'json_pointer_get()' that supports printf() style arguments.
|
||||||
@@ -62,7 +63,8 @@ JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, stru
|
|||||||
*
|
*
|
||||||
* @return negative if an error (or not found), or 0 if succeeded
|
* @return negative if an error (or not found), or 0 if succeeded
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...);
|
JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res,
|
||||||
|
const char *path_fmt, ...);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets JSON object 'value' in the 'obj' tree at the location specified
|
* Sets JSON object 'value' in the 'obj' tree at the location specified
|
||||||
@@ -93,7 +95,8 @@ JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **
|
|||||||
*
|
*
|
||||||
* @return negative if an error (or not found), or 0 if succeeded
|
* @return negative if an error (or not found), or 0 if succeeded
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value);
|
JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path,
|
||||||
|
struct json_object *value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a variant of 'json_pointer_set()' that supports printf() style arguments.
|
* This is a variant of 'json_pointer_set()' that supports printf() style arguments.
|
||||||
@@ -110,8 +113,8 @@ JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, str
|
|||||||
*
|
*
|
||||||
* @return negative if an error (or not found), or 0 if succeeded
|
* @return negative if an error (or not found), or 0 if succeeded
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...);
|
JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value,
|
||||||
|
const char *path_fmt, ...);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
527
json_tokener.c
527
json_tokener.c
@@ -15,24 +15,24 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include "math_compat.h"
|
#include "math_compat.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
|
||||||
#include "printbuf.h"
|
|
||||||
#include "arraylist.h"
|
#include "arraylist.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
#include "json_object_private.h"
|
#include "json_object_private.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
#include "json_util.h"
|
#include "json_util.h"
|
||||||
|
#include "printbuf.h"
|
||||||
#include "strdup_compat.h"
|
#include "strdup_compat.h"
|
||||||
|
|
||||||
#ifdef HAVE_LOCALE_H
|
#ifdef HAVE_LOCALE_H
|
||||||
@@ -115,10 +115,11 @@ struct json_tokener* json_tokener_new_ex(int depth)
|
|||||||
struct json_tokener *tok;
|
struct json_tokener *tok;
|
||||||
|
|
||||||
tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
|
tok = (struct json_tokener *)calloc(1, sizeof(struct json_tokener));
|
||||||
if (!tok) return NULL;
|
if (!tok)
|
||||||
tok->stack = (struct json_tokener_srec *) calloc(depth,
|
return NULL;
|
||||||
sizeof(struct json_tokener_srec));
|
tok->stack = (struct json_tokener_srec *)calloc(depth, sizeof(struct json_tokener_srec));
|
||||||
if (!tok->stack) {
|
if (!tok->stack)
|
||||||
|
{
|
||||||
free(tok);
|
free(tok);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -136,7 +137,8 @@ struct json_tokener* json_tokener_new(void)
|
|||||||
void json_tokener_free(struct json_tokener *tok)
|
void json_tokener_free(struct json_tokener *tok)
|
||||||
{
|
{
|
||||||
json_tokener_reset(tok);
|
json_tokener_reset(tok);
|
||||||
if (tok->pb) printbuf_free(tok->pb);
|
if (tok->pb)
|
||||||
|
printbuf_free(tok->pb);
|
||||||
free(tok->stack);
|
free(tok->stack);
|
||||||
free(tok);
|
free(tok);
|
||||||
}
|
}
|
||||||
@@ -171,8 +173,7 @@ struct json_object* json_tokener_parse(const char *str)
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct json_object* json_tokener_parse_verbose(const char *str,
|
struct json_object *json_tokener_parse_verbose(const char *str, enum json_tokener_error *error)
|
||||||
enum json_tokener_error *error)
|
|
||||||
{
|
{
|
||||||
struct json_tokener *tok;
|
struct json_tokener *tok;
|
||||||
struct json_object *obj;
|
struct json_object *obj;
|
||||||
@@ -182,7 +183,8 @@ struct json_object* json_tokener_parse_verbose(const char *str,
|
|||||||
return NULL;
|
return NULL;
|
||||||
obj = json_tokener_parse_ex(tok, str, -1);
|
obj = json_tokener_parse_ex(tok, str, -1);
|
||||||
*error = tok->err;
|
*error = tok->err;
|
||||||
if(tok->err != json_tokener_success) {
|
if (tok->err != json_tokener_success)
|
||||||
|
{
|
||||||
if (obj != NULL)
|
if (obj != NULL)
|
||||||
json_object_put(obj);
|
json_object_put(obj);
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
@@ -216,36 +218,26 @@ struct json_object* json_tokener_parse_verbose(const char *str,
|
|||||||
* Implicit inputs: str, len vars
|
* Implicit inputs: str, len vars
|
||||||
*/
|
*/
|
||||||
#define PEEK_CHAR(dest, tok) \
|
#define PEEK_CHAR(dest, tok) \
|
||||||
(((tok)->char_offset == len) ? \
|
(((tok)->char_offset == len) \
|
||||||
(((tok)->depth == 0 && \
|
? (((tok)->depth == 0 && state == json_tokener_state_eatws && \
|
||||||
state == json_tokener_state_eatws && \
|
saved_state == json_tokener_state_finish) \
|
||||||
saved_state == json_tokener_state_finish \
|
? (((tok)->err = json_tokener_success), 0) \
|
||||||
) ? \
|
: (((tok)->err = json_tokener_continue), 0)) \
|
||||||
(((tok)->err = json_tokener_success), 0) \
|
: (((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && \
|
||||||
: \
|
(!json_tokener_validate_utf8(*str, nBytesp))) \
|
||||||
(((tok)->err = json_tokener_continue), 0) \
|
? ((tok->err = json_tokener_error_parse_utf8_string), 0) \
|
||||||
) : \
|
: (((dest) = *str), 1)))
|
||||||
(((tok->flags & JSON_TOKENER_VALIDATE_UTF8) && \
|
|
||||||
(!json_tokener_validate_utf8(*str, nBytesp)))? \
|
|
||||||
((tok->err = json_tokener_error_parse_utf8_string), 0) \
|
|
||||||
: \
|
|
||||||
(((dest) = *str), 1) \
|
|
||||||
))
|
|
||||||
|
|
||||||
/* ADVANCE_CHAR() macro:
|
/* ADVANCE_CHAR() macro:
|
||||||
* Increments str & tok->char_offset.
|
* Increments str & tok->char_offset.
|
||||||
* For convenience of existing conditionals, returns the old value of c (0 on eof)
|
* For convenience of existing conditionals, returns the old value of c (0 on eof)
|
||||||
* Implicit inputs: c var
|
* Implicit inputs: c var
|
||||||
*/
|
*/
|
||||||
#define ADVANCE_CHAR(str, tok) \
|
#define ADVANCE_CHAR(str, tok) (++(str), ((tok)->char_offset)++, c)
|
||||||
( ++(str), ((tok)->char_offset)++, c)
|
|
||||||
|
|
||||||
|
|
||||||
/* End optimization macro defs */
|
/* End optimization macro defs */
|
||||||
|
|
||||||
|
struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, int len)
|
||||||
struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|
||||||
const char *str, int len)
|
|
||||||
{
|
{
|
||||||
struct json_object *obj = NULL;
|
struct json_object *obj = NULL;
|
||||||
char c = '\1';
|
char c = '\1';
|
||||||
@@ -268,7 +260,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
* If the function is called with len == -1 then strlen is called to check
|
* If the function is called with len == -1 then strlen is called to check
|
||||||
* the string length is less than INT32_MAX (2GB)
|
* the string length is less than INT32_MAX (2GB)
|
||||||
*/
|
*/
|
||||||
if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
|
if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX))
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_size;
|
tok->err = json_tokener_error_size;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -288,34 +281,42 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
char *tmplocale;
|
char *tmplocale;
|
||||||
tmplocale = setlocale(LC_NUMERIC, NULL);
|
tmplocale = setlocale(LC_NUMERIC, NULL);
|
||||||
if (tmplocale) oldlocale = strdup(tmplocale);
|
if (tmplocale)
|
||||||
|
oldlocale = strdup(tmplocale);
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (PEEK_CHAR(c, tok)) {
|
while (PEEK_CHAR(c, tok))
|
||||||
|
{
|
||||||
|
|
||||||
redo_char:
|
redo_char:
|
||||||
switch(state) {
|
switch (state)
|
||||||
|
{
|
||||||
|
|
||||||
case json_tokener_state_eatws:
|
case json_tokener_state_eatws:
|
||||||
/* Advance until we change state */
|
/* Advance until we change state */
|
||||||
while (isspace((unsigned char)c)) {
|
while (isspace((unsigned char)c))
|
||||||
|
{
|
||||||
if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
|
if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
|
if (c == '/' && !(tok->flags & JSON_TOKENER_STRICT))
|
||||||
|
{
|
||||||
printbuf_reset(tok->pb);
|
printbuf_reset(tok->pb);
|
||||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||||
state = json_tokener_state_comment_start;
|
state = json_tokener_state_comment_start;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
state = saved_state;
|
state = saved_state;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_start:
|
case json_tokener_state_start:
|
||||||
switch(c) {
|
switch (c)
|
||||||
|
{
|
||||||
case '{':
|
case '{':
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
saved_state = json_tokener_state_object_field_start;
|
saved_state = json_tokener_state_object_field_start;
|
||||||
@@ -343,7 +344,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
tok->st_pos = 0;
|
tok->st_pos = 0;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
case '\'':
|
case '\'':
|
||||||
if (tok->flags & JSON_TOKENER_STRICT) {
|
if (tok->flags & JSON_TOKENER_STRICT)
|
||||||
|
{
|
||||||
/* in STRICT mode only double-quote are allowed */
|
/* in STRICT mode only double-quote are allowed */
|
||||||
tok->err = json_tokener_error_parse_unexpected;
|
tok->err = json_tokener_error_parse_unexpected;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -377,14 +379,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
printbuf_reset(tok->pb);
|
printbuf_reset(tok->pb);
|
||||||
tok->is_double = 0;
|
tok->is_double = 0;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
default:
|
default: tok->err = json_tokener_error_parse_unexpected; goto out;
|
||||||
tok->err = json_tokener_error_parse_unexpected;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_finish:
|
case json_tokener_state_finish:
|
||||||
if(tok->depth == 0) goto out;
|
if (tok->depth == 0)
|
||||||
|
goto out;
|
||||||
obj = json_object_get(current);
|
obj = json_object_get(current);
|
||||||
json_tokener_reset_level(tok, tok->depth);
|
json_tokener_reset_level(tok, tok->depth);
|
||||||
tok->depth--;
|
tok->depth--;
|
||||||
@@ -431,14 +432,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
is_negative = 1;
|
is_negative = 1;
|
||||||
}
|
}
|
||||||
current = json_object_new_double(is_negative
|
current = json_object_new_double(is_negative ? -INFINITY : INFINITY);
|
||||||
? -INFINITY : INFINITY);
|
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case json_tokener_state_null: /* aka starts with 'n' */
|
case json_tokener_state_null: /* aka starts with 'n' */
|
||||||
@@ -449,10 +448,11 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
size = json_min(tok->st_pos + 1, json_null_str_len);
|
size = json_min(tok->st_pos + 1, json_null_str_len);
|
||||||
size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
|
size_nan = json_min(tok->st_pos + 1, json_nan_str_len);
|
||||||
if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
strncasecmp(json_null_str, tok->pb->buf, size) == 0)
|
strncasecmp(json_null_str, tok->pb->buf, size) == 0) ||
|
||||||
|| (strncmp(json_null_str, tok->pb->buf, size) == 0)
|
(strncmp(json_null_str, tok->pb->buf, size) == 0))
|
||||||
) {
|
{
|
||||||
if (tok->st_pos == json_null_str_len) {
|
if (tok->st_pos == json_null_str_len)
|
||||||
|
{
|
||||||
current = NULL;
|
current = NULL;
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
@@ -461,8 +461,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
|
strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
|
||||||
(strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
|
(strncmp(json_nan_str, tok->pb->buf, size_nan) == 0))
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (tok->st_pos == json_nan_str_len)
|
if (tok->st_pos == json_nan_str_len)
|
||||||
{
|
{
|
||||||
@@ -473,7 +472,9 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_null;
|
tok->err = json_tokener_error_parse_null;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -482,11 +483,16 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_comment_start:
|
case json_tokener_state_comment_start:
|
||||||
if(c == '*') {
|
if (c == '*')
|
||||||
|
{
|
||||||
state = json_tokener_state_comment;
|
state = json_tokener_state_comment;
|
||||||
} else if(c == '/') {
|
}
|
||||||
|
else if (c == '/')
|
||||||
|
{
|
||||||
state = json_tokener_state_comment_eol;
|
state = json_tokener_state_comment_eol;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_comment;
|
tok->err = json_tokener_error_parse_comment;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -497,9 +503,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
/* Advance until we change state */
|
/* Advance until we change state */
|
||||||
const char *case_start = str;
|
const char *case_start = str;
|
||||||
while(c != '*') {
|
while (c != '*')
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
{
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
|
||||||
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -512,9 +521,12 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
/* Advance until we change state */
|
/* Advance until we change state */
|
||||||
const char *case_start = str;
|
const char *case_start = str;
|
||||||
while(c != '\n') {
|
while (c != '\n')
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
{
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
|
||||||
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -526,10 +538,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
|
|
||||||
case json_tokener_state_comment_end:
|
case json_tokener_state_comment_end:
|
||||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||||
if(c == '/') {
|
if (c == '/')
|
||||||
|
{
|
||||||
MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
|
MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
state = json_tokener_state_comment;
|
state = json_tokener_state_comment;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -538,23 +553,32 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
/* Advance until we change state */
|
/* Advance until we change state */
|
||||||
const char *case_start = str;
|
const char *case_start = str;
|
||||||
while(1) {
|
while (1)
|
||||||
if(c == tok->quote_char) {
|
{
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
if (c == tok->quote_char)
|
||||||
current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
|
current =
|
||||||
|
json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
break;
|
break;
|
||||||
} else if(c == '\\') {
|
}
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
else if (c == '\\')
|
||||||
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
saved_state = json_tokener_state_string;
|
saved_state = json_tokener_state_string;
|
||||||
state = json_tokener_state_string_escape;
|
state = json_tokener_state_string_escape;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -562,7 +586,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_string_escape:
|
case json_tokener_state_string_escape:
|
||||||
switch(c) {
|
switch (c)
|
||||||
|
{
|
||||||
case '"':
|
case '"':
|
||||||
case '\\':
|
case '\\':
|
||||||
case '/':
|
case '/':
|
||||||
@@ -574,11 +599,16 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
case 'r':
|
case 'r':
|
||||||
case 't':
|
case 't':
|
||||||
case 'f':
|
case 'f':
|
||||||
if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
|
if (c == 'b')
|
||||||
else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
|
printbuf_memappend_fast(tok->pb, "\b", 1);
|
||||||
else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
|
else if (c == 'n')
|
||||||
else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
|
printbuf_memappend_fast(tok->pb, "\n", 1);
|
||||||
else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
|
else if (c == 'r')
|
||||||
|
printbuf_memappend_fast(tok->pb, "\r", 1);
|
||||||
|
else if (c == 't')
|
||||||
|
printbuf_memappend_fast(tok->pb, "\t", 1);
|
||||||
|
else if (c == 'f')
|
||||||
|
printbuf_memappend_fast(tok->pb, "\f", 1);
|
||||||
state = saved_state;
|
state = saved_state;
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
@@ -586,9 +616,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
tok->st_pos = 0;
|
tok->st_pos = 0;
|
||||||
state = json_tokener_state_escape_unicode;
|
state = json_tokener_state_escape_unicode;
|
||||||
break;
|
break;
|
||||||
default:
|
default: tok->err = json_tokener_error_parse_string; goto out;
|
||||||
tok->err = json_tokener_error_parse_string;
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -597,100 +625,162 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
unsigned int got_hi_surrogate = 0;
|
unsigned int got_hi_surrogate = 0;
|
||||||
|
|
||||||
/* Handle a 4-byte sequence, or two sequences if a surrogate pair */
|
/* Handle a 4-byte sequence, or two sequences if a surrogate pair */
|
||||||
while(1) {
|
while (1)
|
||||||
if (c && strchr(json_hex_chars, c)) {
|
{
|
||||||
tok->ucs_char += ((unsigned int)jt_hexdigit(c) << ((3-tok->st_pos++)*4));
|
if (c && strchr(json_hex_chars, c))
|
||||||
if(tok->st_pos == 4) {
|
{
|
||||||
|
tok->ucs_char += ((unsigned int)jt_hexdigit(c)
|
||||||
|
<< ((3 - tok->st_pos++) * 4));
|
||||||
|
if (tok->st_pos == 4)
|
||||||
|
{
|
||||||
unsigned char unescaped_utf[4];
|
unsigned char unescaped_utf[4];
|
||||||
|
|
||||||
if (got_hi_surrogate) {
|
if (got_hi_surrogate)
|
||||||
if (IS_LOW_SURROGATE(tok->ucs_char)) {
|
{
|
||||||
|
if (IS_LOW_SURROGATE(tok->ucs_char))
|
||||||
|
{
|
||||||
/* Recalculate the ucs_char, then fall thru to process normally */
|
/* Recalculate the ucs_char, then fall thru to process normally */
|
||||||
tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
|
tok->ucs_char =
|
||||||
} else {
|
DECODE_SURROGATE_PAIR(
|
||||||
|
got_hi_surrogate,
|
||||||
|
tok->ucs_char);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Hi surrogate was not followed by a low surrogate */
|
/* Hi surrogate was not followed by a low surrogate */
|
||||||
/* Replace the hi and process the rest normally */
|
/* Replace the hi and process the rest normally */
|
||||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
printbuf_memappend_fast(
|
||||||
|
tok->pb,
|
||||||
|
(char *)utf8_replacement_char,
|
||||||
|
3);
|
||||||
}
|
}
|
||||||
got_hi_surrogate = 0;
|
got_hi_surrogate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->ucs_char < 0x80) {
|
if (tok->ucs_char < 0x80)
|
||||||
|
{
|
||||||
unescaped_utf[0] = tok->ucs_char;
|
unescaped_utf[0] = tok->ucs_char;
|
||||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
|
printbuf_memappend_fast(
|
||||||
} else if (tok->ucs_char < 0x800) {
|
tok->pb, (char *)unescaped_utf, 1);
|
||||||
unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
|
}
|
||||||
unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
|
else if (tok->ucs_char < 0x800)
|
||||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
|
{
|
||||||
} else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
|
unescaped_utf[0] =
|
||||||
|
0xc0 | (tok->ucs_char >> 6);
|
||||||
|
unescaped_utf[1] =
|
||||||
|
0x80 | (tok->ucs_char & 0x3f);
|
||||||
|
printbuf_memappend_fast(
|
||||||
|
tok->pb, (char *)unescaped_utf, 2);
|
||||||
|
}
|
||||||
|
else if (IS_HIGH_SURROGATE(tok->ucs_char))
|
||||||
|
{
|
||||||
/* Got a high surrogate. Remember it and look for
|
/* Got a high surrogate. Remember it and look for
|
||||||
* the beginning of another sequence, which
|
* the beginning of another sequence, which
|
||||||
* should be the low surrogate.
|
* should be the low surrogate.
|
||||||
*/
|
*/
|
||||||
got_hi_surrogate = tok->ucs_char;
|
got_hi_surrogate = tok->ucs_char;
|
||||||
/* Not at end, and the next two chars should be "\u" */
|
/* Not at end, and the next two chars should be "\u" */
|
||||||
if ((len == -1 || len > (tok->char_offset + 2)) &&
|
if ((len == -1 ||
|
||||||
|
len > (tok->char_offset + 2)) &&
|
||||||
// str[0] != '0' && // implied by json_hex_chars, above.
|
// str[0] != '0' && // implied by json_hex_chars, above.
|
||||||
(str[1] == '\\') &&
|
(str[1] == '\\') && (str[2] == 'u'))
|
||||||
(str[2] == 'u'))
|
|
||||||
{
|
{
|
||||||
/* Advance through the 16 bit surrogate, and move
|
/* Advance through the 16 bit surrogate, and move
|
||||||
* on to the next sequence. The next step is to
|
* on to the next sequence. The next step is to
|
||||||
* process the following characters.
|
* process the following characters.
|
||||||
*/
|
*/
|
||||||
if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
|
if (!ADVANCE_CHAR(str, tok) ||
|
||||||
printbuf_memappend_fast(tok->pb,
|
!ADVANCE_CHAR(str, tok))
|
||||||
(char*) utf8_replacement_char, 3);
|
{
|
||||||
|
printbuf_memappend_fast(
|
||||||
|
tok->pb,
|
||||||
|
(char *)
|
||||||
|
utf8_replacement_char,
|
||||||
|
3);
|
||||||
}
|
}
|
||||||
/* Advance to the first char of the next sequence and
|
/* Advance to the first char of the next sequence and
|
||||||
* continue processing with the next sequence.
|
* continue processing with the next sequence.
|
||||||
*/
|
*/
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) ||
|
||||||
printbuf_memappend_fast(tok->pb,
|
!PEEK_CHAR(c, tok))
|
||||||
(char*) utf8_replacement_char, 3);
|
{
|
||||||
|
printbuf_memappend_fast(
|
||||||
|
tok->pb,
|
||||||
|
(char *)
|
||||||
|
utf8_replacement_char,
|
||||||
|
3);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
tok->ucs_char = 0;
|
tok->ucs_char = 0;
|
||||||
tok->st_pos = 0;
|
tok->st_pos = 0;
|
||||||
/* other json_tokener_state_escape_unicode */
|
/* other json_tokener_state_escape_unicode */
|
||||||
continue;
|
continue;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Got a high surrogate without another sequence following
|
/* Got a high surrogate without another sequence following
|
||||||
* it. Put a replacement char in for the hi surrogate
|
* it. Put a replacement char in for the hi surrogate
|
||||||
* and pretend we finished.
|
* and pretend we finished.
|
||||||
*/
|
*/
|
||||||
printbuf_memappend_fast(tok->pb,
|
printbuf_memappend_fast(
|
||||||
(char*) utf8_replacement_char, 3);
|
tok->pb,
|
||||||
|
(char *)utf8_replacement_char,
|
||||||
|
3);
|
||||||
}
|
}
|
||||||
} else if (IS_LOW_SURROGATE(tok->ucs_char)) {
|
}
|
||||||
|
else if (IS_LOW_SURROGATE(tok->ucs_char))
|
||||||
|
{
|
||||||
/* Got a low surrogate not preceded by a high */
|
/* Got a low surrogate not preceded by a high */
|
||||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
printbuf_memappend_fast(
|
||||||
} else if (tok->ucs_char < 0x10000) {
|
tok->pb, (char *)utf8_replacement_char,
|
||||||
unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
|
3);
|
||||||
unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
|
}
|
||||||
unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
|
else if (tok->ucs_char < 0x10000)
|
||||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
|
{
|
||||||
} else if (tok->ucs_char < 0x110000) {
|
unescaped_utf[0] =
|
||||||
unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
|
0xe0 | (tok->ucs_char >> 12);
|
||||||
unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
|
unescaped_utf[1] =
|
||||||
unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
|
0x80 | ((tok->ucs_char >> 6) & 0x3f);
|
||||||
unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
|
unescaped_utf[2] =
|
||||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
|
0x80 | (tok->ucs_char & 0x3f);
|
||||||
} else {
|
printbuf_memappend_fast(
|
||||||
|
tok->pb, (char *)unescaped_utf, 3);
|
||||||
|
}
|
||||||
|
else if (tok->ucs_char < 0x110000)
|
||||||
|
{
|
||||||
|
unescaped_utf[0] =
|
||||||
|
0xf0 | ((tok->ucs_char >> 18) & 0x07);
|
||||||
|
unescaped_utf[1] =
|
||||||
|
0x80 | ((tok->ucs_char >> 12) & 0x3f);
|
||||||
|
unescaped_utf[2] =
|
||||||
|
0x80 | ((tok->ucs_char >> 6) & 0x3f);
|
||||||
|
unescaped_utf[3] =
|
||||||
|
0x80 | (tok->ucs_char & 0x3f);
|
||||||
|
printbuf_memappend_fast(
|
||||||
|
tok->pb, (char *)unescaped_utf, 4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Don't know what we got--insert the replacement char */
|
/* Don't know what we got--insert the replacement char */
|
||||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
printbuf_memappend_fast(
|
||||||
|
tok->pb, (char *)utf8_replacement_char,
|
||||||
|
3);
|
||||||
}
|
}
|
||||||
state = saved_state;
|
state = saved_state;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_string;
|
tok->err = json_tokener_error_parse_string;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
|
||||||
|
{
|
||||||
/* Clean up any pending chars */
|
/* Clean up any pending chars */
|
||||||
if (got_hi_surrogate)
|
if (got_hi_surrogate)
|
||||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
printbuf_memappend_fast(
|
||||||
|
tok->pb, (char *)utf8_replacement_char, 3);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -704,10 +794,11 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
size1 = json_min(tok->st_pos + 1, json_true_str_len);
|
size1 = json_min(tok->st_pos + 1, json_true_str_len);
|
||||||
size2 = json_min(tok->st_pos + 1, json_false_str_len);
|
size2 = json_min(tok->st_pos + 1, json_false_str_len);
|
||||||
if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
|
strncasecmp(json_true_str, tok->pb->buf, size1) == 0) ||
|
||||||
|| (strncmp(json_true_str, tok->pb->buf, size1) == 0)
|
(strncmp(json_true_str, tok->pb->buf, size1) == 0))
|
||||||
) {
|
{
|
||||||
if(tok->st_pos == json_true_str_len) {
|
if (tok->st_pos == json_true_str_len)
|
||||||
|
{
|
||||||
current = json_object_new_boolean(1);
|
current = json_object_new_boolean(1);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -715,10 +806,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
}
|
}
|
||||||
} else if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
}
|
||||||
strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
|
else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
|| (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
|
strncasecmp(json_false_str, tok->pb->buf, size2) == 0) ||
|
||||||
if(tok->st_pos == json_false_str_len) {
|
(strncmp(json_false_str, tok->pb->buf, size2) == 0))
|
||||||
|
{
|
||||||
|
if (tok->st_pos == json_false_str_len)
|
||||||
|
{
|
||||||
current = json_object_new_boolean(0);
|
current = json_object_new_boolean(0);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
@@ -726,7 +820,9 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_boolean;
|
tok->err = json_tokener_error_parse_boolean;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -741,7 +837,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
int case_len = 0;
|
int case_len = 0;
|
||||||
int is_exponent = 0;
|
int is_exponent = 0;
|
||||||
int negativesign_next_possible_location = 1;
|
int negativesign_next_possible_location = 1;
|
||||||
while(c && strchr(json_number_chars, c)) {
|
while (c && strchr(json_number_chars, c))
|
||||||
|
{
|
||||||
++case_len;
|
++case_len;
|
||||||
|
|
||||||
/* non-digit characters checks */
|
/* non-digit characters checks */
|
||||||
@@ -750,8 +847,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
* protected from input starting with '.' or
|
* protected from input starting with '.' or
|
||||||
* e/E.
|
* e/E.
|
||||||
*/
|
*/
|
||||||
if (c == '.') {
|
if (c == '.')
|
||||||
if (tok->is_double != 0) {
|
{
|
||||||
|
if (tok->is_double != 0)
|
||||||
|
{
|
||||||
/* '.' can only be found once, and out of the exponent part.
|
/* '.' can only be found once, and out of the exponent part.
|
||||||
* Thus, if the input is already flagged as double, it
|
* Thus, if the input is already flagged as double, it
|
||||||
* is invalid.
|
* is invalid.
|
||||||
@@ -761,8 +860,10 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
tok->is_double = 1;
|
tok->is_double = 1;
|
||||||
}
|
}
|
||||||
if (c == 'e' || c == 'E') {
|
if (c == 'e' || c == 'E')
|
||||||
if (is_exponent != 0) {
|
{
|
||||||
|
if (is_exponent != 0)
|
||||||
|
{
|
||||||
/* only one exponent possible */
|
/* only one exponent possible */
|
||||||
tok->err = json_tokener_error_parse_number;
|
tok->err = json_tokener_error_parse_number;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -772,7 +873,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
/* the exponent part can begin with a negative sign */
|
/* the exponent part can begin with a negative sign */
|
||||||
negativesign_next_possible_location = case_len + 1;
|
negativesign_next_possible_location = case_len + 1;
|
||||||
}
|
}
|
||||||
if (c == '-' && case_len != negativesign_next_possible_location) {
|
if (c == '-' && case_len != negativesign_next_possible_location)
|
||||||
|
{
|
||||||
/* If the negative sign is not where expected (ie
|
/* If the negative sign is not where expected (ie
|
||||||
* start of input or start of exponent part), the
|
* start of input or start of exponent part), the
|
||||||
* input is invalid.
|
* input is invalid.
|
||||||
@@ -781,7 +883,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
|
||||||
|
{
|
||||||
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -790,8 +893,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
||||||
|
|
||||||
// Check for -Infinity
|
// Check for -Infinity
|
||||||
if (tok->pb->buf[0] == '-' && case_len <= 1 &&
|
if (tok->pb->buf[0] == '-' && case_len <= 1 && (c == 'i' || c == 'I'))
|
||||||
(c == 'i' || c == 'I'))
|
|
||||||
{
|
{
|
||||||
state = json_tokener_state_inf;
|
state = json_tokener_state_inf;
|
||||||
tok->st_pos = 0;
|
tok->st_pos = 0;
|
||||||
@@ -802,34 +904,45 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
int64_t num64;
|
int64_t num64;
|
||||||
uint64_t numuint64;
|
uint64_t numuint64;
|
||||||
double numd;
|
double numd;
|
||||||
if (!tok->is_double && tok->pb->buf[0] == '-'
|
if (!tok->is_double && tok->pb->buf[0] == '-' &&
|
||||||
&& json_parse_int64(tok->pb->buf, &num64) == 0) {
|
json_parse_int64(tok->pb->buf, &num64) == 0)
|
||||||
|
{
|
||||||
current = json_object_new_int64(num64);
|
current = json_object_new_int64(num64);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
} else if ( !tok->is_double && tok->pb->buf[0] != '-'
|
}
|
||||||
&& json_parse_uint64(tok->pb->buf, &numuint64) == 0) {
|
else if (!tok->is_double && tok->pb->buf[0] != '-' &&
|
||||||
|
json_parse_uint64(tok->pb->buf, &numuint64) == 0)
|
||||||
|
{
|
||||||
if (numuint64 && tok->pb->buf[0] == '0' &&
|
if (numuint64 && tok->pb->buf[0] == '0' &&
|
||||||
(tok->flags & JSON_TOKENER_STRICT)) {
|
(tok->flags & JSON_TOKENER_STRICT))
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_number;
|
tok->err = json_tokener_error_parse_number;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (numuint64 <= INT64_MAX){
|
if (numuint64 <= INT64_MAX)
|
||||||
|
{
|
||||||
num64 = (uint64_t)numuint64;
|
num64 = (uint64_t)numuint64;
|
||||||
current = json_object_new_int64(num64);
|
current = json_object_new_int64(num64);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
current = json_object_new_uint64(numuint64);
|
current = json_object_new_uint64(numuint64);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
|
}
|
||||||
|
else if (tok->is_double &&
|
||||||
|
json_parse_double(tok->pb->buf, &numd) == 0)
|
||||||
{
|
{
|
||||||
current = json_object_new_double_s(numd, tok->pb->buf);
|
current = json_object_new_double_s(numd, tok->pb->buf);
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_number;
|
tok->err = json_tokener_error_parse_number;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -841,7 +954,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
|
|
||||||
case json_tokener_state_array_after_sep:
|
case json_tokener_state_array_after_sep:
|
||||||
case json_tokener_state_array:
|
case json_tokener_state_array:
|
||||||
if(c == ']') {
|
if (c == ']')
|
||||||
|
{
|
||||||
if (state == json_tokener_state_array_after_sep &&
|
if (state == json_tokener_state_array_after_sep &&
|
||||||
(tok->flags & JSON_TOKENER_STRICT))
|
(tok->flags & JSON_TOKENER_STRICT))
|
||||||
{
|
{
|
||||||
@@ -850,8 +964,11 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
}
|
||||||
if(tok->depth >= tok->max_depth-1) {
|
else
|
||||||
|
{
|
||||||
|
if (tok->depth >= tok->max_depth - 1)
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_depth;
|
tok->err = json_tokener_error_depth;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -870,13 +987,18 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
goto redo_char;
|
goto redo_char;
|
||||||
|
|
||||||
case json_tokener_state_array_sep:
|
case json_tokener_state_array_sep:
|
||||||
if(c == ']') {
|
if (c == ']')
|
||||||
|
{
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else if(c == ',') {
|
}
|
||||||
|
else if (c == ',')
|
||||||
|
{
|
||||||
saved_state = json_tokener_state_array_after_sep;
|
saved_state = json_tokener_state_array_after_sep;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_array;
|
tok->err = json_tokener_error_parse_array;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -884,7 +1006,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
|
|
||||||
case json_tokener_state_object_field_start:
|
case json_tokener_state_object_field_start:
|
||||||
case json_tokener_state_object_field_start_after_sep:
|
case json_tokener_state_object_field_start_after_sep:
|
||||||
if(c == '}') {
|
if (c == '}')
|
||||||
|
{
|
||||||
if (state == json_tokener_state_object_field_start_after_sep &&
|
if (state == json_tokener_state_object_field_start_after_sep &&
|
||||||
(tok->flags & JSON_TOKENER_STRICT))
|
(tok->flags & JSON_TOKENER_STRICT))
|
||||||
{
|
{
|
||||||
@@ -893,11 +1016,15 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
}
|
}
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else if (c == '"' || c == '\'') {
|
}
|
||||||
|
else if (c == '"' || c == '\'')
|
||||||
|
{
|
||||||
tok->quote_char = c;
|
tok->quote_char = c;
|
||||||
printbuf_reset(tok->pb);
|
printbuf_reset(tok->pb);
|
||||||
state = json_tokener_state_object_field;
|
state = json_tokener_state_object_field;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_object_key_name;
|
tok->err = json_tokener_error_parse_object_key_name;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -907,21 +1034,29 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
/* Advance until we change state */
|
/* Advance until we change state */
|
||||||
const char *case_start = str;
|
const char *case_start = str;
|
||||||
while(1) {
|
while (1)
|
||||||
if(c == tok->quote_char) {
|
{
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
if (c == tok->quote_char)
|
||||||
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
obj_field_name = strdup(tok->pb->buf);
|
obj_field_name = strdup(tok->pb->buf);
|
||||||
saved_state = json_tokener_state_object_field_end;
|
saved_state = json_tokener_state_object_field_end;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
break;
|
break;
|
||||||
} else if(c == '\\') {
|
}
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
else if (c == '\\')
|
||||||
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
saved_state = json_tokener_state_object_field;
|
saved_state = json_tokener_state_object_field;
|
||||||
state = json_tokener_state_string_escape;
|
state = json_tokener_state_string_escape;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok))
|
||||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
{
|
||||||
|
printbuf_memappend_fast(tok->pb, case_start,
|
||||||
|
str - case_start);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -929,17 +1064,21 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_object_field_end:
|
case json_tokener_state_object_field_end:
|
||||||
if(c == ':') {
|
if (c == ':')
|
||||||
|
{
|
||||||
saved_state = json_tokener_state_object_value;
|
saved_state = json_tokener_state_object_value;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_object_key_sep;
|
tok->err = json_tokener_error_parse_object_key_sep;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case json_tokener_state_object_value:
|
case json_tokener_state_object_value:
|
||||||
if(tok->depth >= tok->max_depth-1) {
|
if (tok->depth >= tok->max_depth - 1)
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_depth;
|
tok->err = json_tokener_error_depth;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -958,18 +1097,22 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
|
|
||||||
case json_tokener_state_object_sep:
|
case json_tokener_state_object_sep:
|
||||||
/* { */
|
/* { */
|
||||||
if(c == '}') {
|
if (c == '}')
|
||||||
|
{
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else if(c == ',') {
|
}
|
||||||
|
else if (c == ',')
|
||||||
|
{
|
||||||
saved_state = json_tokener_state_object_field_start_after_sep;
|
saved_state = json_tokener_state_object_field_start_after_sep;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tok->err = json_tokener_error_parse_object_value_sep;
|
tok->err = json_tokener_error_parse_object_value_sep;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!ADVANCE_CHAR(str, tok))
|
if (!ADVANCE_CHAR(str, tok))
|
||||||
goto out;
|
goto out;
|
||||||
@@ -980,17 +1123,16 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
tok->err = json_tokener_error_parse_utf8_string;
|
tok->err = json_tokener_error_parse_utf8_string;
|
||||||
}
|
}
|
||||||
if (c &&
|
if (c && (state == json_tokener_state_finish) && (tok->depth == 0) &&
|
||||||
(state == json_tokener_state_finish) &&
|
(tok->flags & JSON_TOKENER_STRICT))
|
||||||
(tok->depth == 0) &&
|
{
|
||||||
(tok->flags & JSON_TOKENER_STRICT)) {
|
|
||||||
/* unexpected char after JSON data */
|
/* unexpected char after JSON data */
|
||||||
tok->err = json_tokener_error_parse_unexpected;
|
tok->err = json_tokener_error_parse_unexpected;
|
||||||
}
|
}
|
||||||
if (!c) {
|
if (!c)
|
||||||
|
{
|
||||||
/* We hit an eof char (0) */
|
/* We hit an eof char (0) */
|
||||||
if(state != json_tokener_state_finish &&
|
if (state != json_tokener_state_finish && saved_state != json_tokener_state_finish)
|
||||||
saved_state != json_tokener_state_finish)
|
|
||||||
tok->err = json_tokener_error_parse_eof;
|
tok->err = json_tokener_error_parse_eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,8 +1155,8 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
|
MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n", json_tokener_errors[tok->err],
|
||||||
json_tokener_errors[tok->err], tok->char_offset);
|
tok->char_offset);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1054,4 +1196,3 @@ size_t json_tokener_get_parse_end(struct json_tokener *tok)
|
|||||||
assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
|
assert(tok->char_offset >= 0); /* Drop this line when char_offset becomes a size_t */
|
||||||
return (size_t)tok->char_offset;
|
return (size_t)tok->char_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,15 @@
|
|||||||
#ifndef _json_tokener_h_
|
#ifndef _json_tokener_h_
|
||||||
#define _json_tokener_h_
|
#define _json_tokener_h_
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum json_tokener_error {
|
enum json_tokener_error
|
||||||
|
{
|
||||||
json_tokener_success,
|
json_tokener_success,
|
||||||
json_tokener_continue,
|
json_tokener_continue,
|
||||||
json_tokener_error_depth,
|
json_tokener_error_depth,
|
||||||
@@ -42,7 +43,8 @@ enum json_tokener_error {
|
|||||||
json_tokener_error_size
|
json_tokener_error_size
|
||||||
};
|
};
|
||||||
|
|
||||||
enum json_tokener_state {
|
enum json_tokener_state
|
||||||
|
{
|
||||||
json_tokener_state_eatws,
|
json_tokener_state_eatws,
|
||||||
json_tokener_state_start,
|
json_tokener_state_start,
|
||||||
json_tokener_state_finish,
|
json_tokener_state_finish,
|
||||||
@@ -119,7 +121,6 @@ struct json_tokener
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT size_t json_tokener_get_parse_end(struct json_tokener *tok);
|
JSON_EXPORT size_t json_tokener_get_parse_end(struct json_tokener *tok);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Unused in json-c code
|
* @deprecated Unused in json-c code
|
||||||
*/
|
*/
|
||||||
@@ -172,7 +173,8 @@ JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth);
|
|||||||
JSON_EXPORT void json_tokener_free(struct json_tokener *tok);
|
JSON_EXPORT void json_tokener_free(struct json_tokener *tok);
|
||||||
JSON_EXPORT void json_tokener_reset(struct json_tokener *tok);
|
JSON_EXPORT void json_tokener_reset(struct json_tokener *tok);
|
||||||
JSON_EXPORT struct json_object *json_tokener_parse(const char *str);
|
JSON_EXPORT struct json_object *json_tokener_parse(const char *str);
|
||||||
JSON_EXPORT struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
|
JSON_EXPORT struct json_object *json_tokener_parse_verbose(const char *str,
|
||||||
|
enum json_tokener_error *error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* validete the utf-8 string in strict model.
|
* validete the utf-8 string in strict model.
|
||||||
@@ -253,8 +255,8 @@ if (json_tokener_get_parse_end(tok) < stringlen)
|
|||||||
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
|
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
|
||||||
* @param len the length of str
|
* @param len the length of str
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
JSON_EXPORT struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str,
|
||||||
const char *str, int len);
|
int len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
68
json_util.c
68
json_util.c
@@ -14,13 +14,13 @@
|
|||||||
|
|
||||||
#include "strerror_override.h"
|
#include "strerror_override.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
#define strtoull _strtoui64
|
#define strtoull _strtoui64
|
||||||
#endif
|
#endif
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
# include <windows.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <windows.h>
|
||||||
#endif /* defined(WIN32) */
|
#endif /* defined(WIN32) */
|
||||||
|
|
||||||
#if !defined(HAVE_OPEN) && defined(WIN32)
|
#if !defined(HAVE_OPEN) && defined(WIN32)
|
||||||
@@ -56,11 +56,11 @@
|
|||||||
#include "snprintf_compat.h"
|
#include "snprintf_compat.h"
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "printbuf.h"
|
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
#include "json_util.h"
|
#include "json_util.h"
|
||||||
|
#include "printbuf.h"
|
||||||
|
|
||||||
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
|
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
|
||||||
|
|
||||||
@@ -95,7 +95,8 @@ struct json_object* json_object_from_fd_ex(int fd, int in_depth)
|
|||||||
int depth = JSON_TOKENER_DEFAULT_DEPTH;
|
int depth = JSON_TOKENER_DEFAULT_DEPTH;
|
||||||
json_tokener *tok;
|
json_tokener *tok;
|
||||||
|
|
||||||
if(!(pb = printbuf_new())) {
|
if (!(pb = printbuf_new()))
|
||||||
|
{
|
||||||
_json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
|
_json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -105,16 +106,21 @@ struct json_object* json_object_from_fd_ex(int fd, int in_depth)
|
|||||||
tok = json_tokener_new_ex(depth);
|
tok = json_tokener_new_ex(depth);
|
||||||
if (!tok)
|
if (!tok)
|
||||||
{
|
{
|
||||||
_json_c_set_last_err("json_object_from_fd: unable to allocate json_tokener(depth=%d): %s\n", depth, strerror(errno));
|
_json_c_set_last_err(
|
||||||
|
"json_object_from_fd: unable to allocate json_tokener(depth=%d): %s\n", depth,
|
||||||
|
strerror(errno));
|
||||||
printbuf_free(pb);
|
printbuf_free(pb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
|
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
|
||||||
|
{
|
||||||
printbuf_memappend(pb, buf, ret);
|
printbuf_memappend(pb, buf, ret);
|
||||||
}
|
}
|
||||||
if(ret < 0) {
|
if (ret < 0)
|
||||||
_json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno));
|
{
|
||||||
|
_json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd,
|
||||||
|
strerror(errno));
|
||||||
json_tokener_free(tok);
|
json_tokener_free(tok);
|
||||||
printbuf_free(pb);
|
printbuf_free(pb);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -122,7 +128,8 @@ struct json_object* json_object_from_fd_ex(int fd, int in_depth)
|
|||||||
|
|
||||||
obj = json_tokener_parse_ex(tok, pb->buf, printbuf_length(pb));
|
obj = json_tokener_parse_ex(tok, pb->buf, printbuf_length(pb));
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
_json_c_set_last_err("json_tokener_parse_ex failed: %s\n", json_tokener_error_desc(json_tokener_get_error(tok)));
|
_json_c_set_last_err("json_tokener_parse_ex failed: %s\n",
|
||||||
|
json_tokener_error_desc(json_tokener_get_error(tok)));
|
||||||
|
|
||||||
json_tokener_free(tok);
|
json_tokener_free(tok);
|
||||||
printbuf_free(pb);
|
printbuf_free(pb);
|
||||||
@@ -134,9 +141,10 @@ struct json_object* json_object_from_file(const char *filename)
|
|||||||
struct json_object *obj;
|
struct json_object *obj;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if((fd = open(filename, O_RDONLY)) < 0) {
|
if ((fd = open(filename, O_RDONLY)) < 0)
|
||||||
_json_c_set_last_err("json_object_from_file: error opening file %s: %s\n",
|
{
|
||||||
filename, strerror(errno));
|
_json_c_set_last_err("json_object_from_file: error opening file %s: %s\n", filename,
|
||||||
|
strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
obj = json_object_from_fd(fd);
|
obj = json_object_from_fd(fd);
|
||||||
@@ -151,14 +159,16 @@ int json_object_to_file_ext(const char *filename, struct json_object *obj, int f
|
|||||||
int fd, ret;
|
int fd, ret;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
|
|
||||||
if (!obj) {
|
if (!obj)
|
||||||
|
{
|
||||||
_json_c_set_last_err("json_object_to_file: object is null\n");
|
_json_c_set_last_err("json_object_to_file: object is null\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
|
if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0)
|
||||||
_json_c_set_last_err("json_object_to_file: error opening file %s: %s\n",
|
{
|
||||||
filename, strerror(errno));
|
_json_c_set_last_err("json_object_to_file: error opening file %s: %s\n", filename,
|
||||||
|
strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = _json_object_to_fd(fd, obj, flags, filename);
|
ret = _json_object_to_fd(fd, obj, flags, filename);
|
||||||
@@ -170,7 +180,8 @@ int json_object_to_file_ext(const char *filename, struct json_object *obj, int f
|
|||||||
|
|
||||||
int json_object_to_fd(int fd, struct json_object *obj, int flags)
|
int json_object_to_fd(int fd, struct json_object *obj, int flags)
|
||||||
{
|
{
|
||||||
if (!obj) {
|
if (!obj)
|
||||||
|
{
|
||||||
_json_c_set_last_err("json_object_to_fd: object is null\n");
|
_json_c_set_last_err("json_object_to_fd: object is null\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -185,15 +196,18 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const
|
|||||||
|
|
||||||
filename = filename ? filename : "(fd)";
|
filename = filename ? filename : "(fd)";
|
||||||
|
|
||||||
if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
|
if (!(json_str = json_object_to_json_string_ext(obj, flags)))
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CAW: probably unnecessary, but the most 64bit safe */
|
/* CAW: probably unnecessary, but the most 64bit safe */
|
||||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX);
|
wsize = (unsigned int)(strlen(json_str) & UINT_MAX);
|
||||||
wpos = 0;
|
wpos = 0;
|
||||||
while(wpos < wsize) {
|
while (wpos < wsize)
|
||||||
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
|
{
|
||||||
|
if ((ret = write(fd, json_str + wpos, wsize - wpos)) < 0)
|
||||||
|
{
|
||||||
_json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
|
_json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
|
||||||
filename, strerror(errno));
|
filename, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
@@ -238,10 +252,12 @@ int json_parse_uint64(const char *buf, uint64_t *retval)
|
|||||||
uint64_t val;
|
uint64_t val;
|
||||||
errno = 1;
|
errno = 1;
|
||||||
|
|
||||||
while (*buf == ' ') {
|
while (*buf == ' ')
|
||||||
|
{
|
||||||
buf++;
|
buf++;
|
||||||
}
|
}
|
||||||
if (*buf == '-') errno = 0;
|
if (*buf == '-')
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
val = strtoull(buf, &end, 10);
|
val = strtoull(buf, &end, 10);
|
||||||
if (end != buf)
|
if (end != buf)
|
||||||
@@ -279,7 +295,8 @@ const char *json_type_to_name(enum json_type o_type)
|
|||||||
int o_type_int = (int)o_type;
|
int o_type_int = (int)o_type;
|
||||||
if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
|
if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
|
||||||
{
|
{
|
||||||
_json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
|
_json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type,
|
||||||
|
NELEM(json_type_name));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return json_type_name[o_type];
|
return json_type_name[o_type];
|
||||||
@@ -291,4 +308,3 @@ void json_abort(const char *message)
|
|||||||
fprintf(stderr, "json-c aborts with error: %s\n", message);
|
fprintf(stderr, "json-c aborts with error: %s\n", message);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
#define json_max(a, b) ((a) > (b) ? (a) : (b))
|
#define json_max(a, b) ((a) > (b) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@@ -101,7 +100,6 @@ JSON_EXPORT int json_object_to_fd(int fd, struct json_object *obj, int flags);
|
|||||||
*/
|
*/
|
||||||
JSON_EXPORT const char *json_util_get_last_err(void);
|
JSON_EXPORT const char *json_util_get_last_err(void);
|
||||||
|
|
||||||
|
|
||||||
JSON_EXPORT int json_parse_int64(const char *buf, int64_t *retval);
|
JSON_EXPORT int json_parse_int64(const char *buf, int64_t *retval);
|
||||||
JSON_EXPORT int json_parse_uint64(const char *buf, uint64_t *retval);
|
JSON_EXPORT int json_parse_uint64(const char *buf, uint64_t *retval);
|
||||||
JSON_EXPORT int json_parse_double(const char *buf, double *retval);
|
JSON_EXPORT int json_parse_double(const char *buf, double *retval);
|
||||||
|
|||||||
47
json_visit.c
47
json_visit.c
@@ -13,12 +13,10 @@
|
|||||||
#include "json_visit.h"
|
#include "json_visit.h"
|
||||||
#include "linkhash.h"
|
#include "linkhash.h"
|
||||||
|
|
||||||
static int _json_c_visit(json_object *jso, json_object *parent_jso,
|
static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key,
|
||||||
const char *jso_key, size_t *jso_index,
|
size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg);
|
||||||
json_c_visit_userfunc *userfunc, void *userarg);
|
|
||||||
|
|
||||||
int json_c_visit(json_object *jso, int future_flags,
|
int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, void *userarg)
|
||||||
json_c_visit_userfunc *userfunc, void *userarg)
|
|
||||||
{
|
{
|
||||||
int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg);
|
int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg);
|
||||||
switch (ret)
|
switch (ret)
|
||||||
@@ -26,28 +24,24 @@ int json_c_visit(json_object *jso, int future_flags,
|
|||||||
case JSON_C_VISIT_RETURN_CONTINUE:
|
case JSON_C_VISIT_RETURN_CONTINUE:
|
||||||
case JSON_C_VISIT_RETURN_SKIP:
|
case JSON_C_VISIT_RETURN_SKIP:
|
||||||
case JSON_C_VISIT_RETURN_POP:
|
case JSON_C_VISIT_RETURN_POP:
|
||||||
case JSON_C_VISIT_RETURN_STOP:
|
case JSON_C_VISIT_RETURN_STOP: return 0;
|
||||||
return 0;
|
default: return JSON_C_VISIT_RETURN_ERROR;
|
||||||
default:
|
|
||||||
return JSON_C_VISIT_RETURN_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int _json_c_visit(json_object *jso, json_object *parent_jso,
|
static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key,
|
||||||
const char *jso_key, size_t *jso_index,
|
size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg)
|
||||||
json_c_visit_userfunc *userfunc, void *userarg)
|
|
||||||
{
|
{
|
||||||
int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg);
|
int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg);
|
||||||
switch (userret)
|
switch (userret)
|
||||||
{
|
{
|
||||||
case JSON_C_VISIT_RETURN_CONTINUE:
|
case JSON_C_VISIT_RETURN_CONTINUE: break;
|
||||||
break;
|
|
||||||
case JSON_C_VISIT_RETURN_SKIP:
|
case JSON_C_VISIT_RETURN_SKIP:
|
||||||
case JSON_C_VISIT_RETURN_POP:
|
case JSON_C_VISIT_RETURN_POP:
|
||||||
case JSON_C_VISIT_RETURN_STOP:
|
case JSON_C_VISIT_RETURN_STOP:
|
||||||
case JSON_C_VISIT_RETURN_ERROR:
|
case JSON_C_VISIT_RETURN_ERROR: return userret;
|
||||||
return userret;
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
|
fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n",
|
||||||
|
userret);
|
||||||
return JSON_C_VISIT_RETURN_ERROR;
|
return JSON_C_VISIT_RETURN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +68,8 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso,
|
|||||||
if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
|
if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
|
||||||
userret != JSON_C_VISIT_RETURN_SKIP)
|
userret != JSON_C_VISIT_RETURN_SKIP)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
|
fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n",
|
||||||
|
userret);
|
||||||
return JSON_C_VISIT_RETURN_ERROR;
|
return JSON_C_VISIT_RETURN_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,14 +91,16 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso,
|
|||||||
if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
|
if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
|
||||||
userret != JSON_C_VISIT_RETURN_SKIP)
|
userret != JSON_C_VISIT_RETURN_SKIP)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
|
fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n",
|
||||||
|
userret);
|
||||||
return JSON_C_VISIT_RETURN_ERROR;
|
return JSON_C_VISIT_RETURN_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", json_object_get_type(jso));
|
fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n",
|
||||||
|
json_object_get_type(jso));
|
||||||
return JSON_C_VISIT_RETURN_ERROR;
|
return JSON_C_VISIT_RETURN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,15 +116,13 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso,
|
|||||||
// These are not really sensible during JSON_C_VISIT_SECOND,
|
// These are not really sensible during JSON_C_VISIT_SECOND,
|
||||||
// but map them to JSON_C_VISIT_CONTINUE anyway.
|
// but map them to JSON_C_VISIT_CONTINUE anyway.
|
||||||
// FALLTHROUGH
|
// FALLTHROUGH
|
||||||
case JSON_C_VISIT_RETURN_CONTINUE:
|
case JSON_C_VISIT_RETURN_CONTINUE: return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
|
||||||
case JSON_C_VISIT_RETURN_STOP:
|
case JSON_C_VISIT_RETURN_STOP:
|
||||||
case JSON_C_VISIT_RETURN_ERROR:
|
case JSON_C_VISIT_RETURN_ERROR: return userret;
|
||||||
return userret;
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
|
fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n",
|
||||||
|
userret);
|
||||||
return JSON_C_VISIT_RETURN_ERROR;
|
return JSON_C_VISIT_RETURN_ERROR;
|
||||||
}
|
}
|
||||||
// NOTREACHED
|
// NOTREACHED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
10
json_visit.h
10
json_visit.h
@@ -8,9 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
|
|
||||||
typedef int (json_c_visit_userfunc)(json_object *jso, int flags,
|
typedef int(json_c_visit_userfunc)(json_object *jso, int flags, json_object *parent_jso,
|
||||||
json_object *parent_jso, const char *jso_key,
|
const char *jso_key, size_t *jso_index, void *userarg);
|
||||||
size_t *jso_index, void *userarg);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visit each object in the JSON hierarchy starting at jso.
|
* Visit each object in the JSON hierarchy starting at jso.
|
||||||
@@ -31,8 +30,8 @@ typedef int (json_c_visit_userfunc)(json_object *jso, int flags,
|
|||||||
* Returns <0 if an error occurred during iteration, including if
|
* Returns <0 if an error occurred during iteration, including if
|
||||||
* userfunc returned JSON_C_VISIT_RETURN_ERROR.
|
* userfunc returned JSON_C_VISIT_RETURN_ERROR.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int json_c_visit(json_object *jso, int future_flags,
|
JSON_EXPORT int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc,
|
||||||
json_c_visit_userfunc *userfunc, void *userarg);
|
void *userarg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passed to json_c_visit_userfunc as one of the flags values to indicate
|
* Passed to json_c_visit_userfunc as one of the flags values to indicate
|
||||||
@@ -47,7 +46,6 @@ JSON_EXPORT int json_c_visit(json_object *jso, int future_flags,
|
|||||||
*/
|
*/
|
||||||
#define JSON_C_VISIT_RETURN_CONTINUE 0
|
#define JSON_C_VISIT_RETURN_CONTINUE 0
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This json_c_visit_userfunc return value indicates that iteration
|
* This json_c_visit_userfunc return value indicates that iteration
|
||||||
* over the members of the current object should be skipped.
|
* over the members of the current object should be skipped.
|
||||||
|
|||||||
133
linkhash.c
133
linkhash.c
@@ -12,12 +12,12 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <limits.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef HAVE_ENDIAN_H
|
#ifdef HAVE_ENDIAN_H
|
||||||
#include <endian.h> /* attempt to define endianness */
|
#include <endian.h> /* attempt to define endianness */
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
#include <windows.h> /* Get InterlockedCompareExchange */
|
#include <windows.h> /* Get InterlockedCompareExchange */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "random_seed.h"
|
|
||||||
#include "linkhash.h"
|
#include "linkhash.h"
|
||||||
|
#include "random_seed.h"
|
||||||
|
|
||||||
/* hash functions */
|
/* hash functions */
|
||||||
static unsigned long lh_char_hash(const void *k);
|
static unsigned long lh_char_hash(const void *k);
|
||||||
@@ -40,18 +40,13 @@ static lh_hash_fn *char_hash_fn = lh_char_hash;
|
|||||||
int lh_char_equal(const void *k1, const void *k2);
|
int lh_char_equal(const void *k1, const void *k2);
|
||||||
int lh_ptr_equal(const void *k1, const void *k2);
|
int lh_ptr_equal(const void *k1, const void *k2);
|
||||||
|
|
||||||
int
|
int json_global_set_string_hash(const int h)
|
||||||
json_global_set_string_hash(const int h)
|
|
||||||
{
|
{
|
||||||
switch(h) {
|
switch (h)
|
||||||
case JSON_C_STR_HASH_DFLT:
|
{
|
||||||
char_hash_fn = lh_char_hash;
|
case JSON_C_STR_HASH_DFLT: char_hash_fn = lh_char_hash; break;
|
||||||
break;
|
case JSON_C_STR_HASH_PERLLIKE: char_hash_fn = lh_perllike_str_hash; break;
|
||||||
case JSON_C_STR_HASH_PERLLIKE:
|
default: return -1;
|
||||||
char_hash_fn = lh_perllike_str_hash;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -114,14 +109,12 @@ on 1 byte), but shoehorning those bytes into integers efficiently is messy.
|
|||||||
* My best guess at if you are big-endian or little-endian. This may
|
* My best guess at if you are big-endian or little-endian. This may
|
||||||
* need adjustment.
|
* need adjustment.
|
||||||
*/
|
*/
|
||||||
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
|
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
|
||||||
__BYTE_ORDER == __LITTLE_ENDIAN) || \
|
(defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \
|
||||||
(defined(i386) || defined(__i386__) || defined(__i486__) || \
|
defined(__i686__) || defined(vax) || defined(MIPSEL))
|
||||||
defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
|
|
||||||
#define HASH_LITTLE_ENDIAN 1
|
#define HASH_LITTLE_ENDIAN 1
|
||||||
#define HASH_BIG_ENDIAN 0
|
#define HASH_BIG_ENDIAN 0
|
||||||
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
|
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
|
||||||
__BYTE_ORDER == __BIG_ENDIAN) || \
|
|
||||||
(defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
|
(defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
|
||||||
#define HASH_LITTLE_ENDIAN 0
|
#define HASH_LITTLE_ENDIAN 0
|
||||||
#define HASH_BIG_ENDIAN 1
|
#define HASH_BIG_ENDIAN 1
|
||||||
@@ -228,7 +221,6 @@ and these came close:
|
|||||||
}
|
}
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
hashlittle() -- hash a variable-length key into a 32-bit value
|
hashlittle() -- hash a variable-length key into a 32-bit value
|
||||||
@@ -469,7 +461,8 @@ static unsigned long lh_char_hash(const void *k)
|
|||||||
#endif
|
#endif
|
||||||
static volatile RANDOM_SEED_TYPE random_seed = -1;
|
static volatile RANDOM_SEED_TYPE random_seed = -1;
|
||||||
|
|
||||||
if (random_seed == -1) {
|
if (random_seed == -1)
|
||||||
|
{
|
||||||
RANDOM_SEED_TYPE seed;
|
RANDOM_SEED_TYPE seed;
|
||||||
/* we can't use -1 as it is the unitialized sentinel */
|
/* we can't use -1 as it is the unitialized sentinel */
|
||||||
while ((seed = json_c_get_random_seed()) == -1) {}
|
while ((seed = json_c_get_random_seed()) == -1) {}
|
||||||
@@ -500,9 +493,7 @@ int lh_char_equal(const void *k1, const void *k2)
|
|||||||
return (strcmp((const char *)k1, (const char *)k2) == 0);
|
return (strcmp((const char *)k1, (const char *)k2) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lh_table* lh_table_new(int size,
|
struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn,
|
||||||
lh_entry_free_fn *free_fn,
|
|
||||||
lh_hash_fn *hash_fn,
|
|
||||||
lh_equal_fn *equal_fn)
|
lh_equal_fn *equal_fn)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -523,18 +514,17 @@ struct lh_table* lh_table_new(int size,
|
|||||||
t->free_fn = free_fn;
|
t->free_fn = free_fn;
|
||||||
t->hash_fn = hash_fn;
|
t->hash_fn = hash_fn;
|
||||||
t->equal_fn = equal_fn;
|
t->equal_fn = equal_fn;
|
||||||
for(i = 0; i < size; i++) t->table[i].k = LH_EMPTY;
|
for (i = 0; i < size; i++)
|
||||||
|
t->table[i].k = LH_EMPTY;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lh_table* lh_kchar_table_new(int size,
|
struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn)
|
||||||
lh_entry_free_fn *free_fn)
|
|
||||||
{
|
{
|
||||||
return lh_table_new(size, free_fn, char_hash_fn, lh_char_equal);
|
return lh_table_new(size, free_fn, char_hash_fn, lh_char_equal);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct lh_table* lh_kptr_table_new(int size,
|
struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn)
|
||||||
lh_entry_free_fn *free_fn)
|
|
||||||
{
|
{
|
||||||
return lh_table_new(size, free_fn, lh_ptr_hash, lh_ptr_equal);
|
return lh_table_new(size, free_fn, lh_ptr_hash, lh_ptr_equal);
|
||||||
}
|
}
|
||||||
@@ -573,7 +563,8 @@ int lh_table_resize(struct lh_table *t, int new_size)
|
|||||||
void lh_table_free(struct lh_table *t)
|
void lh_table_free(struct lh_table *t)
|
||||||
{
|
{
|
||||||
struct lh_entry *c;
|
struct lh_entry *c;
|
||||||
if(t->free_fn) {
|
if (t->free_fn)
|
||||||
|
{
|
||||||
for (c = t->head; c != NULL; c = c->next)
|
for (c = t->head; c != NULL; c = c->next)
|
||||||
t->free_fn(c);
|
t->free_fn(c);
|
||||||
}
|
}
|
||||||
@@ -581,8 +572,8 @@ void lh_table_free(struct lh_table *t)
|
|||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h,
|
||||||
int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts)
|
const unsigned opts)
|
||||||
{
|
{
|
||||||
unsigned long n;
|
unsigned long n;
|
||||||
|
|
||||||
@@ -592,9 +583,12 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con
|
|||||||
|
|
||||||
n = h % t->size;
|
n = h % t->size;
|
||||||
|
|
||||||
while( 1 ) {
|
while (1)
|
||||||
if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break;
|
{
|
||||||
if ((int)++n == t->size) n = 0;
|
if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED)
|
||||||
|
break;
|
||||||
|
if ((int)++n == t->size)
|
||||||
|
n = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
t->table[n].k = k;
|
t->table[n].k = k;
|
||||||
@@ -602,10 +596,13 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con
|
|||||||
t->table[n].v = v;
|
t->table[n].v = v;
|
||||||
t->count++;
|
t->count++;
|
||||||
|
|
||||||
if(t->head == NULL) {
|
if (t->head == NULL)
|
||||||
|
{
|
||||||
t->head = t->tail = &t->table[n];
|
t->head = t->tail = &t->table[n];
|
||||||
t->table[n].next = t->table[n].prev = NULL;
|
t->table[n].next = t->table[n].prev = NULL;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
t->tail->next = &t->table[n];
|
t->tail->next = &t->table[n];
|
||||||
t->table[n].prev = t->tail;
|
t->table[n].prev = t->tail;
|
||||||
t->table[n].next = NULL;
|
t->table[n].next = NULL;
|
||||||
@@ -619,17 +616,20 @@ int lh_table_insert(struct lh_table *t, const void *k, const void *v)
|
|||||||
return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0);
|
return lh_table_insert_w_hash(t, k, v, lh_get_hash(t, k), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k,
|
||||||
struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h)
|
const unsigned long h)
|
||||||
{
|
{
|
||||||
unsigned long n = h % t->size;
|
unsigned long n = h % t->size;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
while( count < t->size ) {
|
while (count < t->size)
|
||||||
if(t->table[n].k == LH_EMPTY) return NULL;
|
{
|
||||||
if(t->table[n].k != LH_FREED &&
|
if (t->table[n].k == LH_EMPTY)
|
||||||
t->equal_fn(t->table[n].k, k)) return &t->table[n];
|
return NULL;
|
||||||
if ((int)++n == t->size) n = 0;
|
if (t->table[n].k != LH_FREED && t->equal_fn(t->table[n].k, k))
|
||||||
|
return &t->table[n];
|
||||||
|
if ((int)++n == t->size)
|
||||||
|
n = 0;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -643,11 +643,14 @@ struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
|
|||||||
json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v)
|
json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v)
|
||||||
{
|
{
|
||||||
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
||||||
if (e != NULL) {
|
if (e != NULL)
|
||||||
if (v != NULL) *v = lh_entry_v(e);
|
{
|
||||||
|
if (v != NULL)
|
||||||
|
*v = lh_entry_v(e);
|
||||||
return 1; /* key found */
|
return 1; /* key found */
|
||||||
}
|
}
|
||||||
if (v != NULL) *v = NULL;
|
if (v != NULL)
|
||||||
|
*v = NULL;
|
||||||
return 0; /* key not found */
|
return 0; /* key not found */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,22 +660,34 @@ int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
|||||||
ptrdiff_t n = (ptrdiff_t)(e - t->table);
|
ptrdiff_t n = (ptrdiff_t)(e - t->table);
|
||||||
|
|
||||||
/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
|
/* CAW: this is bad, really bad, maybe stack goes other direction on this machine... */
|
||||||
if(n < 0) { return -2; }
|
if (n < 0)
|
||||||
|
{
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) return -1;
|
if (t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED)
|
||||||
|
return -1;
|
||||||
t->count--;
|
t->count--;
|
||||||
if(t->free_fn) t->free_fn(e);
|
if (t->free_fn)
|
||||||
|
t->free_fn(e);
|
||||||
t->table[n].v = NULL;
|
t->table[n].v = NULL;
|
||||||
t->table[n].k = LH_FREED;
|
t->table[n].k = LH_FREED;
|
||||||
if(t->tail == &t->table[n] && t->head == &t->table[n]) {
|
if (t->tail == &t->table[n] && t->head == &t->table[n])
|
||||||
|
{
|
||||||
t->head = t->tail = NULL;
|
t->head = t->tail = NULL;
|
||||||
} else if (t->head == &t->table[n]) {
|
}
|
||||||
|
else if (t->head == &t->table[n])
|
||||||
|
{
|
||||||
t->head->next->prev = NULL;
|
t->head->next->prev = NULL;
|
||||||
t->head = t->head->next;
|
t->head = t->head->next;
|
||||||
} else if (t->tail == &t->table[n]) {
|
}
|
||||||
|
else if (t->tail == &t->table[n])
|
||||||
|
{
|
||||||
t->tail->prev->next = NULL;
|
t->tail->prev->next = NULL;
|
||||||
t->tail = t->tail->prev;
|
t->tail = t->tail->prev;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
t->table[n].prev->next = t->table[n].next;
|
t->table[n].prev->next = t->table[n].next;
|
||||||
t->table[n].next->prev = t->table[n].prev;
|
t->table[n].next->prev = t->table[n].prev;
|
||||||
}
|
}
|
||||||
@@ -680,11 +695,11 @@ int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int lh_table_delete(struct lh_table *t, const void *k)
|
int lh_table_delete(struct lh_table *t, const void *k)
|
||||||
{
|
{
|
||||||
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
struct lh_entry *e = lh_table_lookup_entry(t, k);
|
||||||
if(!e) return -1;
|
if (!e)
|
||||||
|
return -1;
|
||||||
return lh_table_delete_entry(t, e);
|
return lh_table_delete_entry(t, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
linkhash.h
36
linkhash.h
@@ -82,7 +82,8 @@ typedef int (lh_equal_fn) (const void *k1, const void *k2);
|
|||||||
/**
|
/**
|
||||||
* An entry in the hash table
|
* An entry in the hash table
|
||||||
*/
|
*/
|
||||||
struct lh_entry {
|
struct lh_entry
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* The key. Use lh_entry_k() instead of accessing this directly.
|
* The key. Use lh_entry_k() instead of accessing this directly.
|
||||||
*/
|
*/
|
||||||
@@ -106,11 +107,11 @@ struct lh_entry {
|
|||||||
struct lh_entry *prev;
|
struct lh_entry *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The hash table structure.
|
* The hash table structure.
|
||||||
*/
|
*/
|
||||||
struct lh_table {
|
struct lh_table
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Size of our hash.
|
* Size of our hash.
|
||||||
*/
|
*/
|
||||||
@@ -141,12 +142,10 @@ struct lh_table {
|
|||||||
};
|
};
|
||||||
typedef struct lh_table lh_table;
|
typedef struct lh_table lh_table;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience list iterator.
|
* Convenience list iterator.
|
||||||
*/
|
*/
|
||||||
#define lh_foreach(table, entry) \
|
#define lh_foreach(table, entry) for (entry = table->head; entry; entry = entry->next)
|
||||||
for(entry = table->head; entry; entry = entry->next)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lh_foreach_safe allows calling of deletion routine while iterating.
|
* lh_foreach_safe allows calling of deletion routine while iterating.
|
||||||
@@ -158,8 +157,6 @@ for(entry = table->head; entry; entry = entry->next)
|
|||||||
#define lh_foreach_safe(table, entry, tmp) \
|
#define lh_foreach_safe(table, entry, tmp) \
|
||||||
for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
|
for (entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new linkhash table.
|
* Create a new linkhash table.
|
||||||
*
|
*
|
||||||
@@ -178,9 +175,7 @@ for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
|
|||||||
* @return On success, a pointer to the new linkhash table is returned.
|
* @return On success, a pointer to the new linkhash table is returned.
|
||||||
* On error, a null pointer is returned.
|
* On error, a null pointer is returned.
|
||||||
*/
|
*/
|
||||||
extern struct lh_table* lh_table_new(int size,
|
extern struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn,
|
||||||
lh_entry_free_fn *free_fn,
|
|
||||||
lh_hash_fn *hash_fn,
|
|
||||||
lh_equal_fn *equal_fn);
|
lh_equal_fn *equal_fn);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -191,9 +186,7 @@ extern struct lh_table* lh_table_new(int size,
|
|||||||
* @return On success, a pointer to the new linkhash table is returned.
|
* @return On success, a pointer to the new linkhash table is returned.
|
||||||
* On error, a null pointer is returned.
|
* On error, a null pointer is returned.
|
||||||
*/
|
*/
|
||||||
extern struct lh_table* lh_kchar_table_new(int size,
|
extern struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn);
|
||||||
lh_entry_free_fn *free_fn);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience function to create a new linkhash table with ptr keys.
|
* Convenience function to create a new linkhash table with ptr keys.
|
||||||
@@ -203,9 +196,7 @@ extern struct lh_table* lh_kchar_table_new(int size,
|
|||||||
* @return On success, a pointer to the new linkhash table is returned.
|
* @return On success, a pointer to the new linkhash table is returned.
|
||||||
* On error, a null pointer is returned.
|
* On error, a null pointer is returned.
|
||||||
*/
|
*/
|
||||||
extern struct lh_table* lh_kptr_table_new(int size,
|
extern struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn);
|
||||||
lh_entry_free_fn *free_fn);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a linkhash table.
|
* Free a linkhash table.
|
||||||
@@ -217,7 +208,6 @@ extern struct lh_table* lh_kptr_table_new(int size,
|
|||||||
*/
|
*/
|
||||||
extern void lh_table_free(struct lh_table *t);
|
extern void lh_table_free(struct lh_table *t);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a record into the table.
|
* Insert a record into the table.
|
||||||
*
|
*
|
||||||
@@ -230,7 +220,6 @@ extern void lh_table_free(struct lh_table *t);
|
|||||||
*/
|
*/
|
||||||
extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
|
extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a record into the table using a precalculated key hash.
|
* Insert a record into the table using a precalculated key hash.
|
||||||
*
|
*
|
||||||
@@ -245,8 +234,8 @@ extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
|
|||||||
* @param opts if set to JSON_C_OBJECT_KEY_IS_CONSTANT, sets lh_entry.k_is_constant
|
* @param opts if set to JSON_C_OBJECT_KEY_IS_CONSTANT, sets lh_entry.k_is_constant
|
||||||
* so t's free function knows to avoid freeing the key.
|
* so t's free function knows to avoid freeing the key.
|
||||||
*/
|
*/
|
||||||
extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts);
|
extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v,
|
||||||
|
const unsigned long h, const unsigned opts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a record in the table.
|
* Lookup a record in the table.
|
||||||
@@ -269,7 +258,8 @@ extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k)
|
|||||||
* @param h hash value of the key to lookup
|
* @param h hash value of the key to lookup
|
||||||
* @return a pointer to the record structure of the value or NULL if it does not exist.
|
* @return a pointer to the record structure of the value or NULL if it does not exist.
|
||||||
*/
|
*/
|
||||||
extern struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h);
|
extern struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k,
|
||||||
|
const unsigned long h);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup a record in the table.
|
* Lookup a record in the table.
|
||||||
@@ -293,7 +283,6 @@ extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v)
|
|||||||
*/
|
*/
|
||||||
extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
|
extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a record from the table.
|
* Delete a record from the table.
|
||||||
*
|
*
|
||||||
@@ -319,7 +308,6 @@ extern int lh_table_length(struct lh_table *t);
|
|||||||
*/
|
*/
|
||||||
int lh_table_resize(struct lh_table *t, int new_size);
|
int lh_table_resize(struct lh_table *t, int new_size);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Don't use this outside of linkhash.h:
|
* @deprecated Don't use this outside of linkhash.h:
|
||||||
*/
|
*/
|
||||||
|
|||||||
26
printbuf.c
26
printbuf.c
@@ -37,10 +37,12 @@ struct printbuf* printbuf_new(void)
|
|||||||
struct printbuf *p;
|
struct printbuf *p;
|
||||||
|
|
||||||
p = (struct printbuf *)calloc(1, sizeof(struct printbuf));
|
p = (struct printbuf *)calloc(1, sizeof(struct printbuf));
|
||||||
if(!p) return NULL;
|
if (!p)
|
||||||
|
return NULL;
|
||||||
p->size = 32;
|
p->size = 32;
|
||||||
p->bpos = 0;
|
p->bpos = 0;
|
||||||
if(!(p->buf = (char*)malloc(p->size))) {
|
if (!(p->buf = (char *)malloc(p->size)))
|
||||||
|
{
|
||||||
free(p);
|
free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -48,7 +50,6 @@ struct printbuf* printbuf_new(void)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the buffer p so it has a size of at least min_size.
|
* Extend the buffer p so it has a size of at least min_size.
|
||||||
*
|
*
|
||||||
@@ -82,7 +83,8 @@ static int printbuf_extend(struct printbuf *p, int min_size)
|
|||||||
|
|
||||||
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
|
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
|
||||||
{
|
{
|
||||||
if (p->size <= p->bpos + size + 1) {
|
if (p->size <= p->bpos + size + 1)
|
||||||
|
{
|
||||||
if (printbuf_extend(p, p->bpos + size + 1) < 0)
|
if (printbuf_extend(p, p->bpos + size + 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -128,14 +130,21 @@ int sprintbuf(struct printbuf *p, const char *msg, ...)
|
|||||||
* if output is truncated whereas some return the number of bytes that
|
* if output is truncated whereas some return the number of bytes that
|
||||||
* would have been written - this code handles both cases.
|
* would have been written - this code handles both cases.
|
||||||
*/
|
*/
|
||||||
if(size == -1 || size > 127) {
|
if (size == -1 || size > 127)
|
||||||
|
{
|
||||||
va_start(ap, msg);
|
va_start(ap, msg);
|
||||||
if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
|
if ((size = vasprintf(&t, msg, ap)) < 0)
|
||||||
|
{
|
||||||
|
va_end(ap);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
printbuf_memappend(p, t, size);
|
printbuf_memappend(p, t, size);
|
||||||
free(t);
|
free(t);
|
||||||
return size;
|
return size;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printbuf_memappend(p, buf, size);
|
printbuf_memappend(p, buf, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -149,7 +158,8 @@ void printbuf_reset(struct printbuf *p)
|
|||||||
|
|
||||||
void printbuf_free(struct printbuf *p)
|
void printbuf_free(struct printbuf *p)
|
||||||
{
|
{
|
||||||
if(p) {
|
if (p)
|
||||||
|
{
|
||||||
free(p->buf);
|
free(p->buf);
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|||||||
33
printbuf.h
33
printbuf.h
@@ -35,15 +35,15 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct printbuf {
|
struct printbuf
|
||||||
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int bpos;
|
int bpos;
|
||||||
int size;
|
int size;
|
||||||
};
|
};
|
||||||
typedef struct printbuf printbuf;
|
typedef struct printbuf printbuf;
|
||||||
|
|
||||||
JSON_EXPORT struct printbuf*
|
JSON_EXPORT struct printbuf *printbuf_new(void);
|
||||||
printbuf_new(void);
|
|
||||||
|
|
||||||
/* As an optimization, printbuf_memappend_fast() is defined as a macro
|
/* As an optimization, printbuf_memappend_fast() is defined as a macro
|
||||||
* that handles copying data if the buffer is large enough; otherwise
|
* that handles copying data if the buffer is large enough; otherwise
|
||||||
@@ -53,16 +53,21 @@ printbuf_new(void);
|
|||||||
* Your code should not use printbuf_memappend() directly unless it
|
* Your code should not use printbuf_memappend() directly unless it
|
||||||
* checks the return code. Use printbuf_memappend_fast() instead.
|
* checks the return code. Use printbuf_memappend_fast() instead.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int
|
JSON_EXPORT int printbuf_memappend(struct printbuf *p, const char *buf, int size);
|
||||||
printbuf_memappend(struct printbuf *p, const char *buf, int size);
|
|
||||||
|
|
||||||
#define printbuf_memappend_fast(p, bufptr, bufsize) \
|
#define printbuf_memappend_fast(p, bufptr, bufsize) \
|
||||||
do { \
|
do \
|
||||||
if ((p->size - p->bpos) > bufsize) { \
|
{ \
|
||||||
|
if ((p->size - p->bpos) > bufsize) \
|
||||||
|
{ \
|
||||||
memcpy(p->buf + p->bpos, (bufptr), bufsize); \
|
memcpy(p->buf + p->bpos, (bufptr), bufsize); \
|
||||||
p->bpos += bufsize; \
|
p->bpos += bufsize; \
|
||||||
p->buf[p->bpos] = '\0'; \
|
p->buf[p->bpos] = '\0'; \
|
||||||
} else { printbuf_memappend(p, (bufptr), bufsize); } \
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
printbuf_memappend(p, (bufptr), bufsize); \
|
||||||
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define printbuf_length(p) ((p)->bpos)
|
#define printbuf_length(p) ((p)->bpos)
|
||||||
@@ -97,8 +102,7 @@ do { \
|
|||||||
*
|
*
|
||||||
* If offset is -1, this starts at the end of the current data in the buffer.
|
* If offset is -1, this starts at the end of the current data in the buffer.
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int
|
JSON_EXPORT int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
|
||||||
printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatted print to printbuf.
|
* Formatted print to printbuf.
|
||||||
@@ -114,14 +118,11 @@ printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
|
|||||||
* printbuf_memappend()
|
* printbuf_memappend()
|
||||||
* printbuf_strappend()
|
* printbuf_strappend()
|
||||||
*/
|
*/
|
||||||
JSON_EXPORT int
|
JSON_EXPORT int sprintbuf(struct printbuf *p, const char *msg, ...);
|
||||||
sprintbuf(struct printbuf *p, const char *msg, ...);
|
|
||||||
|
|
||||||
JSON_EXPORT void
|
JSON_EXPORT void printbuf_reset(struct printbuf *p);
|
||||||
printbuf_reset(struct printbuf *p);
|
|
||||||
|
|
||||||
JSON_EXPORT void
|
JSON_EXPORT void printbuf_free(struct printbuf *p);
|
||||||
printbuf_free(struct printbuf *p);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
* Override strerror() to get consistent output across platforms.
|
* Override strerror() to get consistent output across platforms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct {
|
static struct
|
||||||
|
{
|
||||||
int errno_value;
|
int errno_value;
|
||||||
const char *errno_str;
|
const char *errno_str;
|
||||||
} errno_list[] = {
|
} errno_list[] = {
|
||||||
@@ -78,7 +79,8 @@ char *_json_c_strerror(int errno_in)
|
|||||||
if (errno_list[ii].errno_value != errno_in)
|
if (errno_list[ii].errno_value != errno_in)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (start_idx = sizeof(PREFIX) - 1, jj = 0; errno_str[jj] != '\0'; jj++, start_idx++)
|
for (start_idx = sizeof(PREFIX) - 1, jj = 0; errno_str[jj] != '\0';
|
||||||
|
jj++, start_idx++)
|
||||||
{
|
{
|
||||||
errno_buf[start_idx] = errno_str[jj];
|
errno_buf[start_idx] = errno_str[jj];
|
||||||
}
|
}
|
||||||
@@ -100,4 +102,3 @@ char *_json_c_strerror(int errno_in)
|
|||||||
}
|
}
|
||||||
return errno_buf;
|
return errno_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
#error You do not have strcasecmp on your system.
|
#error You do not have strcasecmp on your system.
|
||||||
#endif /* HAVE_STRNCASECMP */
|
#endif /* HAVE_STRNCASECMP */
|
||||||
|
|
||||||
static struct {
|
static struct
|
||||||
|
{
|
||||||
const char *arg;
|
const char *arg;
|
||||||
int flag;
|
int flag;
|
||||||
} format_args[] = {
|
} format_args[] = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "parse_flags.h"
|
#include "parse_flags.h"
|
||||||
@@ -38,7 +38,8 @@ static const char *to_json_string(json_object *obj, int flags)
|
|||||||
copy = strdup(result);
|
copy = strdup(result);
|
||||||
if (copy == NULL)
|
if (copy == NULL)
|
||||||
printf("to_json_string: Allocation failed!\n");
|
printf("to_json_string: Allocation failed!\n");
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
result = json_object_to_json_string_ext(obj, flags);
|
result = json_object_to_json_string_ext(obj, flags);
|
||||||
if (length != strlen(result))
|
if (length != strlen(result))
|
||||||
printf("to_json_string: Length mismatch!\n");
|
printf("to_json_string: Length mismatch!\n");
|
||||||
@@ -94,38 +95,38 @@ void test_array_del_idx()
|
|||||||
for (ii = 0; ii < orig_array_len; ii++)
|
for (ii = 0; ii < orig_array_len; ii++)
|
||||||
{
|
{
|
||||||
rc = json_object_array_del_idx(my_array, 0, 1);
|
rc = json_object_array_del_idx(my_array, 0, 1);
|
||||||
printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n",
|
printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", rc,
|
||||||
rc, json_object_to_json_string(my_array));
|
json_object_to_json_string(my_array));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* One more time, with the empty array: */
|
/* One more time, with the empty array: */
|
||||||
rc = json_object_array_del_idx(my_array, 0, 1);
|
rc = json_object_array_del_idx(my_array, 0, 1);
|
||||||
printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n",
|
printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", rc,
|
||||||
rc, json_object_to_json_string(my_array));
|
json_object_to_json_string(my_array));
|
||||||
|
|
||||||
json_object_put(my_array);
|
json_object_put(my_array);
|
||||||
|
|
||||||
/* Delete all array indexes at once */
|
/* Delete all array indexes at once */
|
||||||
my_array = make_array();
|
my_array = make_array();
|
||||||
rc = json_object_array_del_idx(my_array, 0, orig_array_len);
|
rc = json_object_array_del_idx(my_array, 0, orig_array_len);
|
||||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n",
|
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)orig_array_len, rc,
|
||||||
(int)orig_array_len, rc, json_object_to_json_string(my_array));
|
json_object_to_json_string(my_array));
|
||||||
|
|
||||||
json_object_put(my_array);
|
json_object_put(my_array);
|
||||||
|
|
||||||
/* Delete *more* than all array indexes at once */
|
/* Delete *more* than all array indexes at once */
|
||||||
my_array = make_array();
|
my_array = make_array();
|
||||||
rc = json_object_array_del_idx(my_array, 0, orig_array_len + 1);
|
rc = json_object_array_del_idx(my_array, 0, orig_array_len + 1);
|
||||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n",
|
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)(orig_array_len + 1), rc,
|
||||||
(int)(orig_array_len + 1), rc, json_object_to_json_string(my_array));
|
json_object_to_json_string(my_array));
|
||||||
|
|
||||||
json_object_put(my_array);
|
json_object_put(my_array);
|
||||||
|
|
||||||
/* Delete some array indexes, then add more */
|
/* Delete some array indexes, then add more */
|
||||||
my_array = make_array();
|
my_array = make_array();
|
||||||
rc = json_object_array_del_idx(my_array, 0, orig_array_len - 1);
|
rc = json_object_array_del_idx(my_array, 0, orig_array_len - 1);
|
||||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n",
|
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)(orig_array_len - 1), rc,
|
||||||
(int)(orig_array_len - 1), rc, json_object_to_json_string(my_array));
|
json_object_to_json_string(my_array));
|
||||||
json_object_array_add(my_array, json_object_new_string("s1"));
|
json_object_array_add(my_array, json_object_new_string("s1"));
|
||||||
json_object_array_add(my_array, json_object_new_string("s2"));
|
json_object_array_add(my_array, json_object_new_string("s2"));
|
||||||
json_object_array_add(my_array, json_object_new_string("s3"));
|
json_object_array_add(my_array, json_object_new_string("s3"));
|
||||||
@@ -162,13 +163,15 @@ int main(int argc, char **argv)
|
|||||||
my_string = json_object_new_string("/");
|
my_string = json_object_new_string("/");
|
||||||
printf("my_string=%s\n", json_object_get_string(my_string));
|
printf("my_string=%s\n", json_object_get_string(my_string));
|
||||||
printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
|
printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
|
||||||
printf("my_string.to_string(NOSLASHESCAPE)=%s\n", json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE));
|
printf("my_string.to_string(NOSLASHESCAPE)=%s\n",
|
||||||
|
json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE));
|
||||||
json_object_put(my_string);
|
json_object_put(my_string);
|
||||||
|
|
||||||
my_string = json_object_new_string("/foo/bar/baz");
|
my_string = json_object_new_string("/foo/bar/baz");
|
||||||
printf("my_string=%s\n", json_object_get_string(my_string));
|
printf("my_string=%s\n", json_object_get_string(my_string));
|
||||||
printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
|
printf("my_string.to_string()=%s\n", json_object_to_json_string(my_string));
|
||||||
printf("my_string.to_string(NOSLASHESCAPE)=%s\n", json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE));
|
printf("my_string.to_string(NOSLASHESCAPE)=%s\n",
|
||||||
|
json_object_to_json_string_ext(my_string, JSON_C_TO_STRING_NOSLASHESCAPE));
|
||||||
json_object_put(my_string);
|
json_object_put(my_string);
|
||||||
|
|
||||||
my_string = json_object_new_string("foo");
|
my_string = json_object_new_string("foo");
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
@@ -12,7 +12,6 @@
|
|||||||
/* no special define */
|
/* no special define */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
json_object *new_obj;
|
json_object *new_obj;
|
||||||
@@ -26,8 +25,13 @@ int main(int argc, char **argv)
|
|||||||
sflags = parse_flags(argc, argv);
|
sflags = parse_flags(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
new_obj = json_tokener_parse("/* more difficult test case */"
|
new_obj = json_tokener_parse(
|
||||||
"{ \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", \"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", \"GlossDef\": \"A meta-markup language, used to create markup languages such as DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }");
|
"/* more difficult test case */"
|
||||||
|
"{ \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", "
|
||||||
|
"\"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard "
|
||||||
|
"Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", "
|
||||||
|
"\"GlossDef\": \"A meta-markup language, used to create markup languages such as "
|
||||||
|
"DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }");
|
||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
* gcc -o utf8 utf8.c -I/home/y/include -L./.libs -ljson
|
* gcc -o utf8 utf8.c -I/home/y/include -L./.libs -ljson
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
@@ -27,7 +27,8 @@ void print_hex(const char* s)
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\"";
|
const char *input = "\"\\ud840\\udd26,\\ud840\\udd27,\\ud800\\udd26,\\ud800\\udd27\"";
|
||||||
const char *expected = "\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7";
|
const char *expected =
|
||||||
|
"\xF0\xA0\x84\xA6,\xF0\xA0\x84\xA7,\xF0\x90\x84\xA6,\xF0\x90\x84\xA7";
|
||||||
struct json_object *parse_result = json_tokener_parse(input);
|
struct json_object *parse_result = json_tokener_parse(input);
|
||||||
const char *unjson = json_object_get_string(parse_result);
|
const char *unjson = json_object_get_string(parse_result);
|
||||||
|
|
||||||
@@ -39,7 +40,9 @@ int main(void)
|
|||||||
{
|
{
|
||||||
printf("JSON parse result is correct: %s\n", unjson);
|
printf("JSON parse result is correct: %s\n", unjson);
|
||||||
puts("PASS");
|
puts("PASS");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("JSON parse result doesn't match expected string\n");
|
printf("JSON parse result doesn't match expected string\n");
|
||||||
printf("expected string bytes: ");
|
printf("expected string bytes: ");
|
||||||
print_hex(expected);
|
print_hex(expected);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
@@ -67,8 +67,8 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (new_count != orig_count)
|
if (new_count != orig_count)
|
||||||
{
|
{
|
||||||
printf("mismatch between original count (%d) and new count (%d)\n",
|
printf("mismatch between original count (%d) and new count (%d)\n", orig_count,
|
||||||
orig_count, new_count);
|
new_count);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
* Also checks the json_object_get_type and json_object_is_type functions.
|
* Also checks the json_object_get_type and json_object_is_type functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
@@ -75,30 +75,21 @@ static void getit(struct json_object *new_obj, const char *field)
|
|||||||
printf("Field %s does not exist\n", field);
|
printf("Field %s does not exist\n", field);
|
||||||
|
|
||||||
enum json_type o_type = json_object_get_type(o);
|
enum json_type o_type = json_object_get_type(o);
|
||||||
printf("new_obj.%s json_object_get_type()=%s\n", field,
|
printf("new_obj.%s json_object_get_type()=%s\n", field, json_type_to_name(o_type));
|
||||||
json_type_to_name(o_type));
|
printf("new_obj.%s json_object_get_int()=%d\n", field, json_object_get_int(o));
|
||||||
printf("new_obj.%s json_object_get_int()=%d\n", field,
|
printf("new_obj.%s json_object_get_int64()=%" PRId64 "\n", field, json_object_get_int64(o));
|
||||||
json_object_get_int(o));
|
|
||||||
printf("new_obj.%s json_object_get_int64()=%" PRId64 "\n", field,
|
|
||||||
json_object_get_int64(o));
|
|
||||||
printf("new_obj.%s json_object_get_uint64()=%" PRIu64 "\n", field,
|
printf("new_obj.%s json_object_get_uint64()=%" PRIu64 "\n", field,
|
||||||
json_object_get_uint64(o));
|
json_object_get_uint64(o));
|
||||||
printf("new_obj.%s json_object_get_boolean()=%d\n", field,
|
printf("new_obj.%s json_object_get_boolean()=%d\n", field, json_object_get_boolean(o));
|
||||||
json_object_get_boolean(o));
|
printf("new_obj.%s json_object_get_double()=%f\n", field, json_object_get_double(o));
|
||||||
printf("new_obj.%s json_object_get_double()=%f\n", field,
|
|
||||||
json_object_get_double(o));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checktype_header()
|
static void checktype_header()
|
||||||
{
|
{
|
||||||
printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n",
|
printf("json_object_is_type: %s,%s,%s,%s,%s,%s,%s\n", json_type_to_name(json_type_null),
|
||||||
json_type_to_name(json_type_null),
|
json_type_to_name(json_type_boolean), json_type_to_name(json_type_double),
|
||||||
json_type_to_name(json_type_boolean),
|
json_type_to_name(json_type_int), json_type_to_name(json_type_object),
|
||||||
json_type_to_name(json_type_double),
|
json_type_to_name(json_type_array), json_type_to_name(json_type_string));
|
||||||
json_type_to_name(json_type_int),
|
|
||||||
json_type_to_name(json_type_object),
|
|
||||||
json_type_to_name(json_type_array),
|
|
||||||
json_type_to_name(json_type_string));
|
|
||||||
}
|
}
|
||||||
static void checktype(struct json_object *new_obj, const char *field)
|
static void checktype(struct json_object *new_obj, const char *field)
|
||||||
{
|
{
|
||||||
@@ -106,13 +97,9 @@ static void checktype(struct json_object *new_obj, const char *field)
|
|||||||
if (field && !json_object_object_get_ex(new_obj, field, &o))
|
if (field && !json_object_object_get_ex(new_obj, field, &o))
|
||||||
printf("Field %s does not exist\n", field);
|
printf("Field %s does not exist\n", field);
|
||||||
|
|
||||||
printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n",
|
printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n", field ? "." : " ", field ? field : "",
|
||||||
field ? "." : " ", field ? field : "",
|
json_object_is_type(o, json_type_null), json_object_is_type(o, json_type_boolean),
|
||||||
json_object_is_type(o, json_type_null),
|
json_object_is_type(o, json_type_double), json_object_is_type(o, json_type_int),
|
||||||
json_object_is_type(o, json_type_boolean),
|
json_object_is_type(o, json_type_object), json_object_is_type(o, json_type_array),
|
||||||
json_object_is_type(o, json_type_double),
|
|
||||||
json_object_is_type(o, json_type_int),
|
|
||||||
json_object_is_type(o, json_type_object),
|
|
||||||
json_object_is_type(o, json_type_array),
|
|
||||||
json_object_is_type(o, json_type_string));
|
json_object_is_type(o, json_type_string));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
* Tests if json_object_equal behaves correct.
|
* Tests if json_object_equal behaves correct.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
#undef NDEBUG
|
#undef NDEBUG
|
||||||
@@ -33,7 +33,8 @@ static const char *json_str1 =
|
|||||||
" \"Acronym\": \"SGML\","
|
" \"Acronym\": \"SGML\","
|
||||||
" \"Abbrev\": \"ISO 8879:1986\","
|
" \"Abbrev\": \"ISO 8879:1986\","
|
||||||
" \"GlossDef\": {"
|
" \"GlossDef\": {"
|
||||||
" \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\","
|
" \"para\": \"A meta-markup language, used to create markup languages "
|
||||||
|
"such as DocBook.\","
|
||||||
" \"GlossSeeAlso\": [\"GML\", \"XML\"]"
|
" \"GlossSeeAlso\": [\"GML\", \"XML\"]"
|
||||||
" },"
|
" },"
|
||||||
" \"GlossSee\": \"markup\""
|
" \"GlossSee\": \"markup\""
|
||||||
@@ -72,8 +73,7 @@ static const char *json_str2 =
|
|||||||
" ]"
|
" ]"
|
||||||
"}}";
|
"}}";
|
||||||
|
|
||||||
static const char *json_str3 =
|
static const char *json_str3 = "{\"menu\": {"
|
||||||
"{\"menu\": {"
|
|
||||||
" \"id\": \"file\","
|
" \"id\": \"file\","
|
||||||
" \"value\": \"File\","
|
" \"value\": \"File\","
|
||||||
" \"popup\": {"
|
" \"popup\": {"
|
||||||
@@ -93,7 +93,8 @@ int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level
|
|||||||
}
|
}
|
||||||
|
|
||||||
json_c_shallow_copy_fn my_shallow_copy;
|
json_c_shallow_copy_fn my_shallow_copy;
|
||||||
int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst)
|
int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index,
|
||||||
|
json_object **dst)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
rc = json_c_shallow_copy_default(src, parent, key, index, dst);
|
rc = json_c_shallow_copy_default(src, parent, key, index, dst);
|
||||||
@@ -109,7 +110,6 @@ int my_shallow_copy(json_object *src, json_object *parent, const char *key, size
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct json_object *src1, *src2, *src3;
|
struct json_object *src1, *src2, *src3;
|
||||||
@@ -238,19 +238,24 @@ static void do_benchmark(json_object *src2)
|
|||||||
time_t start = time(NULL);
|
time_t start = time(NULL);
|
||||||
|
|
||||||
start = time(NULL);
|
start = time(NULL);
|
||||||
for (ii = 0; ii < iterations; ii++) {
|
for (ii = 0; ii < iterations; ii++)
|
||||||
|
{
|
||||||
dst2 = json_tokener_parse(json_object_get_string(src2));
|
dst2 = json_tokener_parse(json_object_get_string(src2));
|
||||||
json_object_put(dst2);
|
json_object_put(dst2);
|
||||||
}
|
}
|
||||||
printf("BENCHMARK - %d iterations of 'dst2 = json_tokener_parse(json_object_get_string(src2))' took %d seconds\n", iterations, (int)(time(NULL) - start));
|
printf("BENCHMARK - %d iterations of 'dst2 = "
|
||||||
|
"json_tokener_parse(json_object_get_string(src2))' took %d seconds\n",
|
||||||
|
iterations, (int)(time(NULL) - start));
|
||||||
|
|
||||||
start = time(NULL);
|
start = time(NULL);
|
||||||
dst2 = NULL;
|
dst2 = NULL;
|
||||||
for (ii = 0; ii < iterations; ii++) {
|
for (ii = 0; ii < iterations; ii++)
|
||||||
|
{
|
||||||
json_object_deep_copy(src2, &dst2, NULL);
|
json_object_deep_copy(src2, &dst2, NULL);
|
||||||
json_object_put(dst2);
|
json_object_put(dst2);
|
||||||
dst2 = NULL;
|
dst2 = NULL;
|
||||||
}
|
}
|
||||||
printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d seconds\n", iterations, (int)(time(NULL) - start));
|
printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d "
|
||||||
|
"seconds\n",
|
||||||
|
iterations, (int)(time(NULL) - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
* Tests if the format string for double serialization is handled correctly
|
* Tests if the format string for double serialization is handled correctly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
#include "json_object_private.h"
|
#include "json_object_private.h"
|
||||||
@@ -49,7 +49,8 @@ int main()
|
|||||||
if (json_c_set_serialization_double_format("T%0.2fX", JSON_C_OPTION_THREAD) < 0)
|
if (json_c_set_serialization_double_format("T%0.2fX", JSON_C_OPTION_THREAD) < 0)
|
||||||
printf("ERROR: json_c_set_serialization_double_format() failed");
|
printf("ERROR: json_c_set_serialization_double_format() failed");
|
||||||
printf("obj.to_string(with thread format)=%s\n", json_object_to_json_string(obj));
|
printf("obj.to_string(with thread format)=%s\n", json_object_to_json_string(obj));
|
||||||
if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX", JSON_C_OPTION_THREAD) < 0)
|
if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX",
|
||||||
|
JSON_C_OPTION_THREAD) < 0)
|
||||||
printf("ERROR: json_c_set_serialization_double_format() failed");
|
printf("ERROR: json_c_set_serialization_double_format() failed");
|
||||||
printf("obj.to_string(long thread format)=%s\n", json_object_to_json_string(obj));
|
printf("obj.to_string(long thread format)=%s\n", json_object_to_json_string(obj));
|
||||||
if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_THREAD) < 0)
|
if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_THREAD) < 0)
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* Copyright (C) 2016 by Rainer Gerhards
|
/* Copyright (C) 2016 by Rainer Gerhards
|
||||||
* Released under ASL 2.0 */
|
* Released under ASL 2.0 */
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
|
#include <stdio.h>
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
json_object *json;
|
json_object *json;
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ static void test_example_get()
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct json_object *jo1, *jo2, *jo3;
|
struct json_object *jo1, *jo2, *jo3;
|
||||||
struct json_pointer_map_s_i {
|
struct json_pointer_map_s_i
|
||||||
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
int i;
|
int i;
|
||||||
};
|
};
|
||||||
@@ -239,7 +240,8 @@ static void test_example_set()
|
|||||||
printf("%s\n", json_object_get_string(jo1));
|
printf("%s\n", json_object_get_string(jo1));
|
||||||
|
|
||||||
assert(0 == json_pointer_set(&jo1, "/foo/1", json_object_new_string("cod")));
|
assert(0 == json_pointer_set(&jo1, "/foo/1", json_object_new_string("cod")));
|
||||||
assert(0 == strcmp("cod", json_object_get_string(json_object_array_get_idx(json_object_object_get(jo1, "foo"), 1))));
|
assert(0 == strcmp("cod", json_object_get_string(json_object_array_get_idx(
|
||||||
|
json_object_object_get(jo1, "foo"), 1))));
|
||||||
printf("PASSED - SET - 'cod' in /foo/1\n");
|
printf("PASSED - SET - 'cod' in /foo/1\n");
|
||||||
assert(0 != json_pointer_set(&jo1, "/fud/gaw", (jo2 = json_tokener_parse("[1,2,3]"))));
|
assert(0 != json_pointer_set(&jo1, "/fud/gaw", (jo2 = json_tokener_parse("[1,2,3]"))));
|
||||||
assert(errno == ENOENT);
|
assert(errno == ENOENT);
|
||||||
@@ -256,7 +258,9 @@ static void test_example_set()
|
|||||||
assert(0 == json_pointer_set(&jo1, "/", json_object_new_int(9)));
|
assert(0 == json_pointer_set(&jo1, "/", json_object_new_int(9)));
|
||||||
printf("PASSED - SET - / == 9\n");
|
printf("PASSED - SET - / == 9\n");
|
||||||
|
|
||||||
jo2 = json_tokener_parse("{ 'foo': [ 'bar', 'cod' ], '': 9, 'a/b': 1, 'c%d': 2, 'e^f': 3, 'g|h': 4, 'i\\\\j': 5, 'k\\\"l': 6, ' ': 7, 'm~n': 8, 'fud': { 'gaw': [ 0, 2, 3, 4 ] } }");
|
jo2 = json_tokener_parse(
|
||||||
|
"{ 'foo': [ 'bar', 'cod' ], '': 9, 'a/b': 1, 'c%d': 2, 'e^f': 3, 'g|h': 4, 'i\\\\j': "
|
||||||
|
"5, 'k\\\"l': 6, ' ': 7, 'm~n': 8, 'fud': { 'gaw': [ 0, 2, 3, 4 ] } }");
|
||||||
assert(json_object_equal(jo2, jo1));
|
assert(json_object_equal(jo2, jo1));
|
||||||
printf("PASSED - SET - Final JSON is: %s\n", json_object_get_string(jo1));
|
printf("PASSED - SET - Final JSON is: %s\n", json_object_get_string(jo1));
|
||||||
json_object_put(jo2);
|
json_object_put(jo2);
|
||||||
@@ -286,7 +290,8 @@ static void test_wrong_inputs_set()
|
|||||||
printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n");
|
printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n");
|
||||||
json_object_put(jo2);
|
json_object_put(jo2);
|
||||||
|
|
||||||
assert(0 != json_pointer_setf(&jo1, (jo2 = json_object_new_string("cod")), "%s", "foo/bar"));
|
assert(0 !=
|
||||||
|
json_pointer_setf(&jo1, (jo2 = json_object_new_string("cod")), "%s", "foo/bar"));
|
||||||
printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n");
|
printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n");
|
||||||
json_object_put(jo2);
|
json_object_put(jo2);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
@@ -37,8 +37,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
(void)snprintf(buf2, sizeof(buf2), "%f", 0.1);
|
(void)snprintf(buf2, sizeof(buf2), "%f", 0.1);
|
||||||
if (strcmp(buf1, buf2) != 0)
|
if (strcmp(buf1, buf2) != 0)
|
||||||
printf("ERROR: Original locale not restored \"%s\" != \"%s\"",
|
printf("ERROR: Original locale not restored \"%s\" != \"%s\"", buf1, buf2);
|
||||||
buf1, buf2);
|
|
||||||
|
|
||||||
#ifdef HAVE_SETLOCALE
|
#ifdef HAVE_SETLOCALE
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
@@ -56,9 +55,9 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
printf("]\n");
|
printf("]\n");
|
||||||
|
|
||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string_ext(new_obj,JSON_C_TO_STRING_NOZERO));
|
printf("new_obj.to_string()=%s\n",
|
||||||
|
json_object_to_json_string_ext(new_obj, JSON_C_TO_STRING_NOZERO));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
* Tests if binary strings are supported.
|
* Tests if binary strings are supported.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "json_inttypes.h"
|
#include "json_inttypes.h"
|
||||||
#include "json_object.h"
|
#include "json_object.h"
|
||||||
@@ -24,7 +24,9 @@ int main(void)
|
|||||||
{
|
{
|
||||||
printf("JSON write result is correct: %s\n", json);
|
printf("JSON write result is correct: %s\n", json);
|
||||||
puts("PASS");
|
puts("PASS");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
puts("JSON write result doesn't match expected string");
|
puts("JSON write result doesn't match expected string");
|
||||||
printf("expected string: ");
|
printf("expected string: ");
|
||||||
puts(expected);
|
puts(expected);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
@@ -119,7 +119,9 @@ static void test_basic_parse()
|
|||||||
single_basic_parse("{ \'foo\': \'bar\' }", 0);
|
single_basic_parse("{ \'foo\': \'bar\' }", 0);
|
||||||
single_basic_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }", 0);
|
single_basic_parse("{ \"foo\": \"bar\", \"baz\": null, \"bool0\": true }", 0);
|
||||||
single_basic_parse("{ \"foo\": [null, \"foo\"] }", 0);
|
single_basic_parse("{ \"foo\": [null, \"foo\"] }", 0);
|
||||||
single_basic_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, \"arr\": [ 1, 2, 3, null, 5 ] }", 0);
|
single_basic_parse("{ \"abc\": 12, \"foo\": \"bar\", \"bool0\": false, \"bool1\": true, "
|
||||||
|
"\"arr\": [ 1, 2, 3, null, 5 ] }",
|
||||||
|
0);
|
||||||
single_basic_parse("{ \"abc\": \"blue\nred\\ngreen\" }", 0);
|
single_basic_parse("{ \"abc\": \"blue\nred\\ngreen\" }", 0);
|
||||||
|
|
||||||
// Clear serializer for these tests so we see the actual parsed value.
|
// Clear serializer for these tests so we see the actual parsed value.
|
||||||
@@ -161,10 +163,8 @@ static void do_clear_serializer(json_object *jso)
|
|||||||
json_c_visit(jso, 0, clear_serializer, NULL);
|
json_c_visit(jso, 0, clear_serializer, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clear_serializer(json_object *jso, int flags,
|
static int clear_serializer(json_object *jso, int flags, json_object *parent_jso,
|
||||||
json_object *parent_jso,
|
const char *jso_key, size_t *jso_index, void *userarg)
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
|
||||||
{
|
{
|
||||||
if (jso)
|
if (jso)
|
||||||
json_object_set_serializer(jso, NULL, NULL, NULL);
|
json_object_set_serializer(jso, NULL, NULL, NULL);
|
||||||
@@ -194,7 +194,8 @@ static void test_verbose_parse()
|
|||||||
puts("json_tokener_parse_verbose() OK");
|
puts("json_tokener_parse_verbose() OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct incremental_step {
|
struct incremental_step
|
||||||
|
{
|
||||||
const char *string_to_parse;
|
const char *string_to_parse;
|
||||||
int length;
|
int length;
|
||||||
int char_offset;
|
int char_offset;
|
||||||
@@ -318,8 +319,7 @@ struct incremental_step {
|
|||||||
{"nullx", 5, 4, json_tokener_success, 0},
|
{"nullx", 5, 4, json_tokener_success, 0},
|
||||||
{&"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1},
|
{&"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1},
|
||||||
{"{\"a\":1}{\"b\":2}", 15, 7, json_tokener_success, 0},
|
{"{\"a\":1}{\"b\":2}", 15, 7, json_tokener_success, 0},
|
||||||
{ &"{\"a\":1}{\"b\":2}"[7],
|
{&"{\"a\":1}{\"b\":2}"[7], 8, 7, json_tokener_success, 1},
|
||||||
8, 7, json_tokener_success, 1 },
|
|
||||||
|
|
||||||
/* Some bad formatting. Check we get the correct error status */
|
/* Some bad formatting. Check we get the correct error status */
|
||||||
{"2015-01-15", 10, 4, json_tokener_error_parse_number, 1},
|
{"2015-01-15", 10, 4, json_tokener_error_parse_number, 1},
|
||||||
@@ -393,7 +393,8 @@ struct incremental_step {
|
|||||||
{"\x49\x6e\x66\x81\x6e\x69\x74\x79", -1, 3, json_tokener_error_parse_utf8_string, 5},
|
{"\x49\x6e\x66\x81\x6e\x69\x74\x79", -1, 3, json_tokener_error_parse_utf8_string, 5},
|
||||||
// char in escape unicode
|
// char in escape unicode
|
||||||
{"\x22\x5c\x75\x64\x38\x35\x35\x5c\x75\x64\x63\x35\x35\x22", 15, 14, json_tokener_success, 5},
|
{"\x22\x5c\x75\x64\x38\x35\x35\x5c\x75\x64\x63\x35\x35\x22", 15, 14, json_tokener_success, 5},
|
||||||
{ "\x22\x5c\x75\x64\x38\x35\x35\xc0\x75\x64\x63\x35\x35\x22",-1, 8, json_tokener_error_parse_utf8_string, 5 },
|
{"\x22\x5c\x75\x64\x38\x35\x35\xc0\x75\x64\x63\x35\x35\x22", -1, 8,
|
||||||
|
json_tokener_error_parse_utf8_string, 5},
|
||||||
{"\x22\x5c\x75\x64\x30\x30\x33\x31\xc0\x22", -1, 9, json_tokener_error_parse_utf8_string, 5},
|
{"\x22\x5c\x75\x64\x30\x30\x33\x31\xc0\x22", -1, 9, json_tokener_error_parse_utf8_string, 5},
|
||||||
// char in number
|
// char in number
|
||||||
{"\x31\x31\x81\x31\x31", -1, 2, json_tokener_error_parse_utf8_string, 5},
|
{"\x31\x31\x81\x31\x31", -1, 2, json_tokener_error_parse_utf8_string, 5},
|
||||||
@@ -422,7 +423,8 @@ static void test_incremental_parse()
|
|||||||
string_to_parse = "{ \"foo"; /* } */
|
string_to_parse = "{ \"foo"; /* } */
|
||||||
printf("json_tokener_parse(%s) ... ", string_to_parse);
|
printf("json_tokener_parse(%s) ... ", string_to_parse);
|
||||||
new_obj = json_tokener_parse(string_to_parse);
|
new_obj = json_tokener_parse(string_to_parse);
|
||||||
if (new_obj == NULL) puts("got error as expected");
|
if (new_obj == NULL)
|
||||||
|
puts("got error as expected");
|
||||||
|
|
||||||
/* test incremental parsing in various forms */
|
/* test incremental parsing in various forms */
|
||||||
tok = json_tokener_new();
|
tok = json_tokener_new();
|
||||||
@@ -455,8 +457,8 @@ static void test_incremental_parse()
|
|||||||
else
|
else
|
||||||
expected_char_offset = step->char_offset;
|
expected_char_offset = step->char_offset;
|
||||||
|
|
||||||
printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ",
|
printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ", step->string_to_parse,
|
||||||
step->string_to_parse, length);
|
length);
|
||||||
new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length);
|
new_obj = json_tokener_parse_ex(tok, step->string_to_parse, length);
|
||||||
|
|
||||||
jerr = json_tokener_get_error(tok);
|
jerr = json_tokener_get_error(tok);
|
||||||
@@ -470,8 +472,7 @@ static void test_incremental_parse()
|
|||||||
json_tokener_error_desc(jerr));
|
json_tokener_error_desc(jerr));
|
||||||
else if (json_tokener_get_parse_end(tok) != expected_char_offset)
|
else if (json_tokener_get_parse_end(tok) != expected_char_offset)
|
||||||
printf("ERROR: wrong char_offset %zu != expected %zu\n",
|
printf("ERROR: wrong char_offset %zu != expected %zu\n",
|
||||||
json_tokener_get_parse_end(tok),
|
json_tokener_get_parse_end(tok), expected_char_offset);
|
||||||
expected_char_offset);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("OK: got correct error: %s\n",
|
printf("OK: got correct error: %s\n",
|
||||||
@@ -482,14 +483,12 @@ static void test_incremental_parse()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (new_obj == NULL &&
|
if (new_obj == NULL &&
|
||||||
!(step->length >= 4 &&
|
!(step->length >= 4 && strncmp(step->string_to_parse, "null", 4) == 0))
|
||||||
strncmp(step->string_to_parse, "null", 4) == 0))
|
|
||||||
printf("ERROR: expected valid object, instead: %s\n",
|
printf("ERROR: expected valid object, instead: %s\n",
|
||||||
json_tokener_error_desc(jerr));
|
json_tokener_error_desc(jerr));
|
||||||
else if (json_tokener_get_parse_end(tok) != expected_char_offset)
|
else if (json_tokener_get_parse_end(tok) != expected_char_offset)
|
||||||
printf("ERROR: wrong char_offset %zu != expected %zu\n",
|
printf("ERROR: wrong char_offset %zu != expected %zu\n",
|
||||||
json_tokener_get_parse_end(tok),
|
json_tokener_get_parse_end(tok), expected_char_offset);
|
||||||
expected_char_offset);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("OK: got object of type [%s]: %s\n",
|
printf("OK: got object of type [%s]: %s\n",
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "printbuf.h"
|
#include "printbuf.h"
|
||||||
@@ -127,7 +127,8 @@ static void test_sprintbuf(int before_resize);
|
|||||||
static void test_sprintbuf(int before_resize)
|
static void test_sprintbuf(int before_resize)
|
||||||
{
|
{
|
||||||
struct printbuf *pb;
|
struct printbuf *pb;
|
||||||
const char *max_char = "if string is greater than stack buffer, then use dynamic string"
|
const char *max_char =
|
||||||
|
"if string is greater than stack buffer, then use dynamic string"
|
||||||
" with vasprintf. Note: some implementation of vsnprintf return -1 "
|
" with vasprintf. Note: some implementation of vsnprintf return -1 "
|
||||||
" if output is truncated whereas some return the number of bytes that "
|
" if output is truncated whereas some return the number of bytes that "
|
||||||
" would have been written - this code handles both cases.";
|
" would have been written - this code handles both cases.";
|
||||||
@@ -141,7 +142,8 @@ static void test_sprintbuf(int before_resize)
|
|||||||
data[before_resize + 1] = '\0';
|
data[before_resize + 1] = '\0';
|
||||||
sprintbuf(pb, "%s", data);
|
sprintbuf(pb, "%s", data);
|
||||||
free(data);
|
free(data);
|
||||||
printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf));
|
printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize,
|
||||||
|
printbuf_length(pb), pb->buf, (int)strlen(pb->buf));
|
||||||
|
|
||||||
printbuf_reset(pb);
|
printbuf_reset(pb);
|
||||||
sprintbuf(pb, "plain");
|
sprintbuf(pb, "plain");
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "printbuf.h"
|
#include "printbuf.h"
|
||||||
|
|
||||||
struct myinfo {
|
struct myinfo
|
||||||
|
{
|
||||||
int value;
|
int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -17,10 +18,7 @@ static void freeit(json_object *jso, void *userdata)
|
|||||||
// Don't actually free anything here, the userdata is stack allocated.
|
// Don't actually free anything here, the userdata is stack allocated.
|
||||||
freeit_was_called = 1;
|
freeit_was_called = 1;
|
||||||
}
|
}
|
||||||
static int custom_serializer(struct json_object *o,
|
static int custom_serializer(struct json_object *o, struct printbuf *pb, int level, int flags)
|
||||||
struct printbuf *pb,
|
|
||||||
int level,
|
|
||||||
int flags)
|
|
||||||
{
|
{
|
||||||
sprintbuf(pb, "Custom Output");
|
sprintbuf(pb, "Custom Output");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -42,7 +40,8 @@ int main(int argc, char **argv)
|
|||||||
struct myinfo userdata = {.value = 123};
|
struct myinfo userdata = {.value = 123};
|
||||||
json_object_set_serializer(my_object, custom_serializer, &userdata, freeit);
|
json_object_set_serializer(my_object, custom_serializer, &userdata, freeit);
|
||||||
|
|
||||||
printf("my_object.to_string(custom serializer)=%s\n", json_object_to_json_string(my_object));
|
printf("my_object.to_string(custom serializer)=%s\n",
|
||||||
|
json_object_to_json_string(my_object));
|
||||||
|
|
||||||
printf("Next line of output should be from the custom freeit function:\n");
|
printf("Next line of output should be from the custom freeit function:\n");
|
||||||
freeit_was_called = 0;
|
freeit_was_called = 0;
|
||||||
@@ -60,7 +59,8 @@ int main(int argc, char **argv)
|
|||||||
json_object_set_serializer(my_object, custom_serializer, &userdata, freeit);
|
json_object_set_serializer(my_object, custom_serializer, &userdata, freeit);
|
||||||
json_object_get(my_object);
|
json_object_get(my_object);
|
||||||
json_object_put(my_object);
|
json_object_put(my_object);
|
||||||
printf("my_object.to_string(custom serializer)=%s\n", json_object_to_json_string(my_object));
|
printf("my_object.to_string(custom serializer)=%s\n",
|
||||||
|
json_object_to_json_string(my_object));
|
||||||
printf("Next line of output should be from the custom freeit function:\n");
|
printf("Next line of output should be from the custom freeit function:\n");
|
||||||
|
|
||||||
freeit_was_called = 0;
|
freeit_was_called = 0;
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
#include "strerror_override_private.h"
|
#include "strerror_override_private.h"
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include <windows.h>
|
||||||
#endif /* defined(WIN32) */
|
#endif /* defined(WIN32) */
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#if HAVE_UNISTD_H
|
#if HAVE_UNISTD_H
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif /* HAVE_UNISTD_H */
|
#endif /* HAVE_UNISTD_H */
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "json_util.h"
|
#include "json_util.h"
|
||||||
@@ -51,8 +51,7 @@ static void test_write_to_file()
|
|||||||
"}");
|
"}");
|
||||||
const char *outfile = "json.out";
|
const char *outfile = "json.out";
|
||||||
int rv = json_object_to_file(outfile, jso);
|
int rv = json_object_to_file(outfile, jso);
|
||||||
printf("%s: json_object_to_file(%s, jso)=%d\n",
|
printf("%s: json_object_to_file(%s, jso)=%d\n", (rv == 0) ? "OK" : "FAIL", outfile, rv);
|
||||||
(rv == 0) ? "OK" : "FAIL", outfile, rv);
|
|
||||||
if (rv == 0)
|
if (rv == 0)
|
||||||
stat_and_cat(outfile);
|
stat_and_cat(outfile);
|
||||||
|
|
||||||
@@ -92,14 +91,12 @@ static void stat_and_cat(const char *file)
|
|||||||
int d = open(file, O_RDONLY, 0600);
|
int d = open(file, O_RDONLY, 0600);
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
printf("FAIL: unable to open %s: %s\n",
|
printf("FAIL: unable to open %s: %s\n", file, strerror(errno));
|
||||||
file, strerror(errno));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (fstat(d, &sb) < 0)
|
if (fstat(d, &sb) < 0)
|
||||||
{
|
{
|
||||||
printf("FAIL: unable to stat %s: %s\n",
|
printf("FAIL: unable to stat %s: %s\n", file, strerror(errno));
|
||||||
file, strerror(errno));
|
|
||||||
close(d);
|
close(d);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -112,8 +109,7 @@ static void stat_and_cat(const char *file)
|
|||||||
}
|
}
|
||||||
if (read(d, buf, sb.st_size) < sb.st_size)
|
if (read(d, buf, sb.st_size) < sb.st_size)
|
||||||
{
|
{
|
||||||
printf("FAIL: unable to read all of %s: %s\n",
|
printf("FAIL: unable to read all of %s: %s\n", file, strerror(errno));
|
||||||
file, strerror(errno));
|
|
||||||
free(buf);
|
free(buf);
|
||||||
close(d);
|
close(d);
|
||||||
return;
|
return;
|
||||||
@@ -158,23 +154,19 @@ static void test_read_valid_with_fd(const char *testdir)
|
|||||||
int d = open(filename, O_RDONLY, 0);
|
int d = open(filename, O_RDONLY, 0);
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno));
|
||||||
"FAIL: unable to open %s: %s\n",
|
|
||||||
filename, strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
json_object *jso = json_object_from_fd(d);
|
json_object *jso = json_object_from_fd(d);
|
||||||
if (jso != NULL)
|
if (jso != NULL)
|
||||||
{
|
{
|
||||||
printf("OK: json_object_from_fd(valid.json)=%s\n",
|
printf("OK: json_object_from_fd(valid.json)=%s\n", json_object_to_json_string(jso));
|
||||||
json_object_to_json_string(jso));
|
|
||||||
json_object_put(jso);
|
json_object_put(jso);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr, "FAIL: unable to parse contents of %s: %s\n", filename,
|
||||||
"FAIL: unable to parse contents of %s: %s\n",
|
json_util_get_last_err());
|
||||||
filename, json_util_get_last_err());
|
|
||||||
}
|
}
|
||||||
close(d);
|
close(d);
|
||||||
}
|
}
|
||||||
@@ -187,9 +179,7 @@ static void test_read_valid_nested_with_fd(const char *testdir)
|
|||||||
int d = open(filename, O_RDONLY, 0);
|
int d = open(filename, O_RDONLY, 0);
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr, "FAIL: unable to open %s: %s\n", filename, strerror(errno));
|
||||||
"FAIL: unable to open %s: %s\n",
|
|
||||||
filename, strerror(errno));
|
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
json_object *jso = json_object_from_fd_ex(d, 20);
|
json_object *jso = json_object_from_fd_ex(d, 20);
|
||||||
@@ -201,9 +191,8 @@ static void test_read_valid_nested_with_fd(const char *testdir)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr, "FAIL: unable to parse contents of %s: %s\n", filename,
|
||||||
"FAIL: unable to parse contents of %s: %s\n",
|
json_util_get_last_err());
|
||||||
filename, json_util_get_last_err());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)lseek(d, SEEK_SET, 0);
|
(void)lseek(d, SEEK_SET, 0);
|
||||||
@@ -211,13 +200,14 @@ static void test_read_valid_nested_with_fd(const char *testdir)
|
|||||||
jso = json_object_from_fd_ex(d, 3);
|
jso = json_object_from_fd_ex(d, 3);
|
||||||
if (jso != NULL)
|
if (jso != NULL)
|
||||||
{
|
{
|
||||||
printf("FAIL: json_object_from_fd_ex(%s, 3)=%s\n",
|
printf("FAIL: json_object_from_fd_ex(%s, 3)=%s\n", filename,
|
||||||
filename, json_object_to_json_string(jso));
|
json_object_to_json_string(jso));
|
||||||
json_object_put(jso);
|
json_object_put(jso);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("OK: correctly unable to parse contents of valid_nested.json with low max depth: %s\n",
|
printf("OK: correctly unable to parse contents of valid_nested.json with low max "
|
||||||
|
"depth: %s\n",
|
||||||
json_util_get_last_err());
|
json_util_get_last_err());
|
||||||
}
|
}
|
||||||
close(d);
|
close(d);
|
||||||
@@ -230,14 +220,14 @@ static void test_read_nonexistant()
|
|||||||
json_object *jso = json_object_from_file(filename);
|
json_object *jso = json_object_from_file(filename);
|
||||||
if (jso != NULL)
|
if (jso != NULL)
|
||||||
{
|
{
|
||||||
printf("FAIL: json_object_from_file(%s) returned %p when NULL expected\n",
|
printf("FAIL: json_object_from_file(%s) returned %p when NULL expected\n", filename,
|
||||||
filename, (void *)jso);
|
(void *)jso);
|
||||||
json_object_put(jso);
|
json_object_put(jso);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("OK: json_object_from_file(%s) correctly returned NULL: %s\n",
|
printf("OK: json_object_from_file(%s) correctly returned NULL: %s\n", filename,
|
||||||
filename, json_util_get_last_err());
|
json_util_get_last_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,8 +251,7 @@ static void test_read_closed()
|
|||||||
json_object *jso = json_object_from_fd(fixed_d);
|
json_object *jso = json_object_from_fd(fixed_d);
|
||||||
if (jso != NULL)
|
if (jso != NULL)
|
||||||
{
|
{
|
||||||
printf("FAIL: read from closed fd returning non-NULL: %p\n",
|
printf("FAIL: read from closed fd returning non-NULL: %p\n", (void *)jso);
|
||||||
(void *)jso);
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
printf(" jso=%s\n", json_object_to_json_string(jso));
|
printf(" jso=%s\n", json_object_to_json_string(jso));
|
||||||
json_object_put(jso);
|
json_object_put(jso);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "json.h"
|
#include "json.h"
|
||||||
#include "json_tokener.h"
|
#include "json_tokener.h"
|
||||||
@@ -68,23 +68,16 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int emit_object(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
static int emit_object(json_object *jso, int flags,
|
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n",
|
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags,
|
||||||
flags,
|
(jso_key ? jso_key : "(null)"), (jso_index ? (long)*jso_index : -1L),
|
||||||
(jso_key ? jso_key : "(null)"),
|
|
||||||
(jso_index ? (long)*jso_index : -1L),
|
|
||||||
json_object_to_json_string(jso));
|
json_object_to_json_string(jso));
|
||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int skip_arrays(json_object *jso, int flags,
|
static int skip_arrays(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
||||||
@@ -93,9 +86,7 @@ static int skip_arrays(json_object *jso, int flags,
|
|||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pop_and_stop(json_object *jso, int flags,
|
static int pop_and_stop(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
||||||
@@ -112,9 +103,7 @@ static int pop_and_stop(json_object *jso, int flags,
|
|||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int err_on_subobj2(json_object *jso, int flags,
|
static int err_on_subobj2(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
||||||
@@ -126,9 +115,7 @@ static int err_on_subobj2(json_object *jso, int flags,
|
|||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pop_array(json_object *jso, int flags,
|
static int pop_array(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
||||||
@@ -140,9 +127,7 @@ static int pop_array(json_object *jso, int flags,
|
|||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stop_array(json_object *jso, int flags,
|
static int stop_array(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
(void)emit_object(jso, flags, parent_jso, jso_key, jso_index, userarg);
|
||||||
@@ -154,15 +139,11 @@ static int stop_array(json_object *jso, int flags,
|
|||||||
return JSON_C_VISIT_RETURN_CONTINUE;
|
return JSON_C_VISIT_RETURN_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int err_return(json_object *jso, int flags,
|
static int err_return(json_object *jso, int flags, json_object *parent_jso, const char *jso_key,
|
||||||
json_object *parent_jso,
|
|
||||||
const char *jso_key,
|
|
||||||
size_t *jso_index, void *userarg)
|
size_t *jso_index, void *userarg)
|
||||||
{
|
{
|
||||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n",
|
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags,
|
||||||
flags,
|
(jso_key ? jso_key : "(null)"), (jso_index ? (long)*jso_index : -1L),
|
||||||
(jso_key ? jso_key : "(null)"),
|
|
||||||
(jso_index ? (long)*jso_index : -1L),
|
|
||||||
json_object_to_json_string(jso));
|
json_object_to_json_string(jso));
|
||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ static int vasprintf(char **buf, const char *fmt, va_list ap)
|
|||||||
int chars;
|
int chars;
|
||||||
char *b;
|
char *b;
|
||||||
|
|
||||||
if(!buf) { return -1; }
|
if (!buf)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
chars = _vscprintf(fmt, ap) + 1;
|
chars = _vscprintf(fmt, ap) + 1;
|
||||||
@@ -27,16 +30,24 @@ static int vasprintf(char **buf, const char *fmt, va_list ap)
|
|||||||
* our buffer like on some 64bit sun systems.... but hey, its time to move on
|
* our buffer like on some 64bit sun systems.... but hey, its time to move on
|
||||||
*/
|
*/
|
||||||
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap) + 1;
|
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap) + 1;
|
||||||
if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */
|
if (chars < 0)
|
||||||
|
{
|
||||||
|
chars *= -1;
|
||||||
|
} /* CAW: old glibc versions have this problem */
|
||||||
#endif /* defined(WIN32) */
|
#endif /* defined(WIN32) */
|
||||||
|
|
||||||
b = (char *)malloc(sizeof(char) * chars);
|
b = (char *)malloc(sizeof(char) * chars);
|
||||||
if(!b) { return -1; }
|
if (!b)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((chars = vsprintf(b, fmt, ap)) < 0)
|
if ((chars = vsprintf(b, fmt, ap)) < 0)
|
||||||
{
|
{
|
||||||
free(b);
|
free(b);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
*buf = b;
|
*buf = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user