Browse Source

fix json format issue

pull/4/merge
Max Lv 11 years ago
parent
commit
c06c1495fb
3 changed files with 95 additions and 44 deletions
  1. 10
      src/jconf.c
  2. 85
      src/json.c
  3. 44
      src/json.h

10
src/jconf.c

@ -50,16 +50,20 @@ jconf_t *read_jconf(const char* file) {
if (pos >= MAX_CONF_SIZE) FATAL("Too large config file."); if (pos >= MAX_CONF_SIZE) FATAL("Too large config file.");
buf = malloc(pos);
buf = malloc(pos + 1);
if (buf == NULL) FATAL("No enough memory."); if (buf == NULL) FATAL("No enough memory.");
fread(buf, pos, 1, f); fread(buf, pos, 1, f);
fclose(f); fclose(f);
obj = json_parse(buf);
buf[pos] = '\0'; // end of string
json_settings settings = { 0 };
char error_buf[512];
obj = json_parse_ex(&settings, buf, pos, error_buf);
if (obj == NULL) { if (obj == NULL) {
FATAL("Invalid config file");
FATAL(error_buf);
} }
if (obj->type == json_object) { if (obj->type == json_object) {

85
src/json.c

@ -42,7 +42,6 @@
const struct _json_value json_value_none = { 0 }; const struct _json_value json_value_none = { 0 };
#endif #endif
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
@ -66,20 +65,28 @@ static unsigned char hex_value (json_char c)
typedef struct typedef struct
{ {
json_settings settings;
int first_pass;
unsigned long used_memory; unsigned long used_memory;
unsigned int uint_max; unsigned int uint_max;
unsigned long ulong_max; unsigned long ulong_max;
json_settings settings;
int first_pass;
} json_state; } json_state;
static void * json_alloc (json_state * state, unsigned long size, int zero)
static void * default_alloc (size_t size, int zero, void * user_data)
{
return zero ? calloc (size, 1) : malloc (size);
}
static void default_free (void * ptr, void * user_data)
{ {
void * mem;
free (ptr);
}
static void * json_alloc (json_state * state, unsigned long size, int zero)
{
if ((state->ulong_max - state->used_memory) < size) if ((state->ulong_max - state->used_memory) < size)
return 0; return 0;
@ -89,10 +96,7 @@ static void * json_alloc (json_state * state, unsigned long size, int zero)
return 0; return 0;
} }
if (! (mem = zero ? calloc (size, 1) : malloc (size)))
return 0;
return mem;
return state->settings.mem_alloc (size, zero, state->settings.user_data);
} }
static int new_value static int new_value
@ -190,21 +194,31 @@ const static long
flag_num_negative = 256, flag_num_zero = 512, flag_num_e = 1024, flag_num_negative = 256, flag_num_zero = 512, flag_num_e = 1024,
flag_num_e_got_sign = 2048, flag_num_e_negative = 4096; flag_num_e_got_sign = 2048, flag_num_e_negative = 4096;
json_value * json_parse_ex (json_settings * settings, const json_char * json, char * error_buf)
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error_buf)
{ {
json_char error [128]; json_char error [128];
unsigned int cur_line; unsigned int cur_line;
const json_char * cur_line_begin, * i;
const json_char * cur_line_begin, * i, * end;
json_value * top, * root, * alloc = 0; json_value * top, * root, * alloc = 0;
json_state state;
json_state state = { 0 };
long flags; long flags;
long num_digits, num_fraction, num_e;
long num_digits, num_e;
json_int_t num_fraction;
error[0] = '\0'; error[0] = '\0';
end = (json + length);
memset (&state, 0, sizeof (json_state));
memcpy (&state.settings, settings, sizeof (json_settings)); memcpy (&state.settings, settings, sizeof (json_settings));
if (!state.settings.mem_alloc)
state.settings.mem_alloc = default_alloc;
if (!state.settings.mem_free)
state.settings.mem_free = default_free;
memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); memset (&state.uint_max, 0xFF, sizeof (state.uint_max));
memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max)); memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max));
@ -226,7 +240,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
for (i = json ;; ++ i) for (i = json ;; ++ i)
{ {
json_char b = *i;
json_char b = (json == end ? 0 : *i);
if (flags & flag_done) if (flags & flag_done)
{ {
@ -440,7 +454,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 't': case 't':
if (*(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
if ((end - i) < 3 || *(++ i) != 'r' || *(++ i) != 'u' || *(++ i) != 'e')
goto e_unknown_value; goto e_unknown_value;
if (!new_value (&state, &top, &root, &alloc, json_boolean)) if (!new_value (&state, &top, &root, &alloc, json_boolean))
@ -453,7 +467,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 'f': case 'f':
if (*(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
if ((end - i) < 4 || *(++ i) != 'a' || *(++ i) != 'l' || *(++ i) != 's' || *(++ i) != 'e')
goto e_unknown_value; goto e_unknown_value;
if (!new_value (&state, &top, &root, &alloc, json_boolean)) if (!new_value (&state, &top, &root, &alloc, json_boolean))
@ -464,7 +478,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
case 'n': case 'n':
if (*(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
if ((end - i) < 3 || *(++ i) != 'u' || *(++ i) != 'l' || *(++ i) != 'l')
goto e_unknown_value; goto e_unknown_value;
if (!new_value (&state, &top, &root, &alloc, json_null)) if (!new_value (&state, &top, &root, &alloc, json_null))
@ -617,7 +631,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
} }
top->type = json_double; top->type = json_double;
top->u.dbl = top->u.integer;
top->u.dbl = (double) top->u.integer;
num_digits = 0; num_digits = 0;
continue; continue;
@ -642,7 +656,7 @@ json_value * json_parse_ex (json_settings * settings, const json_char * json, ch
if (top->type == json_integer) if (top->type == json_integer)
{ {
top->type = json_double; top->type = json_double;
top->u.dbl = top->u.integer;
top->u.dbl = (double) top->u.integer;
} }
num_digits = 0; num_digits = 0;
@ -768,25 +782,23 @@ e_failed:
while (alloc) while (alloc)
{ {
top = alloc->_reserved.next_alloc; top = alloc->_reserved.next_alloc;
free (alloc);
state.settings.mem_free (alloc, state.settings.user_data);
alloc = top; alloc = top;
} }
if (!state.first_pass) if (!state.first_pass)
json_value_free (root);
json_value_free_ex (&state.settings, root);
return 0; return 0;
} }
json_value * json_parse (const json_char * json)
json_value * json_parse (const json_char * json, size_t length)
{ {
json_settings settings;
memset (&settings, 0, sizeof (json_settings));
return json_parse_ex (&settings, json, 0);
json_settings settings = { 0 };
return json_parse_ex (&settings, json, length, 0);
} }
void json_value_free (json_value * value)
void json_value_free_ex (json_settings * settings, json_value * value)
{ {
json_value * cur_value; json_value * cur_value;
@ -803,7 +815,7 @@ void json_value_free (json_value * value)
if (!value->u.array.length) if (!value->u.array.length)
{ {
free (value->u.array.values);
settings->mem_free (value->u.array.values, settings->user_data);
break; break;
} }
@ -814,7 +826,7 @@ void json_value_free (json_value * value)
if (!value->u.object.length) if (!value->u.object.length)
{ {
free (value->u.object.values);
settings->mem_free (value->u.object.values, settings->user_data);
break; break;
} }
@ -823,7 +835,7 @@ void json_value_free (json_value * value)
case json_string: case json_string:
free (value->u.string.ptr);
settings->mem_free (value->u.string.ptr, settings->user_data);
break; break;
default: default:
@ -832,7 +844,14 @@ void json_value_free (json_value * value)
cur_value = value; cur_value = value;
value = value->parent; value = value->parent;
free (cur_value);
settings->mem_free (cur_value, settings->user_data);
} }
} }
void json_value_free (json_value * value)
{
json_settings settings = { 0 };
settings.mem_free = default_free;
json_value_free_ex (&settings, value);
}

44
src/json.h

@ -35,6 +35,17 @@
#define json_char char #define json_char char
#endif #endif
#ifndef json_int_t
#ifndef _MSC_VER
#include <inttypes.h>
#define json_int_t int64_t
#else
#define json_int_t __int64
#endif
#endif
#include <stdlib.h>
#ifdef __cplusplus #ifdef __cplusplus
#include <string.h> #include <string.h>
@ -49,6 +60,14 @@ typedef struct
unsigned long max_memory; unsigned long max_memory;
int settings; int settings;
/* Custom allocator support (leave null to use malloc/free)
*/
void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);
void * user_data; /* will be passed to mem_alloc and mem_free */
} json_settings; } json_settings;
#define json_relaxed_commas 1 #define json_relaxed_commas 1
@ -77,7 +96,7 @@ typedef struct _json_value
union union
{ {
int boolean; int boolean;
long integer;
json_int_t integer;
double dbl; double dbl;
struct struct
@ -162,7 +181,7 @@ typedef struct _json_value
}; };
} }
inline operator long () const
inline operator json_int_t () const
{ {
switch (type) switch (type)
{ {
@ -170,7 +189,7 @@ typedef struct _json_value
return u.integer; return u.integer;
case json_double: case json_double:
return (long) u.dbl;
return (json_int_t) u.dbl;
default: default:
return 0; return 0;
@ -190,7 +209,7 @@ typedef struct _json_value
switch (type) switch (type)
{ {
case json_integer: case json_integer:
return u.integer;
return (double) u.integer;
case json_double: case json_double:
return u.dbl; return u.dbl;
@ -204,15 +223,24 @@ typedef struct _json_value
} json_value; } json_value;
json_value * json_parse
(const json_char * json);
json_value * json_parse (const json_char * json,
size_t length);
json_value * json_parse_ex
(json_settings * settings, const json_char * json, char * error);
json_value * json_parse_ex (json_settings * settings,
const json_char * json,
size_t length,
char * error);
void json_value_free (json_value *); void json_value_free (json_value *);
/* Not usually necessary, unless you used a custom mem_alloc and now want to
* use a custom mem_free.
*/
void json_value_free_ex (json_settings * settings,
json_value *);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

Loading…
Cancel
Save