diff --git a/app/cjson/NEWS b/app/cjson/NEWS deleted file mode 100644 index 8927d6e5..00000000 --- a/app/cjson/NEWS +++ /dev/null @@ -1,44 +0,0 @@ -Version 2.1.0 (Mar 1 2012) -* Added cjson.safe module interface which returns nil after an error -* Improved Makefile compatibility with Solaris make - -Version 2.0.0 (Jan 22 2012) -* Improved platform compatibility for strtod/sprintf locale workaround -* Added option to build with David Gay's dtoa.c for improved performance -* Added support for Lua 5.2 -* Added option to encode infinity/NaN as JSON null -* Fixed encode bug with a raised default limit and deeply nested tables -* Updated Makefile for compatibility with non-GNU make implementations -* Added CMake build support -* Added HTML manual -* Increased default nesting limit to 1000 -* Added support for re-entrant use of encode and decode -* Added support for installing lua2json and json2lua utilities -* Added encode_invalid_numbers() and decode_invalid_numbers() -* Added decode_max_depth() -* Removed registration of global cjson module table -* Removed refuse_invalid_numbers() - -Version 1.0.4 (Nov 30 2011) -* Fixed numeric conversion under locales with a comma decimal separator - -Version 1.0.3 (Sep 15 2011) -* Fixed detection of objects with numeric string keys -* Provided work around for missing isinf() on Solaris - -Version 1.0.2 (May 30 2011) -* Portability improvements for Windows - - No longer links with -lm - - Use "socket" instead of "posix" for sub-second timing -* Removed UTF-8 test dependency on Perl Text::Iconv -* Added simple CLI commands for testing Lua <-> JSON conversions -* Added cjson.encode_number_precision() - -Version 1.0.1 (May 10 2011) -* Added build support for OSX -* Removed unnecessary whitespace from JSON output -* Added cjson.encode_keep_buffer() -* Fixed memory leak on Lua stack overflow exception - -Version 1.0 (May 9 2011) -* Initial release diff --git a/app/cjson/dtoa.c.bak b/app/cjson/dtoa.c similarity index 99% rename from app/cjson/dtoa.c.bak rename to app/cjson/dtoa.c index 56398ba7..ff1e744b 100644 --- a/app/cjson/dtoa.c.bak +++ b/app/cjson/dtoa.c @@ -184,7 +184,7 @@ * a decimal expansion to decide close cases. This logic is only * used for input more than STRTOD_DIGLIM digits long (default 40). */ - +#if 0 #include "dtoa_config.h" #ifndef Long @@ -4356,3 +4356,4 @@ dtoa #ifdef __cplusplus } #endif +#endif diff --git a/app/cjson/dtoa_config.h.bak b/app/cjson/dtoa_config.h similarity index 99% rename from app/cjson/dtoa_config.h.bak rename to app/cjson/dtoa_config.h index 380e83b0..483cf85b 100644 --- a/app/cjson/dtoa_config.h.bak +++ b/app/cjson/dtoa_config.h @@ -1,6 +1,6 @@ #ifndef _DTOA_CONFIG_H #define _DTOA_CONFIG_H - +#if 0 #include #include #include @@ -67,7 +67,7 @@ static pthread_mutex_t private_dtoa_lock[2] = { } while (0) #endif /* MULTIPLE_THREADS */ - +#endif #endif /* _DTOA_CONFIG_H */ /* vi:ai et sw=4 ts=4: diff --git a/app/cjson/g_fmt.c b/app/cjson/g_fmt.c index 50d6a1d3..2bf34a83 100644 --- a/app/cjson/g_fmt.c +++ b/app/cjson/g_fmt.c @@ -21,7 +21,7 @@ * it suffices to declare buf * char buf[32]; */ - +#if 0 #ifdef __cplusplus extern "C" { #endif @@ -109,3 +109,4 @@ fpconv_g_fmt(char *b, double x, int precision) #endif return b - b0; } +#endif diff --git a/app/cjson/lua-cjson-2.1devel-1.rockspec b/app/cjson/lua-cjson-2.1devel-1.rockspec deleted file mode 100644 index 154e333d..00000000 --- a/app/cjson/lua-cjson-2.1devel-1.rockspec +++ /dev/null @@ -1,56 +0,0 @@ -package = "lua-cjson" -version = "2.1devel-1" - -source = { - url = "http://www.kyne.com.au/~mark/software/download/lua-cjson-2.1devel.zip", -} - -description = { - summary = "A fast JSON encoding/parsing module", - detailed = [[ - The Lua CJSON module provides JSON support for Lua. It features: - - Fast, standards compliant encoding/parsing routines - - Full support for JSON with UTF-8, including decoding surrogate pairs - - Optional run-time support for common exceptions to the JSON specification - (infinity, NaN,..) - - No dependencies on other libraries - ]], - homepage = "http://www.kyne.com.au/~mark/software/lua-cjson.php", - license = "MIT" -} - -dependencies = { - "lua >= 5.1" -} - -build = { - type = "builtin", - modules = { - cjson = { - sources = { "lua_cjson.c", "strbuf.c", "fpconv.c" }, - defines = { --- LuaRocks does not support platform specific configuration for Solaris. --- Uncomment the line below on Solaris platforms if required. --- "USE_INTERNAL_ISINF" - } - } - }, - install = { - lua = { - ["cjson.util"] = "lua/cjson/util.lua" - }, - bin = { - json2lua = "lua/json2lua.lua", - lua2json = "lua/lua2json.lua" - } - }, - -- Override default build options (per platform) - platforms = { - win32 = { modules = { cjson = { defines = { - "DISABLE_INVALID_NUMBERS" - } } } } - }, - copy_directories = { "tests" } -} - --- vi:ai et sw=4 ts=4: diff --git a/app/cjson/lua-cjson.spec b/app/cjson/lua-cjson.spec deleted file mode 100644 index 13fc56d2..00000000 --- a/app/cjson/lua-cjson.spec +++ /dev/null @@ -1,80 +0,0 @@ -%define luaver 5.1 -%define lualibdir %{_libdir}/lua/%{luaver} -%define luadatadir %{_datadir}/lua/%{luaver} - -Name: lua-cjson -Version: 2.1devel -Release: 1%{?dist} -Summary: A fast JSON encoding/parsing module for Lua - -Group: Development/Libraries -License: MIT -URL: http://www.kyne.com.au/~mark/software/lua-cjson/ -Source0: http://www.kyne.com.au/~mark/software/lua-cjson/download/lua-cjson-%{version}.tar.gz -BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) - -BuildRequires: lua >= %{luaver}, lua-devel >= %{luaver} -Requires: lua >= %{luaver} - -%description -The Lua CJSON module provides JSON support for Lua. It features: -- Fast, standards compliant encoding/parsing routines -- Full support for JSON with UTF-8, including decoding surrogate pairs -- Optional run-time support for common exceptions to the JSON specification - (infinity, NaN,..) -- No dependencies on other libraries - - -%prep -%setup -q - - -%build -make %{?_smp_mflags} CFLAGS="%{optflags}" LUA_INCLUDE_DIR="%{_includedir}" - - -%install -rm -rf "$RPM_BUILD_ROOT" -make install DESTDIR="$RPM_BUILD_ROOT" LUA_CMODULE_DIR="%{lualibdir}" -make install-extra DESTDIR="$RPM_BUILD_ROOT" LUA_MODULE_DIR="%{luadatadir}" \ - LUA_BIN_DIR="%{_bindir}" - - -%clean -rm -rf "$RPM_BUILD_ROOT" - - -%preun -/bin/rm -f "%{luadatadir}/cjson/tests/utf8.dat" - - -%files -%defattr(-,root,root,-) -%doc LICENSE NEWS performance.html performance.txt manual.html manual.txt rfc4627.txt THANKS -%{lualibdir}/* -%{luadatadir}/* -%{_bindir}/* - - -%changelog -* Thu Mar 1 2012 Mark Pulford - 2.1.0-1 -- Update for 2.1.0 - -* Sun Jan 22 2012 Mark Pulford - 2.0.0-1 -- Update for 2.0.0 -- Install lua2json / json2lua utilities - -* Wed Nov 27 2011 Mark Pulford - 1.0.4-1 -- Update for 1.0.4 - -* Wed Sep 15 2011 Mark Pulford - 1.0.3-1 -- Update for 1.0.3 - -* Sun May 29 2011 Mark Pulford - 1.0.2-1 -- Update for 1.0.2 - -* Sun May 10 2011 Mark Pulford - 1.0.1-1 -- Update for 1.0.1 - -* Sun May 1 2011 Mark Pulford - 1.0-1 -- Initial package diff --git a/app/cjson/performance.txt b/app/cjson/performance.txt deleted file mode 100644 index fc3a5bb5..00000000 --- a/app/cjson/performance.txt +++ /dev/null @@ -1,89 +0,0 @@ -JSON module performance comparison under Lua -============================================ -Mark Pulford -:revdate: January 22, 2012 - -This performance comparison aims to provide a guide of relative -performance between several fast and popular JSON modules. - -The examples used in this comparison were mostly sourced from the -http://json.org[JSON website] and -http://tools.ietf.org/html/rfc4627[RFC 4627]. - -Performance will vary widely between platforms and data sets. These -results should only be used as an approximation. - - -Modules -------- - -The following JSON modules for Lua were tested: - -http://chiselapp.com/user/dhkolf/repository/dkjson/[DKJSON 2.1]:: - - Lua implementation with no dependencies on other libraries - - Supports LPeg to improve decode performance - -https://github.com/brimworks/lua-yajl[Lua YAJL 2.0]:: - - C wrapper for the YAJL library - -http://www.kyne.com.au/%7Emark/software/lua-cjson.php[Lua CSJON 2.0.0]:: - - C implementation with no dependencies on other libraries - - -Summary -------- - -All modules were built and tested as follows: - -DKJSON:: Tested with/without LPeg 10.2. -Lua YAJL:: Tested with YAJL 2.0.4. -Lua CJSON:: Tested with Libc and internal floating point conversion - routines. - -The following Lua implementations were used for this comparison: - -- http://www.lua.org[Lua 5.1.4] (_Lua_) -- http://www.luajit.org[LuaJIT 2.0.0-beta9] (_JIT_) - -These results show the number of JSON operations per second sustained by -each module. All results have been normalised against the pure Lua -DKJSON implementation. - -.Decoding performance -............................................................................ - | DKJSON | Lua YAJL | Lua CJSON - | No LPeg With LPeg | | Libc Internal - | Lua JIT Lua JIT | Lua JIT | Lua JIT Lua JIT -example1 | 1x 2x 2.6x 3.4x | 7.1x 10x | 14x 20x 14x 20x -example2 | 1x 2.2x 2.9x 4.4x | 6.7x 9.9x | 14x 22x 14x 22x -example3 | 1x 2.1x 3x 4.3x | 6.9x 9.3x | 14x 21x 15x 22x -example4 | 1x 2x 2.5x 3.7x | 7.3x 10x | 12x 19x 12x 20x -example5 | 1x 2.2x 3x 4.5x | 7.8x 11x | 16x 24x 16x 24x -numbers | 1x 2.2x 2.3x 4x | 4.6x 5.5x | 8.9x 10x 13x 17x -rfc-example1 | 1x 2.1x 2.8x 4.3x | 6.1x 8.1x | 13x 19x 14x 21x -rfc-example2 | 1x 2.1x 3.1x 4.2x | 7.1x 9.2x | 15x 21x 17x 24x -types | 1x 2.2x 2.6x 4.3x | 5.3x 7.4x | 12x 20x 13x 21x --------------|-------------------------|------------|----------------------- -= Average => | 1x 2.1x 2.7x 4.1x | 6.5x 9x | 13x 20x 14x 21x -............................................................................ - -.Encoding performance -............................................................................. - | DKJSON | Lua YAJL | Lua CJSON - | No LPeg With LPeg | | Libc Internal - | Lua JIT Lua JIT | Lua JIT | Lua JIT Lua JIT -example1 | 1x 1.8x 0.97x 1.6x | 3.1x 5.2x | 23x 29x 23x 29x -example2 | 1x 2x 0.97x 1.7x | 2.6x 4.3x | 22x 28x 22x 28x -example3 | 1x 1.9x 0.98x 1.6x | 2.8x 4.3x | 13x 15x 16x 18x -example4 | 1x 1.7x 0.96x 1.3x | 3.9x 6.1x | 15x 19x 17x 21x -example5 | 1x 2x 0.98x 1.7x | 2.7x 4.5x | 20x 23x 20x 23x -numbers | 1x 2.3x 1x 2.2x | 1.3x 1.9x | 3.8x 4.1x 4.2x 4.6x -rfc-example1 | 1x 1.9x 0.97x 1.6x | 2.2x 3.2x | 8.5x 9.3x 11x 12x -rfc-example2 | 1x 1.9x 0.98x 1.6x | 2.6x 3.9x | 10x 11x 17x 19x -types | 1x 2.2x 0.97x 2x | 1.2x 1.9x | 11x 13x 12x 14x --------------|-------------------------|------------|----------------------- -= Average => | 1x 1.9x 0.98x 1.7x | 2.5x 3.9x | 14x 17x 16x 19x -............................................................................. - - -// vi:ft=asciidoc tw=72: diff --git a/app/cjson/strbuf.c b/app/cjson/strbuf.c index c9528fa9..f4f36803 100644 --- a/app/cjson/strbuf.c +++ b/app/cjson/strbuf.c @@ -41,7 +41,7 @@ // exit(-1); // } -void strbuf_init(strbuf_t *s, int len) +int strbuf_init(strbuf_t *s, int len) { int size; @@ -61,10 +61,11 @@ void strbuf_init(strbuf_t *s, int len) s->buf = c_malloc(size); if (!s->buf){ NODE_ERR("not enough memory\n"); - return; + return -1; } strbuf_ensure_null(s); + return 0; } strbuf_t *strbuf_new(int len) @@ -74,7 +75,7 @@ strbuf_t *strbuf_new(int len) s = c_malloc(sizeof(strbuf_t)); if (!s){ NODE_ERR("not enough memory\n"); - return; + return NULL; } strbuf_init(s, len); @@ -85,16 +86,17 @@ strbuf_t *strbuf_new(int len) return s; } -void strbuf_set_increment(strbuf_t *s, int increment) +int strbuf_set_increment(strbuf_t *s, int increment) { /* Increment > 0: Linear buffer growth rate * Increment < -1: Exponential buffer growth rate */ if (increment == 0 || increment == -1){ NODE_ERR("BUG: Invalid string increment"); - return; + return -1; } s->increment = increment; + return 0; } static inline void debug_stats(strbuf_t *s) @@ -169,7 +171,7 @@ static int calculate_new_size(strbuf_t *s, int len) /* Ensure strbuf can handle a string length bytes long (ignoring NULL * optional termination). */ -void strbuf_resize(strbuf_t *s, int len) +int strbuf_resize(strbuf_t *s, int len) { int newsize; @@ -180,13 +182,14 @@ void strbuf_resize(strbuf_t *s, int len) (long)s, s->size, newsize); } - s->size = newsize; - s->buf = (char *)c_realloc(s->buf, s->size); + s->buf = (char *)c_realloc(s->buf, newsize); if (!s->buf){ NODE_ERR("not enough memory"); - return; + return -1; } + s->size = newsize; s->reallocs++; + return 0; } void strbuf_append_string(strbuf_t *s, const char *str) diff --git a/app/cjson/strbuf.h b/app/cjson/strbuf.h index e6044be6..aa1f8c5d 100644 --- a/app/cjson/strbuf.h +++ b/app/cjson/strbuf.h @@ -50,15 +50,15 @@ typedef struct { /* Initialise */ extern strbuf_t *strbuf_new(int len); -extern void strbuf_init(strbuf_t *s, int len); -extern void strbuf_set_increment(strbuf_t *s, int increment); +extern int strbuf_init(strbuf_t *s, int len); +extern int strbuf_set_increment(strbuf_t *s, int increment); /* Release */ extern void strbuf_free(strbuf_t *s); extern char *strbuf_free_to_string(strbuf_t *s, int *len); /* Management */ -extern void strbuf_resize(strbuf_t *s, int len); +extern int strbuf_resize(strbuf_t *s, int len); static int strbuf_empty_length(strbuf_t *s); static int strbuf_length(strbuf_t *s); static char *strbuf_string(strbuf_t *s, int *len); @@ -127,13 +127,13 @@ static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c) static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len) { strbuf_ensure_empty_length(s, len); - memcpy(s->buf + s->length, c, len); + c_memcpy(s->buf + s->length, c, len); s->length += len; } static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len) { - memcpy(s->buf + s->length, c, len); + c_memcpy(s->buf + s->length, c, len); s->length += len; } diff --git a/app/modules/cjson.c b/app/modules/cjson.c index 361c5fa3..15c263db 100644 --- a/app/modules/cjson.c +++ b/app/modules/cjson.c @@ -42,6 +42,7 @@ #include "c_limits.h" #include "lua.h" #include "lauxlib.h" +#include "flash_api.h" #include "strbuf.h" #ifdef LUA_NUMBER_INTEGRAL @@ -50,7 +51,6 @@ #define FPCONV_G_FMT_BUFSIZE 32 #define fpconv_strtod c_strtod #define fpconv_init() ((void)0) -#define fpconv_g_fmt fpconv_g_fmt #endif #ifndef CJSON_MODNAME @@ -73,7 +73,7 @@ #define DEFAULT_DECODE_MAX_DEPTH 1000 #define DEFAULT_ENCODE_INVALID_NUMBERS 0 #define DEFAULT_DECODE_INVALID_NUMBERS 1 -#define DEFAULT_ENCODE_KEEP_BUFFER 1 +#define DEFAULT_ENCODE_KEEP_BUFFER 0 #define DEFAULT_ENCODE_NUMBER_PRECISION 14 #ifdef DISABLE_INVALID_NUMBERS @@ -97,7 +97,7 @@ typedef enum { T_ERROR, T_UNKNOWN } json_token_type_t; - +#if 0 static const char *json_token_type_name[] = { "T_OBJ_BEGIN", "T_OBJ_END", @@ -115,10 +115,27 @@ static const char *json_token_type_name[] = { "T_UNKNOWN", NULL }; +#endif +static const char json_token_type_name[14][16] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = { + {'T','_','O','B','J','_','B','E','G','I','N',0}, + {'T','_','O','B','J','_','E','N','D',0}, + {'T','_','A','R','R','_','B','E','G','I','N',0}, + {'T','_','A','R','R','_','E','N','D',0}, + {'T','_','S','T','R','I','N','G',0}, + {'T','_','N','U','M','B','E','R',0}, + {'T','_','B','O','O','L','E','A','N',0}, + {'T','_','N','U','L','L',0}, + {'T','_','C','O','L','O','N',0}, + {'T','_','C','O','M','M','A',0}, + {'T','_','E','N','D',0}, + {'T','_','W','H','I','T','E','S','P','A','C','E',0}, + {'T','_','E','R','R','O','R',0}, + {'T','_','U','N','K','N','O','W','N',0} +}; typedef struct { - json_token_type_t ch2token[256]; - char escape2char[256]; /* Decoding */ + // json_token_type_t ch2token[256]; // 256*4 = 1024 byte + // char escape2char[256]; /* Decoding */ /* encode_buf is only allocated and used when * encode_keep_buffer is set */ @@ -155,6 +172,7 @@ typedef struct { int string_len; } json_token_t; +#if 0 static const char *char2escape[256] = { "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", @@ -193,6 +211,99 @@ static const char *char2escape[256] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; +#endif + +/* ===== HELPER FUNCTION ===== */ +static const char escape_array[36][8] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = { + {'\\','u','0','0','0','0','\0','\0'}, + {'\\','u','0','0','0','1','\0','\0'}, + {'\\','u','0','0','0','2','\0','\0'}, + {'\\','u','0','0','0','3','\0','\0'}, + {'\\','u','0','0','0','4','\0','\0'}, + {'\\','u','0','0','0','5','\0','\0'}, + {'\\','u','0','0','0','6','\0','\0'}, + {'\\','u','0','0','0','7','\0','\0'}, + {'\\','b','\0','\0','\0','\0','\0','\0'}, + {'\\','t','\0','\0','\0','\0','\0','\0'}, + {'\\','n','\0','\0','\0','\0','\0','\0'}, + {'\\','u','0','0','0','b','\0','\0'}, + {'\\','f','\0','\0','\0','\0','\0','\0'}, + {'\\','r','\0','\0','\0','\0','\0','\0'}, + {'\\','u','0','0','0','e','\0','\0'}, + {'\\','u','0','0','0','f','\0','\0'}, + {'\\','u','0','0','1','0','\0','\0'}, + {'\\','u','0','0','1','1','\0','\0'}, + {'\\','u','0','0','1','2','\0','\0'}, + {'\\','u','0','0','1','3','\0','\0'}, + {'\\','u','0','0','1','4','\0','\0'}, + {'\\','u','0','0','1','5','\0','\0'}, + {'\\','u','0','0','1','6','\0','\0'}, + {'\\','u','0','0','1','7','\0','\0'}, + {'\\','u','0','0','1','8','\0','\0'}, + {'\\','u','0','0','1','9','\0','\0'}, + {'\\','u','0','0','1','a','\0','\0'}, + {'\\','u','0','0','1','b','\0','\0'}, + {'\\','u','0','0','1','c','\0','\0'}, + {'\\','u','0','0','1','d','\0','\0'}, + {'\\','u','0','0','1','e','\0','\0'}, + {'\\','u','0','0','1','f','\0','\0'}, + {'\\','\"','\0','\0','\0','\0','\0','\0'}, + {'\\','/','\0','\0','\0','\0','\0','\0'}, + {'\\','\\','\0','\0','\0','\0','\0','\0'}, + {'\\','u','0','0','7','f','\0','\0'} +}; + +static const char *char2escape(unsigned char c){ + if(c<32) return escape_array[c]; + + switch(c){ + case 34: return escape_array[32]; + case 47: return escape_array[33]; + case 92: return escape_array[34]; + case 127: return escape_array[35]; + default: + return NULL; + } +} + +static json_token_type_t ch2token(unsigned char c){ + switch(c){ + case '{': return T_OBJ_BEGIN; + case '}': return T_OBJ_END; + case '[': return T_ARR_BEGIN; + case ']': return T_ARR_END; + case ',': return T_COMMA; + case ':': return T_COLON; + case '\0': return T_END; + case ' ': return T_WHITESPACE; + case '\t': return T_WHITESPACE; + case '\n': return T_WHITESPACE; + case '\r': return T_WHITESPACE; + + /* Update characters that require further processing */ + case 'f': case 'i': case 'I': case 'n': case 'N': case 't': case '"': case '+': case '-': + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + return T_UNKNOWN; + default: + return T_ERROR; + } +} + +static char escape2char(unsigned char c){ + switch(c){ + case '"': return '"'; + case '\\': return '\\'; + case '/': return '/'; + case 'b': return '\b'; + case 't': return '\t'; + case 'n': return '\n'; + case 'f': return '\f'; + case 'r': return '\r'; + case 'u': return 'u'; + default: + return 0; + } +} /* ===== CONFIGURATION ===== */ #if 0 @@ -319,8 +430,10 @@ static int json_cfg_encode_keep_buffer(lua_State *l) /* Init / free the buffer if the setting has changed */ if (old_value ^ cfg->encode_keep_buffer) { - if (cfg->encode_keep_buffer) - strbuf_init(&cfg->encode_buf, 0); + if (cfg->encode_keep_buffer){ + if(-1==strbuf_init(&cfg->encode_buf, 0)) + return luaL_error(l, "not enough memory"); + } else strbuf_free(&cfg->encode_buf); } @@ -456,9 +569,7 @@ static json_config_t *json_fetch_config(lua_State *l) return &_cfg; } -static void cfg_init(json_config_t *cfg){ - int i; - +static int cfg_init(json_config_t *cfg){ cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; @@ -470,53 +581,13 @@ static void cfg_init(json_config_t *cfg){ cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; #if DEFAULT_ENCODE_KEEP_BUFFER > 0 - strbuf_init(&cfg->encode_buf, 0); + if(-1==strbuf_init(&cfg->encode_buf, 0)){ + NODE_ERR("not enough memory\n"); + return -1; + } #endif - /* Decoding init */ - - /* Tag all characters as an error */ - for (i = 0; i < 256; i++) - cfg->ch2token[i] = T_ERROR; - - /* Set tokens that require no further processing */ - cfg->ch2token['{'] = T_OBJ_BEGIN; - cfg->ch2token['}'] = T_OBJ_END; - cfg->ch2token['['] = T_ARR_BEGIN; - cfg->ch2token[']'] = T_ARR_END; - cfg->ch2token[','] = T_COMMA; - cfg->ch2token[':'] = T_COLON; - cfg->ch2token['\0'] = T_END; - cfg->ch2token[' '] = T_WHITESPACE; - cfg->ch2token['\t'] = T_WHITESPACE; - cfg->ch2token['\n'] = T_WHITESPACE; - cfg->ch2token['\r'] = T_WHITESPACE; - - /* Update characters that require further processing */ - cfg->ch2token['f'] = T_UNKNOWN; /* false? */ - cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */ - cfg->ch2token['I'] = T_UNKNOWN; - cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */ - cfg->ch2token['N'] = T_UNKNOWN; - cfg->ch2token['t'] = T_UNKNOWN; /* true? */ - cfg->ch2token['"'] = T_UNKNOWN; /* string? */ - cfg->ch2token['+'] = T_UNKNOWN; /* number? */ - cfg->ch2token['-'] = T_UNKNOWN; - for (i = 0; i < 10; i++) - cfg->ch2token['0' + i] = T_UNKNOWN; - - /* Lookup table for parsing escape characters */ - for (i = 0; i < 256; i++) - cfg->escape2char[i] = 0; /* String error */ - cfg->escape2char['"'] = '"'; - cfg->escape2char['\\'] = '\\'; - cfg->escape2char['/'] = '/'; - cfg->escape2char['b'] = '\b'; - cfg->escape2char['t'] = '\t'; - cfg->escape2char['n'] = '\n'; - cfg->escape2char['f'] = '\f'; - cfg->escape2char['r'] = '\r'; - cfg->escape2char['u'] = 'u'; /* Unicode parsing required */ + return 0; } /* ===== ENCODING ===== */ @@ -552,9 +623,18 @@ static void json_append_string(lua_State *l, strbuf_t *json, int lindex) strbuf_append_char_unsafe(json, '\"'); for (i = 0; i < len; i++) { - escstr = char2escape[(unsigned char)str[i]]; - if (escstr) + escstr = char2escape((unsigned char)str[i]); + if (escstr){ + int i; + char temp[8]; // for now, 8-bytes is enough. + for (i=0; i < 8; ++i) + { + temp[i] = byte_of_aligned_array(escstr, i); + if(temp[i]==0) break; + } + escstr = temp; strbuf_append_string(json, escstr); + } else strbuf_append_char_unsafe(json, str[i]); } @@ -694,7 +774,12 @@ static void json_append_number(lua_State *l, json_config_t *cfg, } strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); +#ifdef LUA_NUMBER_INTEGRAL len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision); +#else + c_sprintf(strbuf_empty_ptr(json), "%.14g", num); + len = c_strlen(strbuf_empty_ptr(json)); +#endif strbuf_extend_length(json, len); } @@ -796,7 +881,8 @@ static int json_encode(lua_State *l) if (!cfg->encode_keep_buffer) { /* Use private buffer */ encode_buf = &local_encode_buf; - strbuf_init(encode_buf, 0); + if(-1==strbuf_init(encode_buf, 0)) + return luaL_error(l, "not enough memory"); } else { /* Reuse existing buffer */ encode_buf = &cfg->encode_buf; @@ -967,7 +1053,7 @@ static void json_set_token_error(json_token_t *token, json_parse_t *json, static void json_next_string_token(json_parse_t *json, json_token_t *token) { - char *escape2char = json->cfg->escape2char; + // char *escape2char = json->cfg->escape2char; char ch; /* Caller must ensure a string is next */ @@ -995,7 +1081,7 @@ static void json_next_string_token(json_parse_t *json, json_token_t *token) ch = *(json->ptr + 1); /* Translate escape code and append to tmp string */ - ch = escape2char[(unsigned char)ch]; + ch = escape2char((unsigned char)ch); if (ch == 'u') { if (json_append_unicode_escape(json) == 0) continue; @@ -1107,13 +1193,13 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token) */ static void json_next_token(json_parse_t *json, json_token_t *token) { - const json_token_type_t *ch2token = json->cfg->ch2token; + // const json_token_type_t *ch2token = json->cfg->ch2token; int ch; /* Eat whitespace. */ while (1) { ch = (unsigned char)*(json->ptr); - token->type = ch2token[ch]; + token->type = ch2token(ch); if (token->type != T_WHITESPACE) break; json->ptr++; @@ -1194,13 +1280,23 @@ static void json_throw_parse_error(lua_State *l, json_parse_t *json, const char *exp, json_token_t *token) { const char *found; + char temp[16]; // for now, 16-bytes is enough. strbuf_free(json->tmp); if (token->type == T_ERROR) found = token->value.string; else + { found = json_token_type_name[token->type]; + int i; + for (i=0; i < 16; ++i) + { + temp[i] = byte_of_aligned_array(found, i); + if(temp[i]==0) break; + } + found = temp; + } /* Note: token->index is 0 based, display starting from 1 */ luaL_error(l, "Expected %s but found %s at character %d", @@ -1369,6 +1465,9 @@ static int json_decode(lua_State *l) * This means we no longer need to do length checks since the decoded * string must be smaller than the entire json string */ json.tmp = strbuf_new(json_len); + if(json.tmp == NULL){ + return luaL_error(l, "not enought memory"); + } json_next_token(&json, &token); json_process_value(l, &json, &token); @@ -1434,6 +1533,7 @@ static int json_protect_conversion(lua_State *l) return luaL_error(l, "Memory allocation error in CJSON protected call"); } #endif + // Module function map #define MIN_OPT_LEVEL 2 #include "lrodefs.h" @@ -1459,7 +1559,9 @@ LUALIB_API int luaopen_cjson( lua_State *L ) { /* Initialise number conversions */ fpconv_init(); - cfg_init(&_cfg); + if(-1==cfg_init(&_cfg)){ + return luaL_error(L, "BUG: Unable to init config for cjson");; + } #if LUA_OPTIMIZE_MEMORY > 0 return 0; #else // #if LUA_OPTIMIZE_MEMORY > 0