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