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