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