clang-format the files

This commit is contained in:
dota17
2020-03-28 10:25:00 +08:00
parent c117d8a8a8
commit 8b162c4b89
54 changed files with 2860 additions and 2713 deletions

View File

@@ -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;

View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -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
View File

@@ -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
} }

View File

@@ -17,4 +17,3 @@ int json_c_version_num(void)
{ {
return JSON_C_VERSION_NUM; return JSON_C_VERSION_NUM;
} }

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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.
*/ */

View File

@@ -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;
} }

View File

@@ -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
} }

View File

@@ -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;
} }

View File

@@ -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
} }

View File

@@ -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();
} }

View File

@@ -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);

View File

@@ -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
} }

View File

@@ -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.

View File

@@ -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);
} }

View File

@@ -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:
*/ */

View File

@@ -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);
} }

View File

@@ -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
} }

View File

@@ -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;
} }

View File

@@ -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[] = {

View File

@@ -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");

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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));
} }

View File

@@ -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"

View File

@@ -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"

View File

@@ -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));
} }

View File

@@ -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)

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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",

View File

@@ -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");

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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;
} }