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