webmcp
view libraries/json/json.c @ 182:b460ae08dd78
json.import does support even more nested levels
| author | jbe | 
|---|---|
| date | Sat Aug 02 02:53:32 2014 +0200 (2014-08-02) | 
| parents | c2e76617c26c | 
| children | f7c1869b5b32 | 
 line source
     1 #include <lua.h>
     2 #include <lauxlib.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     5 #include <math.h>
     7 // maximum number of nested JSON values (objects and arrays):
     8 // NOTE: json_import can store 2^32 / 3 levels on stack swap (using
     9 //       also negative indicies after integer wraparound), so
    10 //       1024^3 = 1073741824 is a safe value.
    11 #define JSON_MAXDEPTH (1024*1024*1024)
    12 // NOTE: As long as the function json_export_internal is implemented
    13 //       recursively, JSON_MAXDEPTH needs to be low (e.g. 50) to avoid C stack
    14 //       overflows.
    15 #if JSON_MAXDEPTH > 50
    16 #undef JSON_MAXDEPTH
    17 #define JSON_MAXDEPTH 50
    18 #endif
    20 // generate dummy memory addresses that represents null values:
    21 char json_nullmark;
    22 #define json_isnullmark(L, i) (lua_touserdata((L), (i)) == &json_nullmark)
    23 #define json_pushnullmark(L) lua_pushlightuserdata((L), &json_nullmark)
    25 // macros for usage of Lua registry:
    26 #define JSON_REGENT char
    27 #define JSON_REGPOINTER void *
    28 #define json_regpointer(x) (&json_registry.x)
    29 #define json_regfetchpointer(L, x) lua_rawgetp((L), LUA_REGISTRYINDEX, (x))
    30 #define json_regfetch(L, x) json_regfetchpointer(L, json_regpointer(x))
    31 #define json_regstore(L, x) lua_rawsetp(L, LUA_REGISTRYINDEX, json_regpointer(x))
    33 // generate dummy memory addresses that represent Lua objects
    34 // via lightuserdata keys and LUA_REGISTRYINDEX:
    35 static struct {
    36   JSON_REGENT shadowtbl;  // ephemeron table that maps tables to their corresponding shadow table
    37   JSON_REGENT objectmt;   // metatable for JSON objects
    38   JSON_REGENT arraymt;    // metatable for JSON arrays
    39 } json_registry;
    41 // returns the string "<JSON null marker>":
    42 static int json_nullmark_tostring(lua_State *L) {
    43   lua_pushliteral(L, "<JSON null marker>");
    44   return 1;
    45 }
    47 #define json_convert_source_idx 1
    48 #define json_convert_iterator_idx 2
    49 #define json_convert_output_idx 3
    50 #define json_convert_shadow_idx 4
    51 #define json_convert_iterfun_idx 5
    52 #define json_convert_itertbl_idx 6
    54 // converts a Lua table (or any other iterable value) to a JSON object or JSON array:
    55 // (does never modify the argument, returns an empty object or array if argument is nil)
    56 static int json_convert(lua_State *L, int array) {
    57   int arrayidx = 0;
    58   // determine is argument is given:
    59   if (lua_isnoneornil(L, json_convert_source_idx)) {
    60     // if no argument is given (or if argument is nil),
    61     // create table with shadow table, and leave first table on top of stack:
    62     json_regfetch(L, shadowtbl);
    63     lua_newtable(L);
    64     lua_pushvalue(L, -1);
    65     lua_newtable(L);
    66     lua_rawset(L, -4);
    67   } else {
    68     // if an argument was given,
    69     // push its iterator function on stack position 2 if existent,
    70     // else push null for normal tables:
    71     lua_settop(L, 1);
    72     if (lua_getmetatable(L, json_convert_source_idx)) {
    73       lua_getfield(L, -1, array ? "__ipairs" : "__pairs");
    74       if (lua_isnil(L, -1)) luaL_checktype(L, 1, LUA_TTABLE);
    75       else if (lua_type(L, -1) != LUA_TFUNCTION)
    76         return luaL_error(L, "%s metamethod is not a function", array ? "__ipairs" : "__pairs");
    77       lua_replace(L, -2);
    78     } else {
    79       lua_pushnil(L);
    80     }
    81     // create result table on stack position 3:
    82     lua_newtable(L);
    83     // create shadow table on stack position 4:
    84     json_regfetch(L, shadowtbl);
    85     lua_newtable(L);
    86     lua_pushvalue(L, json_convert_output_idx);
    87     lua_pushvalue(L, -2);
    88     lua_rawset(L, -4);
    89     lua_replace(L, -2);
    90     // check if iterator function exists:
    91     if (lua_isnil(L, json_convert_iterator_idx)) {
    92       // if there is no iterator function,
    93       // distinguish between objects and arrays:
    94       if (array == 0) {
    95         // for an object, copy all string key value pairs to shadow table:
    96         for (lua_pushnil(L); lua_next(L, json_convert_source_idx); lua_pop(L, 1)) {
    97           if (lua_type(L, -2) == LUA_TSTRING) {
    98             lua_pushvalue(L, -2);
    99             lua_pushvalue(L, -2);
   100             lua_rawset(L, json_convert_shadow_idx);
   101           }
   102         }
   103       } else {
   104         // for an array, copy consecutive integer value pairs to shadow table:
   105         while (1) {
   106           // throw error if array would exceed INT_MAX elements:
   107           // TODO: Lua 5.3 may support more elements
   108           if (arrayidx == INT_MAX) {
   109             lua_pushnumber(L, (size_t)INT_MAX+1);
   110             lua_rawget(L, json_convert_source_idx);
   111             if (lua_isnil(L, -1)) break;
   112             return luaL_error(L, "Array exceeded length of %d elements", INT_MAX);
   113           }
   114           // get next array entry:
   115           arrayidx++;
   116           lua_rawgeti(L, json_convert_source_idx, arrayidx);
   117           // break if value is nil:
   118           if (lua_isnil(L, -1)) break;
   119           // store value in shadow table:
   120           lua_rawseti(L, json_convert_shadow_idx, arrayidx);
   121         }
   122       }
   123     } else {
   124       // if there is an iterator function,
   125       // call iterator function with source value (first argument)
   126       // and store 3 result values on stack positions 5 through 7:
   127       lua_pushvalue(L, json_convert_iterator_idx);
   128       lua_pushvalue(L, 1);
   129       lua_call(L, 1, 3);
   130       // iterate through key value pairs and store some of them in shadow table
   131       // while replacing nil values with null-marker:
   132       while (1) {
   133         // call iterfun function:
   134         lua_pushvalue(L, json_convert_iterfun_idx);
   135         lua_pushvalue(L, json_convert_itertbl_idx);
   136         lua_pushvalue(L, -3);
   137         lua_remove(L, -4);
   138         lua_call(L, 2, 2);
   139         // break iteration loop if key is nil:
   140         if (lua_isnil(L, -2)) break;
   141         // store key value pair only if key type is correct:
   142         if (lua_type(L, -2) == (array ? LUA_TNUMBER : LUA_TSTRING)) {
   143           // if key type is correct,
   144           // push key onto stack:
   145           lua_pushvalue(L, -2);
   146           // if value is nil, push null-marker onto stack (as value):
   147           if (lua_isnil(L, -2)) json_pushnullmark(L);
   148           // else push value onto stack:
   149           else lua_pushvalue(L, -2);
   150           // set key value pair in shadow table:
   151           lua_rawset(L, json_convert_shadow_idx);
   152         }
   153         // pop value from stack, but leave key on stack:
   154         lua_pop(L, 1);
   155       }
   156     }
   157     // let result table be on top of stack:
   158     lua_settop(L, json_convert_output_idx);
   159   }
   160   // set metatable (for result table on top of stack):
   161   if (array == 0) json_regfetch(L, objectmt);
   162   else json_regfetch(L, arraymt);
   163   lua_setmetatable(L, -2);
   164   // return table on top of stack:
   165   return 1;
   166 }
   168 // converts a Lua table (or any other iterable value) to a JSON object:
   169 // (does never modify the argument, returns an empty object or array if argument is nil)
   170 static int json_object(lua_State *L) {
   171   return json_convert(L, 0);
   172 }
   174 // converts a Lua table (or any other iterable value) to a JSON array:
   175 // (does never modify the argument, returns an empty object or array if argument is nil)
   176 static int json_array(lua_State *L) {
   177   return json_convert(L, 1);
   178 }
   180 // internal states of JSON parser:
   181 #define JSON_STATE_VALUE 0
   182 #define JSON_STATE_OBJECT_KEY 1
   183 #define JSON_STATE_OBJECT_KEY_TERMINATOR 2
   184 #define JSON_STATE_OBJECT_VALUE 3
   185 #define JSON_STATE_OBJECT_SEPARATOR 4
   186 #define JSON_STATE_ARRAY_VALUE 5
   187 #define JSON_STATE_ARRAY_SEPARATOR 6
   188 #define JSON_STATE_END 7
   190 // special Lua stack indicies for json_import function:
   191 #define json_import_objectmt_idx 2
   192 #define json_import_arraymt_idx 3
   193 #define json_import_shadowtbl_idx 4
   194 #define json_import_stackswap_idx 5
   196 // macros for hex decoding:
   197 #define json_utf16_surrogate(x) ((x) >= 0xD800 && (x) <= 0xDFFF)
   198 #define json_utf16_lead(x) ((x) >= 0xD800 && (x) <= 0xDBFF)
   199 #define json_utf16_tail(x) ((x) >= 0xDC00 && (x) <= 0xDFFF)
   200 #define json_import_readhex(x) \
   201   do { \
   202     x = 0; \
   203     for (i=0; i<4; i++) { \
   204       x <<= 4; \
   205       c = str[pos++]; \
   206       if (c >= '0' && c <= '9') x += c - '0'; \
   207       else if (c >= 'A' && c <= 'F') x += c - 'A' + 10; \
   208       else if (c >= 'a' && c <= 'f') x += c - 'a' + 10; \
   209       else if (c == 0) goto json_import_unexpected_eof; \
   210       else goto json_import_unexpected_escape; \
   211     } \
   212   } while (0)
   214 // decodes a JSON document:
   215 static int json_import(lua_State *L) {
   216   int stackswapidx = 0;  // elements in stack swap table
   217   int i;                 // loop variable
   218   const char *str;       // string to parse
   219   size_t total;          // total length of string to parse
   220   size_t pos = 0;        // current position in string to parse
   221   size_t level = 0;      // nested levels of objects/arrays currently being processed
   222   int mode = JSON_STATE_VALUE;  // state of parser (i.e. "what's expected next?")
   223   unsigned char c;       // variable to store a single character to be processed (unsigned!)
   224   luaL_Buffer luabuf;    // Lua buffer to decode JSON string values
   225   char *cbuf;            // C buffer to decode JSON string values
   226   size_t outlen;         // maximum length or write position of C buffer
   227   long codepoint;        // decoded UTF-16 character or higher codepoint
   228   long utf16tail;        // second decoded UTF-16 character (surrogate tail)
   229   size_t arraylen;       // variable to temporarily store the array length
   230   // require string as argument and convert to C string with length information:
   231   str = luaL_checklstring(L, 1, &total);
   232   // if string contains a NULL byte, this is a syntax error
   233   if (strlen(str) != total) goto json_import_syntax_error;
   234   // stack shall contain one function argument:
   235   lua_settop(L, 1);
   236   // push objectmt onto stack position 2:
   237   json_regfetch(L, objectmt);
   238   // push arraymt onto stack position 3:
   239   json_regfetch(L, arraymt);
   240   // push shadowtbl onto stack position 4:
   241   json_regfetch(L, shadowtbl);
   242   // push table for stack swapping onto stack position 5:
   243   // (needed to avoid Lua stack overflows)
   244   lua_newtable(L);
   245   // main loop of parser:
   246   json_import_loop:
   247   // skip whitespace and store next character in variable 'c':
   248   while (c = str[pos],
   249     c == ' ' ||
   250     c == '\f' ||
   251     c == '\n' ||
   252     c == '\r' ||
   253     c == '\t' ||
   254     c == '\v'
   255   ) pos++;
   256   // NOTE: variable c needs to be unsigned in the following code
   257   // switch statement to handle certain (single) characters:
   258   switch (c) {
   259   // handle end of JSON document:
   260   case 0:
   261     // if end of JSON document was expected, then return top element of stack as result:
   262     if (mode == JSON_STATE_END) return 1;
   263     // otherwise, the JSON document was malformed:
   264     if (level == 0) {
   265       lua_pushnil(L);
   266       lua_pushliteral(L, "Empty string");
   267     } else {
   268       json_import_unexpected_eof:
   269       lua_pushnil(L);
   270       lua_pushliteral(L, "Unexpected end of JSON document");
   271     }
   272     return 2;
   273   // new JSON object or JSON array:
   274   case '{':
   275   case '[':
   276     // if an encountered JSON object is not expected here, then return an error:
   277     if (
   278       c == '{' &&
   279       mode != JSON_STATE_VALUE &&
   280       mode != JSON_STATE_OBJECT_VALUE &&
   281       mode != JSON_STATE_ARRAY_VALUE
   282     ) goto json_import_syntax_error;
   283     // if an encountered JSON array is not expected here, then return an error:
   284     if (
   285       c == '[' &&
   286       mode != JSON_STATE_VALUE &&
   287       mode != JSON_STATE_OBJECT_VALUE &&
   288       mode != JSON_STATE_ARRAY_VALUE
   289     ) goto json_import_syntax_error;
   290     // consume input character:
   291     pos++;
   292     // limit nested levels:
   293     if (level >= JSON_MAXDEPTH) {
   294       lua_pushnil(L);
   295       lua_pushfstring(L, "More than %d nested JSON levels", JSON_MAXDEPTH);
   296       return 2;
   297     }
   298     // swap Lua stack entries for previous level to swap table:
   299     // (avoids depth limitations due to Lua stack size)
   300     if (level) {
   301       lua_rawseti(L, json_import_stackswap_idx, ++stackswapidx);
   302       lua_rawseti(L, json_import_stackswap_idx, ++stackswapidx);
   303       lua_rawseti(L, json_import_stackswap_idx, ++stackswapidx);
   304     }
   305     // increment level:
   306     level++;
   307     // create JSON object or JSON array on stack:
   308     lua_newtable(L);
   309     // set metatable of JSON object or JSON array:
   310     lua_pushvalue(L, c == '{' ? json_import_objectmt_idx : json_import_arraymt_idx);
   311     lua_setmetatable(L, -2);
   312     // create internal shadow table on stack:
   313     lua_newtable(L);
   314     // register internal shadow table:
   315     lua_pushvalue(L, -2);
   316     lua_pushvalue(L, -2);
   317     lua_rawset(L, json_import_shadowtbl_idx);
   318     // distinguish between JSON objects and JSON arrays:
   319     if (c == '{') {
   320       // if JSON object,
   321       // expect object key (or end of object) to follow:
   322       mode = JSON_STATE_OBJECT_KEY;
   323     } else {
   324       // if JSON array,
   325       // expect array value (or end of array) to follow:
   326       mode = JSON_STATE_ARRAY_VALUE;
   327       // add nil as key (needed to keep stack balance) and as magic to detect arrays:
   328       if (c == '[') lua_pushnil(L);
   329     }
   330     goto json_import_loop;
   331   // end of JSON object:
   332   case '}':
   333     // if end of JSON object is not expected here, then return an error:
   334     if (
   335       mode != JSON_STATE_OBJECT_KEY &&
   336       mode != JSON_STATE_OBJECT_SEPARATOR
   337     ) goto json_import_syntax_error;
   338     // jump to common code for end of JSON object and JSON array:
   339     goto json_import_close;
   340   // end of JSON array:
   341   case ']':
   342     // if end of JSON array is not expected here, then return an error:
   343     if (
   344       mode != JSON_STATE_ARRAY_VALUE &&
   345       mode != JSON_STATE_ARRAY_SEPARATOR
   346     ) goto json_import_syntax_error;
   347     // pop nil key/magic (that was needed to keep stack balance):
   348     lua_pop(L, 1);
   349     // continue with common code for end of JSON object and JSON array:
   350   // common code for end of JSON object or JSON array:
   351   json_import_close:
   352     // consume input character:
   353     pos++;
   354     // pop shadow table:
   355     lua_pop(L, 1);
   356     // check if nested:
   357     if (--level) {
   358       // if nested,
   359       // restore previous stack elements from stack swap:
   360       lua_rawgeti(L, json_import_stackswap_idx, stackswapidx--);
   361       lua_insert(L, -2);
   362       lua_rawgeti(L, json_import_stackswap_idx, stackswapidx--);
   363       lua_insert(L, -2);
   364       lua_rawgeti(L, json_import_stackswap_idx, stackswapidx--);
   365       lua_insert(L, -2);
   366       // check if outer(!) structure is an array or object:
   367       if (lua_isnil(L, -2)) {
   368         // select array value processing:
   369         mode = JSON_STATE_ARRAY_VALUE;
   370       } else {
   371         // select object value processing:
   372         mode = JSON_STATE_OBJECT_VALUE;
   373       }
   374       // store value in outer structure:
   375       goto json_import_process_value;
   376     }
   377     // if not nested, then expect end of JSON document and continue with loop:
   378     mode = JSON_STATE_END;
   379     goto json_import_loop;
   380   // key terminator:
   381   case ':':
   382     // if key terminator is not expected here, then return an error:
   383     if (mode != JSON_STATE_OBJECT_KEY_TERMINATOR)
   384       goto json_import_syntax_error;
   385     // consume input character:
   386     pos++;
   387     // expect object value to follow:
   388     mode = JSON_STATE_OBJECT_VALUE;
   389     // continue with loop:
   390     goto json_import_loop;
   391   // value terminator (NOTE: trailing comma at end of value or key-value list is tolerated by this parser)
   392   case ',':
   393     // branch according to parser state:
   394     if (mode == JSON_STATE_OBJECT_SEPARATOR) {
   395       // expect an object key to follow:
   396       mode = JSON_STATE_OBJECT_KEY;
   397     } else if (mode == JSON_STATE_ARRAY_SEPARATOR) {
   398       // expect an array value to follow:
   399       mode = JSON_STATE_ARRAY_VALUE;
   400     } else {
   401        // if value terminator is not expected here, then return an error:
   402        goto json_import_syntax_error;
   403     }
   404     // consume input character:
   405     pos++;
   406     // continue with loop:
   407     goto json_import_loop;
   408   // string literal:
   409   case '"':
   410     // consume quote character:
   411     pos++;
   412     // find last character in input string:
   413     outlen = pos;
   414     while ((c = str[outlen]) != '"') {
   415       // consume one character:
   416       outlen++;
   417       // handle unexpected end of JSON document:
   418       if (c == 0) goto json_import_unexpected_eof;
   419       // consume one extra character when encountering an escaped quote:
   420       else if (c == '\\' && str[outlen] == '"') outlen++;
   421     }
   422     // determine buffer length:
   423     outlen -= pos;
   424     // check if string is non empty:
   425     if (outlen) {
   426       // prepare buffer to decode string (with maximum possible length) and set write position to zero:
   427       cbuf = luaL_buffinitsize(L, &luabuf, outlen);
   428       outlen = 0;
   429       // loop through the characters until encountering end quote:
   430       while ((c = str[pos++]) != '"') {
   431         // NOTE: unexpected end cannot happen anymore
   432         if (c < 32 || c == 127) {
   433           // do not allow ASCII control characters:
   434           // NOTE: illegal UTF-8 sequences and extended control characters are not sanitized
   435           //       by this parser to allow different encodings than Unicode
   436           lua_pushnil(L);
   437           lua_pushliteral(L, "Unexpected control character in JSON string");
   438           return 2;
   439         } else if (c == '\\') {
   440           // read next char after backslash escape:
   441           c = str[pos++];
   442           switch (c) {
   443           // unexpected end-of-string:
   444           case 0:
   445             goto json_import_unexpected_eof;
   446           // unescaping of quotation mark, slash, and backslash:
   447           case '"':
   448           case '/':
   449           case '\\':
   450             cbuf[outlen++] = c;
   451             break;
   452           // unescaping of backspace:
   453           case 'b': cbuf[outlen++] = '\b'; break;
   454           // unescaping of form-feed:
   455           case 'f': cbuf[outlen++] = '\f'; break;
   456           // unescaping of new-line:
   457           case 'n': cbuf[outlen++] = '\n'; break;
   458           // unescaping of carriage-return:
   459           case 'r': cbuf[outlen++] = '\r'; break;
   460           // unescaping of tabulator:
   461           case 't': cbuf[outlen++] = '\t'; break;
   462           // unescaping of UTF-16 characters
   463           case 'u':
   464             // decode 4 hex nibbles:
   465             json_import_readhex(codepoint);
   466             // handle surrogate character:
   467             if (json_utf16_surrogate(codepoint)) {
   468               // check if first surrogate is in valid range:
   469               if (json_utf16_lead(codepoint)) {
   470                 // require second surrogate:
   471                 if ((c = str[pos++]) != '\\' || (c = str[pos++]) != 'u') {
   472                   if (c == 0) goto json_import_unexpected_eof;
   473                   else goto json_import_wrong_surrogate;
   474                 }
   475                 // read 4 hex nibbles of second surrogate character:
   476                 json_import_readhex(utf16tail);
   477                 // check if second surrogate is in valid range:
   478                 if (!json_utf16_tail(utf16tail)) goto json_import_wrong_surrogate;
   479                 // calculate codepoint:
   480                 codepoint = 0x10000 + (utf16tail - 0xDC00) + (codepoint - 0xD800) * 0x400;
   481               } else {
   482                 // throw error for wrong surrogates:
   483                 json_import_wrong_surrogate:
   484                 lua_pushnil(L);
   485                 lua_pushliteral(L, "Illegal UTF-16 surrogate in JSON string escape sequence");
   486                 return 2;
   487               }
   488             }
   489             // encode as UTF-8:
   490             if (codepoint < 0x80) {
   491               cbuf[outlen++] = (char)codepoint;
   492             } else if (codepoint < 0x800) {
   493               cbuf[outlen++] = (char)(0xc0 | (codepoint >> 6));
   494               cbuf[outlen++] = (char)(0x80 | (codepoint & 0x3f));
   495             } else if (codepoint < 0x10000) {
   496               cbuf[outlen++] = (char)(0xe0 | (codepoint >> 12));
   497               cbuf[outlen++] = (char)(0x80 | ((codepoint >> 6) & 0x3f));
   498               cbuf[outlen++] = (char)(0x80 | (codepoint & 0x3f));
   499             } else {
   500               cbuf[outlen++] = (char)(0xf0 | (codepoint >> 18));
   501               cbuf[outlen++] = (char)(0x80 | ((codepoint >> 12) & 0x3f));
   502               cbuf[outlen++] = (char)(0x80 | ((codepoint >> 6) & 0x3f));
   503               cbuf[outlen++] = (char)(0x80 | (codepoint & 0x3f));
   504             }
   505             break;
   506           // unexpected escape sequence:
   507           default:
   508             json_import_unexpected_escape:
   509             lua_pushnil(L);
   510             lua_pushliteral(L, "Unexpected string escape sequence in JSON document");
   511             return 2;
   512           }
   513         } else {
   514           // normal character:
   515           cbuf[outlen++] = c;
   516         }
   517       }
   518       // process buffer to Lua string:
   519       luaL_pushresultsize(&luabuf, outlen);
   520     } else {
   521       // if JSON string is empty,
   522       // push empty Lua string:
   523       lua_pushliteral(L, "");
   524       // consume closing quote:
   525       pos++;
   526     }
   527     // continue with processing of decoded string:
   528     goto json_import_process_value;
   529   }
   530   // process values whose type is is not deducible from a single character:
   531   if ((c >= '0' && c <= '9') || c == '-' || c == '+') {
   532     // for numbers,
   533     // use strtod() call to parse a (double precision) floating point number:
   534     double numval;
   535     char *endptr;
   536     numval = strtod(str+pos, &endptr);
   537     // catch parsing errors:
   538     if (endptr == str+pos) goto json_import_syntax_error;
   539     // consume characters that were parsed:
   540     pos += endptr - (str+pos);
   541     // push parsed (double precision) floating point number on Lua stack:
   542     lua_pushnumber(L, numval);
   543   } else if (!strncmp(str+pos, "true", 4)) {
   544     // consume 4 input characters for "true":
   545     pos += 4;
   546     // put Lua true value onto stack:
   547     lua_pushboolean(L, 1);
   548   } else if (!strncmp(str+pos, "false", 5)) {
   549     // consume 5 input characters for "false":
   550     pos += 5;
   551     // put Lua false value onto stack:
   552     lua_pushboolean(L, 0);
   553   } else if (!strncmp(str+pos, "null", 4)) {
   554     // consume 4 input characters for "null":
   555     pos += 4;
   556     // different behavor for top-level and sub-levels:
   557     if (level) {
   558       // if sub-level,
   559       // push special null-marker onto stack:
   560       json_pushnullmark(L);
   561     } else {
   562       // if top-level,
   563       // push nil onto stack:
   564       lua_pushnil(L);
   565     }
   566   } else {
   567     // all other cases are a syntax error:
   568     goto json_import_syntax_error;
   569   }
   570   // process a decoded value or key value pair (expected on top of Lua stack):
   571   json_import_process_value:
   572   switch (mode) {
   573   // an object key has been read:
   574   case JSON_STATE_OBJECT_KEY:
   575     // if an object key is not a string, then this is a syntax error:
   576     if (lua_type(L, -1) != LUA_TSTRING) goto json_import_syntax_error;
   577     // expect key terminator to follow:
   578     mode = JSON_STATE_OBJECT_KEY_TERMINATOR;
   579     // continue with loop:
   580     goto json_import_loop;
   581   // a key value pair has been read:
   582   case JSON_STATE_OBJECT_VALUE:
   583     // store key value pair in outer shadow table:
   584     lua_rawset(L, -3);
   585     // expect value terminator (or end of object) to follow:
   586     mode = JSON_STATE_OBJECT_SEPARATOR;
   587     // continue with loop:
   588     goto json_import_loop;
   589   // an array value has been read:
   590   case JSON_STATE_ARRAY_VALUE:
   591     // get current array length:
   592     arraylen = lua_rawlen(L, -3);
   593     // throw error if array would exceed INT_MAX elements:
   594     // TODO: Lua 5.3 may support more elements
   595     if (arraylen >= INT_MAX) {
   596       lua_pushnil(L);
   597       lua_pushfstring(L, "Array exceeded length of %d elements", INT_MAX);
   598     }
   599     // store value in outer shadow table:
   600     lua_rawseti(L, -3, arraylen + 1);
   601     // expect value terminator (or end of object) to follow:
   602     mode = JSON_STATE_ARRAY_SEPARATOR;
   603     // continue with loop
   604     goto json_import_loop;
   605   // a single value has been read:
   606   case JSON_STATE_VALUE:
   607     // leave value on top of stack, expect end of JSON document, and continue with loop:
   608     mode = JSON_STATE_END;
   609     goto json_import_loop;
   610   }
   611   // syntax error handling (reachable by goto statement):
   612   json_import_syntax_error:
   613   lua_pushnil(L);
   614   lua_pushliteral(L, "Syntax error in JSON document");
   615   return 2;
   616 }
   618 // special Lua stack indicies for json_path function:
   619 #define json_path_shadowtbl_idx 1
   621 // stack offset of arguments to json_path function:
   622 #define json_path_idxshift 1
   624 // gets a value or its type from a JSON document (passed as first argument)
   625 // using a path (passed as variable number of keys after the first argument):
   626 static int json_path(lua_State *L, int type_mode) {
   627   int stacktop;                      // stack index of top of stack (after shifting)
   628   int idx = 2 + json_path_idxshift;  // stack index of current argument to process
   629   // require at least one argument:
   630   luaL_checkany(L, 1);
   631   // insert shadowtbl into stack at position 1 (shifting the arguments):
   632   json_regfetch(L, shadowtbl);
   633   lua_insert(L, 1);
   634   // store stack index of top of stack:
   635   stacktop = lua_gettop(L);
   636   // use first argument as "current value" (stored on top of stack):
   637   lua_pushvalue(L, 1 + json_path_idxshift);
   638   // process each "path key" (2nd argument and following arguments):
   639   while (idx <= stacktop) {
   640     // if "current value" (on top of stack) is nil, then the path cannot be walked and nil is returned:
   641     if (lua_isnil(L, -1)) return 1;
   642     // try to get shadow table of "current value":
   643     lua_pushvalue(L, -1);
   644     lua_rawget(L, json_path_shadowtbl_idx);
   645     if (lua_isnil(L, -1)) {
   646       // if no shadow table is found,
   647       if (lua_type(L, -1) == LUA_TTABLE) {
   648         // and if "current value" is a table,
   649         // drop nil from stack:
   650         lua_pop(L, 1);
   651         // get "next value" using the "path key":
   652         lua_pushvalue(L, idx++);
   653         lua_gettable(L, -2);
   654       } else {
   655         // if "current value" is not a table,
   656         // then the path cannot be walked and nil (already on top of stack) is returned:
   657         return 1;
   658       }
   659     } else {
   660       // if a shadow table is found,
   661       // set "current value" to its shadow table:
   662       lua_replace(L, -2);
   663       // get "next value" using the "path key":
   664       lua_pushvalue(L, idx++);
   665       lua_rawget(L, -2);
   666     }
   667     // the "next value" replaces the "current value":
   668     lua_replace(L, -2);
   669   }
   670   if (!type_mode) {
   671     // if a value (and not its type) was requested,
   672     // check if value is the null-marker, and store nil on top of Lua stack in that case:
   673     if (json_isnullmark(L, -1)) lua_pushnil(L);
   674   } else {
   675     // if the type was requested,
   676     // check if value is the null-marker:
   677     if (json_isnullmark(L, -1)) {
   678       // if yes, store string "null" on top of Lua stack:
   679       lua_pushliteral(L, "null");
   680     } else {
   681       // otherwise,
   682       // check if metatable indicates "object" or "array":
   683       if (lua_getmetatable(L, -1)) {
   684         json_regfetch(L, objectmt);
   685         if (lua_rawequal(L, -2, -1)) {
   686           // if value has metatable for JSON objects,
   687           // return string "object":
   688           lua_pushliteral(L, "object");
   689           return 1;
   690         }
   691         json_regfetch(L, arraymt);
   692         if (lua_rawequal(L, -3, -1)) {
   693           // if value has metatable for JSON arrays,
   694           // return string "object":
   695           lua_pushliteral(L, "array");
   696           return 1;
   697         }
   698         // remove 3 metatables (one of the value, two for comparison) from stack:
   699         lua_pop(L, 3);
   700       }
   701       // otherwise, get the Lua type:
   702       lua_pushstring(L, lua_typename(L, lua_type(L, -1)));
   703     }
   704   }
   705   // return the top most value on the Lua stack:
   706   return 1;
   707 }
   709 // gets a value from a JSON document (passed as first argument)
   710 // using a path (passed as variable number of keys after the first argument):
   711 static int json_get(lua_State *L) {
   712   return json_path(L, 0);
   713 }
   715 // gets a value's type from a JSON document (passed as first argument)
   716 // using a path (passed as variable number of keys after first the argument):
   717 static int json_type(lua_State *L) {
   718   return json_path(L, 1);
   719 }
   721 // special Lua stack indicies for json_set function:
   722 #define json_set_shadowtbl_idx 1
   723 #define json_set_objectmt_idx 2
   724 #define json_set_arraymt_idx 3
   726 // stack offset of arguments to json_set function:
   727 #define json_set_idxshift 3
   729 // sets a value (passed as second argument) in a JSON document (passed as first argument)
   730 // using a path (passed as variable number of keys starting at third argument):
   731 static int json_set(lua_State *L) {
   732   int stacktop;   // stack index of top of stack (after shifting)
   733   int idx = 3;    // stack index of current argument to process
   734   // require at least two arguments:
   735   luaL_checkany(L, 1);
   736   luaL_checkany(L, 2);
   737   // insert shadowtbl into stack at position 1 (shifting the arguments):
   738   json_regfetch(L, shadowtbl);
   739   lua_insert(L, 1);
   740   // insert objectmt into stack at position 2 (shifting the arguments):
   741   json_regfetch(L, objectmt);
   742   lua_insert(L, 2);
   743   // insert arraymt into stack at position 3 (shifting the arguments):
   744   json_regfetch(L, arraymt);
   745   lua_insert(L, 3);
   746   // store stack index of top of stack:
   747   stacktop = lua_gettop(L);
   748   // use nil as initial "parent value":
   749   lua_pushnil(L);
   750   // use first argument as "current value":
   751   lua_pushvalue(L, 1 + json_set_idxshift);
   752   // set all necessary values in path:
   753   for (idx = 3 + json_set_idxshift; idx<=stacktop; idx++) {
   754     // push metatable of "current value" onto stack:
   755     if (!lua_getmetatable(L, -1)) lua_pushnil(L);
   756     // distinguish according to type of path key:
   757     switch (lua_type(L, idx)) {
   758     case LUA_TSTRING:
   759       // if path key is a string,
   760       // check if "current value" is a JSON object (or table without metatable):
   761       if (
   762         lua_rawequal(L, -1, json_set_objectmt_idx) ||
   763         (lua_isnil(L, -1) && lua_type(L, -2) == LUA_TTABLE)
   764       ) {
   765         // if "current value" is acceptable,
   766         // pop metatable and leave "current value" on top of stack:
   767         lua_pop(L, 1);
   768       } else {
   769         // if "current value" is not acceptable:
   770         // pop metatable and "current value":
   771         lua_pop(L, 2);
   772         // throw error if parent element does not exist:
   773         if (lua_isnil(L, -1)) return luaL_error(L, "Root element is not a JSON object");
   774         // push new JSON object as "current value" onto stack:
   775         lua_newtable(L);
   776         // create and register shadow table:
   777         lua_pushvalue(L, -1);
   778         lua_newtable(L);
   779         lua_rawset(L, json_set_shadowtbl_idx);
   780         // set metatable of JSON object: 
   781         lua_pushvalue(L, json_set_objectmt_idx);
   782         lua_setmetatable(L, -2);
   783         // set entry in "parent value":
   784         lua_pushvalue(L, idx-1);
   785         lua_pushvalue(L, -2);
   786         lua_settable(L, -4);
   787       }
   788       break;
   789     case LUA_TNUMBER:
   790       // if path key is a number,
   791       // check if "current value" is a JSON array (or table without metatable):
   792       if (
   793         lua_rawequal(L, -1, json_set_arraymt_idx) ||
   794         (lua_isnil(L, -1) && lua_type(L, -2) == LUA_TTABLE)
   795       ) {
   796         // if "current value" is acceptable,
   797         // pop metatable and leave "current value" on top of stack:
   798         lua_pop(L, 1);
   799       } else {
   800         // if "current value" is not acceptable:
   801         // pop metatable and "current value":
   802         lua_pop(L, 2);
   803         // throw error if parent element does not exist:
   804         if (lua_isnil(L, -1)) return luaL_error(L, "Root element is not a JSON array");
   805         // push new JSON array as "current value" onto stack:
   806         lua_newtable(L);
   807         // create and register shadow table:
   808         lua_pushvalue(L, -1);
   809         lua_newtable(L);
   810         lua_rawset(L, json_set_shadowtbl_idx);
   811         // set metatable of JSON array: 
   812         lua_pushvalue(L, json_set_arraymt_idx);
   813         lua_setmetatable(L, -2);
   814         // set entry in "parent value":
   815         lua_pushvalue(L, idx-1);
   816         lua_pushvalue(L, -2);
   817         lua_settable(L, -4);
   818       }
   819       break;
   820     default:
   821       return luaL_error(L, "Invalid path key of type %s", lua_typename(L, lua_type(L, idx)));
   822     }
   823     // check if last path element is being processed:
   824     if (idx == stacktop) {
   825       // if the last path element is being processed,
   826       // set last path value in "current value" container:
   827       lua_pushvalue(L, idx);
   828       lua_pushvalue(L, 2 + json_set_idxshift);
   829       lua_settable(L, -3);
   830     } else {
   831       // if the processed path element is not the last,
   832       // use old "current value" as new "parent value"
   833       lua_remove(L, -2);
   834       // push new "current value" onto stack by performing a lookup:
   835       lua_pushvalue(L, idx);
   836       lua_gettable(L, -2);
   837     }
   838   }
   839   // return first argument for convenience:
   840   lua_settop(L, 1 + json_set_idxshift);
   841   return 1;
   842 }
   844 // returns the length of a JSON array (or zero for a table without numeric keys):
   845 static int json_len(lua_State *L) {
   846   // stack shall contain one function argument:
   847   lua_settop(L, 1);
   848   // try to get corresponding shadow table for first argument:
   849   json_regfetch(L, shadowtbl);
   850   lua_pushvalue(L, 1);
   851   lua_rawget(L, -2);
   852   // if shadow table does not exist, return length of argument, else length of shadow table:
   853   lua_pushnumber(L, lua_rawlen(L, lua_isnil(L, -1) ? 1 : -1));
   854   return 1;
   855 }
   857 // __index metamethod for JSON objects and JSON arrays:
   858 static int json_index(lua_State *L) {
   859   // stack shall contain two function arguments:
   860   lua_settop(L, 2);
   861   // get corresponding shadow table for first argument:
   862   json_regfetch(L, shadowtbl);
   863   lua_pushvalue(L, 1);
   864   lua_rawget(L, -2);
   865   // throw error if no shadow table was found:
   866   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   867   // use key passed as second argument to lookup value in shadow table:
   868   lua_pushvalue(L, 2);
   869   lua_rawget(L, -2);
   870   // if value is null-marker, then push nil onto stack:
   871   if (json_isnullmark(L, -1)) lua_pushnil(L);
   872   // return either looked up value, or nil
   873   return 1;
   874 }
   876 // __newindex metamethod for JSON objects and JSON arrays:
   877 static int json_newindex(lua_State *L) {
   878   // stack shall contain three function arguments:
   879   lua_settop(L, 3);
   880   // get corresponding shadow table for first argument:
   881   json_regfetch(L, shadowtbl);
   882   lua_pushvalue(L, 1);
   883   lua_rawget(L, -2);
   884   // throw error if no shadow table was found:
   885   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   886   // replace first argument with shadow table:
   887   lua_replace(L, 1);
   888   // reset stack and use second and third argument to write to shadow table:
   889   lua_settop(L, 3);
   890   lua_rawset(L, 1);
   891   // return nothing:
   892   return 0;
   893 }
   895 // function returned as first value by json_pairs function:
   896 static int json_pairs_iterfunc(lua_State *L) {
   897   // stack shall contain two function arguments:
   898   lua_settop(L, 2);
   899   // get corresponding shadow table for first argument:
   900   json_regfetch(L, shadowtbl);
   901   lua_pushvalue(L, 1);
   902   lua_rawget(L, -2);
   903   // throw error if no shadow table was found:
   904   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   905   // get next key value pair from shadow table (using previous key from argument 2)
   906   // and return nothing if there is no next pair:
   907   lua_pushvalue(L, 2);
   908   if (!lua_next(L, -2)) return 0;
   909   // replace null-marker with nil:
   910   if (json_isnullmark(L, -1)) {
   911     lua_pop(L, 1);
   912     lua_pushnil(L);
   913   }
   914   // return key and value (or key and nil, if null-marker was found):
   915   return 2;
   916 }
   918 // returns a triple such that 'for key, value in pairs(obj) do ... end'
   919 // iterates through all key value pairs (including JSON null values represented as Lua nil):
   920 static int json_pairs(lua_State *L) {
   921   // require one argument to function
   922   luaL_checkany(L, 1);
   923   // return triple of function json_pairs_iterfunc, first argument, and nil:
   924   lua_pushcfunction(L, json_pairs_iterfunc);
   925   lua_pushvalue(L, 1);
   926   lua_pushnil(L);
   927   return 3;
   928 }
   930 // function returned as first value by json_ipairs function:
   931 static int json_ipairs_iterfunc(lua_State *L) {
   932   lua_Integer idx;
   933   // stack shall contain two function arguments:
   934   lua_settop(L, 2);
   935   // calculate new index by incrementing second argument:
   936   idx = lua_tointeger(L, 2) + 1;
   937   // get corresponding shadow table for first argument:
   938   json_regfetch(L, shadowtbl);
   939   lua_pushvalue(L, 1);
   940   lua_rawget(L, -2);
   941   // throw error if no shadow table was found:
   942   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   943   // do integer lookup in shadow table:
   944   lua_rawgeti(L, -1, idx);
   945   // return nothing if there was no value:
   946   if (lua_isnil(L, -1)) return 0;
   947   // return new index and
   948   // either the looked up value if it is not equal to the null-marker
   949   // or nil instead of null-marker:
   950   lua_pushinteger(L, idx);
   951   if (json_isnullmark(L, -2)) lua_pushnil(L);
   952   else lua_pushvalue(L, -2);
   953   return 2;
   954 }
   956 // returns a triple such that 'for idx, value in ipairs(ary) do ... end'
   957 // iterates through all values (including JSON null values represented as Lua nil):
   958 static int json_ipairs(lua_State *L) {
   959   // require one argument to function
   960   luaL_checkany(L, 1);
   961   // return triple of function json_ipairs_iterfunc, first argument, and zero:
   962   lua_pushcfunction(L, json_ipairs_iterfunc);
   963   lua_pushvalue(L, 1);
   964   lua_pushinteger(L, 0);
   965   return 3;
   966 }
   968 // datatype representing a table key:
   969 // (used for sorting)
   970 typedef struct {
   971   size_t length;
   972   const char *data;
   973 } json_key_t;
   975 // comparation function for table keys to be passed to qsort function:
   976 static int json_key_cmp(json_key_t *key1, json_key_t *key2) {
   977   size_t pos = 0;
   978   unsigned char c1, c2;
   979   while (1) {
   980     if (key1->length > pos) {
   981       if (key2->length > pos) {
   982         c1 = key1->data[pos];
   983         c2 = key2->data[pos];
   984         if (c1 < c2) return -1;
   985         else if (c1 > c2) return 1;
   986       } else {
   987         return 1;
   988       }
   989     } else {
   990       if (key2->length > pos) {
   991         return -1;
   992       } else {
   993         return 0;
   994       }
   995     }
   996     pos++;
   997   }
   998 }
  1000 // constants for type detection of ambiguous tables:
  1001 #define JSON_TABLETYPE_UNKNOWN 0
  1002 #define JSON_TABLETYPE_OBJECT 1
  1003 #define JSON_TABLETYPE_ARRAY 2
  1005 // special Lua stack indicies for json_export_internal function:
  1006 #define json_export_internal_indentstring_idx 1
  1007 #define json_export_internal_level_idx 2
  1008 #define json_export_internal_value_idx 3
  1009 #define json_export_internal_tmp_idx 4
  1011 // encodes a JSON document (passed as third argument)
  1012 // optionally using indentation (indentation string passed as first argument)
  1013 // for a certain depth level (passed as second argument):
  1014 static int json_export_internal(lua_State *L) {
  1015   int level;        // current depth level
  1016   int pretty;       // pretty printing on? (i.e. printing with indentation)
  1017   int i;            // iteration variable for level dependent repetitions:
  1018   lua_Number num;   // number to encode
  1019   const char *str;  // string to encode
  1020   size_t strlen;    // length of string to encode
  1021   unsigned char c;  // character to encode (unsigned!)
  1022   size_t pos = 0;   // position in string or position of current key (initialized with zero!)
  1023   luaL_Buffer buf;  // Lua buffer to create strings
  1024   char hexcode[7];  // store for unicode hex escape sequence
  1025                     // NOTE: 7 bytes due to backslash, character 'u', 4 hex digits, and terminating NULL byte
  1026   int tabletype = JSON_TABLETYPE_UNKNOWN;  // table type: unknown, JSON object, or JSON array
  1027   int anyelement = 0;         // set to 1 if at least one array element has been processed
  1028   size_t keycount = 0;        // number of string keys in object
  1029   json_key_t *keybuf = NULL;  // temporary buffer to store (and sort) string keys of objects
  1030   lua_Integer arrayidx;       // index to iterate through arrays
  1031   // stack shall contain three function arguments:
  1032   lua_settop(L, json_export_internal_value_idx);
  1033   // if value to encode is the null-marker, then treat it the same as nil:
  1034   if (json_isnullmark(L, json_export_internal_value_idx)) {
  1035     lua_pop(L, 1);
  1036     lua_pushnil(L);
  1037   }
  1038   // distinguish between different Lua types:
  1039   switch (lua_type(L, json_export_internal_value_idx)) {
  1040   // value to encode is nil:
  1041   case LUA_TNIL:
  1042     // return string "null":
  1043     lua_pushliteral(L, "null");
  1044     return 1;
  1045   // value to encode is of type number:
  1046   case LUA_TNUMBER:
  1047     // convert value to double precision number:
  1048     num = lua_tonumber(L, json_export_internal_value_idx);
  1049     // throw error if number is not-a-number:
  1050     if (isnan(num)) return luaL_error(L, "JSON export not possible for NaN value");
  1051     // throw error if number is positive or negative infinity:
  1052     if (isinf(num)) return luaL_error(L, "JSON export not possible for infinite numbers");
  1053     // return Lua's string encoding of the number:
  1054     lua_tostring(L, json_export_internal_value_idx);
  1055     return 1;
  1056   // value to encode is of type boolean:
  1057   case LUA_TBOOLEAN:
  1058     // return string "true" or "false" according to boolean value:
  1059     if (lua_toboolean(L, json_export_internal_value_idx)) {
  1060       lua_pushliteral(L, "true");
  1061     } else {
  1062       lua_pushliteral(L, "false");
  1063     }
  1064     return 1;
  1065   // value to encode is of type string:
  1066   case LUA_TSTRING:
  1067     // quote, escape and return string:
  1068     str = lua_tolstring(L, 3, &strlen);
  1069     luaL_buffinit(L, &buf);
  1070     luaL_addchar(&buf, '"');
  1071     while (pos < strlen) {
  1072       c = str[pos++];
  1073       if (c == '"')       luaL_addstring(&buf, "\\\"");
  1074       else if (c == '\\') luaL_addstring(&buf, "\\\\");
  1075       else if (c == 127)  luaL_addstring(&buf, "\\u007F");
  1076       else if (c >= 32)   luaL_addchar(&buf, c);
  1077       else if (c == '\b') luaL_addstring(&buf, "\\b");
  1078       else if (c == '\f') luaL_addstring(&buf, "\\f");
  1079       else if (c == '\n') luaL_addstring(&buf, "\\n");
  1080       else if (c == '\r') luaL_addstring(&buf, "\\r");
  1081       else if (c == '\t') luaL_addstring(&buf, "\\t");
  1082       else if (c == '\v') luaL_addstring(&buf, "\\v");
  1083       else {
  1084         sprintf(hexcode, "\\u%04X", c);
  1085         luaL_addstring(&buf, hexcode);
  1086       }
  1087     }
  1088     luaL_addchar(&buf, '"');
  1089     luaL_pushresult(&buf);
  1090     return 1;
  1091   // value to encode is of type table (this includes JSON objects and JSON arrays):
  1092   case LUA_TTABLE:
  1093     // use table's metatable to try to determine type of table:
  1094     if (lua_getmetatable(L, json_export_internal_value_idx)) {
  1095       json_regfetch(L, objectmt);
  1096       if (lua_rawequal(L, -2, -1)) {
  1097         tabletype = JSON_TABLETYPE_OBJECT;
  1098       } else {
  1099         json_regfetch(L, arraymt);
  1100         if (lua_rawequal(L, -3, -1)) {
  1101           tabletype = JSON_TABLETYPE_ARRAY;
  1102         } else {
  1103           return luaL_error(L, "JSON export not possible for tables with nonsupported metatable");
  1104         }
  1105       }
  1106     }
  1107     // replace table with its shadow table if existent, and reset stack:
  1108     json_regfetch(L, shadowtbl);
  1109     lua_pushvalue(L, json_export_internal_value_idx);
  1110     lua_rawget(L, -2);
  1111     if (!lua_isnil(L, -1)) lua_replace(L, json_export_internal_value_idx);
  1112     lua_settop(L, json_export_internal_value_idx);
  1113     // check if type of table is still undetermined:
  1114     if (tabletype == JSON_TABLETYPE_UNKNOWN) {
  1115       // if yes, iterate over all keys:
  1116       for (lua_pushnil(L); lua_next(L, json_export_internal_value_idx); lua_pop(L, 1)) {
  1117         switch (lua_type(L, -2)) {
  1118         case LUA_TSTRING:
  1119           // for string keys,
  1120           // increase keycount (may avoid another iteration):
  1121           keycount++;
  1122           // if type of table was unknown, then type of table is a JSON object now:
  1123           if (tabletype == JSON_TABLETYPE_UNKNOWN) tabletype = JSON_TABLETYPE_OBJECT;
  1124           // if type of table was a JSON array, then the type of table is ambiguous now
  1125           // and an error is thrown:
  1126           else if (tabletype == JSON_TABLETYPE_ARRAY) goto json_export_tabletype_error;
  1127           break;
  1128         case LUA_TNUMBER:
  1129           // for numeric keys,
  1130           // if type of table was unknown, then type of table is a JSON array now:
  1131           if (tabletype == JSON_TABLETYPE_UNKNOWN) tabletype = JSON_TABLETYPE_ARRAY;
  1132           // if type of table was a JSON object, then the type of table is ambiguous now
  1133           // and an error is thrown:
  1134           else if (tabletype == JSON_TABLETYPE_OBJECT) goto json_export_tabletype_error;
  1135           break;
  1136         }
  1137       }
  1138     }
  1139     // set pretty variable to 1 if pretty printing (with indentation) is desired:
  1140     pretty = lua_toboolean(L, json_export_internal_indentstring_idx);
  1141     // set level variable to corresponding function argument increased by one:
  1142     level = lua_tointeger(L, json_export_internal_level_idx) + 1;
  1143     // throw error if there are more levels that could be imported by this library:
  1144     if (level > JSON_MAXDEPTH) {
  1145       return luaL_error(L, "More than %d nested JSON levels", JSON_MAXDEPTH);
  1146     }
  1147     // distinguish between JSON objects and JSON arrays:
  1148     switch (tabletype) {
  1149     // JSON object:
  1150     case JSON_TABLETYPE_OBJECT:
  1151       // calculate count of string keys unless it has been calculated before:
  1152       if (!keycount) {
  1153         for (lua_pushnil(L); lua_next(L, json_export_internal_value_idx); lua_pop(L, 1)) {
  1154           if (lua_type(L, -2) == LUA_TSTRING) keycount++;
  1155         }
  1156       }
  1157       // create a sorted list of all string keys in memory:
  1158       if (keycount) {
  1159         // allocate memory for string keys:
  1160         keybuf = calloc(keycount, sizeof(json_key_t));
  1161         // check if memory allocation was successful:
  1162         if (!keybuf) {
  1163           // in case of memory exhaustion, try to collect garbage:
  1164           lua_gc(L, LUA_GCCOLLECT, 0);
  1165           // try to allocate memory again:
  1166           keybuf = calloc(keycount, sizeof(json_key_t));
  1167           // throw error if memory allocation failed again:
  1168           if (!keybuf) {
  1169             return luaL_error(L, "Memory allocation failed in JSON library");
  1170           }
  1171         }
  1172         // copy all string keys to the C array:
  1173         for (lua_pushnil(L); lua_next(L, json_export_internal_value_idx); lua_pop(L, 1)) {
  1174           if (lua_type(L, -2) == LUA_TSTRING) {
  1175             json_key_t *key = keybuf + (pos++);
  1176             key->data = lua_tolstring(L, -2, &key->length);
  1177           }
  1178         }
  1179         // sort C array using quicksort:
  1180         qsort(keybuf, keycount, sizeof(json_key_t), (void *)json_key_cmp);
  1181       }
  1182       // create Lua string buffer:
  1183       luaL_buffinit(L, &buf);
  1184       // add opening bracket to output buffer:
  1185       luaL_addchar(&buf, '{');
  1186       // iterate through all (sorted) string keys:
  1187       for (pos=0; pos<keycount; pos++) {
  1188         json_key_t *key = keybuf + pos;
  1189         // add comma to output buffer unless we process the first key:
  1190         if (pos) luaL_addchar(&buf, ',');
  1191         // handle indentation for pretty results:
  1192         if (pretty) {
  1193           luaL_addchar(&buf, '\n');
  1194           for (i=0; i<level; i++) {
  1195             lua_pushvalue(L, json_export_internal_indentstring_idx);
  1196             luaL_addvalue(&buf);
  1197           }
  1198         }
  1199         // recursive call to encode key:
  1200         lua_pushcfunction(L, json_export_internal);
  1201         lua_pushvalue(L, json_export_internal_indentstring_idx);
  1202         lua_pushinteger(L, level);
  1203         lua_pushlstring(L, key->data, key->length);
  1204         if (lua_pcall(L, 3, 1, 0)) {
  1205           // free memory of sorted string keys on error:
  1206           if (keybuf) free(keybuf);
  1207           // rethrow error:
  1208           return lua_error(L);
  1209         }
  1210         // add encoded key to output buffer:
  1211         luaL_addvalue(&buf);
  1212         // add colon to output buffer:
  1213         luaL_addchar(&buf, ':');
  1214         // handle indentation for pretty results:
  1215         if (pretty) luaL_addchar(&buf, ' ');
  1216         // recursive call to encode value:
  1217         lua_pushcfunction(L, json_export_internal);
  1218         lua_pushvalue(L, json_export_internal_indentstring_idx);
  1219         lua_pushinteger(L, level);
  1220         lua_pushlstring(L, key->data, key->length);
  1221         lua_rawget(L, json_export_internal_value_idx);
  1222         if (lua_pcall(L, 3, 1, 0)) {
  1223           // free memory of sorted string keys on error:
  1224           if (keybuf) free(keybuf);
  1225           // rethrow error:
  1226           return lua_error(L);
  1227         }
  1228         // add encoded value to output buffer:
  1229         luaL_addvalue(&buf);
  1230       }
  1231       // decrement level variable for all following statements:
  1232       level--;
  1233       // free memory of sorted string keys:
  1234       if (keybuf) free(keybuf);
  1235       // handle indentation for pretty results:
  1236       if (pretty && keycount != 0) {
  1237         luaL_addchar(&buf, '\n');
  1238         for (i=0; i<level; i++) {
  1239           lua_pushvalue(L, json_export_internal_indentstring_idx);
  1240           luaL_addvalue(&buf);
  1241         }
  1242       }
  1243       // add closing bracket to output buffer:
  1244       luaL_addchar(&buf, '}');
  1245       // for pretty results, add final newline character if outermost container is processed:
  1246       if (pretty && level == 0) luaL_addchar(&buf, '\n');
  1247       // convert and return buffer:
  1248       luaL_pushresult(&buf);
  1249       return 1;
  1250     // JSON array:
  1251     case JSON_TABLETYPE_ARRAY:
  1252       // reserve an extra element on the stack (needed because Lua buffer has unknown size on stack):
  1253       lua_settop(L, json_export_internal_tmp_idx);
  1254       // create Lua string buffer:
  1255       luaL_buffinit(L, &buf);
  1256       // add opening bracket to output buffer:
  1257       luaL_addchar(&buf, '[');
  1258       // iterate through integer keys:
  1259       for (arrayidx = 1; ; arrayidx++) {
  1260         // get value in array, and break if nil:
  1261         lua_rawgeti(L, json_export_internal_value_idx, arrayidx);
  1262         if (lua_isnil(L, -1)) {
  1263           lua_pop(L, 1);
  1264           break;
  1265         }
  1266         // store value below Lua string buffer on stack (to allow operation on string buffer):
  1267         lua_replace(L, json_export_internal_tmp_idx);
  1268         //
  1269         // add comma to output buffer unless we process the first element:
  1270         if (anyelement) luaL_addchar(&buf, ',');
  1271         // remember that we processed an element:
  1272         anyelement = 1;
  1273         // handle indentation for pretty results:
  1274         if (pretty) {
  1275           luaL_addchar(&buf, '\n');
  1276           for (i=0; i<level; i++) {
  1277             lua_pushvalue(L, json_export_internal_indentstring_idx);
  1278             luaL_addvalue(&buf);
  1279           }
  1280         }
  1281         // recursive call to encode previously stored value:
  1282         lua_pushcfunction(L, json_export_internal);
  1283         lua_pushvalue(L, json_export_internal_indentstring_idx);
  1284         lua_pushinteger(L, level);
  1285         lua_pushvalue(L, json_export_internal_tmp_idx);
  1286         lua_call(L, 3, 1);
  1287         // add encoded value to output buffer:
  1288         luaL_addvalue(&buf);
  1289       }
  1290       // decrement level variable for all following statements:
  1291       level--;
  1292       // handle indentation for pretty results:
  1293       if (pretty && anyelement) {
  1294         luaL_addchar(&buf, '\n');
  1295         for (i=0; i<level; i++) {
  1296           lua_pushvalue(L, json_export_internal_indentstring_idx);
  1297           luaL_addvalue(&buf);
  1298         }
  1299       }
  1300       // add closing bracket to output buffer:
  1301       luaL_addchar(&buf, ']');
  1302       // for pretty results, add final newline character if outermost container is processed:
  1303       if (pretty && level == 0) luaL_addchar(&buf, '\n');
  1304       // convert and return buffer:
  1305       luaL_pushresult(&buf);
  1306       return 1;
  1307     }
  1308     // throw error if table type is unknown:
  1309     json_export_tabletype_error:
  1310     return luaL_error(L, "JSON export not possible for ambiguous table (cannot decide whether it is an object or array)");
  1311   }
  1312   // all other datatypes are considered an error:
  1313   return luaL_error(L, "JSON export not possible for values of type \"%s\"", lua_typename(L, lua_type(L, json_export_internal_value_idx)));
  1314 }
  1316 // encodes a JSON document (passed as argument):
  1317 static int json_export(lua_State *L) {
  1318   // stack shall contain one function argument:
  1319   lua_settop(L, 1);
  1320   // call json_export_internal function with proper arguments:
  1321   lua_pushcfunction(L, json_export_internal);
  1322   lua_pushnil(L);
  1323   lua_pushinteger(L, 0);
  1324   lua_pushvalue(L, 1);
  1325   lua_call(L, 3, 1);
  1326   // return result:
  1327   return 1;
  1328 }
  1330 // encodes a JSON document (passed as first argument)
  1331 // with indentation (indentation string may be passed as second argument):
  1332 static int json_pretty(lua_State *L) {
  1333   // stack shall contain two function arguments:
  1334   lua_settop(L, 2);
  1335   // call json_export_internal function with proper arguments:
  1336   lua_pushcfunction(L, json_export_internal);
  1337   if (lua_isnil(L, 2)) lua_pushliteral(L, "  ");
  1338   else lua_pushvalue(L, 2);
  1339   lua_pushinteger(L, 0);
  1340   lua_pushvalue(L, 1);
  1341   lua_call(L, 3, 1);
  1342   // return result:
  1343   return 1;
  1344 }
  1346 // functions in library module:
  1347 static const struct luaL_Reg json_module_functions[] = {
  1348   {"object", json_object},
  1349   {"array",  json_array},
  1350   {"import", json_import},
  1351   {"export", json_export},
  1352   {"pretty", json_pretty},
  1353   {"get",    json_get},
  1354   {"type",   json_type},
  1355   {"set",    json_set},
  1356   {NULL, NULL}
  1357 };
  1359 // metamethods for JSON objects, JSON arrays, and unknown JSON collections (object or array):
  1360 static const struct luaL_Reg json_metatable_functions[] = {
  1361   {"__len", json_len},
  1362   {"__index", json_index},
  1363   {"__newindex", json_newindex},
  1364   {"__pairs", json_pairs},
  1365   {"__ipairs", json_ipairs},
  1366   {"__tostring", json_export},
  1367   {NULL, NULL}
  1368 };
  1370 // metamethods for JSON null marker:
  1371 static const struct luaL_Reg json_nullmark_metamethods[] = {
  1372   {"__tostring", json_nullmark_tostring},
  1373   {NULL, NULL}
  1374 };
  1376 // initializes json library:
  1377 int luaopen_json(lua_State *L) {
  1378   // empty stack:
  1379   lua_settop(L, 0);
  1380   // push library module onto stack position 1:
  1381   lua_newtable(L);
  1382   // register library functions:
  1383   luaL_setfuncs(L, json_module_functions, 0);
  1384   // create and store objectmt:
  1385   lua_newtable(L);
  1386   luaL_setfuncs(L, json_metatable_functions, 0);
  1387   json_regstore(L, objectmt);
  1388   // create and store arraymt:
  1389   lua_newtable(L);
  1390   luaL_setfuncs(L, json_metatable_functions, 0);
  1391   json_regstore(L, arraymt);
  1392   // create and store ephemeron table to store shadow tables for each JSON object/array
  1393   // to allow NULL values returned as nil
  1394   lua_newtable(L);
  1395   lua_newtable(L);  // metatable for ephemeron table
  1396   lua_pushliteral(L, "__mode");
  1397   lua_pushliteral(L, "k");
  1398   lua_rawset(L, -3);
  1399   lua_setmetatable(L, -2);
  1400   json_regstore(L, shadowtbl);
  1401   // set metatable of null marker and make it available through library module:
  1402   json_pushnullmark(L);
  1403   lua_newtable(L);
  1404   luaL_setfuncs(L, json_nullmark_metamethods, 0);
  1405   lua_setmetatable(L, -2);
  1406   lua_setfield(L, 1, "null");
  1407   // return library module (that's expected on top of stack):
  1408   return 1;
  1409 }
