Format json-c with clang-format tooltags/json-c-0.14-20200419
@@ -0,0 +1,53 @@ | |||||
BasedOnStyle: LLVM | |||||
# If true, clang-format will attempt to re-flow comments | |||||
ReflowComments: false | |||||
# The column limit. | |||||
ColumnLimit: 100 | |||||
# Indent width for line continuations. | |||||
ContinuationIndentWidth: 4 | |||||
# The number of columns to use for indentation. | |||||
IndentWidth: 8 | |||||
# The number of columns used for tab stops. | |||||
TabWidth: 8 | |||||
UseTab: ForIndentation | |||||
# Options for aligning backslashes in escaped newlines. | |||||
AlignEscapedNewlines: Left | |||||
# Short Block Style | |||||
AllowShortBlocksOnASingleLine: true | |||||
# If true, short case labels will be contracted to a single line. | |||||
AllowShortCaseLabelsOnASingleLine: true | |||||
# Dependent on the value, int f() { return 0; } can be put on a single line. | |||||
AllowShortFunctionsOnASingleLine: Empty | |||||
# The brace breaking style to use. | |||||
BreakBeforeBraces: Custom | |||||
# Control of individual brace wrapping cases. | |||||
BraceWrapping: | |||||
# Wrap class definition. | |||||
AfterClass: true | |||||
# Wrap control statements | |||||
AfterControlStatement: true | |||||
# Wrap enum definitions. | |||||
AfterEnum: true | |||||
# Wrap function definitions. | |||||
AfterFunction: true | |||||
# Wrap namespace definitions. | |||||
AfterNamespace: true | |||||
# Wrap struct definitions. | |||||
AfterStruct: true | |||||
# Wrap union definitions. | |||||
AfterUnion: true | |||||
# Wrap extern blocks. | |||||
AfterExternBlock: false | |||||
# Wrap before catch. | |||||
BeforeCatch: true | |||||
# Wrap before else. | |||||
BeforeElse: true | |||||
# Indent the wrapped braces themselves. | |||||
IndentBraces: false | |||||
# If false, empty function body can be put on a single line. | |||||
SplitEmptyFunction: false | |||||
# If false, empty record (e.g. class, struct or union) body can be put on a single line. | |||||
SplitEmptyRecord: false | |||||
# If false, empty namespace body can be put on a single line. | |||||
SplitEmptyNamespace: false |
@@ -14,12 +14,12 @@ | |||||
#include <limits.h> | #include <limits.h> | ||||
#ifdef STDC_HEADERS | #ifdef STDC_HEADERS | ||||
# include <stdlib.h> | |||||
# include <string.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#endif /* STDC_HEADERS */ | #endif /* STDC_HEADERS */ | ||||
#if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD) | #if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD) | ||||
# include <strings.h> | |||||
#include <strings.h> | |||||
#endif /* HAVE_STRINGS_H */ | #endif /* HAVE_STRINGS_H */ | ||||
#ifndef SIZE_T_MAX | #ifndef SIZE_T_MAX | ||||
@@ -36,111 +36,115 @@ | |||||
#include "arraylist.h" | #include "arraylist.h" | ||||
struct array_list* | |||||
array_list_new(array_list_free_fn *free_fn) | |||||
struct array_list *array_list_new(array_list_free_fn *free_fn) | |||||
{ | { | ||||
struct array_list *arr; | |||||
arr = (struct array_list*)calloc(1, sizeof(struct array_list)); | |||||
if(!arr) return NULL; | |||||
arr->size = ARRAY_LIST_DEFAULT_SIZE; | |||||
arr->length = 0; | |||||
arr->free_fn = free_fn; | |||||
if(!(arr->array = (void**)calloc(arr->size, sizeof(void*)))) { | |||||
free(arr); | |||||
return NULL; | |||||
} | |||||
return arr; | |||||
struct array_list *arr; | |||||
arr = (struct array_list *)calloc(1, sizeof(struct array_list)); | |||||
if (!arr) | |||||
return NULL; | |||||
arr->size = ARRAY_LIST_DEFAULT_SIZE; | |||||
arr->length = 0; | |||||
arr->free_fn = free_fn; | |||||
if (!(arr->array = (void **)calloc(arr->size, sizeof(void *)))) | |||||
{ | |||||
free(arr); | |||||
return NULL; | |||||
} | |||||
return arr; | |||||
} | } | ||||
extern void | |||||
array_list_free(struct array_list *arr) | |||||
extern void array_list_free(struct array_list *arr) | |||||
{ | { | ||||
size_t i; | |||||
for(i = 0; i < arr->length; i++) | |||||
if(arr->array[i]) arr->free_fn(arr->array[i]); | |||||
free(arr->array); | |||||
free(arr); | |||||
size_t i; | |||||
for (i = 0; i < arr->length; i++) | |||||
if (arr->array[i]) | |||||
arr->free_fn(arr->array[i]); | |||||
free(arr->array); | |||||
free(arr); | |||||
} | } | ||||
void* | |||||
array_list_get_idx(struct array_list *arr, size_t i) | |||||
void *array_list_get_idx(struct array_list *arr, size_t i) | |||||
{ | { | ||||
if(i >= arr->length) return NULL; | |||||
return arr->array[i]; | |||||
if (i >= arr->length) | |||||
return NULL; | |||||
return arr->array[i]; | |||||
} | } | ||||
static int array_list_expand_internal(struct array_list *arr, size_t max) | static int array_list_expand_internal(struct array_list *arr, size_t max) | ||||
{ | { | ||||
void *t; | |||||
size_t new_size; | |||||
if(max < arr->size) return 0; | |||||
/* Avoid undefined behaviour on size_t overflow */ | |||||
if( arr->size >= SIZE_T_MAX / 2 ) | |||||
new_size = max; | |||||
else | |||||
{ | |||||
new_size = arr->size << 1; | |||||
if (new_size < max) | |||||
new_size = max; | |||||
} | |||||
if (new_size > (~((size_t)0)) / sizeof(void*)) return -1; | |||||
if (!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1; | |||||
arr->array = (void**)t; | |||||
(void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*)); | |||||
arr->size = new_size; | |||||
return 0; | |||||
void *t; | |||||
size_t new_size; | |||||
if (max < arr->size) | |||||
return 0; | |||||
/* Avoid undefined behaviour on size_t overflow */ | |||||
if (arr->size >= SIZE_T_MAX / 2) | |||||
new_size = max; | |||||
else | |||||
{ | |||||
new_size = arr->size << 1; | |||||
if (new_size < max) | |||||
new_size = max; | |||||
} | |||||
if (new_size > (~((size_t)0)) / sizeof(void *)) | |||||
return -1; | |||||
if (!(t = realloc(arr->array, new_size * sizeof(void *)))) | |||||
return -1; | |||||
arr->array = (void **)t; | |||||
(void)memset(arr->array + arr->size, 0, (new_size - arr->size) * sizeof(void *)); | |||||
arr->size = new_size; | |||||
return 0; | |||||
} | } | ||||
int | |||||
array_list_put_idx(struct array_list *arr, size_t idx, void *data) | |||||
int array_list_put_idx(struct array_list *arr, size_t idx, void *data) | |||||
{ | { | ||||
if (idx > SIZE_T_MAX - 1 ) return -1; | |||||
if(array_list_expand_internal(arr, idx+1)) return -1; | |||||
if(idx < arr->length && arr->array[idx]) | |||||
arr->free_fn(arr->array[idx]); | |||||
arr->array[idx] = data; | |||||
if(arr->length <= idx) arr->length = idx + 1; | |||||
return 0; | |||||
if (idx > SIZE_T_MAX - 1) | |||||
return -1; | |||||
if (array_list_expand_internal(arr, idx + 1)) | |||||
return -1; | |||||
if (idx < arr->length && arr->array[idx]) | |||||
arr->free_fn(arr->array[idx]); | |||||
arr->array[idx] = data; | |||||
if (arr->length <= idx) | |||||
arr->length = idx + 1; | |||||
return 0; | |||||
} | } | ||||
int | |||||
array_list_add(struct array_list *arr, void *data) | |||||
int 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 | |||||
array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *)) | |||||
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); | |||||
} | } | ||||
void* array_list_bsearch(const void **key, struct array_list *arr, | |||||
int (*compar)(const void *, const void *)) | |||||
void *array_list_bsearch(const void **key, struct array_list *arr, | |||||
int (*compar)(const void *, const void *)) | |||||
{ | { | ||||
return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), | |||||
compar); | |||||
return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]), compar); | |||||
} | } | ||||
size_t | |||||
array_list_length(struct array_list *arr) | |||||
size_t array_list_length(struct array_list *arr) | |||||
{ | { | ||||
return arr->length; | |||||
return arr->length; | |||||
} | } | ||||
int | |||||
array_list_del_idx( struct array_list *arr, size_t idx, size_t count ) | |||||
int 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; | |||||
for ( i = idx; i < stop; ++i ) { | |||||
if ( arr->array[i] ) arr->free_fn( arr->array[i] ); | |||||
if (idx >= arr->length || stop > arr->length) | |||||
return -1; | |||||
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; | ||||
return 0; | return 0; | ||||
} | } |
@@ -24,44 +24,35 @@ extern "C" { | |||||
#define ARRAY_LIST_DEFAULT_SIZE 32 | #define ARRAY_LIST_DEFAULT_SIZE 32 | ||||
typedef void (array_list_free_fn) (void *data); | |||||
typedef void(array_list_free_fn)(void *data); | |||||
struct array_list | struct array_list | ||||
{ | { | ||||
void **array; | |||||
size_t length; | |||||
size_t size; | |||||
array_list_free_fn *free_fn; | |||||
void **array; | |||||
size_t length; | |||||
size_t size; | |||||
array_list_free_fn *free_fn; | |||||
}; | }; | ||||
typedef struct array_list array_list; | typedef struct array_list array_list; | ||||
extern struct array_list* | |||||
array_list_new(array_list_free_fn *free_fn); | |||||
extern struct array_list *array_list_new(array_list_free_fn *free_fn); | |||||
extern void | |||||
array_list_free(struct array_list *al); | |||||
extern void array_list_free(struct array_list *al); | |||||
extern void* | |||||
array_list_get_idx(struct array_list *al, size_t i); | |||||
extern void *array_list_get_idx(struct array_list *al, size_t i); | |||||
extern int | |||||
array_list_put_idx(struct array_list *al, size_t i, void *data); | |||||
extern int array_list_put_idx(struct array_list *al, size_t i, void *data); | |||||
extern int | |||||
array_list_add(struct array_list *al, void *data); | |||||
extern int array_list_add(struct array_list *al, void *data); | |||||
extern size_t | |||||
array_list_length(struct array_list *al); | |||||
extern size_t array_list_length(struct array_list *al); | |||||
extern void | |||||
array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *)); | |||||
extern void array_list_sort(struct array_list *arr, int (*compar)(const void *, const void *)); | |||||
extern void* | |||||
array_list_bsearch(const void **key, struct array_list *arr, | |||||
int (*compar)(const void *, const void *)); | |||||
extern void *array_list_bsearch(const void **key, struct array_list *arr, | |||||
int (*compar)(const void *, const void *)); | |||||
extern int | |||||
array_list_del_idx(struct array_list *arr, size_t idx, size_t count); | |||||
extern int array_list_del_idx(struct array_list *arr, size_t idx, size_t count); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
@@ -11,17 +11,17 @@ | |||||
#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> | |||||
#endif /* HAVE_SYSLOG_H */ | #endif /* HAVE_SYSLOG_H */ | ||||
#if HAVE_UNISTD_H | #if HAVE_UNISTD_H | ||||
# include <unistd.h> | |||||
#include <unistd.h> | |||||
#endif /* HAVE_UNISTD_H */ | #endif /* HAVE_UNISTD_H */ | ||||
#if HAVE_SYS_PARAM_H | #if HAVE_SYS_PARAM_H | ||||
@@ -33,51 +33,64 @@ | |||||
static int _syslog = 0; | static int _syslog = 0; | ||||
static int _debug = 0; | static int _debug = 0; | ||||
void mc_set_debug(int debug) { _debug = debug; } | |||||
int mc_get_debug(void) { return _debug; } | |||||
void mc_set_debug(int debug) | |||||
{ | |||||
_debug = debug; | |||||
} | |||||
int mc_get_debug(void) | |||||
{ | |||||
return _debug; | |||||
} | |||||
extern void mc_set_syslog(int syslog) | extern void mc_set_syslog(int syslog) | ||||
{ | { | ||||
_syslog = syslog; | |||||
_syslog = syslog; | |||||
} | } | ||||
void mc_debug(const char *msg, ...) | void mc_debug(const char *msg, ...) | ||||
{ | { | ||||
va_list ap; | |||||
if(_debug) { | |||||
va_start(ap, msg); | |||||
va_list ap; | |||||
if (_debug) | |||||
{ | |||||
va_start(ap, msg); | |||||
#if HAVE_VSYSLOG | #if HAVE_VSYSLOG | ||||
if(_syslog) { | |||||
vsyslog(LOG_DEBUG, msg, ap); | |||||
} else | |||||
if (_syslog) | |||||
{ | |||||
vsyslog(LOG_DEBUG, msg, ap); | |||||
} | |||||
else | |||||
#endif | #endif | ||||
vprintf(msg, ap); | |||||
va_end(ap); | |||||
} | |||||
vprintf(msg, ap); | |||||
va_end(ap); | |||||
} | |||||
} | } | ||||
void mc_error(const char *msg, ...) | void mc_error(const char *msg, ...) | ||||
{ | { | ||||
va_list ap; | |||||
va_start(ap, msg); | |||||
va_list ap; | |||||
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); | |||||
} | } | ||||
void mc_info(const char *msg, ...) | void mc_info(const char *msg, ...) | ||||
{ | { | ||||
va_list ap; | |||||
va_start(ap, msg); | |||||
va_list ap; | |||||
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); | |||||
} | } |
@@ -24,7 +24,7 @@ extern "C" { | |||||
#endif | #endif | ||||
#ifndef JSON_EXPORT | #ifndef JSON_EXPORT | ||||
#if defined(_MSC_VER) | |||||
#if defined(_MSC_VER) | |||||
#define JSON_EXPORT __declspec(dllexport) | #define JSON_EXPORT __declspec(dllexport) | ||||
#else | #else | ||||
#define JSON_EXPORT extern | #define JSON_EXPORT extern | ||||
@@ -46,17 +46,24 @@ 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 { \ | |||||
if (!(cond)) { \ | |||||
mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \ | |||||
*(int *)0 = 1;\ | |||||
abort(); \ | |||||
}\ | |||||
} while(0) | |||||
#define JASSERT(cond) \ | |||||
do \ | |||||
{ \ | |||||
if (!(cond)) \ | |||||
{ \ | |||||
mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", \ | |||||
__FILE__, __LINE__); \ | |||||
*(int *)0 = 1; \ | |||||
abort(); \ | |||||
} \ | |||||
} while (0) | |||||
#endif | #endif | ||||
@@ -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_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__) | |||||
#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__) | |||||
#define MC_SET_SYSLOG(x) \ | |||||
if (0) \ | |||||
mc_set_syslog(x) | |||||
#define MC_DEBUG(x, ...) \ | |||||
if (0) \ | |||||
mc_debug(x, ##__VA_ARGS__) | |||||
#define MC_INFO(x, ...) \ | |||||
if (0) \ | |||||
mc_info(x, ##__VA_ARGS__) | |||||
#endif | #endif | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
@@ -2,12 +2,13 @@ | |||||
#include <json.h> | #include <json.h> | ||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | |||||
const char *data1 = reinterpret_cast<const char *>(data); | |||||
json_tokener *tok = json_tokener_new(); | |||||
json_object *obj = json_tokener_parse_ex(tok, data1, size); | |||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | |||||
{ | |||||
const char *data1 = reinterpret_cast<const char *>(data); | |||||
json_tokener *tok = json_tokener_new(); | |||||
json_object *obj = json_tokener_parse_ex(tok, data1, size); | |||||
json_object_put(obj); | |||||
json_tokener_free(tok); | |||||
return 0; | |||||
json_object_put(obj); | |||||
json_tokener_free(tok); | |||||
return 0; | |||||
} | } |
@@ -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_c_version.h" | |||||
#include "json_util.h" | |||||
#include "linkhash.h" | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
@@ -17,4 +17,3 @@ int json_c_version_num(void) | |||||
{ | { | ||||
return JSON_C_VERSION_NUM; | return JSON_C_VERSION_NUM; | ||||
} | } | ||||
@@ -15,13 +15,12 @@ | |||||
#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) | \ | |||||
(JSON_C_MINOR_VERSION << 8) | \ | |||||
JSON_C_MICRO_VERSION) | |||||
#define JSON_C_VERSION_NUM \ | |||||
((JSON_C_MAJOR_VERSION << 16) | (JSON_C_MINOR_VERSION << 8) | JSON_C_MICRO_VERSION) | |||||
#define JSON_C_VERSION "0.13.99" | #define JSON_C_VERSION "0.13.99" | ||||
#ifndef JSON_EXPORT | #ifndef JSON_EXPORT | ||||
#if defined(_MSC_VER) | |||||
#if defined(_MSC_VER) | |||||
#define JSON_EXPORT __declspec(dllexport) | #define JSON_EXPORT __declspec(dllexport) | ||||
#else | #else | ||||
#define JSON_EXPORT extern | #define JSON_EXPORT extern | ||||
@@ -43,6 +42,6 @@ JSON_EXPORT const char *json_c_version(void); /* Returns JSON_C_VERSION */ | |||||
* @see JSON_C_VERSION_NUM | * @see JSON_C_VERSION_NUM | ||||
* @return the version of the json-c library as an int | * @return the version of the json-c library as an int | ||||
*/ | */ | ||||
JSON_EXPORT int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */ | |||||
JSON_EXPORT int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */ | |||||
#endif | #endif |
@@ -18,7 +18,7 @@ | |||||
#define _json_object_h_ | #define _json_object_h_ | ||||
#ifdef __GNUC__ | #ifdef __GNUC__ | ||||
#define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__ ((deprecated)) | |||||
#define THIS_FUNCTION_IS_DEPRECATED(func) func __attribute__((deprecated)) | |||||
#elif defined(_MSC_VER) | #elif defined(_MSC_VER) | ||||
#define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func | #define THIS_FUNCTION_IS_DEPRECATED(func) __declspec(deprecated) func | ||||
#elif defined(__clang__) | #elif defined(__clang__) | ||||
@@ -34,16 +34,16 @@ | |||||
#endif | #endif | ||||
#ifndef JSON_EXPORT | #ifndef JSON_EXPORT | ||||
#if defined(_MSC_VER) | |||||
#if defined(_MSC_VER) | |||||
#define JSON_EXPORT __declspec(dllexport) | #define JSON_EXPORT __declspec(dllexport) | ||||
#else | #else | ||||
#define JSON_EXPORT extern | #define JSON_EXPORT extern | ||||
#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" { | ||||
@@ -56,13 +56,13 @@ extern "C" { | |||||
* json_object_to_file_ext() functions which causes the output | * json_object_to_file_ext() functions which causes the output | ||||
* to have no extra whitespace or formatting applied. | * to have no extra whitespace or formatting applied. | ||||
*/ | */ | ||||
#define JSON_C_TO_STRING_PLAIN 0 | |||||
#define JSON_C_TO_STRING_PLAIN 0 | |||||
/** | /** | ||||
* A flag for the json_object_to_json_string_ext() and | * A flag for the json_object_to_json_string_ext() and | ||||
* json_object_to_file_ext() functions which causes the output to have | * json_object_to_file_ext() functions which causes the output to have | ||||
* minimal whitespace inserted to make things slightly more readable. | * minimal whitespace inserted to make things slightly more readable. | ||||
*/ | */ | ||||
#define JSON_C_TO_STRING_SPACED (1<<0) | |||||
#define JSON_C_TO_STRING_SPACED (1 << 0) | |||||
/** | /** | ||||
* A flag for the json_object_to_json_string_ext() and | * A flag for the json_object_to_json_string_ext() and | ||||
* json_object_to_file_ext() functions which causes | * json_object_to_file_ext() functions which causes | ||||
@@ -71,7 +71,7 @@ extern "C" { | |||||
* See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/ | * See the "Two Space Tab" option at http://jsonformatter.curiousconcept.com/ | ||||
* for an example of the format. | * for an example of the format. | ||||
*/ | */ | ||||
#define JSON_C_TO_STRING_PRETTY (1<<1) | |||||
#define JSON_C_TO_STRING_PRETTY (1 << 1) | |||||
/** | /** | ||||
* A flag for the json_object_to_json_string_ext() and | * A flag for the json_object_to_json_string_ext() and | ||||
* json_object_to_file_ext() functions which causes | * json_object_to_file_ext() functions which causes | ||||
@@ -79,16 +79,16 @@ extern "C" { | |||||
* | * | ||||
* Instead of a "Two Space Tab" this gives a single tab character. | * Instead of a "Two Space Tab" this gives a single tab character. | ||||
*/ | */ | ||||
#define JSON_C_TO_STRING_PRETTY_TAB (1<<3) | |||||
#define JSON_C_TO_STRING_PRETTY_TAB (1 << 3) | |||||
/** | /** | ||||
* A flag to drop trailing zero for float values | * A flag to drop trailing zero for float values | ||||
*/ | */ | ||||
#define JSON_C_TO_STRING_NOZERO (1<<2) | |||||
#define JSON_C_TO_STRING_NOZERO (1 << 2) | |||||
/** | /** | ||||
* Don't escape forward slashes. | * Don't escape forward slashes. | ||||
*/ | */ | ||||
#define JSON_C_TO_STRING_NOSLASHESCAPE (1<<4) | |||||
#define JSON_C_TO_STRING_NOSLASHESCAPE (1 << 4) | |||||
/** | /** | ||||
* A flag for the json_object_object_add_ex function which | * A flag for the json_object_object_add_ex function which | ||||
@@ -100,7 +100,7 @@ extern "C" { | |||||
* knows for sure the key values are unique (e.g. because the | * knows for sure the key values are unique (e.g. because the | ||||
* code adds a well-known set of constant key values). | * code adds a well-known set of constant key values). | ||||
*/ | */ | ||||
#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1<<1) | |||||
#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1 << 1) | |||||
/** | /** | ||||
* A flag for the json_object_object_add_ex function which | * A flag for the json_object_object_add_ex function which | ||||
* flags the key as being constant memory. This means that | * flags the key as being constant memory. This means that | ||||
@@ -118,7 +118,7 @@ extern "C" { | |||||
* json_object_object_add_ex(obj, "ip", json, | * json_object_object_add_ex(obj, "ip", json, | ||||
* JSON_C_OBJECT_KEY_IS_CONSTANT); | * JSON_C_OBJECT_KEY_IS_CONSTANT); | ||||
*/ | */ | ||||
#define JSON_C_OBJECT_KEY_IS_CONSTANT (1<<2) | |||||
#define JSON_C_OBJECT_KEY_IS_CONSTANT (1 << 2) | |||||
/** | /** | ||||
* Set the global value of an option, which will apply to all | * Set the global value of an option, which will apply to all | ||||
@@ -158,27 +158,26 @@ typedef struct json_object json_object; | |||||
/** | /** | ||||
* Type of custom user delete functions. See json_object_set_serializer. | * Type of custom user delete functions. See json_object_set_serializer. | ||||
*/ | */ | ||||
typedef void (json_object_delete_fn)(struct json_object *jso, void *userdata); | |||||
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, | |||||
struct printbuf *pb, | |||||
int level, | |||||
int flags); | |||||
typedef int(json_object_to_json_string_fn)(struct json_object *jso, struct printbuf *pb, int level, | |||||
int flags); | |||||
/* supported object types */ | /* supported object types */ | ||||
typedef enum json_type { | |||||
/* If you change this, be sure to update json_type_to_name() too */ | |||||
json_type_null, | |||||
json_type_boolean, | |||||
json_type_double, | |||||
json_type_int, | |||||
json_type_object, | |||||
json_type_array, | |||||
json_type_string | |||||
typedef enum json_type | |||||
{ | |||||
/* If you change this, be sure to update json_type_to_name() too */ | |||||
json_type_null, | |||||
json_type_boolean, | |||||
json_type_double, | |||||
json_type_int, | |||||
json_type_object, | |||||
json_type_array, | |||||
json_type_string | |||||
} json_type; | } json_type; | ||||
/* reference counting functions */ | /* reference counting functions */ | ||||
@@ -189,7 +188,7 @@ typedef enum json_type { | |||||
* | * | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_get(struct json_object *obj); | |||||
JSON_EXPORT struct json_object *json_object_get(struct json_object *obj); | |||||
/** | /** | ||||
* Decrement the reference count of json_object and free if it reaches zero. | * Decrement the reference count of json_object and free if it reaches zero. | ||||
@@ -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 | ||||
@@ -242,7 +240,7 @@ JSON_EXPORT enum json_type json_object_get_type(const struct json_object *obj); | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a string in JSON format | * @returns a string in JSON format | ||||
*/ | */ | ||||
JSON_EXPORT const char* json_object_to_json_string(struct json_object *obj); | |||||
JSON_EXPORT const char *json_object_to_json_string(struct json_object *obj); | |||||
/** 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. | ||||
@@ -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 | |||||
flags); | |||||
JSON_EXPORT const char *json_object_to_json_string_ext(struct json_object *obj, int 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 | |||||
flags, size_t *length); | |||||
JSON_EXPORT const char *json_object_to_json_string_length(struct json_object *obj, int flags, | |||||
size_t *length); | |||||
/** | /** | ||||
* Returns the userdata set by json_object_set_userdata() or | * Returns the userdata set by json_object_set_userdata() or | ||||
@@ -269,7 +266,7 @@ flags, size_t *length); | |||||
* | * | ||||
* @param jso the object to return the userdata for | * @param jso the object to return the userdata for | ||||
*/ | */ | ||||
JSON_EXPORT void* json_object_get_userdata(json_object *jso); | |||||
JSON_EXPORT void *json_object_get_userdata(json_object *jso); | |||||
/** | /** | ||||
* Set an opaque userdata value for an object | * Set an opaque userdata value for an object | ||||
@@ -297,7 +294,7 @@ JSON_EXPORT void* json_object_get_userdata(json_object *jso); | |||||
* @param user_delete an optional function from freeing userdata | * @param user_delete an optional function from freeing userdata | ||||
*/ | */ | ||||
JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata, | JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata, | ||||
json_object_delete_fn *user_delete); | |||||
json_object_delete_fn *user_delete); | |||||
/** | /** | ||||
* Set a custom serialization function to be used when this particular object | * Set a custom serialization function to be used when this particular object | ||||
@@ -330,9 +327,8 @@ JSON_EXPORT void json_object_set_userdata(json_object *jso, void *userdata, | |||||
* @param user_delete an optional function from freeing userdata | * @param user_delete an optional function from freeing 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, | |||||
void *userdata, | |||||
json_object_delete_fn *user_delete); | |||||
json_object_to_json_string_fn *to_string_func, | |||||
void *userdata, 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 | ||||
@@ -382,18 +377,18 @@ JSON_EXPORT json_object_to_json_string_fn json_object_userdata_to_json_string; | |||||
* | * | ||||
* @returns a json_object of type json_type_object | * @returns a json_object of type json_type_object | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_object(void); | |||||
JSON_EXPORT struct json_object *json_object_new_object(void); | |||||
/** Get the hashtable of a json_object of type json_type_object | /** Get the hashtable of a json_object of type json_type_object | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a linkhash | * @returns a linkhash | ||||
*/ | */ | ||||
JSON_EXPORT struct lh_table* json_object_get_object(const struct json_object *obj); | |||||
JSON_EXPORT struct lh_table *json_object_get_object(const struct json_object *obj); | |||||
/** Get the size of an object in terms of the number of fields it has. | /** Get the size of an object in terms of the number of fields it has. | ||||
* @param obj the json_object whose length to return | * @param obj the json_object whose length to return | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_object_length(const struct json_object* obj); | |||||
JSON_EXPORT int json_object_object_length(const struct json_object *obj); | |||||
/** Get the sizeof (struct json_object). | /** Get the sizeof (struct json_object). | ||||
* @returns a size_t with the sizeof (struct json_object) | * @returns a size_t with the sizeof (struct json_object) | ||||
@@ -419,8 +414,8 @@ JSON_C_CONST_FUNCTION(JSON_EXPORT size_t json_c_object_sizeof(void)); | |||||
* @return On success, <code>0</code> is returned. | * @return On success, <code>0</code> is returned. | ||||
* On error, a negative value is returned. | * On error, a negative value is returned. | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_object_add(struct json_object* obj, const char *key, | |||||
struct json_object *val); | |||||
JSON_EXPORT int json_object_object_add(struct json_object *obj, const char *key, | |||||
struct json_object *val); | |||||
/** Add an object field to a json_object of type json_type_object | /** Add an object field to a json_object of type json_type_object | ||||
* | * | ||||
@@ -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, | |||||
const char *const key, | |||||
struct json_object *const val, | |||||
const unsigned opts); | |||||
JSON_EXPORT int json_object_object_add_ex(struct json_object *obj, const char *const key, | |||||
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. | ||||
@@ -461,8 +454,8 @@ JSON_EXPORT int json_object_object_add_ex(struct json_object* obj, | |||||
* @param key the object field name | * @param key the object field name | ||||
* @returns the json_object associated with the given field name | * @returns the json_object associated with the given field name | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_object_get(const struct json_object* obj, | |||||
const char *key); | |||||
JSON_EXPORT struct json_object *json_object_object_get(const struct json_object *obj, | |||||
const char *key); | |||||
/** Get the json_object associated with a given object field. | /** Get the json_object associated with a given object field. | ||||
* | * | ||||
@@ -482,9 +475,8 @@ 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, | |||||
const char *key, | |||||
struct json_object **value); | |||||
JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object *obj, const char *key, | |||||
struct json_object **value); | |||||
/** Delete the given json_object field | /** Delete the given json_object field | ||||
* | * | ||||
@@ -495,7 +487,7 @@ JSON_EXPORT json_bool json_object_object_get_ex(const struct json_object* obj, | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param key the object field name | * @param key the object field name | ||||
*/ | */ | ||||
JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key); | |||||
JSON_EXPORT void json_object_object_del(struct json_object *obj, const char *key); | |||||
/** | /** | ||||
* Iterate through all keys and values of an object. | * Iterate through all keys and values of an object. | ||||
@@ -512,31 +504,35 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key | |||||
*/ | */ | ||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L | #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L | ||||
# define json_object_object_foreach(obj,key,val) \ | |||||
char *key = NULL; \ | |||||
struct json_object *val __attribute__((__unused__)) = NULL; \ | |||||
for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \ | |||||
({ if(entry ## key) { \ | |||||
key = (char*)lh_entry_k(entry ## key); \ | |||||
val = (struct json_object*)lh_entry_v(entry ## key); \ | |||||
entry_next ## key = entry ## key->next; \ | |||||
} ; entry ## key; }); \ | |||||
entry ## key = entry_next ## key ) | |||||
#define json_object_object_foreach(obj, key, val) \ | |||||
char *key = NULL; \ | |||||
struct json_object *val __attribute__((__unused__)) = NULL; \ | |||||
for (struct lh_entry *entry##key = json_object_get_object(obj)->head, \ | |||||
*entry_next##key = NULL; \ | |||||
({ \ | |||||
if (entry##key) \ | |||||
{ \ | |||||
key = (char *)lh_entry_k(entry##key); \ | |||||
val = (struct json_object *)lh_entry_v(entry##key); \ | |||||
entry_next##key = entry##key->next; \ | |||||
}; \ | |||||
entry##key; \ | |||||
}); \ | |||||
entry##key = entry_next##key) | |||||
#else /* ANSI C or MSC */ | #else /* ANSI C or MSC */ | ||||
# define json_object_object_foreach(obj,key,val) \ | |||||
char *key = NULL;\ | |||||
struct json_object *val = NULL; \ | |||||
struct lh_entry *entry ## key; \ | |||||
struct lh_entry *entry_next ## key = NULL; \ | |||||
for(entry ## key = json_object_get_object(obj)->head; \ | |||||
(entry ## key ? ( \ | |||||
key = (char*)lh_entry_k(entry ## key), \ | |||||
val = (struct json_object*)lh_entry_v(entry ## key), \ | |||||
entry_next ## key = entry ## key->next, \ | |||||
entry ## key) : 0); \ | |||||
entry ## key = entry_next ## key) | |||||
#define json_object_object_foreach(obj, key, val) \ | |||||
char *key = NULL; \ | |||||
struct json_object *val = NULL; \ | |||||
struct lh_entry *entry##key; \ | |||||
struct lh_entry *entry_next##key = NULL; \ | |||||
for (entry##key = json_object_get_object(obj)->head; \ | |||||
(entry##key ? (key = (char *)lh_entry_k(entry##key), \ | |||||
val = (struct json_object *)lh_entry_v(entry##key), \ | |||||
entry_next##key = entry##key->next, entry##key) \ | |||||
: 0); \ | |||||
entry##key = entry_next##key) | |||||
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */ | #endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */ | ||||
@@ -544,23 +540,25 @@ JSON_EXPORT void json_object_object_del(struct json_object* obj, const char *key | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param iter the object iterator, use type json_object_iter | * @param iter the object iterator, use type json_object_iter | ||||
*/ | */ | ||||
#define json_object_object_foreachC(obj,iter) \ | |||||
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.entry->next) | |||||
#define json_object_object_foreachC(obj, iter) \ | |||||
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.entry->next) | |||||
/* Array type methods */ | /* Array type methods */ | ||||
/** Create a new empty json_object of type json_type_array | /** Create a new empty json_object of type json_type_array | ||||
* @returns a json_object of type json_type_array | * @returns a json_object of type json_type_array | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_array(void); | |||||
JSON_EXPORT struct json_object *json_object_new_array(void); | |||||
/** Get the arraylist of a json_object of type json_type_array | /** Get the arraylist of a json_object of type json_type_array | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns an arraylist | * @returns an arraylist | ||||
*/ | */ | ||||
JSON_EXPORT struct array_list* json_object_get_array(const struct json_object *obj); | |||||
JSON_EXPORT struct array_list *json_object_get_array(const struct json_object *obj); | |||||
/** Get the length of a json_object of type json_type_array | /** Get the length of a json_object of type json_type_array | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
@@ -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,10 +591,9 @@ 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( | |||||
const struct json_object *key, | |||||
const struct json_object *jso, | |||||
int (*sort_fn)(const void *, const void *)); | |||||
JSON_EXPORT struct json_object * | |||||
json_object_array_bsearch(const struct json_object *key, const struct json_object *jso, | |||||
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, | |||||
struct json_object *val); | |||||
JSON_EXPORT int json_object_array_add(struct json_object *obj, 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) | ||||
* | * | ||||
@@ -625,15 +622,15 @@ JSON_EXPORT int json_object_array_add(struct json_object *obj, | |||||
* @param val the json_object to be added | * @param val the json_object to be added | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx, | JSON_EXPORT int json_object_array_put_idx(struct json_object *obj, size_t idx, | ||||
struct json_object *val); | |||||
struct json_object *val); | |||||
/** Get the element at specified index of the array (a json_object of type json_type_array) | /** Get the element at specified index of the array (a json_object of type json_type_array) | ||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @param idx the index to get the element at | * @param idx the index to get the element at | ||||
* @returns the json_object at the specified index (or NULL) | * @returns the json_object at the specified index (or NULL) | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_array_get_idx(const struct json_object *obj, | |||||
size_t idx); | |||||
JSON_EXPORT struct json_object *json_object_array_get_idx(const struct json_object *obj, | |||||
size_t idx); | |||||
/** Delete an elements from a specified index in an array (a json_object of type json_type_array) | /** Delete an elements from a specified index in an array (a json_object of type json_type_array) | ||||
* | * | ||||
@@ -654,7 +651,7 @@ JSON_EXPORT int json_object_array_del_idx(struct json_object *obj, size_t idx, s | |||||
* @param b a json_bool 1 or 0 | * @param b a json_bool 1 or 0 | ||||
* @returns a json_object of type json_type_boolean | * @returns a json_object of type json_type_boolean | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_boolean(json_bool b); | |||||
JSON_EXPORT struct json_object *json_object_new_boolean(json_bool b); | |||||
/** Get the json_bool value of a json_object | /** Get the json_bool value of a json_object | ||||
* | * | ||||
@@ -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 | ||||
@@ -680,8 +676,7 @@ JSON_EXPORT json_bool json_object_get_boolean(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
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 */ | ||||
@@ -691,22 +686,19 @@ JSON_EXPORT int json_object_set_boolean(struct json_object *obj,json_bool new_va | |||||
* @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_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 | ||||
* | * | ||||
@@ -734,7 +726,7 @@ JSON_EXPORT int32_t json_object_get_int(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_set_int(struct json_object *obj,int new_value); | |||||
JSON_EXPORT int json_object_set_int(struct json_object *obj, int new_value); | |||||
/** Increment a json_type_int object by the given amount, which may be negative. | /** Increment a json_type_int object by the given amount, which may be negative. | ||||
* | * | ||||
@@ -792,7 +784,7 @@ JSON_EXPORT uint64_t json_object_get_uint64(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_set_int64(struct json_object *obj,int64_t new_value); | |||||
JSON_EXPORT int json_object_set_int64(struct json_object *obj, int64_t new_value); | |||||
/** Set the uint64_t value of a json_object | /** Set the uint64_t value of a json_object | ||||
* | * | ||||
@@ -804,7 +796,7 @@ JSON_EXPORT int json_object_set_int64(struct json_object *obj,int64_t new_value) | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_set_uint64(struct json_object *obj,uint64_t new_value); | |||||
JSON_EXPORT int json_object_set_uint64(struct json_object *obj, uint64_t new_value); | |||||
/* double type methods */ | /* double type methods */ | ||||
@@ -815,7 +807,7 @@ JSON_EXPORT int json_object_set_uint64(struct json_object *obj,uint64_t new_valu | |||||
* @param d the double | * @param d the double | ||||
* @returns a json_object of type json_type_double | * @returns a json_object of type json_type_double | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_double(double d); | |||||
JSON_EXPORT struct json_object *json_object_new_double(double d); | |||||
/** | /** | ||||
* Create a new json_object of type json_type_double, using | * Create a new json_object of type json_type_double, using | ||||
@@ -844,7 +836,7 @@ JSON_EXPORT struct json_object* json_object_new_double(double d); | |||||
* @param d the numeric value of the double. | * @param d the numeric value of the double. | ||||
* @param ds the string representation of the double. This will be copied. | * @param ds the string representation of the double. This will be copied. | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_double_s(double d, const char *ds); | |||||
JSON_EXPORT struct json_object *json_object_new_double_s(double d, const char *ds); | |||||
/** | /** | ||||
* Set a global or thread-local json-c option, depending on whether | * Set a global or thread-local json-c option, depending on whether | ||||
@@ -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, | |||||
struct printbuf *pb, | |||||
int level, | |||||
int flags); | |||||
JSON_EXPORT int json_object_double_to_json_string(struct json_object *jso, struct printbuf *pb, | |||||
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 | ||||
@@ -925,9 +913,7 @@ JSON_EXPORT double json_object_get_double(const struct json_object *obj); | |||||
* @param new_value the value to be set | * @param new_value the value to be set | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
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 */ | ||||
@@ -939,7 +925,7 @@ JSON_EXPORT int json_object_set_double(struct json_object *obj,double new_value) | |||||
* @returns a json_object of type json_type_string | * @returns a json_object of type json_type_string | ||||
* @see json_object_new_string_len() | * @see json_object_new_string_len() | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_string(const char *s); | |||||
JSON_EXPORT struct json_object *json_object_new_string(const char *s); | |||||
/** Create a new empty json_object of type json_type_string and allocate | /** Create a new empty json_object of type json_type_string and allocate | ||||
* len characters for the new string. | * len characters for the new string. | ||||
@@ -951,7 +937,7 @@ JSON_EXPORT struct json_object* json_object_new_string(const char *s); | |||||
* @returns a json_object of type json_type_string | * @returns a json_object of type json_type_string | ||||
* @see json_object_new_string() | * @see json_object_new_string() | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_string_len(const char *s, const int len); | |||||
JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len); | |||||
/** Get the string value of a json_object | /** Get the string value of a json_object | ||||
* | * | ||||
@@ -969,7 +955,7 @@ JSON_EXPORT struct json_object* json_object_new_string_len(const char *s, const | |||||
* @param obj the json_object instance | * @param obj the json_object instance | ||||
* @returns a string or NULL | * @returns a string or NULL | ||||
*/ | */ | ||||
JSON_EXPORT const char* json_object_get_string(struct json_object *obj); | |||||
JSON_EXPORT const char *json_object_get_string(struct json_object *obj); | |||||
/** Get the string length of a json_object | /** Get the string length of a json_object | ||||
* | * | ||||
@@ -981,12 +967,11 @@ 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 | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_set_string(json_object* obj, const char* new_value); | |||||
JSON_EXPORT int json_object_set_string(json_object *obj, const char *new_value); | |||||
/** Set the string value of a json_object str | /** Set the string value of a json_object str | ||||
* | * | ||||
@@ -999,13 +984,13 @@ JSON_EXPORT int json_object_set_string(json_object* obj, const char* new_value); | |||||
* @param len the length of new_value | * @param len the length of new_value | ||||
* @returns 1 if value is set correctly, 0 otherwise | * @returns 1 if value is set correctly, 0 otherwise | ||||
*/ | */ | ||||
JSON_EXPORT int json_object_set_string_len(json_object* obj, const char* new_value, int len); | |||||
JSON_EXPORT int json_object_set_string_len(json_object *obj, const char *new_value, int len); | |||||
/** This method exists only to provide a complementary function | /** This method exists only to provide a complementary function | ||||
* along the lines of the other json_object_new_* functions. | * along the lines of the other json_object_new_* functions. | ||||
* It always returns NULL, and it is entirely acceptable to simply use NULL directly. | * It always returns NULL, and it is entirely acceptable to simply use NULL directly. | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_new_null(); | |||||
JSON_EXPORT struct json_object *json_object_new_null(); | |||||
/** Check if two json_object's are equal | /** Check if two json_object's are equal | ||||
* | * | ||||
@@ -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, | |||||
struct json_object *obj2); | |||||
JSON_EXPORT int json_object_equal(struct json_object *obj1, 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 | ||||
@@ -53,111 +53,100 @@ | |||||
/// Our current representation of the "end" iterator; | /// Our current representation of the "end" iterator; | ||||
/// | /// | ||||
/// @note May not always be NULL | /// @note May not always be NULL | ||||
static const void* kObjectEndIterValue = NULL; | |||||
static const void *kObjectEndIterValue = NULL; | |||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
struct json_object_iterator | |||||
json_object_iter_begin(struct json_object* obj) | |||||
struct json_object_iterator json_object_iter_begin(struct json_object *obj) | |||||
{ | { | ||||
struct json_object_iterator iter; | |||||
struct lh_table* pTable; | |||||
/// @note json_object_get_object will return NULL if passed NULL | |||||
/// or a non-json_type_object instance | |||||
pTable = json_object_get_object(obj); | |||||
JASSERT(NULL != pTable); | |||||
/// @note For a pair-less Object, head is NULL, which matches our | |||||
/// definition of the "end" iterator | |||||
iter.opaque_ = pTable->head; | |||||
return iter; | |||||
struct json_object_iterator iter; | |||||
struct lh_table *pTable; | |||||
/// @note json_object_get_object will return NULL if passed NULL | |||||
/// or a non-json_type_object instance | |||||
pTable = json_object_get_object(obj); | |||||
JASSERT(NULL != pTable); | |||||
/// @note For a pair-less Object, head is NULL, which matches our | |||||
/// definition of the "end" iterator | |||||
iter.opaque_ = pTable->head; | |||||
return iter; | |||||
} | } | ||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
struct json_object_iterator | |||||
json_object_iter_end(const struct json_object* obj) | |||||
struct json_object_iterator json_object_iter_end(const struct json_object *obj) | |||||
{ | { | ||||
struct json_object_iterator iter; | |||||
struct json_object_iterator iter; | |||||
JASSERT(NULL != obj); | |||||
JASSERT(json_object_is_type(obj, json_type_object)); | |||||
JASSERT(NULL != obj); | |||||
JASSERT(json_object_is_type(obj, json_type_object)); | |||||
iter.opaque_ = kObjectEndIterValue; | |||||
iter.opaque_ = kObjectEndIterValue; | |||||
return iter; | |||||
return iter; | |||||
} | } | ||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
void | |||||
json_object_iter_next(struct json_object_iterator* iter) | |||||
void json_object_iter_next(struct json_object_iterator *iter) | |||||
{ | { | ||||
JASSERT(NULL != iter); | |||||
JASSERT(kObjectEndIterValue != iter->opaque_); | |||||
JASSERT(NULL != iter); | |||||
JASSERT(kObjectEndIterValue != iter->opaque_); | |||||
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next; | |||||
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next; | |||||
} | } | ||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
const char* | |||||
json_object_iter_peek_name(const struct json_object_iterator* iter) | |||||
const char *json_object_iter_peek_name(const struct json_object_iterator *iter) | |||||
{ | { | ||||
JASSERT(NULL != iter); | |||||
JASSERT(kObjectEndIterValue != iter->opaque_); | |||||
JASSERT(NULL != iter); | |||||
JASSERT(kObjectEndIterValue != iter->opaque_); | |||||
return (const char*)(((const struct lh_entry *)iter->opaque_)->k); | |||||
return (const char *)(((const struct lh_entry *)iter->opaque_)->k); | |||||
} | } | ||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
struct json_object* | |||||
json_object_iter_peek_value(const struct json_object_iterator* iter) | |||||
struct json_object *json_object_iter_peek_value(const struct json_object_iterator *iter) | |||||
{ | { | ||||
JASSERT(NULL != iter); | |||||
JASSERT(kObjectEndIterValue != iter->opaque_); | |||||
JASSERT(NULL != iter); | |||||
JASSERT(kObjectEndIterValue != iter->opaque_); | |||||
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_object_iter_equal(const struct json_object_iterator* iter1, | |||||
const struct json_object_iterator* iter2) | |||||
json_bool json_object_iter_equal(const struct json_object_iterator *iter1, | |||||
const struct json_object_iterator *iter2) | |||||
{ | { | ||||
JASSERT(NULL != iter1); | |||||
JASSERT(NULL != iter2); | |||||
JASSERT(NULL != iter1); | |||||
JASSERT(NULL != iter2); | |||||
return (iter1->opaque_ == iter2->opaque_); | |||||
return (iter1->opaque_ == iter2->opaque_); | |||||
} | } | ||||
/** | /** | ||||
* **************************************************************************** | * **************************************************************************** | ||||
*/ | */ | ||||
struct json_object_iterator | |||||
json_object_iter_init_default(void) | |||||
struct json_object_iterator json_object_iter_init_default(void) | |||||
{ | { | ||||
struct json_object_iterator iter; | |||||
struct json_object_iterator iter; | |||||
/** | |||||
* @note Make this a negative, invalid value, such that | |||||
* accidental access to it would likely be trapped by the | |||||
* hardware as an invalid address. | |||||
*/ | |||||
iter.opaque_ = NULL; | |||||
/** | |||||
* @note Make this a negative, invalid value, such that | |||||
* accidental access to it would likely be trapped by the | |||||
* hardware as an invalid address. | |||||
*/ | |||||
iter.opaque_ = NULL; | |||||
return iter; | |||||
return iter; | |||||
} | } |
@@ -20,14 +20,13 @@ | |||||
******************************************************************************* | ******************************************************************************* | ||||
*/ | */ | ||||
#ifndef JSON_OBJECT_ITERATOR_H | #ifndef JSON_OBJECT_ITERATOR_H | ||||
#define JSON_OBJECT_ITERATOR_H | #define JSON_OBJECT_ITERATOR_H | ||||
#include <stddef.h> | #include <stddef.h> | ||||
#ifndef JSON_EXPORT | #ifndef JSON_EXPORT | ||||
#if defined(_MSC_VER) | |||||
#if defined(_MSC_VER) | |||||
#define JSON_EXPORT __declspec(dllexport) | #define JSON_EXPORT __declspec(dllexport) | ||||
#else | #else | ||||
#define JSON_EXPORT extern | #define JSON_EXPORT extern | ||||
@@ -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 { | |||||
const void* opaque_; | |||||
struct json_object_iterator | |||||
{ | |||||
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_object_iter_init_default(void); | |||||
JSON_EXPORT struct json_object_iterator 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_object_iter_begin(struct json_object* obj); | |||||
JSON_EXPORT struct json_object_iterator 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_object_iter_end(const struct json_object* obj); | |||||
JSON_EXPORT struct json_object_iterator 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_object_iter_next(struct json_object_iterator* iter); | |||||
JSON_EXPORT void 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_object_iter_peek_name(const struct json_object_iterator* iter); | |||||
JSON_EXPORT const char *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 | ||||
@@ -205,9 +196,8 @@ json_object_iter_peek_name(const struct json_object_iterator* iter); | |||||
* the JSON Null value as a NULL json_object instance | * the JSON Null value as a NULL json_object instance | ||||
* pointer. | * pointer. | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* | |||||
json_object_iter_peek_value(const struct json_object_iterator* iter); | |||||
JSON_EXPORT struct json_object * | |||||
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 | ||||
@@ -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_object_iter_equal(const struct json_object_iterator* iter1, | |||||
const struct json_object_iterator* iter2); | |||||
JSON_EXPORT json_bool json_object_iter_equal(const struct json_object_iterator *iter1, | |||||
const struct json_object_iterator *iter2); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
#endif /* JSON_OBJECT_ITERATOR_H */ | #endif /* JSON_OBJECT_ITERATOR_H */ |
@@ -20,48 +20,55 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
#define LEN_DIRECT_STRING_DATA 32 /**< how many bytes are directly stored in json_object for strings? */ | |||||
/**< how many bytes are directly stored in json_object for strings? */ | |||||
#define LEN_DIRECT_STRING_DATA 32 | |||||
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 { | |||||
json_object_int_type_int64, | |||||
json_object_int_type_uint64 | |||||
}json_object_int_type; | |||||
typedef enum json_object_int_type | |||||
{ | |||||
json_object_int_type_int64, | |||||
json_object_int_type_uint64 | |||||
} json_object_int_type; | |||||
struct json_object | struct json_object | ||||
{ | { | ||||
enum json_type o_type; | |||||
uint32_t _ref_count; | |||||
json_object_private_delete_fn *_delete; | |||||
json_object_to_json_string_fn *_to_json_string; | |||||
struct printbuf *_pb; | |||||
union data { | |||||
json_bool c_boolean; | |||||
double c_double; | |||||
struct { | |||||
union { | |||||
int64_t c_int64; | |||||
uint64_t c_uint64; | |||||
} cint; | |||||
enum json_object_int_type cint_type; | |||||
} c_int; | |||||
struct lh_table *c_object; | |||||
struct array_list *c_array; | |||||
struct { | |||||
union { | |||||
/* optimize: if we have small strings, we can store them | |||||
* directly. This saves considerable CPU cycles AND memory. | |||||
*/ | |||||
char *ptr; | |||||
char data[LEN_DIRECT_STRING_DATA]; | |||||
} str; | |||||
int len; | |||||
} c_string; | |||||
} o; | |||||
json_object_delete_fn *_user_delete; | |||||
void *_userdata; | |||||
enum json_type o_type; | |||||
uint32_t _ref_count; | |||||
json_object_private_delete_fn *_delete; | |||||
json_object_to_json_string_fn *_to_json_string; | |||||
struct printbuf *_pb; | |||||
union data | |||||
{ | |||||
json_bool c_boolean; | |||||
double c_double; | |||||
struct | |||||
{ | |||||
union | |||||
{ | |||||
int64_t c_int64; | |||||
uint64_t c_uint64; | |||||
} cint; | |||||
enum json_object_int_type cint_type; | |||||
} c_int; | |||||
struct lh_table *c_object; | |||||
struct array_list *c_array; | |||||
struct | |||||
{ | |||||
union | |||||
{ | |||||
/* optimize: if we have small strings, we can store them | |||||
* directly. This saves considerable CPU cycles AND memory. | |||||
*/ | |||||
char *ptr; | |||||
char data[LEN_DIRECT_STRING_DATA]; | |||||
} str; | |||||
int len; | |||||
} c_string; | |||||
} o; | |||||
json_object_delete_fn *_user_delete; | |||||
void *_userdata; | |||||
}; | }; | ||||
void _json_c_set_last_err(const char *err_fmt, ...); | void _json_c_set_last_err(const char *err_fmt, ...); | ||||
@@ -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; | ||||
@@ -41,10 +42,13 @@ static void string_replace_all_occurrences_with_char(char *s, const char *occur, | |||||
static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx) | static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx) | ||||
{ | { | ||||
int i, len = strlen(path); | int i, len = strlen(path); | ||||
/* 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 */ | |||||
if (len == 1) { | |||||
if (isdigit((unsigned char)path[0])) { | |||||
/* 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 | |||||
*/ | |||||
if (len == 1) | |||||
{ | |||||
if (isdigit((unsigned char)path[0])) | |||||
{ | |||||
*idx = (path[0] - '0'); | *idx = (path[0] - '0'); | ||||
goto check_oob; | goto check_oob; | ||||
} | } | ||||
@@ -52,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++) { | |||||
if (!isdigit((unsigned char)path[i])) { | |||||
for (i = 0; i < len; 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; | ||||
} | } | ||||
@@ -79,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; | ||||
@@ -100,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; | ||||
} | } | ||||
@@ -108,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( | |||||
struct json_object *parent, | |||||
const char *path, | |||||
struct json_object *value) | |||||
static int json_pointer_set_single_path(struct json_object *parent, const char *path, | |||||
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') | ||||
@@ -124,26 +136,27 @@ static int json_pointer_set_single_path( | |||||
} | } | ||||
/* path replacements should have been done in json_pointer_get_single_path(), | /* path replacements should have been done in json_pointer_get_single_path(), | ||||
and we should still be good here */ | |||||
* and we should still be good here | |||||
*/ | |||||
if (json_object_is_type(parent, json_type_object)) | if (json_object_is_type(parent, json_type_object)) | ||||
return json_object_object_add(parent, path, value); | return json_object_object_add(parent, path, value); | ||||
/* Getting here means that we tried to "dereference" a primitive JSON type (like string, int, bool). | |||||
i.e. add a sub-object to it */ | |||||
/* Getting here means that we tried to "dereference" a primitive JSON type | |||||
* (like string, int, bool).i.e. add a sub-object to it | |||||
*/ | |||||
errno = ENOENT; | errno = ENOENT; | ||||
return -1; | return -1; | ||||
} | } | ||||
static int json_pointer_get_recursive( | |||||
struct json_object *obj, | |||||
char *path, | |||||
struct json_object **value) | |||||
static int json_pointer_get_recursive(struct json_object *obj, char *path, | |||||
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; | ||||
} | } | ||||
@@ -157,8 +170,10 @@ 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) { | |||||
*endp = '/'; /* Put the slash back, so that the sanity check passes on next recursion level */ | |||||
if (endp) | |||||
{ | |||||
/* Put the slash back, so that the sanity check passes on next recursion level */ | |||||
*endp = '/'; | |||||
return json_pointer_get_recursive(obj, endp, value); | return json_pointer_get_recursive(obj, endp, value); | ||||
} | } | ||||
@@ -174,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; | ||||
} | } | ||||
@@ -202,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; | ||||
} | } | ||||
@@ -214,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; | ||||
@@ -234,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; | ||||
} | } | ||||
@@ -272,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; | ||||
@@ -280,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; | ||||
} | } | ||||
@@ -293,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; | ||||
} | } | ||||
@@ -324,4 +354,3 @@ out: | |||||
free(path_copy); | free(path_copy); | ||||
return rc; | return rc; | ||||
} | } | ||||
@@ -44,7 +44,8 @@ extern "C" { | |||||
* | * | ||||
* @return negative if an error (or not found), or 0 if succeeded | * @return negative if an error (or not found), or 0 if succeeded | ||||
*/ | */ | ||||
JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res); | |||||
JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, | |||||
struct json_object **res); | |||||
/** | /** | ||||
* This is a variant of 'json_pointer_get()' that supports printf() style arguments. | * This is a variant of 'json_pointer_get()' that supports printf() style arguments. | ||||
@@ -62,7 +63,8 @@ JSON_EXPORT int json_pointer_get(struct json_object *obj, const char *path, stru | |||||
* | * | ||||
* @return negative if an error (or not found), or 0 if succeeded | * @return negative if an error (or not found), or 0 if succeeded | ||||
*/ | */ | ||||
JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...); | |||||
JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object **res, | |||||
const char *path_fmt, ...); | |||||
/** | /** | ||||
* Sets JSON object 'value' in the 'obj' tree at the location specified | * Sets JSON object 'value' in the 'obj' tree at the location specified | ||||
@@ -93,7 +95,8 @@ JSON_EXPORT int json_pointer_getf(struct json_object *obj, struct json_object ** | |||||
* | * | ||||
* @return negative if an error (or not found), or 0 if succeeded | * @return negative if an error (or not found), or 0 if succeeded | ||||
*/ | */ | ||||
JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value); | |||||
JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, | |||||
struct json_object *value); | |||||
/** | /** | ||||
* This is a variant of 'json_pointer_set()' that supports printf() style arguments. | * This is a variant of 'json_pointer_set()' that supports printf() style arguments. | ||||
@@ -110,8 +113,8 @@ JSON_EXPORT int json_pointer_set(struct json_object **obj, const char *path, str | |||||
* | * | ||||
* @return negative if an error (or not found), or 0 if succeeded | * @return negative if an error (or not found), or 0 if succeeded | ||||
*/ | */ | ||||
JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...); | |||||
JSON_EXPORT int json_pointer_setf(struct json_object **obj, struct json_object *value, | |||||
const char *path_fmt, ...); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
@@ -16,66 +16,68 @@ | |||||
#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 { | |||||
json_tokener_success, | |||||
json_tokener_continue, | |||||
json_tokener_error_depth, | |||||
json_tokener_error_parse_eof, | |||||
json_tokener_error_parse_unexpected, | |||||
json_tokener_error_parse_null, | |||||
json_tokener_error_parse_boolean, | |||||
json_tokener_error_parse_number, | |||||
json_tokener_error_parse_array, | |||||
json_tokener_error_parse_object_key_name, | |||||
json_tokener_error_parse_object_key_sep, | |||||
json_tokener_error_parse_object_value_sep, | |||||
json_tokener_error_parse_string, | |||||
json_tokener_error_parse_comment, | |||||
json_tokener_error_parse_utf8_string, | |||||
json_tokener_error_size | |||||
enum json_tokener_error | |||||
{ | |||||
json_tokener_success, | |||||
json_tokener_continue, | |||||
json_tokener_error_depth, | |||||
json_tokener_error_parse_eof, | |||||
json_tokener_error_parse_unexpected, | |||||
json_tokener_error_parse_null, | |||||
json_tokener_error_parse_boolean, | |||||
json_tokener_error_parse_number, | |||||
json_tokener_error_parse_array, | |||||
json_tokener_error_parse_object_key_name, | |||||
json_tokener_error_parse_object_key_sep, | |||||
json_tokener_error_parse_object_value_sep, | |||||
json_tokener_error_parse_string, | |||||
json_tokener_error_parse_comment, | |||||
json_tokener_error_parse_utf8_string, | |||||
json_tokener_error_size | |||||
}; | }; | ||||
enum json_tokener_state { | |||||
json_tokener_state_eatws, | |||||
json_tokener_state_start, | |||||
json_tokener_state_finish, | |||||
json_tokener_state_null, | |||||
json_tokener_state_comment_start, | |||||
json_tokener_state_comment, | |||||
json_tokener_state_comment_eol, | |||||
json_tokener_state_comment_end, | |||||
json_tokener_state_string, | |||||
json_tokener_state_string_escape, | |||||
json_tokener_state_escape_unicode, | |||||
json_tokener_state_boolean, | |||||
json_tokener_state_number, | |||||
json_tokener_state_array, | |||||
json_tokener_state_array_add, | |||||
json_tokener_state_array_sep, | |||||
json_tokener_state_object_field_start, | |||||
json_tokener_state_object_field, | |||||
json_tokener_state_object_field_end, | |||||
json_tokener_state_object_value, | |||||
json_tokener_state_object_value_add, | |||||
json_tokener_state_object_sep, | |||||
json_tokener_state_array_after_sep, | |||||
json_tokener_state_object_field_start_after_sep, | |||||
json_tokener_state_inf | |||||
enum json_tokener_state | |||||
{ | |||||
json_tokener_state_eatws, | |||||
json_tokener_state_start, | |||||
json_tokener_state_finish, | |||||
json_tokener_state_null, | |||||
json_tokener_state_comment_start, | |||||
json_tokener_state_comment, | |||||
json_tokener_state_comment_eol, | |||||
json_tokener_state_comment_end, | |||||
json_tokener_state_string, | |||||
json_tokener_state_string_escape, | |||||
json_tokener_state_escape_unicode, | |||||
json_tokener_state_boolean, | |||||
json_tokener_state_number, | |||||
json_tokener_state_array, | |||||
json_tokener_state_array_add, | |||||
json_tokener_state_array_sep, | |||||
json_tokener_state_object_field_start, | |||||
json_tokener_state_object_field, | |||||
json_tokener_state_object_field_end, | |||||
json_tokener_state_object_value, | |||||
json_tokener_state_object_value_add, | |||||
json_tokener_state_object_sep, | |||||
json_tokener_state_array_after_sep, | |||||
json_tokener_state_object_field_start_after_sep, | |||||
json_tokener_state_inf | |||||
}; | }; | ||||
struct json_tokener_srec | struct json_tokener_srec | ||||
{ | { | ||||
enum json_tokener_state state, saved_state; | |||||
struct json_object *obj; | |||||
struct json_object *current; | |||||
char *obj_field_name; | |||||
enum json_tokener_state state, saved_state; | |||||
struct json_object *obj; | |||||
struct json_object *current; | |||||
char *obj_field_name; | |||||
}; | }; | ||||
#define JSON_TOKENER_DEFAULT_DEPTH 32 | #define JSON_TOKENER_DEFAULT_DEPTH 32 | ||||
@@ -89,18 +91,18 @@ struct json_tokener_srec | |||||
*/ | */ | ||||
struct json_tokener | struct json_tokener | ||||
{ | { | ||||
char *str; | |||||
struct printbuf *pb; | |||||
int max_depth, depth, is_double, st_pos; | |||||
/** | |||||
* See json_tokener_get_parse_end() | |||||
*/ | |||||
int char_offset; | |||||
enum json_tokener_error err; | |||||
unsigned int ucs_char; | |||||
char quote_char; | |||||
struct json_tokener_srec *stack; | |||||
int flags; | |||||
char *str; | |||||
struct printbuf *pb; | |||||
int max_depth, depth, is_double, st_pos; | |||||
/** | |||||
* See json_tokener_get_parse_end() | |||||
*/ | |||||
int char_offset; | |||||
enum json_tokener_error err; | |||||
unsigned int ucs_char; | |||||
char quote_char; | |||||
struct json_tokener_srec *stack; | |||||
int flags; | |||||
}; | }; | ||||
/** | /** | ||||
@@ -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 | ||||
*/ | */ | ||||
@@ -135,7 +136,7 @@ typedef struct json_tokener json_tokener; | |||||
* | * | ||||
* @see json_tokener_set_flags() | * @see json_tokener_set_flags() | ||||
*/ | */ | ||||
#define JSON_TOKENER_STRICT 0x01 | |||||
#define JSON_TOKENER_STRICT 0x01 | |||||
/** | /** | ||||
* Allow json_tokener_parse_ex() validate utf-8 char. | * Allow json_tokener_parse_ex() validate utf-8 char. | ||||
@@ -146,7 +147,7 @@ typedef struct json_tokener json_tokener; | |||||
* | * | ||||
* @see json_tokener_set_flags() | * @see json_tokener_set_flags() | ||||
*/ | */ | ||||
#define JSON_TOKENER_VALIDATE_UTF8 0x10 | |||||
#define JSON_TOKENER_VALIDATE_UTF8 0x10 | |||||
/** | /** | ||||
* Given an error previously returned by json_tokener_get_error(), | * Given an error previously returned by json_tokener_get_error(), | ||||
@@ -167,12 +168,13 @@ JSON_EXPORT const char *json_tokener_error_desc(enum json_tokener_error jerr); | |||||
*/ | */ | ||||
JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok); | JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok); | ||||
JSON_EXPORT struct json_tokener* json_tokener_new(void); | |||||
JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth); | |||||
JSON_EXPORT struct json_tokener *json_tokener_new(void); | |||||
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_verbose(const char *str, enum json_tokener_error *error); | |||||
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); | |||||
/** | /** | ||||
* 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, | |||||
const char *str, int len); | |||||
JSON_EXPORT struct json_object *json_tokener_parse_ex(struct json_tokener *tok, const char *str, | |||||
int len); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
@@ -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> | ||||
@@ -35,32 +35,32 @@ | |||||
#endif /* HAVE_FCNTL_H */ | #endif /* HAVE_FCNTL_H */ | ||||
#ifdef HAVE_UNISTD_H | #ifdef HAVE_UNISTD_H | ||||
# include <unistd.h> | |||||
#include <unistd.h> | |||||
#endif /* HAVE_UNISTD_H */ | #endif /* HAVE_UNISTD_H */ | ||||
#ifdef WIN32 | #ifdef WIN32 | ||||
# if MSC_VER < 1800 | |||||
#if MSC_VER < 1800 | |||||
/* strtoll/strtoull is available only since Visual Studio 2013 */ | /* strtoll/strtoull is available only since Visual Studio 2013 */ | ||||
# define strtoll _strtoi64 | |||||
# define strtoull _strtoui64 | |||||
# endif | |||||
# define WIN32_LEAN_AND_MEAN | |||||
# include <windows.h> | |||||
# include <io.h> | |||||
#define strtoll _strtoi64 | |||||
#define strtoull _strtoui64 | |||||
#endif | |||||
#define WIN32_LEAN_AND_MEAN | |||||
#include <io.h> | |||||
#include <windows.h> | |||||
#endif /* defined(WIN32) */ | #endif /* defined(WIN32) */ | ||||
#if !defined(HAVE_OPEN) && defined(WIN32) | #if !defined(HAVE_OPEN) && defined(WIN32) | ||||
# define open _open | |||||
#define open _open | |||||
#endif | #endif | ||||
#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); | ||||
@@ -82,66 +82,74 @@ void _json_c_set_last_err(const char *err_fmt, ...) | |||||
va_end(ap); | va_end(ap); | ||||
} | } | ||||
struct json_object* json_object_from_fd(int fd) | |||||
struct json_object *json_object_from_fd(int fd) | |||||
{ | { | ||||
return json_object_from_fd_ex(fd, -1); | return json_object_from_fd_ex(fd, -1); | ||||
} | } | ||||
struct json_object* json_object_from_fd_ex(int fd, int in_depth) | |||||
struct json_object *json_object_from_fd_ex(int fd, int in_depth) | |||||
{ | { | ||||
struct printbuf *pb; | |||||
struct json_object *obj; | |||||
char buf[JSON_FILE_BUF_SIZE]; | |||||
int ret; | |||||
struct printbuf *pb; | |||||
struct json_object *obj; | |||||
char buf[JSON_FILE_BUF_SIZE]; | |||||
int ret; | |||||
int depth = JSON_TOKENER_DEFAULT_DEPTH; | int depth = JSON_TOKENER_DEFAULT_DEPTH; | ||||
json_tokener *tok; | json_tokener *tok; | ||||
if(!(pb = printbuf_new())) { | |||||
_json_c_set_last_err("json_object_from_file: printbuf_new failed\n"); | |||||
return NULL; | |||||
} | |||||
if (!(pb = printbuf_new())) | |||||
{ | |||||
_json_c_set_last_err("json_object_from_file: printbuf_new failed\n"); | |||||
return NULL; | |||||
} | |||||
if (in_depth != -1) | if (in_depth != -1) | ||||
depth = in_depth; | depth = 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) { | |||||
printbuf_memappend(pb, buf, ret); | |||||
} | |||||
if(ret < 0) { | |||||
_json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno)); | |||||
json_tokener_free(tok); | |||||
printbuf_free(pb); | |||||
return NULL; | |||||
} | |||||
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) | |||||
{ | |||||
printbuf_memappend(pb, buf, ret); | |||||
} | |||||
if (ret < 0) | |||||
{ | |||||
_json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, | |||||
strerror(errno)); | |||||
json_tokener_free(tok); | |||||
printbuf_free(pb); | |||||
return NULL; | |||||
} | |||||
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); | ||||
return obj; | return obj; | ||||
} | } | ||||
struct json_object* json_object_from_file(const char *filename) | |||||
struct json_object *json_object_from_file(const char *filename) | |||||
{ | { | ||||
struct json_object *obj; | |||||
int fd; | |||||
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)); | |||||
return NULL; | |||||
} | |||||
obj = json_object_from_fd(fd); | |||||
close(fd); | |||||
return obj; | |||||
struct json_object *obj; | |||||
int fd; | |||||
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)); | |||||
return NULL; | |||||
} | |||||
obj = json_object_from_fd(fd); | |||||
close(fd); | |||||
return obj; | |||||
} | } | ||||
/* extended "format and write to file" function */ | /* extended "format and write to file" function */ | ||||
@@ -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) { | |||||
_json_c_set_last_err("json_object_to_file: error opening file %s: %s\n", | |||||
filename, strerror(errno)); | |||||
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)); | |||||
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,17 +196,21 @@ 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; | ||||
} | } | ||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ | |||||
/* CAW: probably unnecessary, but the most 64bit safe */ | |||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); | |||||
wpos = 0; | wpos = 0; | ||||
while(wpos < wsize) { | |||||
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", | |||||
filename, strerror(errno)); | |||||
return -1; | |||||
while (wpos < wsize) | |||||
{ | |||||
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", | |||||
filename, strerror(errno)); | |||||
return -1; | |||||
} | } | ||||
/* because of the above check for ret < 0, we can safely cast and add */ | /* because of the above check for ret < 0, we can safely cast and add */ | ||||
@@ -209,14 +224,14 @@ static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const | |||||
int json_object_to_file(const char *filename, struct json_object *obj) | int json_object_to_file(const char *filename, struct json_object *obj) | ||||
{ | { | ||||
return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN); | |||||
return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN); | |||||
} | } | ||||
int json_parse_double(const char *buf, double *retval) | int json_parse_double(const char *buf, double *retval) | ||||
{ | { | ||||
char *end; | |||||
*retval = strtod(buf, &end); | |||||
return end == buf ? 1 : 0; | |||||
char *end; | |||||
*retval = strtod(buf, &end); | |||||
return end == buf ? 1 : 0; | |||||
} | } | ||||
int json_parse_int64(const char *buf, int64_t *retval) | int json_parse_int64(const char *buf, int64_t *retval) | ||||
@@ -237,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) | ||||
@@ -249,7 +266,7 @@ int json_parse_uint64(const char *buf, uint64_t *retval) | |||||
} | } | ||||
#ifndef HAVE_REALLOC | #ifndef HAVE_REALLOC | ||||
void* rpl_realloc(void* p, size_t n) | |||||
void *rpl_realloc(void *p, size_t n) | |||||
{ | { | ||||
if (n == 0) | if (n == 0) | ||||
n = 1; | n = 1; | ||||
@@ -259,24 +276,27 @@ void* rpl_realloc(void* p, size_t n) | |||||
} | } | ||||
#endif | #endif | ||||
#define NELEM(a) (sizeof(a) / sizeof(a[0])) | |||||
static const char* json_type_name[] = { | |||||
/* If you change this, be sure to update the enum json_type definition too */ | |||||
"null", | |||||
"boolean", | |||||
"double", | |||||
"int", | |||||
"object", | |||||
"array", | |||||
"string", | |||||
#define NELEM(a) (sizeof(a) / sizeof(a[0])) | |||||
/* clang-format off */ | |||||
static const char *json_type_name[] = { | |||||
/* If you change this, be sure to update the enum json_type definition too */ | |||||
"null", | |||||
"boolean", | |||||
"double", | |||||
"int", | |||||
"object", | |||||
"array", | |||||
"string", | |||||
}; | }; | ||||
/* clang-format on */ | |||||
const char *json_type_to_name(enum json_type o_type) | 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]; | ||||
@@ -284,8 +304,7 @@ const char *json_type_to_name(enum json_type o_type) | |||||
void json_abort(const char *message) | void json_abort(const char *message) | ||||
{ | { | ||||
if (message != NULL) | |||||
fprintf (stderr, "json-c aborts with error: %s\n", message); | |||||
abort(); | |||||
if (message != NULL) | |||||
fprintf(stderr, "json-c aborts with error: %s\n", message); | |||||
abort(); | |||||
} | } | ||||
@@ -12,21 +12,20 @@ | |||||
/** | /** | ||||
* @file | * @file | ||||
* @brief Miscllaneous utility functions and macros. | * @brief Miscllaneous utility functions and macros. | ||||
*/ | |||||
*/ | |||||
#ifndef _json_util_h_ | #ifndef _json_util_h_ | ||||
#define _json_util_h_ | #define _json_util_h_ | ||||
#include "json_object.h" | #include "json_object.h" | ||||
#ifndef json_min | #ifndef json_min | ||||
#define json_min(a,b) ((a) < (b) ? (a) : (b)) | |||||
#define json_min(a, b) ((a) < (b) ? (a) : (b)) | |||||
#endif | #endif | ||||
#ifndef json_max | #ifndef json_max | ||||
#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 | ||||
@@ -40,7 +39,7 @@ extern "C" { | |||||
* | * | ||||
* Returns NULL on failure. See json_util_get_last_err() for details. | * Returns NULL on failure. See json_util_get_last_err() for details. | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_from_file(const char *filename); | |||||
JSON_EXPORT struct json_object *json_object_from_file(const char *filename); | |||||
/** | /** | ||||
* Create a JSON object from already opened file descriptor. | * Create a JSON object from already opened file descriptor. | ||||
@@ -56,7 +55,7 @@ JSON_EXPORT struct json_object* json_object_from_file(const char *filename); | |||||
* | * | ||||
* Returns NULL on failure. See json_util_get_last_err() for details. | * Returns NULL on failure. See json_util_get_last_err() for details. | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_from_fd_ex(int fd, int depth); | |||||
JSON_EXPORT struct json_object *json_object_from_fd_ex(int fd, int depth); | |||||
/** | /** | ||||
* Create a JSON object from an already opened file descriptor, using | * Create a JSON object from an already opened file descriptor, using | ||||
@@ -64,7 +63,7 @@ JSON_EXPORT struct json_object* json_object_from_fd_ex(int fd, int depth); | |||||
* | * | ||||
* See json_object_from_fd_ex() for details. | * See json_object_from_fd_ex() for details. | ||||
*/ | */ | ||||
JSON_EXPORT struct json_object* json_object_from_fd(int fd); | |||||
JSON_EXPORT struct json_object *json_object_from_fd(int fd); | |||||
/** | /** | ||||
* Equivalent to: | * Equivalent to: | ||||
@@ -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); | ||||
@@ -119,7 +117,7 @@ JSON_EXPORT const char *json_type_to_name(enum json_type o_type); | |||||
/* 'cold' attribute is for optimization, telling the computer this code | /* 'cold' attribute is for optimization, telling the computer this code | ||||
* path is unlikely. | * path is unlikely. | ||||
*/ | */ | ||||
#define JSON_NORETURN __attribute__ ((noreturn, cold)) | |||||
#define JSON_NORETURN __attribute__((noreturn, cold)) | |||||
#endif | #endif | ||||
#endif | #endif | ||||
/** | /** | ||||
@@ -13,45 +13,39 @@ | |||||
#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, | |||||
const char *jso_key, size_t *jso_index, | |||||
json_c_visit_userfunc *userfunc, void *userarg); | |||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key, | |||||
size_t *jso_index, json_c_visit_userfunc *userfunc, void *userarg); | |||||
int json_c_visit(json_object *jso, int future_flags, | |||||
json_c_visit_userfunc *userfunc, void *userarg) | |||||
int json_c_visit(json_object *jso, int future_flags, 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) | |||||
{ | { | ||||
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: | |||||
return 0; | |||||
default: | |||||
return JSON_C_VISIT_RETURN_ERROR; | |||||
case JSON_C_VISIT_RETURN_STOP: return 0; | |||||
default: return JSON_C_VISIT_RETURN_ERROR; | |||||
} | } | ||||
} | } | ||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||||
const char *jso_key, size_t *jso_index, | |||||
json_c_visit_userfunc *userfunc, void *userarg) | |||||
static int _json_c_visit(json_object *jso, json_object *parent_jso, const char *jso_key, | |||||
size_t *jso_index, 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: | |||||
break; | |||||
case JSON_C_VISIT_RETURN_CONTINUE: 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: | |||||
return userret; | |||||
case JSON_C_VISIT_RETURN_ERROR: 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; | ||||
} | } | ||||
switch(json_object_get_type(jso)) | |||||
switch (json_object_get_type(jso)) | |||||
{ | { | ||||
case json_type_null: | case json_type_null: | ||||
case json_type_boolean: | case json_type_boolean: | ||||
@@ -69,12 +63,13 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||||
if (userret == JSON_C_VISIT_RETURN_POP) | if (userret == JSON_C_VISIT_RETURN_POP) | ||||
break; | break; | ||||
if (userret == JSON_C_VISIT_RETURN_STOP || | if (userret == JSON_C_VISIT_RETURN_STOP || | ||||
userret == JSON_C_VISIT_RETURN_ERROR) | |||||
userret == JSON_C_VISIT_RETURN_ERROR) | |||||
return userret; | return userret; | ||||
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; | ||||
} | } | ||||
} | } | ||||
@@ -91,19 +86,21 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||||
if (userret == JSON_C_VISIT_RETURN_POP) | if (userret == JSON_C_VISIT_RETURN_POP) | ||||
break; | break; | ||||
if (userret == JSON_C_VISIT_RETURN_STOP || | if (userret == JSON_C_VISIT_RETURN_STOP || | ||||
userret == JSON_C_VISIT_RETURN_ERROR) | |||||
userret == JSON_C_VISIT_RETURN_ERROR) | |||||
return userret; | return userret; | ||||
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; | ||||
} | } | ||||
@@ -112,22 +109,20 @@ static int _json_c_visit(json_object *jso, json_object *parent_jso, | |||||
// Non-container types will have already returned before this point. | // Non-container types will have already returned before this point. | ||||
userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg); | userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg); | ||||
switch(userret) | |||||
switch (userret) | |||||
{ | { | ||||
case JSON_C_VISIT_RETURN_SKIP: | case JSON_C_VISIT_RETURN_SKIP: | ||||
case JSON_C_VISIT_RETURN_POP: | case JSON_C_VISIT_RETURN_POP: | ||||
// 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: | |||||
return JSON_C_VISIT_RETURN_CONTINUE; | |||||
case 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: | |||||
return userret; | |||||
case JSON_C_VISIT_RETURN_ERROR: 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 | ||||
} | } | ||||
@@ -8,9 +8,8 @@ | |||||
*/ | */ | ||||
#include "json_object.h" | #include "json_object.h" | ||||
typedef int (json_c_visit_userfunc)(json_object *jso, int flags, | |||||
json_object *parent_jso, const char *jso_key, | |||||
size_t *jso_index, void *userarg); | |||||
typedef int(json_c_visit_userfunc)(json_object *jso, int flags, json_object *parent_jso, | |||||
const char *jso_key, 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,15 +30,15 @@ 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_c_visit_userfunc *userfunc, void *userarg); | |||||
JSON_EXPORT int json_c_visit(json_object *jso, int future_flags, json_c_visit_userfunc *userfunc, | |||||
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 | ||||
* that this is the second time a container (array or object) is being | * that this is the second time a container (array or object) is being | ||||
* called, after all of it's members have been iterated over. | * called, after all of it's members have been iterated over. | ||||
*/ | */ | ||||
#define JSON_C_VISIT_SECOND 0x02 | |||||
#define JSON_C_VISIT_SECOND 0x02 | |||||
/** | /** | ||||
* This json_c_visit_userfunc return value indicates that iteration | * This json_c_visit_userfunc return value indicates that iteration | ||||
@@ -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. | ||||
@@ -7,13 +7,13 @@ | |||||
#ifndef __warn_references | #ifndef __warn_references | ||||
#if defined(__GNUC__) && defined (HAS_GNU_WARNING_LONG) | |||||
#if defined(__GNUC__) && defined(HAS_GNU_WARNING_LONG) | |||||
#define __warn_references(sym,msg) \ | |||||
__asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text"); | |||||
#define __warn_references(sym, msg) \ | |||||
__asm__(".section .gnu" #sym ",\n\t.ascii \"" msg "\"\n\t.text"); | |||||
#else | #else | ||||
#define __warn_references(sym,msg) /* nothing */ | |||||
#define __warn_references(sym, msg) /* nothing */ | |||||
#endif | #endif | ||||
#endif | #endif | ||||
@@ -12,24 +12,24 @@ | |||||
#include "config.h" | #include "config.h" | ||||
#include <stdio.h> | |||||
#include <string.h> | |||||
#include <stdlib.h> | |||||
#include <limits.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 */ | |||||
#endif | #endif | ||||
#if defined(_MSC_VER) || defined(__MINGW32__) | #if defined(_MSC_VER) || defined(__MINGW32__) | ||||
# define WIN32_LEAN_AND_MEAN | |||||
# include <windows.h> /* Get InterlockedCompareExchange */ | |||||
#define WIN32_LEAN_AND_MEAN | |||||
#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 | |||||
json_global_set_string_hash(const int h) | |||||
int json_global_set_string_hash(const int h) | |||||
{ | { | ||||
switch(h) { | |||||
case JSON_C_STR_HASH_DFLT: | |||||
char_hash_fn = lh_char_hash; | |||||
break; | |||||
case JSON_C_STR_HASH_PERLLIKE: | |||||
char_hash_fn = lh_perllike_str_hash; | |||||
break; | |||||
default: | |||||
return -1; | |||||
switch (h) | |||||
{ | |||||
case JSON_C_STR_HASH_DFLT: char_hash_fn = lh_char_hash; break; | |||||
case JSON_C_STR_HASH_PERLLIKE: char_hash_fn = lh_perllike_str_hash; break; | |||||
default: return -1; | |||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -114,25 +109,23 @@ 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) && \ | |||||
__BYTE_ORDER == __LITTLE_ENDIAN) || \ | |||||
(defined(i386) || defined(__i386__) || defined(__i486__) || \ | |||||
defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL)) | |||||
# define HASH_LITTLE_ENDIAN 1 | |||||
# define HASH_BIG_ENDIAN 0 | |||||
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ | |||||
__BYTE_ORDER == __BIG_ENDIAN) || \ | |||||
(defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) | |||||
# define HASH_LITTLE_ENDIAN 0 | |||||
# define HASH_BIG_ENDIAN 1 | |||||
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ | |||||
(defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \ | |||||
defined(__i686__) || defined(vax) || defined(MIPSEL)) | |||||
#define HASH_LITTLE_ENDIAN 1 | |||||
#define HASH_BIG_ENDIAN 0 | |||||
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \ | |||||
(defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel)) | |||||
#define HASH_LITTLE_ENDIAN 0 | |||||
#define HASH_BIG_ENDIAN 1 | |||||
#else | #else | ||||
# define HASH_LITTLE_ENDIAN 0 | |||||
# define HASH_BIG_ENDIAN 0 | |||||
#define HASH_LITTLE_ENDIAN 0 | |||||
#define HASH_BIG_ENDIAN 0 | |||||
#endif | #endif | ||||
#define hashsize(n) ((uint32_t)1<<(n)) | |||||
#define hashmask(n) (hashsize(n)-1) | |||||
#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) | |||||
#define hashsize(n) ((uint32_t)1 << (n)) | |||||
#define hashmask(n) (hashsize(n) - 1) | |||||
#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k)))) | |||||
/* | /* | ||||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||||
@@ -178,15 +171,17 @@ on, and rotates are much kinder to the top and bottom bits, so I used | |||||
rotates. | rotates. | ||||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||||
*/ | */ | ||||
/* clang-format off */ | |||||
#define mix(a,b,c) \ | #define mix(a,b,c) \ | ||||
{ \ | { \ | ||||
a -= c; a ^= rot(c, 4); c += b; \ | |||||
b -= a; b ^= rot(a, 6); a += c; \ | |||||
c -= b; c ^= rot(b, 8); b += a; \ | |||||
a -= c; a ^= rot(c,16); c += b; \ | |||||
b -= a; b ^= rot(a,19); a += c; \ | |||||
c -= b; c ^= rot(b, 4); b += a; \ | |||||
a -= c; a ^= rot(c, 4); c += b; \ | |||||
b -= a; b ^= rot(a, 6); a += c; \ | |||||
c -= b; c ^= rot(b, 8); b += a; \ | |||||
a -= c; a ^= rot(c,16); c += b; \ | |||||
b -= a; b ^= rot(a,19); a += c; \ | |||||
c -= b; c ^= rot(b, 4); b += a; \ | |||||
} | } | ||||
/* clang-format on */ | |||||
/* | /* | ||||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||||
@@ -213,17 +208,18 @@ and these came close: | |||||
11 8 15 26 3 22 24 | 11 8 15 26 3 22 24 | ||||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||||
*/ | */ | ||||
/* clang-format off */ | |||||
#define final(a,b,c) \ | #define final(a,b,c) \ | ||||
{ \ | { \ | ||||
c ^= b; c -= rot(b,14); \ | |||||
a ^= c; a -= rot(c,11); \ | |||||
b ^= a; b -= rot(a,25); \ | |||||
c ^= b; c -= rot(b,16); \ | |||||
a ^= c; a -= rot(c,4); \ | |||||
b ^= a; b -= rot(a,14); \ | |||||
c ^= b; c -= rot(b,24); \ | |||||
c ^= b; c -= rot(b,14); \ | |||||
a ^= c; a -= rot(c,11); \ | |||||
b ^= a; b -= rot(a,25); \ | |||||
c ^= b; c -= rot(b,16); \ | |||||
a ^= c; a -= rot(c,4); \ | |||||
b ^= a; b -= rot(a,14); \ | |||||
c ^= b; c -= rot(b,24); \ | |||||
} | } | ||||
/* clang-format on */ | |||||
/* | /* | ||||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||||
@@ -252,197 +248,208 @@ acceptable. Do NOT use for cryptographic purposes. | |||||
------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | ||||
*/ | */ | ||||
static uint32_t hashlittle( const void *key, size_t length, uint32_t initval) | |||||
/* clang-format off */ | |||||
static uint32_t hashlittle(const void *key, size_t length, uint32_t initval) | |||||
{ | { | ||||
uint32_t a,b,c; /* internal state */ | |||||
union { const void *ptr; size_t i; } u; /* needed for Mac Powerbook G4 */ | |||||
/* Set up the internal state */ | |||||
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; | |||||
u.ptr = key; | |||||
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { | |||||
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ | |||||
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ | |||||
while (length > 12) | |||||
{ | |||||
a += k[0]; | |||||
b += k[1]; | |||||
c += k[2]; | |||||
mix(a,b,c); | |||||
length -= 12; | |||||
k += 3; | |||||
} | |||||
/*----------------------------- handle the last (probably partial) block */ | |||||
/* | |||||
* "k[2]&0xffffff" actually reads beyond the end of the string, but | |||||
* then masks off the part it's not allowed to read. Because the | |||||
* string is aligned, the masked-off tail is in the same word as the | |||||
* rest of the string. Every machine with memory protection I've seen | |||||
* does it on word boundaries, so is OK with this. But VALGRIND will | |||||
* still catch it and complain. The masking trick does make the hash | |||||
* noticably faster for short strings (like English words). | |||||
* AddressSanitizer is similarly picky about overrunning | |||||
* the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html | |||||
*/ | |||||
uint32_t a,b,c; /* internal state */ | |||||
union | |||||
{ | |||||
const void *ptr; | |||||
size_t i; | |||||
} u; /* needed for Mac Powerbook G4 */ | |||||
/* Set up the internal state */ | |||||
a = b = c = 0xdeadbeef + ((uint32_t)length) + initval; | |||||
u.ptr = key; | |||||
if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) { | |||||
const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */ | |||||
/*------ all but last block: aligned reads and affect 32 bits of (a,b,c) */ | |||||
while (length > 12) | |||||
{ | |||||
a += k[0]; | |||||
b += k[1]; | |||||
c += k[2]; | |||||
mix(a,b,c); | |||||
length -= 12; | |||||
k += 3; | |||||
} | |||||
/*----------------------------- handle the last (probably partial) block */ | |||||
/* | |||||
* "k[2]&0xffffff" actually reads beyond the end of the string, but | |||||
* then masks off the part it's not allowed to read. Because the | |||||
* string is aligned, the masked-off tail is in the same word as the | |||||
* rest of the string. Every machine with memory protection I've seen | |||||
* does it on word boundaries, so is OK with this. But VALGRIND will | |||||
* still catch it and complain. The masking trick does make the hash | |||||
* noticably faster for short strings (like English words). | |||||
* AddressSanitizer is similarly picky about overrunning | |||||
* the buffer. (http://clang.llvm.org/docs/AddressSanitizer.html | |||||
*/ | |||||
#ifdef VALGRIND | #ifdef VALGRIND | ||||
# define PRECISE_MEMORY_ACCESS 1 | |||||
#define PRECISE_MEMORY_ACCESS 1 | |||||
#elif defined(__SANITIZE_ADDRESS__) /* GCC's ASAN */ | #elif defined(__SANITIZE_ADDRESS__) /* GCC's ASAN */ | ||||
# define PRECISE_MEMORY_ACCESS 1 | |||||
#define PRECISE_MEMORY_ACCESS 1 | |||||
#elif defined(__has_feature) | #elif defined(__has_feature) | ||||
# if __has_feature(address_sanitizer) /* Clang's ASAN */ | |||||
# define PRECISE_MEMORY_ACCESS 1 | |||||
# endif | |||||
#if __has_feature(address_sanitizer) /* Clang's ASAN */ | |||||
#define PRECISE_MEMORY_ACCESS 1 | |||||
#endif | |||||
#endif | #endif | ||||
#ifndef PRECISE_MEMORY_ACCESS | #ifndef PRECISE_MEMORY_ACCESS | ||||
switch(length) | |||||
{ | |||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||||
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; | |||||
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; | |||||
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; | |||||
case 8 : b+=k[1]; a+=k[0]; break; | |||||
case 7 : b+=k[1]&0xffffff; a+=k[0]; break; | |||||
case 6 : b+=k[1]&0xffff; a+=k[0]; break; | |||||
case 5 : b+=k[1]&0xff; a+=k[0]; break; | |||||
case 4 : a+=k[0]; break; | |||||
case 3 : a+=k[0]&0xffffff; break; | |||||
case 2 : a+=k[0]&0xffff; break; | |||||
case 1 : a+=k[0]&0xff; break; | |||||
case 0 : return c; /* zero length strings require no mixing */ | |||||
} | |||||
switch(length) | |||||
{ | |||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||||
case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; | |||||
case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; | |||||
case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; | |||||
case 8 : b+=k[1]; a+=k[0]; break; | |||||
case 7 : b+=k[1]&0xffffff; a+=k[0]; break; | |||||
case 6 : b+=k[1]&0xffff; a+=k[0]; break; | |||||
case 5 : b+=k[1]&0xff; a+=k[0]; break; | |||||
case 4 : a+=k[0]; break; | |||||
case 3 : a+=k[0]&0xffffff; break; | |||||
case 2 : a+=k[0]&0xffff; break; | |||||
case 1 : a+=k[0]&0xff; break; | |||||
case 0 : return c; /* zero length strings require no mixing */ | |||||
} | |||||
#else /* make valgrind happy */ | #else /* make valgrind happy */ | ||||
const uint8_t *k8 = (const uint8_t *)k; | |||||
switch(length) | |||||
{ | |||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ | |||||
case 9 : c+=k8[8]; /* fall through */ | |||||
case 8 : b+=k[1]; a+=k[0]; break; | |||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ | |||||
case 5 : b+=k8[4]; /* fall through */ | |||||
case 4 : a+=k[0]; break; | |||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ | |||||
case 1 : a+=k8[0]; break; | |||||
case 0 : return c; | |||||
} | |||||
const uint8_t *k8 = (const uint8_t *)k; | |||||
switch(length) | |||||
{ | |||||
case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; | |||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||||
case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ | |||||
case 9 : c+=k8[8]; /* fall through */ | |||||
case 8 : b+=k[1]; a+=k[0]; break; | |||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||||
case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ | |||||
case 5 : b+=k8[4]; /* fall through */ | |||||
case 4 : a+=k[0]; break; | |||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||||
case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ | |||||
case 1 : a+=k8[0]; break; | |||||
case 0 : return c; | |||||
} | |||||
#endif /* !valgrind */ | #endif /* !valgrind */ | ||||
} else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { | |||||
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ | |||||
const uint8_t *k8; | |||||
/*--------------- all but last block: aligned reads and different mixing */ | |||||
while (length > 12) | |||||
{ | |||||
a += k[0] + (((uint32_t)k[1])<<16); | |||||
b += k[2] + (((uint32_t)k[3])<<16); | |||||
c += k[4] + (((uint32_t)k[5])<<16); | |||||
mix(a,b,c); | |||||
length -= 12; | |||||
k += 6; | |||||
} | |||||
/*----------------------------- handle the last (probably partial) block */ | |||||
k8 = (const uint8_t *)k; | |||||
switch(length) | |||||
{ | |||||
case 12: c+=k[4]+(((uint32_t)k[5])<<16); | |||||
b+=k[2]+(((uint32_t)k[3])<<16); | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||||
case 10: c+=k[4]; | |||||
b+=k[2]+(((uint32_t)k[3])<<16); | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 9 : c+=k8[8]; /* fall through */ | |||||
case 8 : b+=k[2]+(((uint32_t)k[3])<<16); | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||||
case 6 : b+=k[2]; | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 5 : b+=k8[4]; /* fall through */ | |||||
case 4 : a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||||
case 2 : a+=k[0]; | |||||
break; | |||||
case 1 : a+=k8[0]; | |||||
break; | |||||
case 0 : return c; /* zero length requires no mixing */ | |||||
} | |||||
} else { /* need to read the key one byte at a time */ | |||||
const uint8_t *k = (const uint8_t *)key; | |||||
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */ | |||||
while (length > 12) | |||||
{ | |||||
a += k[0]; | |||||
a += ((uint32_t)k[1])<<8; | |||||
a += ((uint32_t)k[2])<<16; | |||||
a += ((uint32_t)k[3])<<24; | |||||
b += k[4]; | |||||
b += ((uint32_t)k[5])<<8; | |||||
b += ((uint32_t)k[6])<<16; | |||||
b += ((uint32_t)k[7])<<24; | |||||
c += k[8]; | |||||
c += ((uint32_t)k[9])<<8; | |||||
c += ((uint32_t)k[10])<<16; | |||||
c += ((uint32_t)k[11])<<24; | |||||
mix(a,b,c); | |||||
length -= 12; | |||||
k += 12; | |||||
} | |||||
/*-------------------------------- last block: affect all 32 bits of (c) */ | |||||
switch(length) /* all the case statements fall through */ | |||||
{ | |||||
case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */ | |||||
case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */ | |||||
case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */ | |||||
case 9 : c+=k[8]; /* FALLTHRU */ | |||||
case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */ | |||||
case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */ | |||||
case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */ | |||||
case 5 : b+=k[4]; /* FALLTHRU */ | |||||
case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */ | |||||
case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */ | |||||
case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */ | |||||
case 1 : a+=k[0]; | |||||
break; | |||||
case 0 : return c; | |||||
} | |||||
} | |||||
} | |||||
else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) | |||||
{ | |||||
const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ | |||||
const uint8_t *k8; | |||||
final(a,b,c); | |||||
return c; | |||||
/*--------------- all but last block: aligned reads and different mixing */ | |||||
while (length > 12) | |||||
{ | |||||
a += k[0] + (((uint32_t)k[1])<<16); | |||||
b += k[2] + (((uint32_t)k[3])<<16); | |||||
c += k[4] + (((uint32_t)k[5])<<16); | |||||
mix(a,b,c); | |||||
length -= 12; | |||||
k += 6; | |||||
} | |||||
/*----------------------------- handle the last (probably partial) block */ | |||||
k8 = (const uint8_t *)k; | |||||
switch(length) | |||||
{ | |||||
case 12: c+=k[4]+(((uint32_t)k[5])<<16); | |||||
b+=k[2]+(((uint32_t)k[3])<<16); | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ | |||||
case 10: c+=k[4]; | |||||
b+=k[2]+(((uint32_t)k[3])<<16); | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 9 : c+=k8[8]; /* fall through */ | |||||
case 8 : b+=k[2]+(((uint32_t)k[3])<<16); | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ | |||||
case 6 : b+=k[2]; | |||||
a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 5 : b+=k8[4]; /* fall through */ | |||||
case 4 : a+=k[0]+(((uint32_t)k[1])<<16); | |||||
break; | |||||
case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ | |||||
case 2 : a+=k[0]; | |||||
break; | |||||
case 1 : a+=k8[0]; | |||||
break; | |||||
case 0 : return c; /* zero length requires no mixing */ | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
/* need to read the key one byte at a time */ | |||||
const uint8_t *k = (const uint8_t *)key; | |||||
/*--------------- all but the last block: affect some 32 bits of (a,b,c) */ | |||||
while (length > 12) | |||||
{ | |||||
a += k[0]; | |||||
a += ((uint32_t)k[1])<<8; | |||||
a += ((uint32_t)k[2])<<16; | |||||
a += ((uint32_t)k[3])<<24; | |||||
b += k[4]; | |||||
b += ((uint32_t)k[5])<<8; | |||||
b += ((uint32_t)k[6])<<16; | |||||
b += ((uint32_t)k[7])<<24; | |||||
c += k[8]; | |||||
c += ((uint32_t)k[9])<<8; | |||||
c += ((uint32_t)k[10])<<16; | |||||
c += ((uint32_t)k[11])<<24; | |||||
mix(a,b,c); | |||||
length -= 12; | |||||
k += 12; | |||||
} | |||||
/*-------------------------------- last block: affect all 32 bits of (c) */ | |||||
switch(length) /* all the case statements fall through */ | |||||
{ | |||||
case 12: c+=((uint32_t)k[11])<<24; /* FALLTHRU */ | |||||
case 11: c+=((uint32_t)k[10])<<16; /* FALLTHRU */ | |||||
case 10: c+=((uint32_t)k[9])<<8; /* FALLTHRU */ | |||||
case 9 : c+=k[8]; /* FALLTHRU */ | |||||
case 8 : b+=((uint32_t)k[7])<<24; /* FALLTHRU */ | |||||
case 7 : b+=((uint32_t)k[6])<<16; /* FALLTHRU */ | |||||
case 6 : b+=((uint32_t)k[5])<<8; /* FALLTHRU */ | |||||
case 5 : b+=k[4]; /* FALLTHRU */ | |||||
case 4 : a+=((uint32_t)k[3])<<24; /* FALLTHRU */ | |||||
case 3 : a+=((uint32_t)k[2])<<16; /* FALLTHRU */ | |||||
case 2 : a+=((uint32_t)k[1])<<8; /* FALLTHRU */ | |||||
case 1 : a+=k[0]; | |||||
break; | |||||
case 0 : return c; | |||||
} | |||||
} | |||||
final(a,b,c); | |||||
return c; | |||||
} | } | ||||
/* clang-format on */ | |||||
/* a simple hash function similiar to what perl does for strings. | /* a simple hash function similiar to what perl does for strings. | ||||
* for good results, the string should not be excessivly large. | * for good results, the string should not be excessivly large. | ||||
*/ | */ | ||||
static unsigned long lh_perllike_str_hash(const void *k) | |||||
static unsigned long lh_perllike_str_hash(const void *k) | |||||
{ | { | ||||
const char *rkey = (const char *)k; | |||||
unsigned hashval = 1; | |||||
const char *rkey = (const char *)k; | |||||
unsigned hashval = 1; | |||||
while (*rkey) | |||||
hashval = hashval * 33 + *rkey++; | |||||
while (*rkey) | |||||
hashval = hashval * 33 + *rkey++; | |||||
return hashval; | |||||
return hashval; | |||||
} | } | ||||
static unsigned long lh_char_hash(const void *k) | static unsigned long lh_char_hash(const void *k) | ||||
@@ -454,10 +461,11 @@ 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) {} | |||||
#if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 | #if SIZEOF_INT == 8 && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 | ||||
#define USE_SYNC_COMPARE_AND_SWAP 1 | #define USE_SYNC_COMPARE_AND_SWAP 1 | ||||
#endif | #endif | ||||
@@ -472,34 +480,32 @@ static unsigned long lh_char_hash(const void *k) | |||||
#elif defined _MSC_VER || defined __MINGW32__ | #elif defined _MSC_VER || defined __MINGW32__ | ||||
InterlockedCompareExchange(&random_seed, seed, -1); | InterlockedCompareExchange(&random_seed, seed, -1); | ||||
#else | #else | ||||
//#warning "racy random seed initializtion if used by multiple threads" | |||||
//#warning "racy random seed initializtion if used by multiple threads" | |||||
random_seed = seed; /* potentially racy */ | random_seed = seed; /* potentially racy */ | ||||
#endif | #endif | ||||
} | } | ||||
return hashlittle((const char*)k, strlen((const char*)k), random_seed); | |||||
return hashlittle((const char *)k, strlen((const char *)k), random_seed); | |||||
} | } | ||||
int lh_char_equal(const void *k1, const void *k2) | 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, | |||||
lh_entry_free_fn *free_fn, | |||||
lh_hash_fn *hash_fn, | |||||
lh_equal_fn *equal_fn) | |||||
struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn, | |||||
lh_equal_fn *equal_fn) | |||||
{ | { | ||||
int i; | int i; | ||||
struct lh_table *t; | struct lh_table *t; | ||||
t = (struct lh_table*)calloc(1, sizeof(struct lh_table)); | |||||
t = (struct lh_table *)calloc(1, sizeof(struct lh_table)); | |||||
if (!t) | if (!t) | ||||
return NULL; | return NULL; | ||||
t->count = 0; | t->count = 0; | ||||
t->size = size; | t->size = size; | ||||
t->table = (struct lh_entry*)calloc(size, sizeof(struct lh_entry)); | |||||
t->table = (struct lh_entry *)calloc(size, sizeof(struct lh_entry)); | |||||
if (!t->table) | if (!t->table) | ||||
{ | { | ||||
free(t); | free(t); | ||||
@@ -508,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, | |||||
lh_entry_free_fn *free_fn) | |||||
struct lh_table *lh_kchar_table_new(int size, 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, | |||||
lh_entry_free_fn *free_fn) | |||||
struct lh_table *lh_kptr_table_new(int size, 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); | ||||
} | } | ||||
@@ -558,16 +563,17 @@ 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) { | |||||
for(c = t->head; c != NULL; c = c->next) | |||||
if (t->free_fn) | |||||
{ | |||||
for (c = t->head; c != NULL; c = c->next) | |||||
t->free_fn(c); | t->free_fn(c); | ||||
} | } | ||||
free(t->table); | free(t->table); | ||||
free(t); | free(t); | ||||
} | } | ||||
int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts) | |||||
int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, | |||||
const unsigned opts) | |||||
{ | { | ||||
unsigned long n; | unsigned long n; | ||||
@@ -577,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 ) { | |||||
if(t->table[n].k == LH_EMPTY || t->table[n].k == LH_FREED) break; | |||||
if ((int)++n == t->size) n = 0; | |||||
while (1) | |||||
{ | |||||
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; | ||||
@@ -587,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; | ||||
@@ -604,59 +616,78 @@ 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, const unsigned long h) | |||||
struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, | |||||
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 ) { | |||||
if(t->table[n].k == LH_EMPTY) return NULL; | |||||
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; | |||||
while (count < t->size) | |||||
{ | |||||
if (t->table[n].k == LH_EMPTY) | |||||
return NULL; | |||||
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; | ||||
} | } | ||||
struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k) | |||||
struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k) | |||||
{ | { | ||||
return lh_table_lookup_entry_w_hash(t, k, lh_get_hash(t, k)); | return lh_table_lookup_entry_w_hash(t, k, lh_get_hash(t, 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 (v != NULL) *v = lh_entry_v(e); | |||||
if (e != NULL) | |||||
{ | |||||
if (v != NULL) | |||||
*v = lh_entry_v(e); | |||||
return 1; /* key found */ | return 1; /* key found */ | ||||
} | } | ||||
if (v != NULL) *v = NULL; | |||||
return 0; /* key not found */ | |||||
if (v != NULL) | |||||
*v = NULL; | |||||
return 0; /* key not found */ | |||||
} | } | ||||
int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) | int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e) | ||||
{ | { | ||||
ptrdiff_t n = (ptrdiff_t)(e - t->table); /* CAW: fixed to be 64bit nice, still need the crazy negative case... */ | |||||
/* CAW: fixed to be 64bit nice, still need the crazy negative case... */ | |||||
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; | ||||
} | } | ||||
@@ -664,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); | ||||
} | } | ||||
@@ -40,12 +40,12 @@ extern "C" { | |||||
/** | /** | ||||
* sentinel pointer value for empty slots | * sentinel pointer value for empty slots | ||||
*/ | */ | ||||
#define LH_EMPTY (void*)-1 | |||||
#define LH_EMPTY (void *)-1 | |||||
/** | /** | ||||
* sentinel pointer value for freed slots | * sentinel pointer value for freed slots | ||||
*/ | */ | ||||
#define LH_FREED (void*)-2 | |||||
#define LH_FREED (void *)-2 | |||||
/** | /** | ||||
* default string hash function | * default string hash function | ||||
@@ -69,20 +69,21 @@ struct lh_entry; | |||||
/** | /** | ||||
* callback function prototypes | * callback function prototypes | ||||
*/ | */ | ||||
typedef void (lh_entry_free_fn) (struct lh_entry *e); | |||||
typedef void(lh_entry_free_fn)(struct lh_entry *e); | |||||
/** | /** | ||||
* callback function prototypes | * callback function prototypes | ||||
*/ | */ | ||||
typedef unsigned long (lh_hash_fn) (const void *k); | |||||
typedef unsigned long(lh_hash_fn)(const void *k); | |||||
/** | /** | ||||
* callback function prototypes | * callback function prototypes | ||||
*/ | */ | ||||
typedef int (lh_equal_fn) (const void *k1, const void *k2); | |||||
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) \ | |||||
for(entry = table->head; entry; entry = entry->next) | |||||
#define lh_foreach(table, entry) 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. | ||||
@@ -156,9 +155,7 @@ for(entry = table->head; entry; entry = entry->next) | |||||
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element | * @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element | ||||
*/ | */ | ||||
#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,10 +175,8 @@ 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, | |||||
lh_entry_free_fn *free_fn, | |||||
lh_hash_fn *hash_fn, | |||||
lh_equal_fn *equal_fn); | |||||
extern struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn, | |||||
lh_equal_fn *equal_fn); | |||||
/** | /** | ||||
* Convenience function to create a new linkhash table with char keys. | * Convenience function to create a new linkhash table with char keys. | ||||
@@ -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, | |||||
lh_entry_free_fn *free_fn); | |||||
extern struct lh_table *lh_kchar_table_new(int size, 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, | |||||
lh_entry_free_fn *free_fn); | |||||
extern struct lh_table *lh_kptr_table_new(int size, 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. | ||||
@@ -255,7 +244,7 @@ extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void | |||||
* @param k a pointer to the key to lookup | * @param k a pointer to 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(struct lh_table *t, const void *k); | |||||
extern struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k); | |||||
/** | /** | ||||
* Lookup a record in the table using a precalculated key hash. | * Lookup a record in the table using a precalculated key hash. | ||||
@@ -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: | ||||
*/ | */ | ||||
@@ -9,17 +9,17 @@ | |||||
/* Define isnan, isinf, infinity and nan on Windows/MSVC */ | /* Define isnan, isinf, infinity and nan on Windows/MSVC */ | ||||
#ifndef HAVE_DECL_ISNAN | #ifndef HAVE_DECL_ISNAN | ||||
# ifdef HAVE_DECL__ISNAN | |||||
#ifdef HAVE_DECL__ISNAN | |||||
#include <float.h> | #include <float.h> | ||||
#define isnan(x) _isnan(x) | #define isnan(x) _isnan(x) | ||||
# endif | |||||
#endif | |||||
#endif | #endif | ||||
#ifndef HAVE_DECL_ISINF | #ifndef HAVE_DECL_ISINF | ||||
# ifdef HAVE_DECL__FINITE | |||||
#ifdef HAVE_DECL__FINITE | |||||
#include <float.h> | #include <float.h> | ||||
#define isinf(x) (!_finite(x)) | #define isinf(x) (!_finite(x)) | ||||
# endif | |||||
#endif | |||||
#endif | #endif | ||||
#ifndef HAVE_DECL_INFINITY | #ifndef HAVE_DECL_INFINITY | ||||
@@ -20,9 +20,9 @@ | |||||
#include <string.h> | #include <string.h> | ||||
#ifdef HAVE_STDARG_H | #ifdef HAVE_STDARG_H | ||||
# include <stdarg.h> | |||||
#include <stdarg.h> | |||||
#else /* !HAVE_STDARG_H */ | #else /* !HAVE_STDARG_H */ | ||||
# error Not enough var arg support! | |||||
#error Not enough var arg support! | |||||
#endif /* HAVE_STDARG_H */ | #endif /* HAVE_STDARG_H */ | ||||
#include "debug.h" | #include "debug.h" | ||||
@@ -32,23 +32,24 @@ | |||||
static int printbuf_extend(struct printbuf *p, int min_size); | static int printbuf_extend(struct printbuf *p, int min_size); | ||||
struct printbuf* printbuf_new(void) | |||||
struct printbuf *printbuf_new(void) | |||||
{ | { | ||||
struct printbuf *p; | |||||
p = (struct printbuf*)calloc(1, sizeof(struct printbuf)); | |||||
if(!p) return NULL; | |||||
p->size = 32; | |||||
p->bpos = 0; | |||||
if(!(p->buf = (char*)malloc(p->size))) { | |||||
free(p); | |||||
return NULL; | |||||
} | |||||
p->buf[0]= '\0'; | |||||
return p; | |||||
struct printbuf *p; | |||||
p = (struct printbuf *)calloc(1, sizeof(struct printbuf)); | |||||
if (!p) | |||||
return NULL; | |||||
p->size = 32; | |||||
p->bpos = 0; | |||||
if (!(p->buf = (char *)malloc(p->size))) | |||||
{ | |||||
free(p); | |||||
return NULL; | |||||
} | |||||
p->buf[0] = '\0'; | |||||
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. | ||||
* | * | ||||
@@ -67,13 +68,13 @@ static int printbuf_extend(struct printbuf *p, int min_size) | |||||
new_size = p->size * 2; | new_size = p->size * 2; | ||||
if (new_size < min_size + 8) | if (new_size < min_size + 8) | ||||
new_size = min_size + 8; | |||||
new_size = min_size + 8; | |||||
#ifdef PRINTBUF_DEBUG | #ifdef PRINTBUF_DEBUG | ||||
MC_DEBUG("printbuf_memappend: realloc " | MC_DEBUG("printbuf_memappend: realloc " | ||||
"bpos=%d min_size=%d old_size=%d new_size=%d\n", | |||||
p->bpos, min_size, p->size, new_size); | |||||
"bpos=%d min_size=%d old_size=%d new_size=%d\n", | |||||
p->bpos, min_size, p->size, new_size); | |||||
#endif /* PRINTBUF_DEBUG */ | #endif /* PRINTBUF_DEBUG */ | ||||
if(!(t = (char*)realloc(p->buf, new_size))) | |||||
if (!(t = (char *)realloc(p->buf, new_size))) | |||||
return -1; | return -1; | ||||
p->size = new_size; | p->size = new_size; | ||||
p->buf = t; | p->buf = t; | ||||
@@ -82,14 +83,15 @@ 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 (printbuf_extend(p, p->bpos + size + 1) < 0) | |||||
return -1; | |||||
} | |||||
memcpy(p->buf + p->bpos, buf, size); | |||||
p->bpos += size; | |||||
p->buf[p->bpos]= '\0'; | |||||
return size; | |||||
if (p->size <= p->bpos + size + 1) | |||||
{ | |||||
if (printbuf_extend(p, p->bpos + size + 1) < 0) | |||||
return -1; | |||||
} | |||||
memcpy(p->buf + p->bpos, buf, size); | |||||
p->bpos += size; | |||||
p->buf[p->bpos] = '\0'; | |||||
return size; | |||||
} | } | ||||
int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | ||||
@@ -114,42 +116,51 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len) | |||||
int sprintbuf(struct printbuf *p, const char *msg, ...) | int sprintbuf(struct printbuf *p, const char *msg, ...) | ||||
{ | { | ||||
va_list ap; | |||||
char *t; | |||||
int size; | |||||
char buf[128]; | |||||
/* user stack buffer first */ | |||||
va_start(ap, msg); | |||||
size = vsnprintf(buf, 128, msg, ap); | |||||
va_end(ap); | |||||
/* if string is greater than stack buffer, then use dynamic string | |||||
with vasprintf. Note: some implementation of vsnprintf return -1 | |||||
if output is truncated whereas some return the number of bytes that | |||||
would have been written - this code handles both cases. */ | |||||
if(size == -1 || size > 127) { | |||||
va_start(ap, msg); | |||||
if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; } | |||||
va_end(ap); | |||||
printbuf_memappend(p, t, size); | |||||
free(t); | |||||
return size; | |||||
} else { | |||||
printbuf_memappend(p, buf, size); | |||||
return size; | |||||
} | |||||
va_list ap; | |||||
char *t; | |||||
int size; | |||||
char buf[128]; | |||||
/* user stack buffer first */ | |||||
va_start(ap, msg); | |||||
size = vsnprintf(buf, 128, msg, ap); | |||||
va_end(ap); | |||||
/* if string is greater than stack buffer, then use dynamic string | |||||
* with vasprintf. Note: some implementation of vsnprintf return -1 | |||||
* if output is truncated whereas some return the number of bytes that | |||||
* would have been written - this code handles both cases. | |||||
*/ | |||||
if (size == -1 || size > 127) | |||||
{ | |||||
va_start(ap, msg); | |||||
if ((size = vasprintf(&t, msg, ap)) < 0) | |||||
{ | |||||
va_end(ap); | |||||
return -1; | |||||
} | |||||
va_end(ap); | |||||
printbuf_memappend(p, t, size); | |||||
free(t); | |||||
return size; | |||||
} | |||||
else | |||||
{ | |||||
printbuf_memappend(p, buf, size); | |||||
return size; | |||||
} | |||||
} | } | ||||
void printbuf_reset(struct printbuf *p) | void printbuf_reset(struct printbuf *p) | ||||
{ | { | ||||
p->buf[0] = '\0'; | |||||
p->bpos = 0; | |||||
p->buf[0] = '\0'; | |||||
p->bpos = 0; | |||||
} | } | ||||
void printbuf_free(struct printbuf *p) | void printbuf_free(struct printbuf *p) | ||||
{ | { | ||||
if(p) { | |||||
free(p->buf); | |||||
free(p); | |||||
} | |||||
if (p) | |||||
{ | |||||
free(p->buf); | |||||
free(p); | |||||
} | |||||
} | } |
@@ -24,7 +24,7 @@ | |||||
#define _printbuf_h_ | #define _printbuf_h_ | ||||
#ifndef JSON_EXPORT | #ifndef JSON_EXPORT | ||||
#if defined(_MSC_VER) | |||||
#if defined(_MSC_VER) | |||||
#define JSON_EXPORT __declspec(dllexport) | #define JSON_EXPORT __declspec(dllexport) | ||||
#else | #else | ||||
#define JSON_EXPORT extern | #define JSON_EXPORT extern | ||||
@@ -35,15 +35,15 @@ | |||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
struct printbuf { | |||||
char *buf; | |||||
int bpos; | |||||
int size; | |||||
struct printbuf | |||||
{ | |||||
char *buf; | |||||
int bpos; | |||||
int size; | |||||
}; | }; | ||||
typedef struct printbuf printbuf; | typedef struct printbuf printbuf; | ||||
JSON_EXPORT struct printbuf* | |||||
printbuf_new(void); | |||||
JSON_EXPORT struct printbuf *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,17 +53,22 @@ 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 | |||||
printbuf_memappend(struct printbuf *p, const char *buf, int size); | |||||
#define printbuf_memappend_fast(p, bufptr, bufsize) \ | |||||
do { \ | |||||
if ((p->size - p->bpos) > bufsize) { \ | |||||
memcpy(p->buf + p->bpos, (bufptr), bufsize); \ | |||||
p->bpos += bufsize; \ | |||||
p->buf[p->bpos]= '\0'; \ | |||||
} else { printbuf_memappend(p, (bufptr), bufsize); } \ | |||||
} while (0) | |||||
JSON_EXPORT int printbuf_memappend(struct printbuf *p, const char *buf, int size); | |||||
#define printbuf_memappend_fast(p, bufptr, bufsize) \ | |||||
do \ | |||||
{ \ | |||||
if ((p->size - p->bpos) > bufsize) \ | |||||
{ \ | |||||
memcpy(p->buf + p->bpos, (bufptr), bufsize); \ | |||||
p->bpos += bufsize; \ | |||||
p->buf[p->bpos] = '\0'; \ | |||||
} \ | |||||
else \ | |||||
{ \ | |||||
printbuf_memappend(p, (bufptr), bufsize); \ | |||||
} \ | |||||
} while (0) | |||||
#define printbuf_length(p) ((p)->bpos) | #define printbuf_length(p) ((p)->bpos) | ||||
@@ -87,7 +92,7 @@ do { \ | |||||
* sprintbuf() | * sprintbuf() | ||||
*/ | */ | ||||
#define printbuf_strappend(pb, str) \ | #define printbuf_strappend(pb, str) \ | ||||
printbuf_memappend ((pb), _printbuf_check_literal(str), sizeof(str) - 1) | |||||
printbuf_memappend((pb), _printbuf_check_literal(str), sizeof(str) - 1) | |||||
/** | /** | ||||
* Set len bytes of the buffer to charvalue, starting at offset offset. | * Set len bytes of the buffer to charvalue, starting at offset offset. | ||||
@@ -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 | |||||
printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len); | |||||
JSON_EXPORT int 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 | |||||
sprintbuf(struct printbuf *p, const char *msg, ...); | |||||
JSON_EXPORT int sprintbuf(struct printbuf *p, const char *msg, ...); | |||||
JSON_EXPORT void | |||||
printbuf_reset(struct printbuf *p); | |||||
JSON_EXPORT void printbuf_reset(struct printbuf *p); | |||||
JSON_EXPORT void | |||||
printbuf_free(struct printbuf *p); | |||||
JSON_EXPORT void printbuf_free(struct printbuf *p); | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
@@ -35,7 +35,7 @@ static int json_c_snprintf(char *str, size_t size, const char *format, ...) | |||||
#define snprintf json_c_snprintf | #define snprintf json_c_snprintf | ||||
#elif !defined(HAVE_SNPRINTF) /* !HAVE_SNPRINTF */ | #elif !defined(HAVE_SNPRINTF) /* !HAVE_SNPRINTF */ | ||||
# error Need vsnprintf! | |||||
#error Need vsnprintf! | |||||
#endif /* !HAVE_SNPRINTF && defined(WIN32) */ | #endif /* !HAVE_SNPRINTF && defined(WIN32) */ | ||||
#endif /* __snprintf_compat_h */ | #endif /* __snprintf_compat_h */ |
@@ -7,10 +7,10 @@ | |||||
*/ | */ | ||||
#if !defined(HAVE_STRDUP) && defined(_MSC_VER) | #if !defined(HAVE_STRDUP) && defined(_MSC_VER) | ||||
/* MSC has the version as _strdup */ | |||||
# define strdup _strdup | |||||
/* MSC has the version as _strdup */ | |||||
#define strdup _strdup | |||||
#elif !defined(HAVE_STRDUP) | #elif !defined(HAVE_STRDUP) | ||||
# error You do not have strdup on your system. | |||||
#error You do not have strdup on your system. | |||||
#endif /* HAVE_STRDUP */ | #endif /* HAVE_STRDUP */ | ||||
#endif | #endif |
@@ -5,10 +5,12 @@ | |||||
* 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[] = { | ||||
/* clang-format off */ | |||||
#define STRINGIFY(x) #x | #define STRINGIFY(x) #x | ||||
#define ENTRY(x) {x, &STRINGIFY(undef_ ## x)[6]} | #define ENTRY(x) {x, &STRINGIFY(undef_ ## x)[6]} | ||||
ENTRY(EPERM), | ENTRY(EPERM), | ||||
@@ -52,6 +54,7 @@ static struct { | |||||
ENTRY(EAGAIN), | ENTRY(EAGAIN), | ||||
{ 0, (char *)0 } | { 0, (char *)0 } | ||||
}; | }; | ||||
/* clang-format on */ | |||||
// Enabled during tests | // Enabled during tests | ||||
int _json_c_strerror_enable = 0; | int _json_c_strerror_enable = 0; | ||||
@@ -76,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]; | ||||
} | } | ||||
@@ -92,10 +96,9 @@ char *_json_c_strerror(int errno_in) | |||||
digbuf[ii] = "0123456789"[(errno_in % 10)]; | digbuf[ii] = "0123456789"[(errno_in % 10)]; | ||||
// Reverse the digits | // Reverse the digits | ||||
for (start_idx = sizeof(PREFIX) - 1 ; ii >= 0; ii--, start_idx++) | |||||
for (start_idx = sizeof(PREFIX) - 1; ii >= 0; ii--, start_idx++) | |||||
{ | { | ||||
errno_buf[start_idx] = digbuf[ii]; | errno_buf[start_idx] = digbuf[ii]; | ||||
} | } | ||||
return errno_buf; | return errno_buf; | ||||
} | } | ||||
@@ -20,11 +20,11 @@ extern "C" { | |||||
JSON_EXPORT char *_json_c_strerror(int errno_in); | JSON_EXPORT char *_json_c_strerror(int errno_in); | ||||
#ifndef STRERROR_OVERRIDE_IMPL | #ifndef STRERROR_OVERRIDE_IMPL | ||||
#define strerror _json_c_strerror | |||||
#define strerror _json_c_strerror | |||||
#endif | #endif | ||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
#endif /* _json_strerror_override_h_ */ | |||||
#endif /* _json_strerror_override_h_ */ |
@@ -7,19 +7,20 @@ | |||||
#include "parse_flags.h" | #include "parse_flags.h" | ||||
#if !defined(HAVE_STRCASECMP) && defined(_MSC_VER) | #if !defined(HAVE_STRCASECMP) && defined(_MSC_VER) | ||||
# define strcasecmp _stricmp | |||||
#define strcasecmp _stricmp | |||||
#elif !defined(HAVE_STRCASECMP) | #elif !defined(HAVE_STRCASECMP) | ||||
# 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[] = { | ||||
{ "plain", JSON_C_TO_STRING_PLAIN }, | |||||
{ "spaced", JSON_C_TO_STRING_SPACED }, | |||||
{ "pretty", JSON_C_TO_STRING_PRETTY }, | |||||
{ "pretty_tab", JSON_C_TO_STRING_PRETTY_TAB }, | |||||
{"plain", JSON_C_TO_STRING_PLAIN}, | |||||
{"spaced", JSON_C_TO_STRING_SPACED}, | |||||
{"pretty", JSON_C_TO_STRING_PRETTY}, | |||||
{"pretty_tab", JSON_C_TO_STRING_PRETTY_TAB}, | |||||
}; | }; | ||||
#ifndef NELEM | #ifndef NELEM | ||||
@@ -30,7 +31,7 @@ int parse_flags(int argc, char **argv) | |||||
{ | { | ||||
int arg_idx; | int arg_idx; | ||||
int sflags = 0; | int sflags = 0; | ||||
for (arg_idx = 1; arg_idx < argc ; arg_idx++) | |||||
for (arg_idx = 1; arg_idx < argc; arg_idx++) | |||||
{ | { | ||||
int jj; | int jj; | ||||
for (jj = 0; jj < (int)NELEM(format_args); jj++) | for (jj = 0; jj < (int)NELEM(format_args); jj++) | ||||
@@ -1,19 +1,19 @@ | |||||
#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" | ||||
static int sort_fn (const void *j1, const void *j2) | |||||
static int sort_fn(const void *j1, const void *j2) | |||||
{ | { | ||||
json_object * const *jso1, * const *jso2; | |||||
json_object *const *jso1, *const *jso2; | |||||
int i1, i2; | int i1, i2; | ||||
jso1 = (json_object* const*)j1; | |||||
jso2 = (json_object* const*)j2; | |||||
jso1 = (json_object *const *)j1; | |||||
jso2 = (json_object *const *)j2; | |||||
if (!*jso1 && !*jso2) | if (!*jso1 && !*jso2) | ||||
return 0; | return 0; | ||||
if (!*jso1) | if (!*jso1) | ||||
@@ -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"); | ||||
@@ -48,7 +49,7 @@ static const char *to_json_string(json_object *obj, int flags) | |||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
#define json_object_to_json_string(obj) to_json_string(obj,sflags) | |||||
#define json_object_to_json_string(obj) to_json_string(obj, sflags) | |||||
#else | #else | ||||
/* no special define */ | /* no special define */ | ||||
#endif | #endif | ||||
@@ -84,7 +85,7 @@ void test_array_del_idx() | |||||
orig_array_len = json_object_array_length(my_array); | orig_array_len = json_object_array_length(my_array); | ||||
printf("my_array=\n"); | printf("my_array=\n"); | ||||
for(ii = 0; ii < json_object_array_length(my_array); ii++) | |||||
for (ii = 0; ii < json_object_array_length(my_array); ii++) | |||||
{ | { | ||||
json_object *obj = json_object_array_get_idx(my_array, ii); | json_object *obj = json_object_array_get_idx(my_array, ii); | ||||
printf("\t[%d]=%s\n", (int)ii, json_object_to_json_string(obj)); | printf("\t[%d]=%s\n", (int)ii, json_object_to_json_string(obj)); | ||||
@@ -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", | |||||
rc, json_object_to_json_string(my_array)); | |||||
printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", rc, | |||||
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", | |||||
rc, json_object_to_json_string(my_array)); | |||||
printf("after del_idx(0,1)=%d, my_array.to_string()=%s\n", rc, | |||||
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", | |||||
(int)orig_array_len, rc, json_object_to_json_string(my_array)); | |||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)orig_array_len, rc, | |||||
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", | |||||
(int)(orig_array_len + 1), rc, json_object_to_json_string(my_array)); | |||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)(orig_array_len + 1), rc, | |||||
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", | |||||
(int)(orig_array_len - 1), rc, json_object_to_json_string(my_array)); | |||||
printf("after del_idx(0,%d)=%d, my_array.to_string()=%s\n", (int)(orig_array_len - 1), rc, | |||||
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"); | ||||
@@ -188,7 +191,7 @@ int main(int argc, char **argv) | |||||
json_object_array_add(my_array, json_object_new_int(3)); | json_object_array_add(my_array, json_object_new_int(3)); | ||||
json_object_array_put_idx(my_array, 4, json_object_new_int(5)); | json_object_array_put_idx(my_array, 4, json_object_new_int(5)); | ||||
printf("my_array=\n"); | printf("my_array=\n"); | ||||
for(i=0; i < json_object_array_length(my_array); i++) | |||||
for (i = 0; i < json_object_array_length(my_array); i++) | |||||
{ | { | ||||
json_object *obj = json_object_array_get_idx(my_array, i); | json_object *obj = json_object_array_get_idx(my_array, i); | ||||
printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | ||||
@@ -205,7 +208,7 @@ int main(int argc, char **argv) | |||||
json_object_array_add(my_array, json_object_new_int(2)); | json_object_array_add(my_array, json_object_new_int(2)); | ||||
json_object_array_put_idx(my_array, 4, json_object_new_int(0)); | json_object_array_put_idx(my_array, 4, json_object_new_int(0)); | ||||
printf("my_array=\n"); | printf("my_array=\n"); | ||||
for(i=0; i < json_object_array_length(my_array); i++) | |||||
for (i = 0; i < json_object_array_length(my_array); i++) | |||||
{ | { | ||||
json_object *obj = json_object_array_get_idx(my_array, i); | json_object *obj = json_object_array_get_idx(my_array, i); | ||||
printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | ||||
@@ -213,7 +216,7 @@ int main(int argc, char **argv) | |||||
printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array)); | printf("my_array.to_string()=%s\n", json_object_to_json_string(my_array)); | ||||
json_object_array_sort(my_array, sort_fn); | json_object_array_sort(my_array, sort_fn); | ||||
printf("my_array=\n"); | printf("my_array=\n"); | ||||
for(i=0; i < json_object_array_length(my_array); i++) | |||||
for (i = 0; i < json_object_array_length(my_array); i++) | |||||
{ | { | ||||
json_object *obj = json_object_array_get_idx(my_array, i); | json_object *obj = json_object_array_get_idx(my_array, i); | ||||
printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | printf("\t[%d]=%s\n", (int)i, json_object_to_json_string(obj)); | ||||
@@ -1,18 +1,17 @@ | |||||
#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" | ||||
#include "parse_flags.h" | #include "parse_flags.h" | ||||
#ifdef TEST_FORMATTED | #ifdef TEST_FORMATTED | ||||
#define json_object_to_json_string(obj) json_object_to_json_string_ext(obj,sflags) | |||||
#define json_object_to_json_string(obj) json_object_to_json_string_ext(obj, sflags) | |||||
#else | #else | ||||
/* 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 */" | |||||
"{ \"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\"] } ] } } }"); | |||||
new_obj = json_tokener_parse( | |||||
"/* more difficult test case */" | |||||
"{ \"glossary\": { \"title\": \"example glossary\", \"GlossDiv\": { \"title\": \"S\", " | |||||
"\"GlossList\": [ { \"ID\": \"SGML\", \"SortAs\": \"SGML\", \"GlossTerm\": \"Standard " | |||||
"Generalized Markup Language\", \"Acronym\": \"SGML\", \"Abbrev\": \"ISO 8879:1986\", " | |||||
"\"GlossDef\": \"A meta-markup language, used to create markup languages such as " | |||||
"DocBook.\", \"GlossSeeAlso\": [\"GML\", \"XML\", \"markup\"] } ] } } }"); | |||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); | printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj)); | ||||
json_object_put(new_obj); | json_object_put(new_obj); | ||||
@@ -2,24 +2,24 @@ | |||||
* 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" | ||||
#include "json_tokener.h" | #include "json_tokener.h" | ||||
void print_hex(const char* s) | |||||
void print_hex(const char *s) | |||||
{ | { | ||||
const char *iter = s; | const char *iter = s; | ||||
unsigned char ch; | unsigned char ch; | ||||
while ((ch = *iter++) != 0) | while ((ch = *iter++) != 0) | ||||
{ | { | ||||
if( ',' != ch) | |||||
if (',' != ch) | |||||
printf("%x ", ch); | printf("%x ", ch); | ||||
else | else | ||||
printf( ","); | |||||
printf(","); | |||||
} | } | ||||
putchar('\n'); | putchar('\n'); | ||||
} | } | ||||
@@ -27,19 +27,22 @@ 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); | ||||
printf("input: %s\n", input); | printf("input: %s\n", input); | ||||
int strings_match = !strcmp( expected, unjson); | |||||
int strings_match = !strcmp(expected, unjson); | |||||
int retval = 0; | int retval = 0; | ||||
if (strings_match) | if (strings_match) | ||||
{ | { | ||||
printf("JSON parse result is correct: %s\n", unjson); | printf("JSON parse result is correct: %s\n", unjson); | ||||
puts("PASS"); | puts("PASS"); | ||||
} else { | |||||
} | |||||
else | |||||
{ | |||||
printf("JSON parse result doesn't match expected string\n"); | printf("JSON parse result doesn't match expected string\n"); | ||||
printf("expected string bytes: "); | printf("expected string bytes: "); | ||||
print_hex(expected); | print_hex(expected); | ||||
@@ -1,6 +1,6 @@ | |||||
#include <stddef.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include "json.h" | #include "json.h" | ||||
@@ -67,12 +67,12 @@ 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", | |||||
orig_count, new_count); | |||||
printf("mismatch between original count (%d) and new count (%d)\n", orig_count, | |||||
new_count); | |||||
retval = 1; | retval = 1; | ||||
} | } | ||||
json_object_put( my_object ); | |||||
json_object_put(my_object); | |||||
return retval; | return retval; | ||||
} | } |
@@ -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 "config.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | |||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include "config.h" | |||||
#include <string.h> | |||||
#include "json_inttypes.h" | #include "json_inttypes.h" | ||||
#include "json_object.h" | #include "json_object.h" | ||||
@@ -75,44 +75,31 @@ 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, | |||||
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_int64()=%" PRId64 "\n", field, | |||||
json_object_get_int64(o)); | |||||
printf("new_obj.%s json_object_get_type()=%s\n", field, 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_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, | |||||
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_boolean()=%d\n", field, json_object_get_boolean(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", | |||||
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_int), | |||||
json_type_to_name(json_type_object), | |||||
json_type_to_name(json_type_array), | |||||
json_type_to_name(json_type_string)); | |||||
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_boolean), json_type_to_name(json_type_double), | |||||
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) | ||||
{ | { | ||||
struct json_object *o = new_obj; | struct json_object *o = new_obj; | ||||
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", | |||||
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_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)); | |||||
printf("new_obj%s%-18s: %d,%d,%d,%d,%d,%d,%d\n", 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_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)); | |||||
} | } |
@@ -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" | ||||
@@ -28,13 +28,13 @@ static void test_case_parse() | |||||
json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | ||||
new_obj = json_tokener_parse_ex(tok, "True", 4); | new_obj = json_tokener_parse_ex(tok, "True", 4); | ||||
assert (new_obj == NULL); | |||||
assert(new_obj == NULL); | |||||
new_obj = json_tokener_parse_ex(tok, "False", 5); | new_obj = json_tokener_parse_ex(tok, "False", 5); | ||||
assert (new_obj == NULL); | |||||
assert(new_obj == NULL); | |||||
new_obj = json_tokener_parse_ex(tok, "Null", 4); | new_obj = json_tokener_parse_ex(tok, "Null", 4); | ||||
assert (new_obj == NULL); | |||||
assert(new_obj == NULL); | |||||
printf("OK\n"); | printf("OK\n"); | ||||
@@ -2,9 +2,9 @@ | |||||
* Tests if json_object_equal behaves correct. | * Tests if json_object_equal behaves correct. | ||||
*/ | */ | ||||
#include "config.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "config.h" | |||||
#include "json_inttypes.h" | #include "json_inttypes.h" | ||||
#include "json_object.h" | #include "json_object.h" | ||||
@@ -1,6 +1,6 @@ | |||||
#include <stddef.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | |||||
#include <string.h> | #include <string.h> | ||||
#ifdef NDEBUG | #ifdef NDEBUG | ||||
#undef NDEBUG | #undef NDEBUG | ||||
@@ -14,76 +14,76 @@ | |||||
static void do_benchmark(json_object *src1); | static void do_benchmark(json_object *src1); | ||||
static const char *json_str1 = | |||||
"{" | |||||
" \"glossary\": {" | |||||
" \"title\": \"example glossary\"," | |||||
" \"GlossDiv\": {" | |||||
" \"number\": 16446744073709551615," | |||||
" \"title\": \"S\"," | |||||
" \"null_obj\": null, " | |||||
" \"exixt\": false," | |||||
" \"quantity\":20," | |||||
" \"univalent\":19.8," | |||||
" \"GlossList\": {" | |||||
" \"GlossEntry\": {" | |||||
" \"ID\": \"SGML\"," | |||||
" \"SortAs\": \"SGML\"," | |||||
" \"GlossTerm\": \"Standard Generalized Markup Language\"," | |||||
" \"Acronym\": \"SGML\"," | |||||
" \"Abbrev\": \"ISO 8879:1986\"," | |||||
" \"GlossDef\": {" | |||||
" \"para\": \"A meta-markup language, used to create markup languages such as DocBook.\"," | |||||
" \"GlossSeeAlso\": [\"GML\", \"XML\"]" | |||||
" }," | |||||
" \"GlossSee\": \"markup\"" | |||||
" }" | |||||
" }" | |||||
" }" | |||||
" }" | |||||
"}"; | |||||
static const char *json_str1 = | |||||
"{" | |||||
" \"glossary\": {" | |||||
" \"title\": \"example glossary\"," | |||||
" \"GlossDiv\": {" | |||||
" \"number\": 16446744073709551615," | |||||
" \"title\": \"S\"," | |||||
" \"null_obj\": null, " | |||||
" \"exixt\": false," | |||||
" \"quantity\":20," | |||||
" \"univalent\":19.8," | |||||
" \"GlossList\": {" | |||||
" \"GlossEntry\": {" | |||||
" \"ID\": \"SGML\"," | |||||
" \"SortAs\": \"SGML\"," | |||||
" \"GlossTerm\": \"Standard Generalized Markup Language\"," | |||||
" \"Acronym\": \"SGML\"," | |||||
" \"Abbrev\": \"ISO 8879:1986\"," | |||||
" \"GlossDef\": {" | |||||
" \"para\": \"A meta-markup language, used to create markup languages " | |||||
"such as DocBook.\"," | |||||
" \"GlossSeeAlso\": [\"GML\", \"XML\"]" | |||||
" }," | |||||
" \"GlossSee\": \"markup\"" | |||||
" }" | |||||
" }" | |||||
" }" | |||||
" }" | |||||
"}"; | |||||
static const char *json_str2 = | static const char *json_str2 = | ||||
"{\"menu\": {" | |||||
" \"header\": \"SVG Viewer\"," | |||||
" \"items\": [" | |||||
" {\"id\": \"Open\"}," | |||||
" {\"id\": \"OpenNew\", \"label\": \"Open New\"}," | |||||
" null," | |||||
" {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"}," | |||||
" {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"}," | |||||
" {\"id\": \"OriginalView\", \"label\": \"Original View\"}," | |||||
" null," | |||||
" {\"id\": \"Quality\", \"another_null\": null}," | |||||
" {\"id\": \"Pause\"}," | |||||
" {\"id\": \"Mute\"}," | |||||
" null," | |||||
" {\"id\": \"Find\", \"label\": \"Find...\"}," | |||||
" {\"id\": \"FindAgain\", \"label\": \"Find Again\"}," | |||||
" {\"id\": \"Copy\"}," | |||||
" {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"}," | |||||
" {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"}," | |||||
" {\"id\": \"ViewSVG\", \"label\": \"View SVG\"}," | |||||
" {\"id\": \"ViewSource\", \"label\": \"View Source\"}," | |||||
" {\"id\": \"SaveAs\", \"label\": \"Save As\"}," | |||||
" null," | |||||
" {\"id\": \"Help\"}," | |||||
" {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"}" | |||||
" ]" | |||||
"}}"; | |||||
static const char *json_str3 = | |||||
"{\"menu\": {" | |||||
" \"id\": \"file\"," | |||||
" \"value\": \"File\"," | |||||
" \"popup\": {" | |||||
" \"menuitem\": [" | |||||
" {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"}," | |||||
" {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}," | |||||
" {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}" | |||||
" ]" | |||||
" }" | |||||
"}}"; | |||||
"{\"menu\": {" | |||||
" \"header\": \"SVG Viewer\"," | |||||
" \"items\": [" | |||||
" {\"id\": \"Open\"}," | |||||
" {\"id\": \"OpenNew\", \"label\": \"Open New\"}," | |||||
" null," | |||||
" {\"id\": \"ZoomIn\", \"label\": \"Zoom In\"}," | |||||
" {\"id\": \"ZoomOut\", \"label\": \"Zoom Out\"}," | |||||
" {\"id\": \"OriginalView\", \"label\": \"Original View\"}," | |||||
" null," | |||||
" {\"id\": \"Quality\", \"another_null\": null}," | |||||
" {\"id\": \"Pause\"}," | |||||
" {\"id\": \"Mute\"}," | |||||
" null," | |||||
" {\"id\": \"Find\", \"label\": \"Find...\"}," | |||||
" {\"id\": \"FindAgain\", \"label\": \"Find Again\"}," | |||||
" {\"id\": \"Copy\"}," | |||||
" {\"id\": \"CopyAgain\", \"label\": \"Copy Again\"}," | |||||
" {\"id\": \"CopySVG\", \"label\": \"Copy SVG\"}," | |||||
" {\"id\": \"ViewSVG\", \"label\": \"View SVG\"}," | |||||
" {\"id\": \"ViewSource\", \"label\": \"View Source\"}," | |||||
" {\"id\": \"SaveAs\", \"label\": \"Save As\"}," | |||||
" null," | |||||
" {\"id\": \"Help\"}," | |||||
" {\"id\": \"About\", \"label\": \"About Adobe CVG Viewer...\"}" | |||||
" ]" | |||||
"}}"; | |||||
static const char *json_str3 = "{\"menu\": {" | |||||
" \"id\": \"file\"," | |||||
" \"value\": \"File\"," | |||||
" \"popup\": {" | |||||
" \"menuitem\": [" | |||||
" {\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"}," | |||||
" {\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}," | |||||
" {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}" | |||||
" ]" | |||||
" }" | |||||
"}}"; | |||||
json_object_to_json_string_fn my_custom_serializer; | json_object_to_json_string_fn my_custom_serializer; | ||||
int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level, int flags) | int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level, int flags) | ||||
@@ -93,7 +93,8 @@ int my_custom_serializer(struct json_object *jso, struct printbuf *pb, int level | |||||
} | } | ||||
json_c_shallow_copy_fn my_shallow_copy; | json_c_shallow_copy_fn my_shallow_copy; | ||||
int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index, json_object **dst) | |||||
int my_shallow_copy(json_object *src, json_object *parent, const char *key, size_t index, | |||||
json_object **dst) | |||||
{ | { | ||||
int rc; | int rc; | ||||
rc = json_c_shallow_copy_default(src, parent, key, index, dst); | rc = json_c_shallow_copy_default(src, parent, key, index, dst); | ||||
@@ -109,7 +110,6 @@ int my_shallow_copy(json_object *src, json_object *parent, const char *key, size | |||||
return rc; | return rc; | ||||
} | } | ||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | { | ||||
struct json_object *src1, *src2, *src3; | struct json_object *src1, *src2, *src3; | ||||
@@ -238,19 +238,24 @@ static void do_benchmark(json_object *src2) | |||||
time_t start = time(NULL); | time_t start = time(NULL); | ||||
start = time(NULL); | start = time(NULL); | ||||
for (ii = 0; ii < iterations; ii++) { | |||||
for (ii = 0; ii < iterations; ii++) | |||||
{ | |||||
dst2 = json_tokener_parse(json_object_get_string(src2)); | dst2 = json_tokener_parse(json_object_get_string(src2)); | ||||
json_object_put(dst2); | json_object_put(dst2); | ||||
} | } | ||||
printf("BENCHMARK - %d iterations of 'dst2 = json_tokener_parse(json_object_get_string(src2))' took %d seconds\n", iterations, (int)(time(NULL) - start)); | |||||
printf("BENCHMARK - %d iterations of 'dst2 = " | |||||
"json_tokener_parse(json_object_get_string(src2))' took %d seconds\n", | |||||
iterations, (int)(time(NULL) - start)); | |||||
start = time(NULL); | start = time(NULL); | ||||
dst2 = NULL; | dst2 = NULL; | ||||
for (ii = 0; ii < iterations; ii++) { | |||||
for (ii = 0; ii < iterations; ii++) | |||||
{ | |||||
json_object_deep_copy(src2, &dst2, NULL); | json_object_deep_copy(src2, &dst2, NULL); | ||||
json_object_put(dst2); | json_object_put(dst2); | ||||
dst2 = NULL; | dst2 = NULL; | ||||
} | } | ||||
printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d seconds\n", iterations, (int)(time(NULL) - start)); | |||||
printf("BENCHMARK - %d iterations of 'json_object_deep_copy(src2, &dst2, NULL)' took %d " | |||||
"seconds\n", | |||||
iterations, (int)(time(NULL) - start)); | |||||
} | } | ||||
@@ -2,8 +2,8 @@ | |||||
* Tests if the format string for double serialization is handled correctly | * Tests if the format string for double serialization is handled correctly | ||||
*/ | */ | ||||
#include <stdio.h> | |||||
#include "config.h" | #include "config.h" | ||||
#include <stdio.h> | |||||
#include "json_object.h" | #include "json_object.h" | ||||
#include "json_object_private.h" | #include "json_object_private.h" | ||||
@@ -49,7 +49,8 @@ int main() | |||||
if (json_c_set_serialization_double_format("T%0.2fX", JSON_C_OPTION_THREAD) < 0) | if (json_c_set_serialization_double_format("T%0.2fX", JSON_C_OPTION_THREAD) < 0) | ||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | printf("ERROR: json_c_set_serialization_double_format() failed"); | ||||
printf("obj.to_string(with thread format)=%s\n", json_object_to_json_string(obj)); | printf("obj.to_string(with thread format)=%s\n", json_object_to_json_string(obj)); | ||||
if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX", JSON_C_OPTION_THREAD) < 0) | |||||
if (json_c_set_serialization_double_format("Ttttttttttttt%0.2fxxxxxxxxxxxxxxxxxxX", | |||||
JSON_C_OPTION_THREAD) < 0) | |||||
printf("ERROR: json_c_set_serialization_double_format() failed"); | printf("ERROR: json_c_set_serialization_double_format() failed"); | ||||
printf("obj.to_string(long thread format)=%s\n", json_object_to_json_string(obj)); | printf("obj.to_string(long thread format)=%s\n", json_object_to_json_string(obj)); | ||||
if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_THREAD) < 0) | if (json_c_set_serialization_double_format(NULL, JSON_C_OPTION_THREAD) < 0) | ||||
@@ -96,11 +97,11 @@ int main() | |||||
json_object_put(obj); | json_object_put(obj); | ||||
/* Test Infinity and -Infinity handling */ | /* Test Infinity and -Infinity handling */ | ||||
obj = json_object_new_double(1.0/zero_dot_zero); | |||||
obj = json_object_new_double(1.0 / zero_dot_zero); | |||||
printf("obj(1.0/0.0)=%s\n", json_object_to_json_string(obj)); | printf("obj(1.0/0.0)=%s\n", json_object_to_json_string(obj)); | ||||
json_object_put(obj); | json_object_put(obj); | ||||
obj = json_object_new_double(-1.0/zero_dot_zero); | |||||
obj = json_object_new_double(-1.0 / zero_dot_zero); | |||||
printf("obj(-1.0/0.0)=%s\n", json_object_to_json_string(obj)); | printf("obj(-1.0/0.0)=%s\n", json_object_to_json_string(obj)); | ||||
json_object_put(obj); | json_object_put(obj); | ||||
@@ -1,28 +1,28 @@ | |||||
/* 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; | |||||
json = json_object_new_double(1.0); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(1.0); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(-1.0); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(1.23); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(123456789.0); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(123456789.123); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
return 0; | |||||
json = json_object_new_double(-1.0); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(1.23); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(123456789.0); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
json = json_object_new_double(123456789.123); | |||||
printf("json = %s\n", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY)); | |||||
json_object_put(json); | |||||
return 0; | |||||
} | } |
@@ -43,7 +43,7 @@ int main(int argc, char **argv) | |||||
assert(json_object_get_int64(tmp) != INT64_MIN); | assert(json_object_get_int64(tmp) != INT64_MIN); | ||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("INT64 ADD UNDERFLOW PASSED\n"); | printf("INT64 ADD UNDERFLOW PASSED\n"); | ||||
// uint64 + negative int64--> negative int64 | |||||
// uint64 + negative int64--> negative int64 | |||||
tmp = json_object_new_uint64(400); | tmp = json_object_new_uint64(400); | ||||
json_object_int_inc(tmp, -200); | json_object_int_inc(tmp, -200); | ||||
assert(json_object_get_int64(tmp) == 200); | assert(json_object_get_int64(tmp) == 200); | ||||
@@ -20,53 +20,57 @@ static void test_example_int(struct json_object *jo1, const char *json_pointer, | |||||
} | } | ||||
static const char *input_json_str = "{ " | static const char *input_json_str = "{ " | ||||
"'foo': ['bar', 'baz'], " | |||||
"'': 0, " | |||||
"'a/b': 1, " | |||||
"'c%d': 2, " | |||||
"'e^f': 3, " | |||||
"'g|h': 4, " | |||||
"'i\\\\j': 5, " | |||||
"'k\\\"l': 6, " | |||||
"' ': 7, " | |||||
"'m~n': 8 " | |||||
"}"; | |||||
static const char *rec_input_json_str = "{" | |||||
"'arr' : [" | |||||
"{" | |||||
"'obj': [" | |||||
"{},{}," | |||||
"{" | |||||
"'obj1': 0," | |||||
"'obj2': \"1\"" | |||||
"}" | |||||
"]" | |||||
"}" | |||||
"]," | |||||
"'obj' : {" | |||||
"'obj': {" | |||||
"'obj': [" | |||||
"{" | |||||
"'obj1': 0," | |||||
"'obj2': \"1\"" | |||||
"}" | |||||
"]" | |||||
"}" | |||||
"}" | |||||
"}"; | |||||
"'foo': ['bar', 'baz'], " | |||||
"'': 0, " | |||||
"'a/b': 1, " | |||||
"'c%d': 2, " | |||||
"'e^f': 3, " | |||||
"'g|h': 4, " | |||||
"'i\\\\j': 5, " | |||||
"'k\\\"l': 6, " | |||||
"' ': 7, " | |||||
"'m~n': 8 " | |||||
"}"; | |||||
/* clang-format off */ | |||||
static const char *rec_input_json_str = | |||||
"{" | |||||
"'arr' : [" | |||||
"{" | |||||
"'obj': [" | |||||
"{},{}," | |||||
"{" | |||||
"'obj1': 0," | |||||
"'obj2': \"1\"" | |||||
"}" | |||||
"]" | |||||
"}" | |||||
"]," | |||||
"'obj' : {" | |||||
"'obj': {" | |||||
"'obj': [" | |||||
"{" | |||||
"'obj1': 0," | |||||
"'obj2': \"1\"" | |||||
"}" | |||||
"]" | |||||
"}" | |||||
"}" | |||||
"}"; | |||||
/* clang-format on */ | |||||
/* Example from RFC */ | /* Example from RFC */ | ||||
static void test_example_get() | 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; | ||||
}; | }; | ||||
/* Create a map to iterate over for the ints */ | /* Create a map to iterate over for the ints */ | ||||
/* clang-format off */ | |||||
struct json_pointer_map_s_i json_pointers[] = { | struct json_pointer_map_s_i json_pointers[] = { | ||||
{ "/", 0 }, | { "/", 0 }, | ||||
{ "/a~1b", 1 }, | { "/a~1b", 1 }, | ||||
@@ -79,6 +83,7 @@ static void test_example_get() | |||||
{ "/m~0n", 8 }, | { "/m~0n", 8 }, | ||||
{ NULL, 0} | { NULL, 0} | ||||
}; | }; | ||||
/* clang-format on */ | |||||
jo1 = json_tokener_parse(input_json_str); | jo1 = json_tokener_parse(input_json_str); | ||||
assert(NULL != jo1); | assert(NULL != jo1); | ||||
@@ -114,7 +119,7 @@ static void test_example_get() | |||||
assert(0 == strcmp("bar", json_object_get_string(jo2))); | assert(0 == strcmp("bar", json_object_get_string(jo2))); | ||||
printf("PASSED - GET - /foo/0 == 'bar'\n"); | printf("PASSED - GET - /foo/0 == 'bar'\n"); | ||||
for (i = 0 ; json_pointers[i].s; i++) | |||||
for (i = 0; json_pointers[i].s; i++) | |||||
test_example_int(jo1, json_pointers[i].s, json_pointers[i].i); | test_example_int(jo1, json_pointers[i].s, json_pointers[i].i); | ||||
json_object_put(jo1); | json_object_put(jo1); | ||||
@@ -235,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); | ||||
@@ -252,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); | ||||
@@ -282,7 +290,8 @@ static void test_wrong_inputs_set() | |||||
printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n"); | printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n"); | ||||
json_object_put(jo2); | json_object_put(jo2); | ||||
assert(0 != json_pointer_setf(&jo1, (jo2 = json_object_new_string("cod")), "%s", "foo/bar")); | |||||
assert(0 != | |||||
json_pointer_setf(&jo1, (jo2 = json_object_new_string("cod")), "%s", "foo/bar")); | |||||
printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n"); | printf("PASSED - SET - failed 'cod' with path 'foo/bar'\n"); | ||||
json_object_put(jo2); | json_object_put(jo2); | ||||
@@ -1,8 +1,8 @@ | |||||
#include <assert.h> | |||||
#include <stddef.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include <assert.h> | |||||
#include "config.h" | #include "config.h" | ||||
#include "json.h" | #include "json.h" | ||||
@@ -37,8 +37,7 @@ int main(int argc, char **argv) | |||||
(void)snprintf(buf2, sizeof(buf2), "%f", 0.1); | (void)snprintf(buf2, sizeof(buf2), "%f", 0.1); | ||||
if (strcmp(buf1, buf2) != 0) | if (strcmp(buf1, buf2) != 0) | ||||
printf("ERROR: Original locale not restored \"%s\" != \"%s\"", | |||||
buf1, buf2); | |||||
printf("ERROR: Original locale not restored \"%s\" != \"%s\"", buf1, buf2); | |||||
#ifdef HAVE_SETLOCALE | #ifdef HAVE_SETLOCALE | ||||
setlocale(LC_NUMERIC, "C"); | setlocale(LC_NUMERIC, "C"); | ||||
@@ -49,16 +48,16 @@ int main(int argc, char **argv) | |||||
// string that was parsed. (see json_object_new_double_s()) | // string that was parsed. (see json_object_new_double_s()) | ||||
printf("new_obj.to_string()=["); | printf("new_obj.to_string()=["); | ||||
unsigned int ii; | unsigned int ii; | ||||
for (ii = 0 ; ii < json_object_array_length(new_obj); ii++) | |||||
for (ii = 0; ii < json_object_array_length(new_obj); ii++) | |||||
{ | { | ||||
json_object *val = json_object_array_get_idx(new_obj, ii); | json_object *val = json_object_array_get_idx(new_obj, ii); | ||||
printf("%s%.2lf", (ii > 0) ? "," : "", json_object_get_double(val)); | printf("%s%.2lf", (ii > 0) ? "," : "", json_object_get_double(val)); | ||||
} | } | ||||
printf("]\n"); | printf("]\n"); | ||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string_ext(new_obj,JSON_C_TO_STRING_NOZERO)); | |||||
printf("new_obj.to_string()=%s\n", | |||||
json_object_to_json_string_ext(new_obj, JSON_C_TO_STRING_NOZERO)); | |||||
json_object_put(new_obj); | json_object_put(new_obj); | ||||
return 0; | return 0; | ||||
} | } | ||||
@@ -2,9 +2,9 @@ | |||||
* Tests if binary strings are supported. | * Tests if binary strings are supported. | ||||
*/ | */ | ||||
#include "config.h" | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "config.h" | |||||
#include "json_inttypes.h" | #include "json_inttypes.h" | ||||
#include "json_object.h" | #include "json_object.h" | ||||
@@ -18,20 +18,22 @@ int main(void) | |||||
struct json_object *string = json_object_new_string_len(input, 3); | struct json_object *string = json_object_new_string_len(input, 3); | ||||
const char *json = json_object_to_json_string(string); | const char *json = json_object_to_json_string(string); | ||||
int strings_match = !strcmp( expected, json); | |||||
int strings_match = !strcmp(expected, json); | |||||
int retval = 0; | int retval = 0; | ||||
if (strings_match) | if (strings_match) | ||||
{ | { | ||||
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); | ||||
printf("parsed string: "); | printf("parsed string: "); | ||||
puts(json); | puts(json); | ||||
puts("FAIL"); | puts("FAIL"); | ||||
retval=1; | |||||
retval = 1; | |||||
} | } | ||||
json_object_put(string); | json_object_put(string); | ||||
@@ -42,7 +44,7 @@ int main(void) | |||||
const char *parsed_cstr = json_object_get_string(parsed_str); | const char *parsed_cstr = json_object_get_string(parsed_str); | ||||
int ii; | int ii; | ||||
printf("Re-parsed object string len=%d, chars=[", parsed_len); | printf("Re-parsed object string len=%d, chars=[", parsed_len); | ||||
for (ii = 0; ii < parsed_len ; ii++) | |||||
for (ii = 0; ii < parsed_len; ii++) | |||||
{ | { | ||||
printf("%s%d", (ii ? ", " : ""), (int)parsed_cstr[ii]); | printf("%s%d", (ii ? ", " : ""), (int)parsed_cstr[ii]); | ||||
} | } | ||||
@@ -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" | ||||
@@ -106,7 +106,7 @@ static void test_basic_parse() | |||||
single_basic_parse("{\"FoO\" : -12.3E512}", 0); | single_basic_parse("{\"FoO\" : -12.3E512}", 0); | ||||
single_basic_parse("{\"FoO\" : -12.3e512}", 0); | single_basic_parse("{\"FoO\" : -12.3e512}", 0); | ||||
single_basic_parse("{\"FoO\" : -12.3E51.2}", 0); /* non-sensical, returns null */ | |||||
single_basic_parse("{\"FoO\" : -12.3E51.2}", 0); /* non-sensical, returns null */ | |||||
single_basic_parse("{\"FoO\" : -12.3E512E12}", 0); /* non-sensical, returns null */ | single_basic_parse("{\"FoO\" : -12.3E512E12}", 0); /* non-sensical, returns null */ | ||||
single_basic_parse("[\"\\n\"]", 0); | single_basic_parse("[\"\\n\"]", 0); | ||||
single_basic_parse("[\"\\nabc\\n\"]", 0); | single_basic_parse("[\"\\nabc\\n\"]", 0); | ||||
@@ -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. | ||||
@@ -130,7 +132,7 @@ static void test_basic_parse() | |||||
single_basic_parse("[0e+-1]", 1); | single_basic_parse("[0e+-1]", 1); | ||||
single_basic_parse("\"hello world!\"", 1); | single_basic_parse("\"hello world!\"", 1); | ||||
// uint64/int64 range test | |||||
// uint64/int64 range test | |||||
single_basic_parse("[9223372036854775806]", 1); | single_basic_parse("[9223372036854775806]", 1); | ||||
single_basic_parse("[9223372036854775807]", 1); | single_basic_parse("[9223372036854775807]", 1); | ||||
single_basic_parse("[9223372036854775808]", 1); | single_basic_parse("[9223372036854775808]", 1); | ||||
@@ -147,8 +149,8 @@ static void test_utf8_parse() | |||||
// json_tokener_parse doesn't support checking for byte order marks. | // json_tokener_parse doesn't support checking for byte order marks. | ||||
// It's the responsibility of the caller to detect and skip a BOM. | // It's the responsibility of the caller to detect and skip a BOM. | ||||
// Both of these checks return null. | // Both of these checks return null. | ||||
char utf8_bom[] = { 0xEF, 0xBB, 0xBF, 0x00 }; | |||||
char utf8_bom_and_chars[] = { 0xEF, 0xBB, 0xBF, '{', '}', 0x00 }; | |||||
char utf8_bom[] = {0xEF, 0xBB, 0xBF, 0x00}; | |||||
char utf8_bom_and_chars[] = {0xEF, 0xBB, 0xBF, '{', '}', 0x00}; | |||||
single_basic_parse(utf8_bom, 0); | single_basic_parse(utf8_bom, 0); | ||||
single_basic_parse(utf8_bom_and_chars, 0); | single_basic_parse(utf8_bom_and_chars, 0); | ||||
} | } | ||||
@@ -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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int clear_serializer(json_object *jso, int flags, json_object *parent_jso, | |||||
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); | ||||
@@ -177,24 +177,25 @@ static void test_verbose_parse() | |||||
enum json_tokener_error error = json_tokener_success; | enum json_tokener_error error = json_tokener_success; | ||||
new_obj = json_tokener_parse_verbose("{ foo }", &error); | new_obj = json_tokener_parse_verbose("{ foo }", &error); | ||||
assert (error == json_tokener_error_parse_object_key_name); | |||||
assert (new_obj == NULL); | |||||
assert(error == json_tokener_error_parse_object_key_name); | |||||
assert(new_obj == NULL); | |||||
new_obj = json_tokener_parse("{ foo }"); | new_obj = json_tokener_parse("{ foo }"); | ||||
assert (new_obj == NULL); | |||||
assert(new_obj == NULL); | |||||
new_obj = json_tokener_parse("foo"); | new_obj = json_tokener_parse("foo"); | ||||
assert (new_obj == NULL); | |||||
assert(new_obj == NULL); | |||||
new_obj = json_tokener_parse_verbose("foo", &error); | new_obj = json_tokener_parse_verbose("foo", &error); | ||||
assert (new_obj == NULL); | |||||
assert(new_obj == NULL); | |||||
/* b/c the string starts with 'f' parsing return a boolean error */ | /* b/c the string starts with 'f' parsing return a boolean error */ | ||||
assert (error == json_tokener_error_parse_boolean); | |||||
assert(error == json_tokener_error_parse_boolean); | |||||
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; | ||||
@@ -202,203 +203,205 @@ struct incremental_step { | |||||
int reset_tokener; | int reset_tokener; | ||||
} incremental_steps[] = { | } incremental_steps[] = { | ||||
/* Check that full json messages can be parsed, both w/ and w/o a reset */ | |||||
{ "{ \"foo\": 123 }", -1, -1, json_tokener_success, 0 }, | |||||
{ "{ \"foo\": 456 }", -1, -1, json_tokener_success, 1 }, | |||||
{ "{ \"foo\": 789 }", -1, -1, json_tokener_success, 1 }, | |||||
/* Check the comment parse*/ | |||||
{ "/* hello */{ \"foo\"", -1, -1, json_tokener_continue, 0 }, | |||||
{ "/* hello */:/* hello */", -1, -1, json_tokener_continue, 0 }, | |||||
{ "\"bar\"/* hello */", -1, -1, json_tokener_continue, 0 }, | |||||
{ "}/* hello */", -1, -1, json_tokener_success, 1 }, | |||||
{ "/ hello ", -1, 1, json_tokener_error_parse_comment, 1 }, | |||||
{ "/* hello\"foo\"", -1, -1, json_tokener_continue, 1 }, | |||||
{ "/* hello*\"foo\"", -1, -1, json_tokener_continue, 1 }, | |||||
{ "// hello\"foo\"", -1, -1, json_tokener_continue, 1 }, | |||||
/* Check a basic incremental parse */ | |||||
{ "{ \"foo", -1, -1, json_tokener_continue, 0 }, | |||||
{ "\": {\"bar", -1, -1, json_tokener_continue, 0 }, | |||||
{ "\":13}}", -1, -1, json_tokener_success, 1 }, | |||||
/* Check that json_tokener_reset actually resets */ | |||||
{ "{ \"foo", -1, -1, json_tokener_continue, 1 }, | |||||
{ ": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1 }, | |||||
/* Check incremental parsing with trailing characters */ | |||||
{ "{ \"foo", -1, -1, json_tokener_continue, 0 }, | |||||
{ "\": {\"bar", -1, -1, json_tokener_continue, 0 }, | |||||
{ "\":13}}XXXX", 10, 6, json_tokener_success, 0 }, | |||||
{ "XXXX", 4, 0, json_tokener_error_parse_unexpected, 1 }, | |||||
/* Check that trailing characters can change w/o a reset */ | |||||
{ "{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0 }, | |||||
{ "\"Y\"", -1, -1, json_tokener_success, 1 }, | |||||
/* To stop parsing a number we need to reach a non-digit, e.g. a \0 */ | |||||
{ "1", 1, 1, json_tokener_continue, 0 }, | |||||
/* This should parse as the number 12, since it continues the "1" */ | |||||
{ "2", 2, 1, json_tokener_success, 0 }, | |||||
{ "12{", 3, 2, json_tokener_success, 1 }, | |||||
/* Parse number in strict model */ | |||||
{ "[02]", -1, 3, json_tokener_error_parse_number, 3 }, | |||||
/* Similar tests for other kinds of objects: */ | |||||
/* These could all return success immediately, since regardless of | |||||
/* Check that full json messages can be parsed, both w/ and w/o a reset */ | |||||
{"{ \"foo\": 123 }", -1, -1, json_tokener_success, 0}, | |||||
{"{ \"foo\": 456 }", -1, -1, json_tokener_success, 1}, | |||||
{"{ \"foo\": 789 }", -1, -1, json_tokener_success, 1}, | |||||
/* Check the comment parse*/ | |||||
{"/* hello */{ \"foo\"", -1, -1, json_tokener_continue, 0}, | |||||
{"/* hello */:/* hello */", -1, -1, json_tokener_continue, 0}, | |||||
{"\"bar\"/* hello */", -1, -1, json_tokener_continue, 0}, | |||||
{"}/* hello */", -1, -1, json_tokener_success, 1}, | |||||
{"/ hello ", -1, 1, json_tokener_error_parse_comment, 1}, | |||||
{"/* hello\"foo\"", -1, -1, json_tokener_continue, 1}, | |||||
{"/* hello*\"foo\"", -1, -1, json_tokener_continue, 1}, | |||||
{"// hello\"foo\"", -1, -1, json_tokener_continue, 1}, | |||||
/* Check a basic incremental parse */ | |||||
{"{ \"foo", -1, -1, json_tokener_continue, 0}, | |||||
{"\": {\"bar", -1, -1, json_tokener_continue, 0}, | |||||
{"\":13}}", -1, -1, json_tokener_success, 1}, | |||||
/* Check that json_tokener_reset actually resets */ | |||||
{"{ \"foo", -1, -1, json_tokener_continue, 1}, | |||||
{": \"bar\"}", -1, 0, json_tokener_error_parse_unexpected, 1}, | |||||
/* Check incremental parsing with trailing characters */ | |||||
{"{ \"foo", -1, -1, json_tokener_continue, 0}, | |||||
{"\": {\"bar", -1, -1, json_tokener_continue, 0}, | |||||
{"\":13}}XXXX", 10, 6, json_tokener_success, 0}, | |||||
{"XXXX", 4, 0, json_tokener_error_parse_unexpected, 1}, | |||||
/* Check that trailing characters can change w/o a reset */ | |||||
{"{\"x\": 123 }\"X\"", -1, 11, json_tokener_success, 0}, | |||||
{"\"Y\"", -1, -1, json_tokener_success, 1}, | |||||
/* To stop parsing a number we need to reach a non-digit, e.g. a \0 */ | |||||
{"1", 1, 1, json_tokener_continue, 0}, | |||||
/* This should parse as the number 12, since it continues the "1" */ | |||||
{"2", 2, 1, json_tokener_success, 0}, | |||||
{"12{", 3, 2, json_tokener_success, 1}, | |||||
/* Parse number in strict model */ | |||||
{"[02]", -1, 3, json_tokener_error_parse_number, 3}, | |||||
/* Similar tests for other kinds of objects: */ | |||||
/* These could all return success immediately, since regardless of | |||||
what follows the false/true/null token we *will* return a json object, | what follows the false/true/null token we *will* return a json object, | ||||
but it currently doesn't work that way. hmm... */ | but it currently doesn't work that way. hmm... */ | ||||
{ "false", 5, 5, json_tokener_continue, 1 }, | |||||
{ "false", 6, 5, json_tokener_success, 1 }, | |||||
{ "true", 4, 4, json_tokener_continue, 1 }, | |||||
{ "true", 5, 4, json_tokener_success, 1 }, | |||||
{ "null", 4, 4, json_tokener_continue, 1 }, | |||||
{ "null", 5, 4, json_tokener_success, 1 }, | |||||
{ "Infinity", 9, 8, json_tokener_success, 1 }, | |||||
{ "infinity", 9, 8, json_tokener_success, 1 }, | |||||
{ "-infinity", 10, 9, json_tokener_success, 1 }, | |||||
{ "infinity", 9, 0, json_tokener_error_parse_unexpected, 3 }, | |||||
{ "-infinity", 10, 1, json_tokener_error_parse_unexpected, 3 }, | |||||
{ "inf", 3, 3, json_tokener_continue, 0 }, | |||||
{ "inity", 6, 5, json_tokener_success, 1 }, | |||||
{ "-inf", 4, 4, json_tokener_continue, 0 }, | |||||
{ "inity", 6, 5, json_tokener_success, 1 }, | |||||
{ "i", 1, 1, json_tokener_continue, 0 }, | |||||
{ "n", 1, 1, json_tokener_continue, 0 }, | |||||
{ "f", 1, 1, json_tokener_continue, 0 }, | |||||
{ "i", 1, 1, json_tokener_continue, 0 }, | |||||
{ "n", 1, 1, json_tokener_continue, 0 }, | |||||
{ "i", 1, 1, json_tokener_continue, 0 }, | |||||
{ "t", 1, 1, json_tokener_continue, 0 }, | |||||
{ "y", 1, 1, json_tokener_continue, 0 }, | |||||
{ "", 1, 0, json_tokener_success, 1 }, | |||||
{ "-", 1, 1, json_tokener_continue, 0 }, | |||||
{ "inf", 3, 3, json_tokener_continue, 0 }, | |||||
{ "ini", 3, 3, json_tokener_continue, 0 }, | |||||
{ "ty", 3, 2, json_tokener_success, 1 }, | |||||
{ "-", 1, 1, json_tokener_continue, 0 }, | |||||
{ "i", 1, 1, json_tokener_continue, 0 }, | |||||
{ "nfini", 5, 5, json_tokener_continue, 0 }, | |||||
{ "ty", 3, 2, json_tokener_success, 1 }, | |||||
{ "-i", 2, 2, json_tokener_continue, 0 }, | |||||
{ "nfinity", 8, 7, json_tokener_success, 1 }, | |||||
{ "InfinityX", 10, 8, json_tokener_success, 0 }, | |||||
{ "X", 1, 0, json_tokener_error_parse_unexpected, 1 }, | |||||
{ "Infinity1234", 13, 8, json_tokener_success, 0 }, | |||||
{ "1234", 5, 4, json_tokener_success, 1 }, | |||||
{ "Infinity9999", 8, 8, json_tokener_continue, 0 }, | |||||
/* returns the Infinity loaded up by the previous call: */ | |||||
{ "1234", 5, 0, json_tokener_success, 0 }, | |||||
{ "1234", 5, 4, json_tokener_success, 1 }, | |||||
/* offset=1 because "n" is the start of "null". hmm... */ | |||||
{ "noodle", 7, 1, json_tokener_error_parse_null, 1 }, | |||||
/* offset=2 because "na" is the start of "nan". hmm... */ | |||||
{ "naodle", 7, 2, json_tokener_error_parse_null, 1 }, | |||||
/* offset=2 because "tr" is the start of "true". hmm... */ | |||||
{ "track", 6, 2, json_tokener_error_parse_boolean, 1 }, | |||||
{ "fail", 5, 2, json_tokener_error_parse_boolean, 1 }, | |||||
/* Although they may initially look like they should fail, | |||||
the next few tests check that parsing multiple sequential | |||||
json objects in the input works as expected */ | |||||
{ "null123", 9, 4, json_tokener_success, 0 }, | |||||
{ &"null123"[4], 4, 3, json_tokener_success, 1 }, | |||||
{ "nullx", 5, 4, json_tokener_success, 0 }, | |||||
{ &"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1 }, | |||||
{ "{\"a\":1}{\"b\":2}",15, 7, json_tokener_success, 0 }, | |||||
{ &"{\"a\":1}{\"b\":2}"[7], | |||||
8, 7, json_tokener_success, 1 }, | |||||
/* Some bad formatting. Check we get the correct error status */ | |||||
{ "2015-01-15", 10, 4, json_tokener_error_parse_number, 1 }, | |||||
/* Strings have a well defined end point, so we can stop at the quote */ | |||||
{ "\"blue\"", -1, -1, json_tokener_success, 0 }, | |||||
/* Check each of the escape sequences defined by the spec */ | |||||
{ "\"\\\"\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\\\\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\b\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\f\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\n\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\r\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\t\"", -1, -1, json_tokener_success, 0 }, | |||||
{ "\"\\/\"", -1, -1, json_tokener_success, 0 }, | |||||
// Escaping a forward slash is optional | |||||
{ "\"/\"", -1, -1, json_tokener_success, 0 }, | |||||
/* Check wrong escape sequences */ | |||||
{ "\"\\a\"", -1, 2, json_tokener_error_parse_string, 1 }, | |||||
/* Check '\'' in strict model */ | |||||
{ "\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 3 }, | |||||
/* Parse array/object */ | |||||
{ "[1,2,3]", -1, -1, json_tokener_success, 0 }, | |||||
{ "[1,2,3}", -1, 6, json_tokener_error_parse_array, 1 }, | |||||
{ "{\"a\"}", -1, 4, json_tokener_error_parse_object_key_sep, 1 }, | |||||
{ "{\"a\":1]", -1, 6, json_tokener_error_parse_object_value_sep, 1 }, | |||||
{ "{\"a\"::1}", -1, 5, json_tokener_error_parse_unexpected, 1 }, | |||||
{ "{\"a\":}", -1, 5, json_tokener_error_parse_unexpected, 1 }, | |||||
{ "{\"a\":1,\"a\":2}",-1, -1, json_tokener_success, 1 }, | |||||
{ "\"a\":1}", -1, 3, json_tokener_success, 1 }, | |||||
{ "{\"a\":1", -1, -1, json_tokener_continue, 1 }, | |||||
{ "[,]", -1, 1, json_tokener_error_parse_unexpected, 1 }, | |||||
{ "[,1]", -1, 1, json_tokener_error_parse_unexpected, 1 }, | |||||
/* This behaviour doesn't entirely follow the json spec, but until we have | |||||
a way to specify how strict to be we follow Postel's Law and be liberal | |||||
in what we accept (up to a point). */ | |||||
{ "[1,2,3,]", -1, -1, json_tokener_success, 0 }, | |||||
{ "[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0 }, | |||||
{ "[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3 }, | |||||
{ "{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3 }, | |||||
// utf-8 test | |||||
// acsll encoding | |||||
{ "\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22",-1, -1, json_tokener_success, 5 }, | |||||
{ "\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22",-1, -1, json_tokener_success, 1 }, | |||||
// utf-8 encoding | |||||
{ "\x22\xe4\xb8\x96\xe7\x95\x8c\x22",-1, -1, json_tokener_success, 5 }, | |||||
{ "\x22\xe4\xb8",-1, 3, json_tokener_error_parse_utf8_string, 4 }, | |||||
{ "\x96\xe7\x95\x8c\x22",-1, 0, json_tokener_error_parse_utf8_string, 5 }, | |||||
{ "\x22\xe4\xb8\x96\xe7\x95\x8c\x22",-1, -1, json_tokener_success, 1 }, | |||||
{ "\x22\xcf\x80\xcf\x86\x22",-1, -1, json_tokener_success, 5 }, | |||||
{ "\x22\xf0\xa5\x91\x95\x22",-1, -1, json_tokener_success, 5 }, | |||||
// wrong utf-8 encoding | |||||
{ "\x22\xe6\x9d\x4e\x22",-1, 3, json_tokener_error_parse_utf8_string, 5 }, | |||||
{ "\x22\xe6\x9d\x4e\x22",-1, 5, json_tokener_success, 1 }, | |||||
// GBK encoding | |||||
{ "\x22\xc0\xee\xc5\xf4\x22",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||||
{ "\x22\xc0\xee\xc5\xf4\x22",-1, 6, json_tokener_success, 1 }, | |||||
// char after space | |||||
{ "\x20\x20\x22\xe4\xb8\x96\x22",-1, -1, json_tokener_success, 5 }, | |||||
{ "\x20\x20\x81\x22\xe4\xb8\x96\x22",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||||
{ "\x5b\x20\x81\x31\x5d",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||||
// char in state inf | |||||
{ "\x49\x6e\x66\x69\x6e\x69\x74\x79",9, 8, json_tokener_success, 1 }, | |||||
{ "\x49\x6e\x66\x81\x6e\x69\x74\x79",-1, 3, json_tokener_error_parse_utf8_string, 5 }, | |||||
// 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\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 }, | |||||
// char in number | |||||
{ "\x31\x31\x81\x31\x31",-1, 2, json_tokener_error_parse_utf8_string, 5 }, | |||||
// char in object | |||||
{ "\x7b\x22\x31\x81\x22\x3a\x31\x7d",-1, 3, json_tokener_error_parse_utf8_string, 5 }, | |||||
{ NULL, -1, -1, json_tokener_success, 0 }, | |||||
{"false", 5, 5, json_tokener_continue, 1}, | |||||
{"false", 6, 5, json_tokener_success, 1}, | |||||
{"true", 4, 4, json_tokener_continue, 1}, | |||||
{"true", 5, 4, json_tokener_success, 1}, | |||||
{"null", 4, 4, json_tokener_continue, 1}, | |||||
{"null", 5, 4, json_tokener_success, 1}, | |||||
{"Infinity", 9, 8, json_tokener_success, 1}, | |||||
{"infinity", 9, 8, json_tokener_success, 1}, | |||||
{"-infinity", 10, 9, json_tokener_success, 1}, | |||||
{"infinity", 9, 0, json_tokener_error_parse_unexpected, 3}, | |||||
{"-infinity", 10, 1, json_tokener_error_parse_unexpected, 3}, | |||||
{"inf", 3, 3, json_tokener_continue, 0}, | |||||
{"inity", 6, 5, json_tokener_success, 1}, | |||||
{"-inf", 4, 4, json_tokener_continue, 0}, | |||||
{"inity", 6, 5, json_tokener_success, 1}, | |||||
{"i", 1, 1, json_tokener_continue, 0}, | |||||
{"n", 1, 1, json_tokener_continue, 0}, | |||||
{"f", 1, 1, json_tokener_continue, 0}, | |||||
{"i", 1, 1, json_tokener_continue, 0}, | |||||
{"n", 1, 1, json_tokener_continue, 0}, | |||||
{"i", 1, 1, json_tokener_continue, 0}, | |||||
{"t", 1, 1, json_tokener_continue, 0}, | |||||
{"y", 1, 1, json_tokener_continue, 0}, | |||||
{"", 1, 0, json_tokener_success, 1}, | |||||
{"-", 1, 1, json_tokener_continue, 0}, | |||||
{"inf", 3, 3, json_tokener_continue, 0}, | |||||
{"ini", 3, 3, json_tokener_continue, 0}, | |||||
{"ty", 3, 2, json_tokener_success, 1}, | |||||
{"-", 1, 1, json_tokener_continue, 0}, | |||||
{"i", 1, 1, json_tokener_continue, 0}, | |||||
{"nfini", 5, 5, json_tokener_continue, 0}, | |||||
{"ty", 3, 2, json_tokener_success, 1}, | |||||
{"-i", 2, 2, json_tokener_continue, 0}, | |||||
{"nfinity", 8, 7, json_tokener_success, 1}, | |||||
{"InfinityX", 10, 8, json_tokener_success, 0}, | |||||
{"X", 1, 0, json_tokener_error_parse_unexpected, 1}, | |||||
{"Infinity1234", 13, 8, json_tokener_success, 0}, | |||||
{"1234", 5, 4, json_tokener_success, 1}, | |||||
{"Infinity9999", 8, 8, json_tokener_continue, 0}, | |||||
/* returns the Infinity loaded up by the previous call: */ | |||||
{"1234", 5, 0, json_tokener_success, 0}, | |||||
{"1234", 5, 4, json_tokener_success, 1}, | |||||
/* offset=1 because "n" is the start of "null". hmm... */ | |||||
{"noodle", 7, 1, json_tokener_error_parse_null, 1}, | |||||
/* offset=2 because "na" is the start of "nan". hmm... */ | |||||
{"naodle", 7, 2, json_tokener_error_parse_null, 1}, | |||||
/* offset=2 because "tr" is the start of "true". hmm... */ | |||||
{"track", 6, 2, json_tokener_error_parse_boolean, 1}, | |||||
{"fail", 5, 2, json_tokener_error_parse_boolean, 1}, | |||||
/* Although they may initially look like they should fail, | |||||
* the next few tests check that parsing multiple sequential | |||||
* json objects in the input works as expected | |||||
*/ | |||||
{"null123", 9, 4, json_tokener_success, 0}, | |||||
{&"null123"[4], 4, 3, json_tokener_success, 1}, | |||||
{"nullx", 5, 4, json_tokener_success, 0}, | |||||
{&"nullx"[4], 2, 0, json_tokener_error_parse_unexpected, 1}, | |||||
{"{\"a\":1}{\"b\":2}", 15, 7, json_tokener_success, 0}, | |||||
{&"{\"a\":1}{\"b\":2}"[7], 8, 7, json_tokener_success, 1}, | |||||
/* Some bad formatting. Check we get the correct error status */ | |||||
{"2015-01-15", 10, 4, json_tokener_error_parse_number, 1}, | |||||
/* Strings have a well defined end point, so we can stop at the quote */ | |||||
{"\"blue\"", -1, -1, json_tokener_success, 0}, | |||||
/* Check each of the escape sequences defined by the spec */ | |||||
{"\"\\\"\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\\\\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\b\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\f\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\n\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\r\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\t\"", -1, -1, json_tokener_success, 0}, | |||||
{"\"\\/\"", -1, -1, json_tokener_success, 0}, | |||||
// Escaping a forward slash is optional | |||||
{"\"/\"", -1, -1, json_tokener_success, 0}, | |||||
/* Check wrong escape sequences */ | |||||
{"\"\\a\"", -1, 2, json_tokener_error_parse_string, 1}, | |||||
/* Check '\'' in strict model */ | |||||
{"\'foo\'", -1, 0, json_tokener_error_parse_unexpected, 3}, | |||||
/* Parse array/object */ | |||||
{"[1,2,3]", -1, -1, json_tokener_success, 0}, | |||||
{"[1,2,3}", -1, 6, json_tokener_error_parse_array, 1}, | |||||
{"{\"a\"}", -1, 4, json_tokener_error_parse_object_key_sep, 1}, | |||||
{"{\"a\":1]", -1, 6, json_tokener_error_parse_object_value_sep, 1}, | |||||
{"{\"a\"::1}", -1, 5, json_tokener_error_parse_unexpected, 1}, | |||||
{"{\"a\":}", -1, 5, json_tokener_error_parse_unexpected, 1}, | |||||
{"{\"a\":1,\"a\":2}", -1, -1, json_tokener_success, 1}, | |||||
{"\"a\":1}", -1, 3, json_tokener_success, 1}, | |||||
{"{\"a\":1", -1, -1, json_tokener_continue, 1}, | |||||
{"[,]", -1, 1, json_tokener_error_parse_unexpected, 1}, | |||||
{"[,1]", -1, 1, json_tokener_error_parse_unexpected, 1}, | |||||
/* This behaviour doesn't entirely follow the json spec, but until we have | |||||
* a way to specify how strict to be we follow Postel's Law and be liberal | |||||
* in what we accept (up to a point). | |||||
*/ | |||||
{"[1,2,3,]", -1, -1, json_tokener_success, 0}, | |||||
{"[1,2,,3,]", -1, 5, json_tokener_error_parse_unexpected, 0}, | |||||
{"[1,2,3,]", -1, 7, json_tokener_error_parse_unexpected, 3}, | |||||
{"{\"a\":1,}", -1, 7, json_tokener_error_parse_unexpected, 3}, | |||||
// utf-8 test | |||||
// acsll encoding | |||||
{"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 5}, | |||||
{"\x22\x31\x32\x33\x61\x73\x63\x24\x25\x26\x22", -1, -1, json_tokener_success, 1}, | |||||
// utf-8 encoding | |||||
{"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 5}, | |||||
{"\x22\xe4\xb8", -1, 3, json_tokener_error_parse_utf8_string, 4}, | |||||
{"\x96\xe7\x95\x8c\x22", -1, 0, json_tokener_error_parse_utf8_string, 5}, | |||||
{"\x22\xe4\xb8\x96\xe7\x95\x8c\x22", -1, -1, json_tokener_success, 1}, | |||||
{"\x22\xcf\x80\xcf\x86\x22", -1, -1, json_tokener_success, 5}, | |||||
{"\x22\xf0\xa5\x91\x95\x22", -1, -1, json_tokener_success, 5}, | |||||
// wrong utf-8 encoding | |||||
{"\x22\xe6\x9d\x4e\x22", -1, 3, json_tokener_error_parse_utf8_string, 5}, | |||||
{"\x22\xe6\x9d\x4e\x22", -1, 5, json_tokener_success, 1}, | |||||
// GBK encoding | |||||
{"\x22\xc0\xee\xc5\xf4\x22", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||||
{"\x22\xc0\xee\xc5\xf4\x22", -1, 6, json_tokener_success, 1}, | |||||
// char after space | |||||
{"\x20\x20\x22\xe4\xb8\x96\x22", -1, -1, json_tokener_success, 5}, | |||||
{"\x20\x20\x81\x22\xe4\xb8\x96\x22", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||||
{"\x5b\x20\x81\x31\x5d", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||||
// char in state inf | |||||
{"\x49\x6e\x66\x69\x6e\x69\x74\x79", 9, 8, json_tokener_success, 1}, | |||||
{"\x49\x6e\x66\x81\x6e\x69\x74\x79", -1, 3, json_tokener_error_parse_utf8_string, 5}, | |||||
// 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\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}, | |||||
// char in number | |||||
{"\x31\x31\x81\x31\x31", -1, 2, json_tokener_error_parse_utf8_string, 5}, | |||||
// char in object | |||||
{"\x7b\x22\x31\x81\x22\x3a\x31\x7d", -1, 3, json_tokener_error_parse_utf8_string, 5}, | |||||
{NULL, -1, -1, json_tokener_success, 0}, | |||||
}; | }; | ||||
static void test_incremental_parse() | static void test_incremental_parse() | ||||
@@ -420,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(); | ||||
@@ -432,19 +436,19 @@ static void test_incremental_parse() | |||||
size_t expected_char_offset; | size_t expected_char_offset; | ||||
if (step->reset_tokener & 2) | if (step->reset_tokener & 2) | ||||
{ | |||||
if (step->reset_tokener & 4) | |||||
json_tokener_set_flags(tok, 3); | |||||
else | |||||
json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | |||||
} | |||||
{ | |||||
if (step->reset_tokener & 4) | |||||
json_tokener_set_flags(tok, 3); | |||||
else | |||||
json_tokener_set_flags(tok, JSON_TOKENER_STRICT); | |||||
} | |||||
else | else | ||||
{ | |||||
if (step->reset_tokener & 4) | |||||
json_tokener_set_flags(tok, JSON_TOKENER_VALIDATE_UTF8); | |||||
else | |||||
json_tokener_set_flags(tok, 0); | |||||
} | |||||
{ | |||||
if (step->reset_tokener & 4) | |||||
json_tokener_set_flags(tok, JSON_TOKENER_VALIDATE_UTF8); | |||||
else | |||||
json_tokener_set_flags(tok, 0); | |||||
} | |||||
if (length == -1) | if (length == -1) | ||||
length = strlen(step->string_to_parse); | length = strlen(step->string_to_parse); | ||||
@@ -453,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) ... ", | |||||
step->string_to_parse, length); | |||||
printf("json_tokener_parse_ex(tok, %-12s, %3d) ... ", step->string_to_parse, | |||||
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); | ||||
@@ -468,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), | |||||
expected_char_offset); | |||||
json_tokener_get_parse_end(tok), expected_char_offset); | |||||
else | else | ||||
{ | { | ||||
printf("OK: got correct error: %s\n", | printf("OK: got correct error: %s\n", | ||||
@@ -480,19 +483,17 @@ static void test_incremental_parse() | |||||
else | else | ||||
{ | { | ||||
if (new_obj == NULL && | if (new_obj == NULL && | ||||
!(step->length >= 4 && | |||||
strncmp(step->string_to_parse, "null", 4) == 0)) | |||||
!(step->length >= 4 && 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), | |||||
expected_char_offset); | |||||
json_tokener_get_parse_end(tok), expected_char_offset); | |||||
else | else | ||||
{ | { | ||||
printf("OK: got object of type [%s]: %s\n", | printf("OK: got object of type [%s]: %s\n", | ||||
json_type_to_name(json_object_get_type(new_obj)), | |||||
json_object_to_json_string(new_obj)); | |||||
json_type_to_name(json_object_get_type(new_obj)), | |||||
json_object_to_json_string(new_obj)); | |||||
this_step_ok = 1; | this_step_ok = 1; | ||||
} | } | ||||
} | } | ||||
@@ -35,7 +35,7 @@ int main() | |||||
{ | { | ||||
char buf[100]; | char buf[100]; | ||||
printf("==========json_parse_int64() test===========\n"); | |||||
printf("==========json_parse_int64() test===========\n"); | |||||
checkit("x"); | checkit("x"); | ||||
checkit("0"); | checkit("0"); | ||||
@@ -70,7 +70,7 @@ int main() | |||||
strcpy(buf, "4294967295"); // aka UINT32_MAX | strcpy(buf, "4294967295"); // aka UINT32_MAX | ||||
checkit(buf); | checkit(buf); | ||||
strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||||
strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||||
checkit(buf); | checkit(buf); | ||||
strcpy(buf, "21474836470"); // INT32_MAX * 10 | strcpy(buf, "21474836470"); // INT32_MAX * 10 | ||||
@@ -122,7 +122,7 @@ int main() | |||||
strcpy(buf, "123"); | strcpy(buf, "123"); | ||||
checkit(buf); | checkit(buf); | ||||
printf("\n==========json_parse_uint64() test===========\n"); | |||||
printf("\n==========json_parse_uint64() test===========\n"); | |||||
checkit_uint("x"); | checkit_uint("x"); | ||||
checkit_uint("0"); | checkit_uint("0"); | ||||
@@ -154,7 +154,7 @@ int main() | |||||
strcpy(buf, "4294967295"); // aka UINT32_MAX | strcpy(buf, "4294967295"); // aka UINT32_MAX | ||||
checkit_uint(buf); | checkit_uint(buf); | ||||
strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||||
strcpy(buf, "4294967296"); // aka UINT32_MAX + 1 | |||||
checkit_uint(buf); | checkit_uint(buf); | ||||
strcpy(buf, "21474836470"); // INT32_MAX * 10 | strcpy(buf, "21474836470"); // INT32_MAX * 10 | ||||
@@ -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" | ||||
@@ -78,7 +78,7 @@ static void test_printbuf_memappend(int *before_resize) | |||||
initial_size = pb->size; | initial_size = pb->size; | ||||
while(pb->size == initial_size) | |||||
while (pb->size == initial_size) | |||||
{ | { | ||||
printbuf_memappend_fast(pb, "x", 1); | printbuf_memappend_fast(pb, "x", 1); | ||||
} | } | ||||
@@ -89,7 +89,7 @@ static void test_printbuf_memappend(int *before_resize) | |||||
printbuf_memappend_fast(pb, "bluexyz123", 3); | printbuf_memappend_fast(pb, "bluexyz123", 3); | ||||
printf("Partial append: %d, [%s]\n", printbuf_length(pb), pb->buf); | printf("Partial append: %d, [%s]\n", printbuf_length(pb), pb->buf); | ||||
char with_nulls[] = { 'a', 'b', '\0', 'c' }; | |||||
char with_nulls[] = {'a', 'b', '\0', 'c'}; | |||||
printbuf_reset(pb); | printbuf_reset(pb); | ||||
printbuf_memappend_fast(pb, with_nulls, (int)sizeof(with_nulls)); | printbuf_memappend_fast(pb, with_nulls, (int)sizeof(with_nulls)); | ||||
printf("With embedded \\0 character: %d, [%s]\n", printbuf_length(pb), pb->buf); | printf("With embedded \\0 character: %d, [%s]\n", printbuf_length(pb), pb->buf); | ||||
@@ -118,7 +118,7 @@ static void test_printbuf_memappend(int *before_resize) | |||||
printbuf_strappend(pb, SA_TEST_STR); | printbuf_strappend(pb, SA_TEST_STR); | ||||
printf("Buffer size after printbuf_strappend(): %d, [%s]\n", printbuf_length(pb), pb->buf); | printf("Buffer size after printbuf_strappend(): %d, [%s]\n", printbuf_length(pb), pb->buf); | ||||
printbuf_free(pb); | printbuf_free(pb); | ||||
#undef SA_TEST_STR | |||||
#undef SA_TEST_STR | |||||
printf("%s: end test\n", __func__); | printf("%s: end test\n", __func__); | ||||
} | } | ||||
@@ -127,10 +127,11 @@ 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" | |||||
" with vasprintf. Note: some implementation of vsnprintf return -1 " | |||||
" if output is truncated whereas some return the number of bytes that " | |||||
" would have been written - this code handles both cases."; | |||||
const char *max_char = | |||||
"if string is greater than stack buffer, then use dynamic string" | |||||
" with vasprintf. Note: some implementation of vsnprintf return -1 " | |||||
" if output is truncated whereas some return the number of bytes that " | |||||
" would have been written - this code handles both cases."; | |||||
printf("%s: starting test\n", __func__); | printf("%s: starting test\n", __func__); | ||||
pb = printbuf_new(); | pb = printbuf_new(); | ||||
@@ -141,7 +142,8 @@ static void test_sprintbuf(int before_resize) | |||||
data[before_resize + 1] = '\0'; | data[before_resize + 1] = '\0'; | ||||
sprintbuf(pb, "%s", data); | sprintbuf(pb, "%s", data); | ||||
free(data); | free(data); | ||||
printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); | |||||
printf("sprintbuf to just after resize(%d+1): %d, [%s], strlen(buf)=%d\n", before_resize, | |||||
printbuf_length(pb), pb->buf, (int)strlen(pb->buf)); | |||||
printbuf_reset(pb); | printbuf_reset(pb); | ||||
sprintbuf(pb, "plain"); | sprintbuf(pb, "plain"); | ||||
@@ -5,7 +5,8 @@ | |||||
#include "json.h" | #include "json.h" | ||||
#include "printbuf.h" | #include "printbuf.h" | ||||
struct myinfo { | |||||
struct myinfo | |||||
{ | |||||
int value; | int value; | ||||
}; | }; | ||||
@@ -17,10 +18,7 @@ static void freeit(json_object *jso, void *userdata) | |||||
// Don't actually free anything here, the userdata is stack allocated. | // Don't actually free anything here, the userdata is stack allocated. | ||||
freeit_was_called = 1; | freeit_was_called = 1; | ||||
} | } | ||||
static int custom_serializer(struct json_object *o, | |||||
struct printbuf *pb, | |||||
int level, | |||||
int flags) | |||||
static int custom_serializer(struct json_object *o, struct printbuf *pb, int level, int flags) | |||||
{ | { | ||||
sprintbuf(pb, "Custom Output"); | sprintbuf(pb, "Custom Output"); | ||||
return 0; | return 0; | ||||
@@ -39,10 +37,11 @@ int main(int argc, char **argv) | |||||
printf("my_object.to_string(standard)=%s\n", json_object_to_json_string(my_object)); | printf("my_object.to_string(standard)=%s\n", json_object_to_json_string(my_object)); | ||||
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; | ||||
@@ -6,85 +6,85 @@ | |||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | { | ||||
json_object *tmp=json_object_new_int(123); | |||||
assert (json_object_get_int(tmp)==123); | |||||
json_object_set_int(tmp,321); | |||||
assert (json_object_get_int(tmp)==321); | |||||
json_object *tmp = json_object_new_int(123); | |||||
assert(json_object_get_int(tmp) == 123); | |||||
json_object_set_int(tmp, 321); | |||||
assert(json_object_get_int(tmp) == 321); | |||||
printf("INT PASSED\n"); | printf("INT PASSED\n"); | ||||
json_object_set_int64(tmp,(int64_t)321321321); | |||||
assert (json_object_get_int64(tmp)==321321321); | |||||
json_object_set_int64(tmp, (int64_t)321321321); | |||||
assert(json_object_get_int64(tmp) == 321321321); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("INT64 PASSED\n"); | printf("INT64 PASSED\n"); | ||||
tmp=json_object_new_uint64(123); | |||||
assert (json_object_get_boolean(tmp)==1); | |||||
assert (json_object_get_int(tmp)==123); | |||||
assert (json_object_get_int64(tmp)==123); | |||||
assert (json_object_get_uint64(tmp)==123); | |||||
assert (json_object_get_double(tmp)==123.000000); | |||||
json_object_set_uint64(tmp,(uint64_t)321321321); | |||||
assert (json_object_get_uint64(tmp)==321321321); | |||||
json_object_set_uint64(tmp,9223372036854775808U); | |||||
assert (json_object_get_int(tmp)==INT32_MAX); | |||||
assert (json_object_get_uint64(tmp)==9223372036854775808U); | |||||
tmp = json_object_new_uint64(123); | |||||
assert(json_object_get_boolean(tmp) == 1); | |||||
assert(json_object_get_int(tmp) == 123); | |||||
assert(json_object_get_int64(tmp) == 123); | |||||
assert(json_object_get_uint64(tmp) == 123); | |||||
assert(json_object_get_double(tmp) == 123.000000); | |||||
json_object_set_uint64(tmp, (uint64_t)321321321); | |||||
assert(json_object_get_uint64(tmp) == 321321321); | |||||
json_object_set_uint64(tmp, 9223372036854775808U); | |||||
assert(json_object_get_int(tmp) == INT32_MAX); | |||||
assert(json_object_get_uint64(tmp) == 9223372036854775808U); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("UINT64 PASSED\n"); | printf("UINT64 PASSED\n"); | ||||
tmp=json_object_new_boolean(1); | |||||
assert (json_object_get_boolean(tmp)==1); | |||||
json_object_set_boolean(tmp,0); | |||||
assert (json_object_get_boolean(tmp)==0); | |||||
json_object_set_boolean(tmp,1); | |||||
assert (json_object_get_boolean(tmp)==1); | |||||
tmp = json_object_new_boolean(1); | |||||
assert(json_object_get_boolean(tmp) == 1); | |||||
json_object_set_boolean(tmp, 0); | |||||
assert(json_object_get_boolean(tmp) == 0); | |||||
json_object_set_boolean(tmp, 1); | |||||
assert(json_object_get_boolean(tmp) == 1); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("BOOL PASSED\n"); | printf("BOOL PASSED\n"); | ||||
tmp=json_object_new_double(12.34); | |||||
assert (json_object_get_double(tmp)==12.34); | |||||
json_object_set_double(tmp,34.56); | |||||
assert (json_object_get_double(tmp)==34.56); | |||||
json_object_set_double(tmp,6435.34); | |||||
assert (json_object_get_double(tmp)==6435.34); | |||||
json_object_set_double(tmp,2e21); | |||||
assert (json_object_get_int(tmp)==INT32_MAX); | |||||
assert (json_object_get_int64(tmp)==INT64_MAX); | |||||
assert (json_object_get_uint64(tmp)==UINT64_MAX); | |||||
json_object_set_double(tmp,-2e21); | |||||
assert (json_object_get_int(tmp)==INT32_MIN); | |||||
assert (json_object_get_int64(tmp)==INT64_MIN); | |||||
assert (json_object_get_uint64(tmp)==0); | |||||
tmp = json_object_new_double(12.34); | |||||
assert(json_object_get_double(tmp) == 12.34); | |||||
json_object_set_double(tmp, 34.56); | |||||
assert(json_object_get_double(tmp) == 34.56); | |||||
json_object_set_double(tmp, 6435.34); | |||||
assert(json_object_get_double(tmp) == 6435.34); | |||||
json_object_set_double(tmp, 2e21); | |||||
assert(json_object_get_int(tmp) == INT32_MAX); | |||||
assert(json_object_get_int64(tmp) == INT64_MAX); | |||||
assert(json_object_get_uint64(tmp) == UINT64_MAX); | |||||
json_object_set_double(tmp, -2e21); | |||||
assert(json_object_get_int(tmp) == INT32_MIN); | |||||
assert(json_object_get_int64(tmp) == INT64_MIN); | |||||
assert(json_object_get_uint64(tmp) == 0); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("DOUBLE PASSED\n"); | printf("DOUBLE PASSED\n"); | ||||
#define SHORT "SHORT" | |||||
#define MID "A MID STRING" | |||||
// 12345678901234567890123456789012.... | |||||
#define HUGE "A string longer than 32 chars as to check non local buf codepath" | |||||
tmp=json_object_new_string(SHORT); | |||||
assert (strcmp(json_object_get_string(tmp),SHORT)==0); | |||||
json_object_set_string(tmp,MID); | |||||
assert (strcmp(json_object_get_string(tmp),MID)==0); | |||||
json_object_set_string(tmp,HUGE); | |||||
assert (strcmp(json_object_get_string(tmp),HUGE)==0); | |||||
json_object_set_string(tmp,SHORT); | |||||
assert (strcmp(json_object_get_string(tmp),SHORT)==0); | |||||
#define SHORT "SHORT" | |||||
#define MID "A MID STRING" | |||||
// 12345678901234567890123456789012.... | |||||
#define HUGE "A string longer than 32 chars as to check non local buf codepath" | |||||
tmp = json_object_new_string(SHORT); | |||||
assert(strcmp(json_object_get_string(tmp), SHORT) == 0); | |||||
json_object_set_string(tmp, MID); | |||||
assert(strcmp(json_object_get_string(tmp), MID) == 0); | |||||
json_object_set_string(tmp, HUGE); | |||||
assert(strcmp(json_object_get_string(tmp), HUGE) == 0); | |||||
json_object_set_string(tmp, SHORT); | |||||
assert(strcmp(json_object_get_string(tmp), SHORT) == 0); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("STRING PASSED\n"); | printf("STRING PASSED\n"); | ||||
#define STR "STR" | |||||
#define DOUBLE "123.123" | |||||
#define DOUBLE_E "12E+3" | |||||
#define DOUBLE_STR "123.123STR" | |||||
#define DOUBLE_OVER "1.8E+308" | |||||
#define DOUBLE_OVER_NEGATIVE "-1.8E+308" | |||||
tmp=json_object_new_string(STR); | |||||
assert (json_object_get_double(tmp)==0.0); | |||||
json_object_set_string(tmp,DOUBLE); | |||||
assert (json_object_get_double(tmp)==123.123000); | |||||
json_object_set_string(tmp,DOUBLE_E); | |||||
assert (json_object_get_double(tmp)==12000.000000); | |||||
json_object_set_string(tmp,DOUBLE_STR); | |||||
assert (json_object_get_double(tmp)==0.0); | |||||
json_object_set_string(tmp,DOUBLE_OVER); | |||||
assert (json_object_get_double(tmp)==0.0); | |||||
json_object_set_string(tmp,DOUBLE_OVER_NEGATIVE); | |||||
assert (json_object_get_double(tmp)==0.0); | |||||
#define STR "STR" | |||||
#define DOUBLE "123.123" | |||||
#define DOUBLE_E "12E+3" | |||||
#define DOUBLE_STR "123.123STR" | |||||
#define DOUBLE_OVER "1.8E+308" | |||||
#define DOUBLE_OVER_NEGATIVE "-1.8E+308" | |||||
tmp = json_object_new_string(STR); | |||||
assert(json_object_get_double(tmp) == 0.0); | |||||
json_object_set_string(tmp, DOUBLE); | |||||
assert(json_object_get_double(tmp) == 123.123000); | |||||
json_object_set_string(tmp, DOUBLE_E); | |||||
assert(json_object_get_double(tmp) == 12000.000000); | |||||
json_object_set_string(tmp, DOUBLE_STR); | |||||
assert(json_object_get_double(tmp) == 0.0); | |||||
json_object_set_string(tmp, DOUBLE_OVER); | |||||
assert(json_object_get_double(tmp) == 0.0); | |||||
json_object_set_string(tmp, DOUBLE_OVER_NEGATIVE); | |||||
assert(json_object_get_double(tmp) == 0.0); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("STRINGTODOUBLE PASSED\n"); | printf("STRINGTODOUBLE PASSED\n"); | ||||
@@ -92,7 +92,7 @@ int main(int argc, char **argv) | |||||
json_object_set_double(tmp, 12.3); | json_object_set_double(tmp, 12.3); | ||||
const char *serialized = json_object_to_json_string(tmp); | const char *serialized = json_object_to_json_string(tmp); | ||||
fprintf(stderr, "%s\n", serialized); | fprintf(stderr, "%s\n", serialized); | ||||
assert(strncmp(serialized, "12.3", 4)==0); | |||||
assert(strncmp(serialized, "12.3", 4) == 0); | |||||
json_object_put(tmp); | json_object_put(tmp); | ||||
printf("PARSE AND SET PASSED\n"); | printf("PARSE AND SET PASSED\n"); | ||||
@@ -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> | ||||
#endif /* defined(WIN32) */ | |||||
#include <windows.h> | |||||
#endif /* defined(WIN32) */ | |||||
#include <fcntl.h> | |||||
#include <limits.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 <fcntl.h> | |||||
#include <limits.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" | ||||
@@ -38,21 +38,20 @@ static void test_write_to_file() | |||||
json_object *jso; | json_object *jso; | ||||
jso = json_tokener_parse("{" | jso = json_tokener_parse("{" | ||||
"\"foo\":1234," | |||||
"\"foo1\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo2\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo3\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo4\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo5\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo6\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo7\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo8\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo9\":\"abcdefghijklmnopqrstuvwxyz\"" | |||||
"}"); | |||||
"\"foo\":1234," | |||||
"\"foo1\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo2\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo3\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo4\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo5\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo6\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo7\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo8\":\"abcdefghijklmnopqrstuvwxyz\"," | |||||
"\"foo9\":\"abcdefghijklmnopqrstuvwxyz\"" | |||||
"}"); | |||||
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", | |||||
(rv == 0) ? "OK" : "FAIL", outfile, rv); | |||||
printf("%s: json_object_to_file(%s, jso)=%d\n", (rv == 0) ? "OK" : "FAIL", outfile, rv); | |||||
if (rv == 0) | if (rv == 0) | ||||
stat_and_cat(outfile); | stat_and_cat(outfile); | ||||
@@ -66,7 +65,7 @@ static void test_write_to_file() | |||||
stat_and_cat(outfile2); | stat_and_cat(outfile2); | ||||
const char *outfile3 = "json3.out"; | const char *outfile3 = "json3.out"; | ||||
int d = open(outfile3, O_WRONLY|O_CREAT, 0600); | |||||
int d = open(outfile3, O_WRONLY | O_CREAT, 0600); | |||||
if (d < 0) | if (d < 0) | ||||
{ | { | ||||
printf("FAIL: unable to open %s %s\n", outfile3, strerror(errno)); | printf("FAIL: unable to open %s %s\n", outfile3, strerror(errno)); | ||||
@@ -92,19 +91,17 @@ 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", | |||||
file, strerror(errno)); | |||||
printf("FAIL: unable to open %s: %s\n", file, strerror(errno)); | |||||
return; | return; | ||||
} | } | ||||
if (fstat(d, &sb) < 0) | if (fstat(d, &sb) < 0) | ||||
{ | { | ||||
printf("FAIL: unable to stat %s: %s\n", | |||||
file, strerror(errno)); | |||||
printf("FAIL: unable to stat %s: %s\n", file, strerror(errno)); | |||||
close(d); | close(d); | ||||
return; | return; | ||||
} | } | ||||
char *buf = malloc(sb.st_size + 1); | char *buf = malloc(sb.st_size + 1); | ||||
if(!buf) | |||||
if (!buf) | |||||
{ | { | ||||
printf("FAIL: unable to allocate memory\n"); | printf("FAIL: unable to allocate memory\n"); | ||||
close(d); | close(d); | ||||
@@ -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", | |||||
file, strerror(errno)); | |||||
printf("FAIL: unable to read all of %s: %s\n", file, strerror(errno)); | |||||
free(buf); | free(buf); | ||||
close(d); | close(d); | ||||
return; | return; | ||||
@@ -126,8 +122,8 @@ static void stat_and_cat(const char *file) | |||||
int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
{ | { | ||||
// json_object_to_file(file, obj); | |||||
// json_object_to_file_ext(file, obj, flags); | |||||
// json_object_to_file(file, obj); | |||||
// json_object_to_file_ext(file, obj, flags); | |||||
_json_c_strerror_enable = 1; | _json_c_strerror_enable = 1; | ||||
@@ -135,9 +131,9 @@ int main(int argc, char **argv) | |||||
if (argc < 2) | if (argc < 2) | ||||
{ | { | ||||
fprintf(stderr, | fprintf(stderr, | ||||
"Usage: %s <testdir>\n" | |||||
" <testdir> is the location of input files\n", | |||||
argv[0]); | |||||
"Usage: %s <testdir>\n" | |||||
" <testdir> is the location of input files\n", | |||||
argv[0]); | |||||
return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
} | } | ||||
testdir = argv[1]; | testdir = argv[1]; | ||||
@@ -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, | |||||
"FAIL: unable to open %s: %s\n", | |||||
filename, strerror(errno)); | |||||
fprintf(stderr, "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", | |||||
json_object_to_json_string(jso)); | |||||
printf("OK: json_object_from_fd(valid.json)=%s\n", json_object_to_json_string(jso)); | |||||
json_object_put(jso); | json_object_put(jso); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
fprintf(stderr, | |||||
"FAIL: unable to parse contents of %s: %s\n", | |||||
filename, json_util_get_last_err()); | |||||
fprintf(stderr, "FAIL: unable to parse contents of %s: %s\n", 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, | |||||
"FAIL: unable to open %s: %s\n", | |||||
filename, strerror(errno)); | |||||
fprintf(stderr, "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, | |||||
"FAIL: unable to parse contents of %s: %s\n", | |||||
filename, json_util_get_last_err()); | |||||
fprintf(stderr, "FAIL: unable to parse contents of %s: %s\n", filename, | |||||
json_util_get_last_err()); | |||||
} | } | ||||
(void)lseek(d, SEEK_SET, 0); | (void)lseek(d, SEEK_SET, 0); | ||||
@@ -211,14 +200,15 @@ 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", | |||||
filename, json_object_to_json_string(jso)); | |||||
printf("FAIL: json_object_from_fd_ex(%s, 3)=%s\n", filename, | |||||
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", | |||||
json_util_get_last_err()); | |||||
printf("OK: correctly unable to parse contents of valid_nested.json with low max " | |||||
"depth: %s\n", | |||||
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", | |||||
filename, (void *)jso); | |||||
printf("FAIL: json_object_from_file(%s) returned %p when NULL expected\n", filename, | |||||
(void *)jso); | |||||
json_object_put(jso); | json_object_put(jso); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
printf("OK: json_object_from_file(%s) correctly returned NULL: %s\n", | |||||
filename, json_util_get_last_err()); | |||||
printf("OK: json_object_from_file(%s) correctly returned NULL: %s\n", filename, | |||||
json_util_get_last_err()); | |||||
} | } | ||||
} | } | ||||
@@ -245,7 +235,7 @@ static void test_read_closed() | |||||
{ | { | ||||
// Test reading from a closed fd | // Test reading from a closed fd | ||||
int d = open("/dev/null", O_RDONLY, 0); | int d = open("/dev/null", O_RDONLY, 0); | ||||
if(d < 0) | |||||
if (d < 0) | |||||
{ | { | ||||
puts("FAIL: unable to open"); | puts("FAIL: unable to open"); | ||||
} | } | ||||
@@ -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", | |||||
(void *)jso); | |||||
printf("FAIL: read from closed fd returning non-NULL: %p\n", (void *)jso); | |||||
fflush(stdout); | fflush(stdout); | ||||
printf(" jso=%s\n", json_object_to_json_string(jso)); | printf(" jso=%s\n", json_object_to_json_string(jso)); | ||||
json_object_put(jso); | json_object_put(jso); | ||||
@@ -1,8 +1,8 @@ | |||||
#include <assert.h> | |||||
#include <stddef.h> | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <stddef.h> | |||||
#include <string.h> | #include <string.h> | ||||
#include <assert.h> | |||||
#include "json.h" | #include "json.h" | ||||
#include "json_tokener.h" | #include "json_tokener.h" | ||||
@@ -68,24 +68,17 @@ int main(void) | |||||
return 0; | return 0; | ||||
} | } | ||||
static int emit_object(json_object *jso, int flags, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int emit_object(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
{ | { | ||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", | |||||
flags, | |||||
(jso_key ? jso_key : "(null)"), | |||||
(jso_index ? (long)*jso_index : -1L), | |||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | |||||
(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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int skip_arrays(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||||
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); | ||||
if (json_object_get_type(jso) == json_type_array) | if (json_object_get_type(jso) == json_type_array) | ||||
@@ -93,10 +86,8 @@ 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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int pop_and_stop(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||||
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); | ||||
if (jso_key != NULL && strcmp(jso_key, "subobj1") == 0) | if (jso_key != NULL && strcmp(jso_key, "subobj1") == 0) | ||||
@@ -112,10 +103,8 @@ 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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int err_on_subobj2(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||||
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); | ||||
if (jso_key != NULL && strcmp(jso_key, "subobj2") == 0) | if (jso_key != NULL && strcmp(jso_key, "subobj2") == 0) | ||||
@@ -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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
static int pop_array(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) | ||||
{ | { | ||||
(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,10 +127,8 @@ 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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int stop_array(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||||
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); | ||||
if (jso_index != NULL && (*jso_index == 0)) | if (jso_index != NULL && (*jso_index == 0)) | ||||
@@ -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, | |||||
json_object *parent_jso, | |||||
const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
static int err_return(json_object *jso, int flags, json_object *parent_jso, const char *jso_key, | |||||
size_t *jso_index, void *userarg) | |||||
{ | { | ||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", | |||||
flags, | |||||
(jso_key ? jso_key : "(null)"), | |||||
(jso_index ? (long)*jso_index : -1L), | |||||
printf("flags: 0x%x, key: %s, index: %ld, value: %s\n", flags, | |||||
(jso_key ? jso_key : "(null)"), (jso_index ? (long)*jso_index : -1L), | |||||
json_object_to_json_string(jso)); | json_object_to_json_string(jso)); | ||||
return 100; | return 100; | ||||
} | } |
@@ -18,24 +18,36 @@ 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; | |||||
#else /* !defined(WIN32) */ | |||||
chars = _vscprintf(fmt, ap) + 1; | |||||
#else /* !defined(WIN32) */ | |||||
/* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite | /* CAW: RAWR! We have to hope to god here that vsnprintf doesn't overwrite | ||||
our buffer like on some 64bit sun systems.... but hey, its time to move on */ | |||||
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap)+1; | |||||
if(chars < 0) { chars *= -1; } /* CAW: old glibc versions have this problem */ | |||||
* our buffer like on some 64bit sun systems.... but hey, its time to move on | |||||
*/ | |||||
chars = vsnprintf(&_T_emptybuffer, 0, fmt, ap) + 1; | |||||
if (chars < 0) | |||||
{ | |||||
chars *= -1; | |||||
} /* CAW: old glibc versions have this problem */ | |||||
#endif /* defined(WIN32) */ | #endif /* defined(WIN32) */ | ||||
b = (char*)malloc(sizeof(char)*chars); | |||||
if(!b) { return -1; } | |||||
b = (char *)malloc(sizeof(char) * chars); | |||||
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; | ||||
} | } | ||||