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