webmcp
view libraries/json/json.c @ 429:387a303918a6
Handle special corner case for integral floats in json.export(...)
| author | jbe | 
|---|---|
| date | Thu Jan 14 18:01:33 2016 +0100 (2016-01-14) | 
| parents | 52ebde158c92 | 
| children | 33d43f5a319b | 
 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     // try to parse number:
   548     double numval;
   549     char *endptr;
   550     size_t endpos;
   551     // use strtod() call to parse a (double precision) floating point number
   552     // and to determine length of number:
   553     numval = strtod(str+pos, &endptr);
   554     // catch parsing errors:
   555     if (endptr == str+pos) goto json_import_syntax_error;
   556     // calculate end position of number:
   557     endpos = endptr - str;
   558 #if LUA_VERSION_NUM >= 503
   559     // try alternative integer interpretation:
   560     {
   561       lua_Integer intval = 0;
   562       size_t curpos;
   563       if (c >= '0' && c <= '9') intval = c - '0';
   564       for (curpos=pos+1; curpos<endpos; curpos++) {
   565         lua_Integer d = str[curpos] - '0';
   566         if (d < 0 || d > 9) break;
   567         if (c == '-') {
   568           // NOTE: rounding of negative integer division may be undefined
   569           if (
   570             intval == LUA_MININTEGER ||
   571             -intval > (-(LUA_MININTEGER+10) - d) / 10 + 1
   572           ) break;
   573           intval = 10 * intval - d;
   574         } else {
   575           if (intval > (LUA_MAXINTEGER - d) / 10) break;
   576           intval = 10 * intval + d;
   577         }
   578       }
   579       if (curpos == endpos) lua_pushinteger(L, intval);
   580       else lua_pushnumber(L, numval);
   581     }
   582 #endif
   583     // consume characters that were parsed:
   584     pos = endpos;
   585   } else if (!strncmp(str+pos, "true", 4)) {
   586     // consume 4 input characters for "true":
   587     pos += 4;
   588     // put Lua true value onto stack:
   589     lua_pushboolean(L, 1);
   590   } else if (!strncmp(str+pos, "false", 5)) {
   591     // consume 5 input characters for "false":
   592     pos += 5;
   593     // put Lua false value onto stack:
   594     lua_pushboolean(L, 0);
   595   } else if (!strncmp(str+pos, "null", 4)) {
   596     // consume 4 input characters for "null":
   597     pos += 4;
   598     // push special null-marker onto stack:
   599     json_pushnullmark(L);
   600   } else {
   601     // all other cases are a syntax error:
   602     goto json_import_syntax_error;
   603   }
   604   // process a decoded value or key value pair (expected on top of Lua stack):
   605   json_import_process_value:
   606   switch (mode) {
   607   // an object key has been read:
   608   case JSON_STATE_OBJECT_KEY:
   609     // if an object key is not a string, then this is a syntax error:
   610     if (lua_type(L, -1) != LUA_TSTRING) goto json_import_syntax_error;
   611     // expect key terminator to follow:
   612     mode = JSON_STATE_OBJECT_KEY_TERMINATOR;
   613     // continue with loop:
   614     goto json_import_loop;
   615   // a key value pair has been read:
   616   case JSON_STATE_OBJECT_VALUE:
   617     // store key value pair in outer shadow table:
   618     lua_rawset(L, -3);
   619     // expect value terminator (or end of object) to follow:
   620     mode = JSON_STATE_OBJECT_SEPARATOR;
   621     // continue with loop:
   622     goto json_import_loop;
   623   // an array value has been read:
   624   case JSON_STATE_ARRAY_VALUE:
   625     // get current array length:
   626     arraylen = lua_rawlen(L, -3);
   627     // throw error if array would exceed INT_MAX-1 elements:
   628     // NOTE: Lua 5.3 may support more elements, but C libraries may not
   629     if (arraylen > INT_MAX-1) {
   630       lua_pushnil(L);
   631       lua_pushfstring(L, "Array exceeded length of %d elements", INT_MAX-1);
   632     }
   633     // store value in outer shadow table:
   634     lua_rawseti(L, -3, arraylen + 1);
   635     // expect value terminator (or end of object) to follow:
   636     mode = JSON_STATE_ARRAY_SEPARATOR;
   637     // continue with loop
   638     goto json_import_loop;
   639   // a single value has been read:
   640   case JSON_STATE_VALUE:
   641     // leave value on top of stack, expect end of JSON document, and continue with loop:
   642     mode = JSON_STATE_END;
   643     goto json_import_loop;
   644   }
   645   // syntax error handling (reachable by goto statement):
   646   json_import_syntax_error:
   647   lua_pushnil(L);
   648   lua_pushliteral(L, "Syntax error in JSON document");
   649   return 2;
   650 }
   652 // gets a value or its type from a JSON document (passed as first argument)
   653 // using a path (passed as variable number of keys after the first argument):
   654 static int json_path(lua_State *L, int type_mode) {
   655   int stacktop;  // number of arguments
   656   int idx = 2;   // stack index of current argument to process
   657   // require at least one argument:
   658   luaL_checkany(L, 1);
   659   // store stack index of top of stack (number of arguments):
   660   stacktop = lua_gettop(L);
   661   // use first argument as "current value" (stored on top of stack):
   662   lua_pushvalue(L, 1);
   663   // process each "path key" (2nd argument and following arguments):
   664   while (idx <= stacktop) {
   665     // if "current value" (on top of stack) is nil, then the path cannot be walked and nil is returned:
   666     if (lua_isnil(L, -1)) return 1;
   667     // try to get shadow table of "current value":
   668     json_getshadow(L, -1);
   669     if (lua_isnil(L, -1)) {
   670       // if no shadow table is found,
   671       if (lua_type(L, -2) == LUA_TTABLE) {
   672         // and if "current value" is a table,
   673         // pop nil from stack:
   674         lua_pop(L, 1);
   675         // get "next value" using the "path key":
   676         lua_pushvalue(L, idx++);
   677         lua_gettable(L, -2);
   678       } else {
   679         // if "current value" is not a table,
   680         // then the path cannot be walked and nil (already on top of stack) is returned:
   681         return 1;
   682       }
   683     } else {
   684       // if a shadow table is found,
   685       // set "current value" to its shadow table:
   686       lua_replace(L, -2);
   687       // get "next value" using the "path key":
   688       lua_pushvalue(L, idx++);
   689       lua_rawget(L, -2);
   690     }
   691     // the "next value" replaces the "current value":
   692     lua_replace(L, -2);
   693   }
   694   if (!type_mode) {
   695     // if a value (and not its type) was requested,
   696     // check if value is the null-marker, and store nil on top of Lua stack in that case:
   697     if (json_isnullmark(L, -1)) lua_pushnil(L);
   698   } else {
   699     // if the type was requested,
   700     // check if value is the null-marker:
   701     if (json_isnullmark(L, -1)) {
   702       // if yes, store string "null" on top of Lua stack:
   703       lua_pushliteral(L, "null");
   704     } else {
   705       // otherwise,
   706       // check if metatable indicates "object" or "array":
   707       if (lua_getmetatable(L, -1)) {
   708         json_regfetch(L, objectmt);
   709         if (lua_rawequal(L, -2, -1)) {
   710           // if value has metatable for JSON objects,
   711           // return string "object":
   712           lua_pushliteral(L, "object");
   713           return 1;
   714         }
   715         json_regfetch(L, arraymt);
   716         if (lua_rawequal(L, -3, -1)) {
   717           // if value has metatable for JSON arrays,
   718           // return string "object":
   719           lua_pushliteral(L, "array");
   720           return 1;
   721         }
   722         // remove 3 metatables (one of the value, two for comparison) from stack:
   723         lua_pop(L, 3);
   724       }
   725       // otherwise, get the Lua type:
   726       lua_pushstring(L, lua_typename(L, lua_type(L, -1)));
   727     }
   728   }
   729   // return the top most value on the Lua stack:
   730   return 1;
   731 }
   733 // gets a value from a JSON document (passed as first argument)
   734 // using a path (passed as variable number of keys after the first argument):
   735 static int json_get(lua_State *L) {
   736   return json_path(L, 0);
   737 }
   739 // gets a value's type from a JSON document (passed as first argument)
   740 // using a path (passed as variable number of keys after first the argument):
   741 static int json_type(lua_State *L) {
   742   return json_path(L, 1);
   743 }
   745 // special Lua stack indicies for json_set function:
   746 #define json_set_objectmt_idx 1
   747 #define json_set_arraymt_idx 2
   749 // stack offset of arguments to json_set function:
   750 #define json_set_idxshift 2
   752 // sets a value (passed as second argument) in a JSON document (passed as first argument)
   753 // using a path (passed as variable number of keys starting at third argument):
   754 static int json_set(lua_State *L) {
   755   int stacktop;  // stack index of top of stack (after shifting)
   756   int idx;       // stack index of current argument to process
   757   // require at least three arguments:
   758   luaL_checkany(L, 1);
   759   luaL_checkany(L, 2);
   760   luaL_checkany(L, 3);
   761   // insert objectmt into stack at position 1 (shifting the arguments):
   762   json_regfetch(L, objectmt);
   763   lua_insert(L, 1);
   764   // insert arraymt into stack at position 2 (shifting the arguments):
   765   json_regfetch(L, arraymt);
   766   lua_insert(L, 2);
   767   // store stack index of top of stack:
   768   stacktop = lua_gettop(L);
   769   // use nil as initial "parent value":
   770   lua_pushnil(L);
   771   // use first argument as "current value":
   772   lua_pushvalue(L, 1 + json_set_idxshift);
   773   // set all necessary values in path:
   774   for (idx = 3 + json_set_idxshift; idx<=stacktop; idx++) {
   775     // push metatable of "current value" onto stack:
   776     if (!lua_getmetatable(L, -1)) lua_pushnil(L);
   777     // distinguish according to type of path key:
   778     switch (lua_type(L, idx)) {
   779     case LUA_TSTRING:
   780       // if path key is a string,
   781       // check if "current value" is a JSON object (or table without metatable):
   782       if (
   783         lua_rawequal(L, -1, json_set_objectmt_idx) ||
   784         (lua_isnil(L, -1) && lua_type(L, -2) == LUA_TTABLE)
   785       ) {
   786         // if "current value" is acceptable,
   787         // pop metatable and leave "current value" on top of stack:
   788         lua_pop(L, 1);
   789       } else {
   790         // if "current value" is not acceptable:
   791         // pop metatable and "current value":
   792         lua_pop(L, 2);
   793         // throw error if parent element does not exist:
   794         if (lua_isnil(L, -1)) return luaL_error(L, "Root element is not a JSON object");
   795         // push new JSON object as "current value" onto stack:
   796         json_createproxy(L);
   797         // create and register shadow table:
   798         lua_newtable(L);
   799         json_setshadow(L, -2);
   800         // set metatable of JSON object: 
   801         lua_pushvalue(L, json_set_objectmt_idx);
   802         lua_setmetatable(L, -2);
   803         // set entry in "parent value":
   804         lua_pushvalue(L, idx-1);
   805         lua_pushvalue(L, -2);
   806         lua_settable(L, -4);
   807       }
   808       break;
   809     case LUA_TNUMBER:
   810       // if path key is a number,
   811       // check if "current value" is a JSON array (or table without metatable):
   812       if (
   813         lua_rawequal(L, -1, json_set_arraymt_idx) ||
   814         (lua_isnil(L, -1) && lua_type(L, -2) == LUA_TTABLE)
   815       ) {
   816         // if "current value" is acceptable,
   817         // pop metatable and leave "current value" on top of stack:
   818         lua_pop(L, 1);
   819       } else {
   820         // if "current value" is not acceptable:
   821         // pop metatable and "current value":
   822         lua_pop(L, 2);
   823         // throw error if parent element does not exist:
   824         if (lua_isnil(L, -1)) return luaL_error(L, "Root element is not a JSON array");
   825         // push new JSON array as "current value" onto stack:
   826         json_createproxy(L);
   827         // create and register shadow table:
   828         lua_newtable(L);
   829         json_setshadow(L, -2);
   830         // set metatable of JSON array: 
   831         lua_pushvalue(L, json_set_arraymt_idx);
   832         lua_setmetatable(L, -2);
   833         // set entry in "parent value":
   834         lua_pushvalue(L, idx-1);
   835         lua_pushvalue(L, -2);
   836         lua_settable(L, -4);
   837       }
   838       break;
   839     default:
   840       return luaL_error(L, "Invalid path key of type %s", lua_typename(L, lua_type(L, idx)));
   841     }
   842     // check if last path element is being processed:
   843     if (idx == stacktop) {
   844       // if the last path element is being processed,
   845       // set last path value in "current value" container:
   846       lua_pushvalue(L, idx);
   847       lua_pushvalue(L, 2 + json_set_idxshift);
   848       lua_settable(L, -3);
   849     } else {
   850       // if the processed path element is not the last,
   851       // use old "current value" as new "parent value"
   852       lua_remove(L, -2);
   853       // push new "current value" onto stack by performing a lookup:
   854       lua_pushvalue(L, idx);
   855       lua_gettable(L, -2);
   856     }
   857   }
   858   // return first argument for convenience:
   859   lua_settop(L, 1 + json_set_idxshift);
   860   return 1;
   861 }
   863 // returns the length of a JSON array (or zero for a table without numeric keys):
   864 static int json_len(lua_State *L) {
   865   // require table as first argument:
   866   luaL_checktype(L, 1, LUA_TTABLE);
   867   // stack shall contain one function argument:
   868   lua_settop(L, 1);
   869   // push shadow table or nil onto stack:
   870   json_getshadow(L, 1);
   871   // pop nil from stack if no shadow table has been found:
   872   if (lua_isnil(L, -1)) lua_pop(L, 1);
   873   // return length of argument or shadow table:
   874   lua_pushnumber(L, lua_rawlen(L, -1));
   875   return 1;
   876 }
   878 // __index metamethod for JSON objects and JSON arrays:
   879 static int json_index(lua_State *L) {
   880   // require table as first argument:
   881   luaL_checktype(L, 1, LUA_TTABLE);
   882   // stack shall contain two function arguments:
   883   lua_settop(L, 2);
   884   // replace first argument with its shadow table
   885   // or throw error if no shadow table is found:
   886   json_getshadow(L, 1);
   887   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   888   lua_replace(L, 1);
   889   // use key passed as second argument to lookup value in shadow table:
   890   lua_rawget(L, 1);
   891   // if value is null-marker, then push nil onto stack:
   892   if (json_isnullmark(L, 2)) lua_pushnil(L);
   893   // return either looked up value, or nil
   894   return 1;
   895 }
   897 // __newindex metamethod for JSON objects and JSON arrays:
   898 static int json_newindex(lua_State *L) {
   899   // require table as first argument
   900   luaL_checktype(L, 1, LUA_TTABLE);
   901   // stack shall contain three function arguments:
   902   lua_settop(L, 3);
   903   // replace first argument with its shadow table
   904   // or throw error if no shadow table is found:
   905   json_getshadow(L, 1);
   906   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   907   lua_replace(L, 1);
   908   // second and third argument to write to shadow table:
   909   lua_rawset(L, 1);
   910   // return nothing:
   911   return 0;
   912 }
   914 // function returned as first value by json_pairs function:
   915 static int json_pairs_iterfunc(lua_State *L) {
   916   // require table as first argument
   917   luaL_checktype(L, 1, LUA_TTABLE);
   918   // stack shall contain two function arguments:
   919   lua_settop(L, 2);
   920   // get next key value pair from shadow table (argument 1) using previous key (argument 2)
   921   // and return nothing if there is no next pair:
   922   if (!lua_next(L, 1)) return 0;
   923   // replace null-marker with nil:
   924   if (json_isnullmark(L, -1)) {
   925     lua_pop(L, 1);
   926     lua_pushnil(L);
   927   }
   928   // return key and value (or key and nil, if null-marker was found):
   929   return 2;
   930 }
   932 // returns a triple such that 'for key, value in pairs(obj) do ... end'
   933 // iterates through all key value pairs (including JSON null values represented as Lua nil):
   934 static int json_pairs(lua_State *L) {
   935   // require table as first argument
   936   luaL_checktype(L, 1, LUA_TTABLE);
   937   // return triple of function json_pairs_iterfunc, shadow table of first argument, and nil:
   938   lua_pushcfunction(L, json_pairs_iterfunc);
   939   json_getshadow(L, 1);
   940   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   941   lua_pushnil(L);
   942   return 3;
   943 }
   945 // function returned as first value by json_ipairs function:
   946 static int json_ipairs_iterfunc(lua_State *L) {
   947   lua_Integer idx;
   948   // require table as first argument
   949   luaL_checktype(L, 1, LUA_TTABLE);
   950   // stack shall contain two function arguments:
   951   lua_settop(L, 2);
   952   // calculate new index by incrementing second argument:
   953   idx = lua_tointeger(L, 2) + 1;
   954   // do integer lookup in shadow table and store result on stack position 3:
   955   lua_rawgeti(L, 1, idx);
   956   // return nothing if there was no value:
   957   if (lua_isnil(L, 3)) return 0;
   958   // return new index and
   959   // either the looked up value if it is not equal to the null-marker
   960   // or nil instead of null-marker:
   961   lua_pushinteger(L, idx);
   962   if (json_isnullmark(L, 3)) lua_pushnil(L);
   963   else lua_pushvalue(L, 3);
   964   return 2;
   965 }
   967 // returns a triple such that 'for idx, value in ipairs(ary) do ... end'
   968 // iterates through all values (including JSON null values represented as Lua nil):
   969 static int json_ipairs(lua_State *L) {
   970   // require table as first argument
   971   luaL_checktype(L, 1, LUA_TTABLE);
   972   // return triple of function json_ipairs_iterfunc, shadow table of first argument, and zero:
   973   lua_pushcfunction(L, json_ipairs_iterfunc);
   974   json_getshadow(L, 1);
   975   if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found");
   976   lua_pushinteger(L, 0);
   977   return 3;
   978 }
   980 // datatype representing a table key:
   981 // (used for sorting)
   982 typedef struct {
   983   size_t length;
   984   const char *data;
   985 } json_key_t;
   987 // comparation function for table keys to be passed to qsort function:
   988 static int json_key_cmp(json_key_t *key1, json_key_t *key2) {
   989   size_t pos = 0;
   990   unsigned char c1, c2;
   991   while (1) {
   992     if (key1->length > pos) {
   993       if (key2->length > pos) {
   994         c1 = key1->data[pos];
   995         c2 = key2->data[pos];
   996         if (c1 < c2) return -1;
   997         else if (c1 > c2) return 1;
   998       } else {
   999         return 1;
  1000       }
  1001     } else {
  1002       if (key2->length > pos) {
  1003         return -1;
  1004       } else {
  1005         return 0;
  1006       }
  1007     }
  1008     pos++;
  1009   }
  1010 }
  1012 // constants for type detection of ambiguous tables:
  1013 #define JSON_TABLETYPE_UNKNOWN 0
  1014 #define JSON_TABLETYPE_OBJECT 1
  1015 #define JSON_TABLETYPE_ARRAY 2
  1017 typedef struct {
  1018   int type;
  1019   int pos;
  1020   int count;
  1021   json_key_t keys[1];  // or more
  1022 } json_container_t;
  1024 // special Lua stack indicies for json_export function:
  1025 #define json_export_value_idx 1
  1026 #define json_export_indentstring_idx 2
  1027 #define json_export_objectmt_idx 3
  1028 #define json_export_arraymt_idx 4
  1029 #define json_export_stackswap_idx 5
  1030 #define json_export_luacontainer_idx 6
  1031 #define json_export_ccontainer_idx 7
  1032 #define json_export_buffer_idx 8
  1034 // encodes a JSON document (passed as first argument)
  1035 // optionally using indentation (indentation string or true passed as second argument)
  1036 static int json_export(lua_State *L) {
  1037   int pretty;           // pretty printing on? (i.e. printing with indentation)
  1038   luaL_Buffer buf;      // Lua buffer containing result string
  1039   lua_Number num;       // number to encode
  1040   char numstr[80];      // encoded number
  1041                         // (21 chars needed for sign, zero, point, 17 significant digits, and NULL byte)
  1042                         // (21 chars needed for sign, 19 digits INT64, and NULL byte)
  1043                         // (80 chars needed for sign, 78 digits INT256, and NULL byte)
  1044                         // (NOTE: we don't know the size of intmax_t and thus use 80)
  1045   const char *str;      // string to encode
  1046   size_t strlen;        // length of string to encode
  1047   size_t strpos ;       // position in string or position of current key
  1048   unsigned char c;      // character to encode (unsigned!)
  1049   char hexcode[7];      // store for unicode hex escape sequence
  1050                         // NOTE: 7 bytes due to backslash, character 'u', 4 hex digits, and terminating NULL byte
  1051   int tabletype;        // table type: unknown, JSON object, or JSON array
  1052   size_t keycount = 0;  // number of string keys in object
  1053   json_key_t *key;      // pointer to C structure containing a string key
  1054   int level = 0;        // current depth level
  1055   int i;                // iteration variable for level dependent repetitions
  1056   int stackswapidx = 0; // elements in stack swap table
  1057   int containerkey = 0; // temporarily set to 1, if a container key is being encoded
  1058   json_container_t *container = NULL; // pointer to current C struct for container information
  1059   // stack shall contain two function arguments:
  1060   lua_settop(L, 2);
  1061   // check if pretty printing (with indentation) is desired:
  1062   if (lua_toboolean(L, json_export_indentstring_idx)) {
  1063     // if yes,
  1064     // set pretty variable to 1:
  1065     pretty = 1;
  1066     // check if second argument is a boolean (true):
  1067     if (lua_isboolean(L, json_export_indentstring_idx)) {
  1068       // if yes,
  1069       // use default indentation if indentation argument is boolean true:
  1070       lua_pushliteral(L, "  ");
  1071       lua_replace(L, json_export_indentstring_idx);
  1072     } else {
  1073       // if no,
  1074       // require second argument to be a string:
  1075       luaL_checktype(L, json_export_indentstring_idx, LUA_TSTRING);
  1076     }
  1077   } else {
  1078     // if no,
  1079     // set pretty variable to 0:
  1080     pretty = 0;
  1081   }
  1082   // push objectmt onto stack position 3:
  1083   json_regfetch(L, objectmt);
  1084   // push arraymt onto stack position 4:
  1085   json_regfetch(L, arraymt);
  1086   // push table for stack swapping onto stack position 5:
  1087   lua_newtable(L);
  1088   // create placeholders on stack positions 6 through 7:
  1089   lua_settop(L, json_export_buffer_idx);
  1090   // create Lua string buffer:
  1091   luaL_buffinit(L, &buf);
  1092   // loop:
  1093   while (1) {
  1094     // if value to encode is the null-marker, then treat it the same as nil:
  1095     if (json_isnullmark(L, json_export_value_idx)) {
  1096       lua_pushnil(L);
  1097       lua_replace(L, json_export_value_idx);
  1098     }
  1099     // distinguish between different Lua types:
  1100     switch (lua_type(L, json_export_value_idx)) {
  1101     // value to encode is nil:
  1102     case LUA_TNIL:
  1103       // add string "null" to output buffer:
  1104       luaL_addstring(&buf, "null");
  1105       break;
  1106     // value to encode is of type number:
  1107     case LUA_TNUMBER:
  1108 #if LUA_VERSION_NUM >= 503
  1109       // handle integers:
  1110       if (lua_isinteger(L, json_export_value_idx)) {
  1111         sprintf(numstr, "%ji", (intmax_t)lua_tointeger(L, json_export_value_idx));
  1112         luaL_addstring(&buf, numstr);
  1113         break;
  1114       }
  1115 #endif
  1116       // convert value to double precision number:
  1117       num = lua_tonumber(L, json_export_value_idx);
  1118       // throw error if number is not-a-number:
  1119       if (isnan(num)) return luaL_error(L, "JSON export not possible for NaN value");
  1120       // throw error if number is positive or negative infinity:
  1121       if (isinf(num)) return luaL_error(L, "JSON export not possible for infinite numbers");
  1122       // check if float is integral:
  1123       if (trunc(num) == num) {
  1124         // if yes, use maximum precision:
  1125         sprintf(numstr, "%.17g", num);  // NOTE: e.g. 12345678901234560
  1126       } else {
  1127         // determine necessary precision to represent double precision floating point number:
  1128         sprintf(numstr, "%.15g", num);  // NOTE: e.g. 0.009 should not be 0.008999999999999999
  1129         if (strtod(numstr, NULL) != num) sprintf(numstr, "%.16g", num);
  1130         if (strtod(numstr, NULL) != num) sprintf(numstr, "%.17g", num);
  1131       }
  1132       // add string encoding of the number to the output buffer:
  1133       luaL_addstring(&buf, numstr);
  1134 #if LUA_VERSION_NUM >= 503
  1135       // enforce trailing ".0" for floats unless exponential notation was chosen:
  1136       {
  1137         char *p;
  1138         if (numstr[0] == '-' || numstr[0] == '+') p = numstr+1;
  1139         else p = numstr;
  1140         for (; *p; p++) if (*p < '0' || *p > '9') break;
  1141         if (!*p) luaL_addstring(&buf, ".0");
  1142       }
  1143 #endif
  1144       break;
  1145     // value to encode is of type boolean:
  1146     case LUA_TBOOLEAN:
  1147       // add string "true" or "false" according to boolean value:
  1148       luaL_addstring(&buf, lua_toboolean(L, json_export_value_idx) ? "true" : "false");
  1149       break;
  1150     // value to encode is of type string:
  1151     case LUA_TSTRING:
  1152       // add quoted and escaped string to output buffer:
  1153       str = lua_tolstring(L, json_export_value_idx, &strlen);
  1154       luaL_addchar(&buf, '"');
  1155       strpos = 0;
  1156       while (strpos < strlen) {
  1157         c = str[strpos++];
  1158         if (c == '"')       luaL_addstring(&buf, "\\\"");
  1159         else if (c == '\\') luaL_addstring(&buf, "\\\\");
  1160         else if (c == 127)  luaL_addstring(&buf, "\\u007F");
  1161         else if (c >= 32)   luaL_addchar(&buf, c);
  1162         else if (c == '\b') luaL_addstring(&buf, "\\b");
  1163         else if (c == '\f') luaL_addstring(&buf, "\\f");
  1164         else if (c == '\n') luaL_addstring(&buf, "\\n");
  1165         else if (c == '\r') luaL_addstring(&buf, "\\r");
  1166         else if (c == '\t') luaL_addstring(&buf, "\\t");
  1167         else if (c == '\v') luaL_addstring(&buf, "\\v");
  1168         else {
  1169           sprintf(hexcode, "\\u%04X", c);
  1170           luaL_addstring(&buf, hexcode);
  1171         }
  1172       }
  1173       luaL_addchar(&buf, '"');
  1174       break;
  1175     // value to encode is of type table (this includes JSON objects and JSON arrays):
  1176     case LUA_TTABLE:
  1177       // use table's metatable to try to determine type of table:
  1178       tabletype = JSON_TABLETYPE_UNKNOWN;
  1179       if (lua_getmetatable(L, json_export_value_idx)) {
  1180         if (lua_rawequal(L, -1, json_export_objectmt_idx)) {
  1181           tabletype = JSON_TABLETYPE_OBJECT;
  1182         } else {
  1183           if (lua_rawequal(L, -1, json_export_arraymt_idx)) {
  1184             tabletype = JSON_TABLETYPE_ARRAY;
  1185           } else {
  1186             return luaL_error(L, "JSON export not possible for tables with nonsupported metatable");
  1187           }
  1188         }
  1189         // reset stack (pop metatable from stack):
  1190         lua_pop(L, 1);
  1191       }
  1192       // replace table with its shadow table if existent:
  1193       json_getshadow(L, json_export_value_idx);
  1194       if (lua_isnil(L, -1)) lua_pop(L, 1);
  1195       else lua_replace(L, json_export_value_idx); 
  1196       // check if type of table is still undetermined
  1197       // and optionally calculate number of string keys (keycount)
  1198       // or set keycount to zero:
  1199       keycount = 0;
  1200       if (tabletype == JSON_TABLETYPE_UNKNOWN) {
  1201         // if type of table is undetermined,
  1202         // iterate over all keys:
  1203         for (lua_pushnil(L); lua_next(L, json_export_value_idx); lua_pop(L, 1)) {
  1204           switch (lua_type(L, -2)) {
  1205           case LUA_TSTRING:
  1206             // for string keys,
  1207             // increase keycount (may avoid another iteration):
  1208             keycount++;
  1209             // if type of table was unknown, then type of table is a JSON object now:
  1210             if (tabletype == JSON_TABLETYPE_UNKNOWN) tabletype = JSON_TABLETYPE_OBJECT;
  1211             // if type of table was a JSON array, then the type of table is ambiguous now
  1212             // and an error is thrown:
  1213             else if (tabletype == JSON_TABLETYPE_ARRAY) goto json_export_tabletype_error;
  1214             break;
  1215           case LUA_TNUMBER:
  1216             // for numeric keys,
  1217             // if type of table was unknown, then type of table is a JSON array now:
  1218             if (tabletype == JSON_TABLETYPE_UNKNOWN) tabletype = JSON_TABLETYPE_ARRAY;
  1219             // if type of table was a JSON object, then the type of table is ambiguous now
  1220             // and an error is thrown:
  1221             else if (tabletype == JSON_TABLETYPE_OBJECT) goto json_export_tabletype_error;
  1222             break;
  1223           }
  1224         }
  1225       }
  1226       // raise error if too many nested levels:
  1227       if (level >= JSON_MAXDEPTH) {
  1228         return luaL_error(L, "More than %d nested JSON levels", JSON_MAXDEPTH);
  1229       }
  1230       // store previous container information (if existent) on stack swap
  1231       // and increase level variable:
  1232       if (level++) {
  1233         lua_pushvalue(L, json_export_luacontainer_idx);
  1234         lua_rawseti(L, json_export_stackswap_idx, ++stackswapidx);
  1235         lua_pushvalue(L, json_export_ccontainer_idx);
  1236         lua_rawseti(L, json_export_stackswap_idx, ++stackswapidx);
  1237       }
  1238       // use value as current container:
  1239       lua_pushvalue(L, json_export_value_idx);
  1240       lua_replace(L, json_export_luacontainer_idx);
  1241       // distinguish between JSON objects and JSON arrays:
  1242       switch (tabletype) {
  1243       // JSON object:
  1244       case JSON_TABLETYPE_OBJECT:
  1245         // calculate count of string keys unless it has been calculated before:
  1246         if (!keycount) {
  1247           for (lua_pushnil(L); lua_next(L, json_export_luacontainer_idx); lua_pop(L, 1)) {
  1248             if (lua_type(L, -2) == LUA_TSTRING) keycount++;
  1249           }
  1250         }
  1251         // allocate memory for C structure containing string keys and container iteration state:
  1252         container = lua_newuserdata(L, sizeof(json_container_t) + (keycount-1) * sizeof(json_key_t));
  1253         // store reference to C structure on designated stack position:
  1254         lua_replace(L, json_export_ccontainer_idx);
  1255         // initialize C structure for container state:
  1256         container->type = JSON_TABLETYPE_OBJECT;
  1257         container->count = keycount;
  1258         container->pos = 0;
  1259         // check if object contains any keys:
  1260         if (keycount) {
  1261           // if yes,
  1262           // copy all string keys to the C structure (and reset container->pos again):
  1263           for (lua_pushnil(L); lua_next(L, json_export_luacontainer_idx); lua_pop(L, 1)) {
  1264             if (lua_type(L, -2) == LUA_TSTRING) {
  1265               json_key_t *key = &container->keys[container->pos++];
  1266               key->data = lua_tolstring(L, -2, &key->length);
  1267             }
  1268           }
  1269           container->pos = 0;
  1270           // sort C array using quicksort:
  1271           qsort(container->keys, keycount, sizeof(json_key_t), (void *)json_key_cmp);
  1272         }
  1273         // add opening bracket to output buffer:
  1274         luaL_addchar(&buf, '{');
  1275         break;
  1276       // JSON array:
  1277       case JSON_TABLETYPE_ARRAY:
  1278         // allocate memory for C structure for container iteration state:
  1279         container = lua_newuserdata(L, sizeof(json_container_t) - sizeof(json_key_t));
  1280         // store reference to C structure on designated stack position:
  1281         lua_replace(L, json_export_ccontainer_idx);
  1282         // initialize C structure for container state:
  1283         container->type = JSON_TABLETYPE_ARRAY;
  1284         container->pos = 0;
  1285         // add opening bracket to output buffer:
  1286         luaL_addchar(&buf, '[');
  1287         break;
  1288       default:
  1289         // throw error if table type is unknown:
  1290         json_export_tabletype_error:
  1291         return luaL_error(L, "JSON export not possible for ambiguous table (cannot decide whether it is an object or array)");
  1292       }
  1293       break;
  1294     default:
  1295     // all other datatypes are considered an error:
  1296     return luaL_error(L, "JSON export not possible for values of type \"%s\"", lua_typename(L, lua_type(L, json_export_value_idx)));
  1297     }
  1298     // check if a container is being processed:
  1299     if (container) {
  1300       // if yes,
  1301       // execute code for container iteration:
  1302       json_export_container:
  1303       // distinguish between JSON objects and JSON arrays:
  1304       switch (container->type) {
  1305       // JSON object:
  1306       case JSON_TABLETYPE_OBJECT:
  1307         // finish iteration if all string keys have been processed:
  1308         if (container->pos == container->count) goto json_export_close;
  1309         // push current string key on top of stack:
  1310         key = &container->keys[container->pos];
  1311         lua_pushlstring(L, key->data, key->length);
  1312         // check if the key has already been exported:
  1313         if (!containerkey) {
  1314           // if no,
  1315           // add a comma to the output buffer if necessary:
  1316           if (container->pos) luaL_addchar(&buf, ',');
  1317           // set containerkey variable to true:
  1318           containerkey = 1;
  1319         } else {
  1320           // if a key has already been exported,
  1321           // add a colon to the output buffer:
  1322           luaL_addchar(&buf, ':');
  1323           // add a space to the output buffer for pretty results:
  1324           if (pretty) luaL_addchar(&buf, ' ');
  1325           // replace string key on top of stack with corresponding value:
  1326           lua_rawget(L, json_export_luacontainer_idx);
  1327           // reset containerkey variable
  1328           containerkey = 0;
  1329           // increase number of processed key value pairs:
  1330           container->pos++;
  1331         }
  1332         // store key or value on top of stack in designated stack position:
  1333         lua_replace(L, json_export_value_idx);
  1334         break;
  1335       // JSON array:
  1336       case JSON_TABLETYPE_ARRAY:
  1337         // store next value in designated stack position:
  1338         lua_rawgeti(L, json_export_luacontainer_idx, container->pos+1);
  1339         lua_replace(L, json_export_value_idx);
  1340         // finish iteration if value is nil:
  1341         if (lua_isnil(L, json_export_value_idx)) goto json_export_close;
  1342         // add a comma to the output buffer if necessary:
  1343         if (container->pos) luaL_addchar(&buf, ',');
  1344         // increase number of processed values:
  1345         container->pos++;
  1346         break;
  1347       // common code for closing JSON objects or JSON arrays:
  1348       json_export_close:
  1349         // decrement level variable:
  1350         level--;
  1351         // handle indentation for pretty results:
  1352         if (pretty && container->pos) {
  1353           luaL_addchar(&buf, '\n');
  1354           for (i=0; i<level; i++) {
  1355             lua_pushvalue(L, json_export_indentstring_idx);
  1356             luaL_addvalue(&buf);
  1357           }
  1358         }
  1359         // add closing bracket to output buffer:
  1360         luaL_addchar(&buf, container->type == JSON_TABLETYPE_OBJECT ? '}' : ']');
  1361         // finish export if last level has been closed:
  1362         if (!level) goto json_export_finish;
  1363         // otherwise,
  1364         // recall previous container information from stack swap
  1365         // and set C pointer to corresponding C struct:
  1366         lua_rawgeti(L, json_export_stackswap_idx, stackswapidx--);
  1367         lua_replace(L, json_export_ccontainer_idx);
  1368         container = lua_touserdata(L, json_export_ccontainer_idx);
  1369         lua_rawgeti(L, json_export_stackswap_idx, stackswapidx--);
  1370         lua_replace(L, json_export_luacontainer_idx);
  1371         // repeat code for container iteration:
  1372         goto json_export_container;
  1373       }
  1374       // handle indentation for pretty results:
  1375       if (pretty && (containerkey || container->type == JSON_TABLETYPE_ARRAY)) {
  1376         luaL_addchar(&buf, '\n');
  1377         for (i=0; i<level; i++) {
  1378           lua_pushvalue(L, json_export_indentstring_idx);
  1379           luaL_addvalue(&buf);
  1380         }
  1381       }
  1382     } else {
  1383       // if no container is being processed,
  1384       // finish export:
  1385       json_export_finish:
  1386       // for pretty results, add final newline character if outermost container is processed:
  1387       if (pretty) luaL_addchar(&buf, '\n');
  1388       // create and return Lua string from buffer contents
  1389       luaL_pushresult(&buf);
  1390       return 1;
  1391     }
  1392   }
  1393 }
  1395 // functions in library module:
  1396 static const struct luaL_Reg json_module_functions[] = {
  1397   {"object", json_object},
  1398   {"array",  json_array},
  1399   {"import", json_import},
  1400   {"export", json_export},
  1401   {"get",    json_get},
  1402   {"type",   json_type},
  1403   {"set",    json_set},
  1404   {NULL, NULL}
  1405 };
  1407 // metamethods for JSON objects, JSON arrays, and unknown JSON collections (object or array):
  1408 static const struct luaL_Reg json_metatable_functions[] = {
  1409   {"__len", json_len},
  1410   {"__index", json_index},
  1411   {"__newindex", json_newindex},
  1412   {"__pairs", json_pairs},
  1413   {"__ipairs", json_ipairs},
  1414   {"__tostring", json_export},
  1415   {NULL, NULL}
  1416 };
  1418 // metamethods for JSON null marker:
  1419 static const struct luaL_Reg json_nullmark_metamethods[] = {
  1420   {"__tostring", json_nullmark_tostring},
  1421   {NULL, NULL}
  1422 };
  1424 // initializes json library:
  1425 int luaopen_json(lua_State *L) {
  1426   // empty stack:
  1427   lua_settop(L, 0);
  1428   // push library module onto stack position 1:
  1429   lua_newtable(L);
  1430   // register library functions:
  1431   luaL_setfuncs(L, json_module_functions, 0);
  1432   // create and store objectmt:
  1433   lua_newtable(L);
  1434   luaL_setfuncs(L, json_metatable_functions, 0);
  1435   json_regstore(L, objectmt);
  1436   // create and store arraymt:
  1437   lua_newtable(L);
  1438   luaL_setfuncs(L, json_metatable_functions, 0);
  1439   json_regstore(L, arraymt);
  1440   // set metatable of null marker and make it available through library module:
  1441   json_pushnullmark(L);
  1442   lua_newtable(L);
  1443   luaL_setfuncs(L, json_nullmark_metamethods, 0);
  1444   lua_setmetatable(L, -2);
  1445   lua_setfield(L, 1, "null");
  1446   // return library module (that's expected on top of stack):
  1447   return 1;
  1448 }
