sjson.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. #define LUA_LIB
  2. #include "lauxlib.h"
  3. #ifndef LOCAL_LUA
  4. #include "module.h"
  5. #include <string.h>
  6. #include <math.h>
  7. #include <limits.h>
  8. #endif
  9. #include "sjson/json_config.h"
  10. #include "sjson/jsonsl.h"
  11. #define LUA_SJSONLIBNAME "sjson"
  12. #define DEFAULT_DEPTH 20
  13. #define DBG_PRINTF(...)
  14. typedef struct {
  15. jsonsl_t jsn;
  16. int result_ref;
  17. int hkey_ref;
  18. int null_ref;
  19. int metatable;
  20. int pos_ref;
  21. uint8_t complete;
  22. const char *error;
  23. lua_State *L;
  24. size_t min_needed;
  25. size_t min_available;
  26. size_t buffer_len;
  27. const char *buffer; // Points into buffer_ref
  28. int buffer_ref;
  29. } JSN_DATA;
  30. #define get_parent_object_ref() ((state->level == 1) ? data->result_ref : state[-1].lua_object_ref)
  31. #define get_parent_object_used_count_pre_inc() ((state->level == 1) ? 1 : ++state[-1].used_count)
  32. static const char* get_state_buffer(JSN_DATA *ctx, struct jsonsl_state_st *state)
  33. {
  34. size_t offset = state->pos_begin - ctx->min_available;
  35. return ctx->buffer + offset;
  36. }
  37. // The elem data is a ref
  38. static int error_callback(jsonsl_t jsn,
  39. jsonsl_error_t err,
  40. struct jsonsl_state_st *state,
  41. char *at)
  42. {
  43. JSN_DATA *data = (JSN_DATA *) jsn->data;
  44. if (!data->complete) {
  45. data->error = jsonsl_strerror(err);
  46. }
  47. //fprintf(stderr, "Got error at pos %lu: %s\n", jsn->pos, jsonsl_strerror(err));
  48. return 0;
  49. }
  50. static void
  51. create_table(JSN_DATA *data) {
  52. lua_newtable(data->L);
  53. if (data->metatable != LUA_NOREF) {
  54. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->metatable);
  55. lua_setmetatable(data->L, -2);
  56. }
  57. }
  58. static void
  59. create_new_element(jsonsl_t jsn,
  60. jsonsl_action_t action,
  61. struct jsonsl_state_st *state,
  62. const char *buf)
  63. {
  64. JSN_DATA *data = jsn->data;
  65. DBG_PRINTF("L%d: new action %d @ %d state->type %s\n", state->level, action, state->pos_begin, jsonsl_strtype(state->type));
  66. DBG_PRINTF("buf: '%s' ('%.10s')\n", buf, get_state_buffer(data, state));
  67. state->lua_object_ref = LUA_NOREF;
  68. switch(state->type) {
  69. case JSONSL_T_SPECIAL:
  70. case JSONSL_T_STRING:
  71. case JSONSL_T_HKEY:
  72. break;
  73. case JSONSL_T_LIST:
  74. case JSONSL_T_OBJECT:
  75. create_table(data);
  76. state->lua_object_ref = luaL_ref(data->L, LUA_REGISTRYINDEX);
  77. state->used_count = 0;
  78. lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
  79. if (data->hkey_ref == LUA_NOREF) {
  80. // list, so append
  81. lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
  82. DBG_PRINTF("Adding array element\n");
  83. } else {
  84. // object, so
  85. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
  86. luaL_unref(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
  87. data->hkey_ref = LUA_NOREF;
  88. DBG_PRINTF("Adding hash element\n");
  89. }
  90. if (data->pos_ref != LUA_NOREF && state->level > 1) {
  91. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
  92. lua_pushinteger(data->L, state->level - 1);
  93. lua_pushvalue(data->L, -3); // get the key
  94. lua_settable(data->L, -3);
  95. lua_pop(data->L, 1);
  96. }
  97. // At this point, the stack:
  98. // top: index/hash key
  99. // : table
  100. int want_value = 1;
  101. // Invoke the checkpath method if possible
  102. if (data->pos_ref != LUA_NOREF) {
  103. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->metatable);
  104. lua_getfield(data->L, -1, "checkpath");
  105. if (!lua_isnil(data->L, -1)) {
  106. // Call with the new table and the path as arguments
  107. lua_rawgeti(data->L, LUA_REGISTRYINDEX, state->lua_object_ref);
  108. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
  109. lua_call(data->L, 2, 1);
  110. want_value = lua_toboolean(data->L, -1);
  111. }
  112. lua_pop(data->L, 2); // Discard the metatable and either the getfield result or retval
  113. }
  114. if (want_value) {
  115. lua_rawgeti(data->L, LUA_REGISTRYINDEX, state->lua_object_ref);
  116. lua_settable(data->L, -3);
  117. lua_pop(data->L, 1); // the table
  118. } else {
  119. lua_pop(data->L, 2); // the index and table
  120. }
  121. break;
  122. default:
  123. DBG_PRINTF("Unhandled type %c\n", state->type);
  124. luaL_error(data->L, "Unhandled type");
  125. break;
  126. }
  127. data->min_needed = state->pos_begin;
  128. }
  129. static void push_number(JSN_DATA *data, struct jsonsl_state_st *state) {
  130. const char *start = get_state_buffer(data, state);
  131. const char *end = start + state->pos_cur - state->pos_begin;
  132. lua_pushlstring(data->L, start, end - start);
  133. #if LUA_VERSION_NUM >= 503
  134. int sz = lua_stringtonumber(data->L, lua_tostring(data->L, -1));
  135. if (sz) {
  136. lua_pop(data->L, 1);
  137. } else {
  138. luaL_error(data->L, "Invalid number");
  139. }
  140. #else
  141. lua_Number result = lua_tonumber(data->L, -1);
  142. lua_pop(data->L, 1);
  143. lua_pushnumber(data->L, result);
  144. #endif
  145. }
  146. static int fromhex(char c) {
  147. if (c <= '9') {
  148. return c & 0xf;
  149. }
  150. return ((c - 'A' + 10) & 0xf);
  151. }
  152. static void output_utf8(luaL_Buffer *buf, int c) {
  153. char space[4];
  154. char *b = space;
  155. if (c<0x80) *b++=c;
  156. else if (c<0x800) *b++=192+c/64, *b++=128+c%64;
  157. else if (c-0xd800u<0x800) *b++ = '?';
  158. else if (c<0x10000) *b++=224+c/4096, *b++=128+c/64%64, *b++=128+c%64;
  159. else if (c<0x110000) *b++=240+c/262144, *b++=128+c/4096%64, *b++=128+c/64%64, *b++=128+c%64;
  160. else *b++ = '?';
  161. luaL_addlstring(buf, space, b - space);
  162. }
  163. static void push_string(JSN_DATA *data, struct jsonsl_state_st *state) {
  164. luaL_Buffer b;
  165. luaL_buffinit(data->L, &b);
  166. int i;
  167. const char *c = get_state_buffer(data, state) + 1;
  168. for (i = 0; i < state->pos_cur - state->pos_begin - 1; i++) {
  169. int nc = c[i];
  170. if (nc == '\\') {
  171. i++;
  172. nc = c[i] & 255;
  173. switch (c[i]) {
  174. case 'b':
  175. nc = '\b';
  176. break;
  177. case 'f':
  178. nc = '\f';
  179. break;
  180. case 'n':
  181. nc = '\n';
  182. break;
  183. case 'r':
  184. nc = '\r';
  185. break;
  186. case 't':
  187. nc = '\t';
  188. break;
  189. case 'u':
  190. nc = fromhex(c[++i]) << 12;
  191. nc += fromhex(c[++i]) << 8;
  192. nc += fromhex(c[++i]) << 4;
  193. nc += fromhex(c[++i]) ;
  194. output_utf8(&b, nc);
  195. continue;
  196. }
  197. }
  198. luaL_addchar(&b, nc);
  199. }
  200. luaL_pushresult(&b);
  201. }
  202. static void
  203. cleanup_closing_element(jsonsl_t jsn,
  204. jsonsl_action_t action,
  205. struct jsonsl_state_st *state,
  206. const char *at)
  207. {
  208. JSN_DATA *data = (JSN_DATA *) jsn->data;
  209. DBG_PRINTF( "L%d: cc action %d state->type %s\n", state->level, action, jsonsl_strtype(state->type));
  210. DBG_PRINTF( "buf (%d - %d): '%.*s'\n", state->pos_begin, state->pos_cur, state->pos_cur - state->pos_begin, get_state_buffer(data, state));
  211. DBG_PRINTF( "at: '%s'\n", at);
  212. switch (state->type) {
  213. case JSONSL_T_HKEY:
  214. push_string(data, state);
  215. data->hkey_ref = luaL_ref(data->L, LUA_REGISTRYINDEX);
  216. break;
  217. case JSONSL_T_STRING:
  218. lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
  219. if (data->hkey_ref == LUA_NOREF) {
  220. // list, so append
  221. lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
  222. } else {
  223. // object, so
  224. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
  225. luaL_unref(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
  226. data->hkey_ref = LUA_NOREF;
  227. }
  228. push_string(data, state);
  229. lua_settable(data->L, -3);
  230. lua_pop(data->L, 1);
  231. break;
  232. case JSONSL_T_SPECIAL:
  233. DBG_PRINTF("Special flags = 0x%x\n", state->special_flags);
  234. // need to deal with true/false/null
  235. if (state->special_flags & (JSONSL_SPECIALf_TRUE|JSONSL_SPECIALf_FALSE|JSONSL_SPECIALf_NUMERIC|JSONSL_SPECIALf_NULL)) {
  236. if (state->special_flags & JSONSL_SPECIALf_TRUE) {
  237. lua_pushboolean(data->L, 1);
  238. } else if (state->special_flags & JSONSL_SPECIALf_FALSE) {
  239. lua_pushboolean(data->L, 0);
  240. } else if (state->special_flags & JSONSL_SPECIALf_NULL) {
  241. DBG_PRINTF("Outputting null\n");
  242. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->null_ref);
  243. } else if (state->special_flags & JSONSL_SPECIALf_NUMERIC) {
  244. push_number(data, state);
  245. }
  246. lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
  247. if (data->hkey_ref == LUA_NOREF) {
  248. // list, so append
  249. lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
  250. } else {
  251. // object, so
  252. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
  253. luaL_unref(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
  254. data->hkey_ref = LUA_NOREF;
  255. }
  256. lua_pushvalue(data->L, -3);
  257. lua_remove(data->L, -4);
  258. lua_settable(data->L, -3);
  259. lua_pop(data->L, 1);
  260. }
  261. break;
  262. case JSONSL_T_OBJECT:
  263. case JSONSL_T_LIST:
  264. luaL_unref(data->L, LUA_REGISTRYINDEX, state->lua_object_ref);
  265. state->lua_object_ref = LUA_NOREF;
  266. if (data->pos_ref != LUA_NOREF) {
  267. lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
  268. lua_pushinteger(data->L, state->level);
  269. lua_pushnil(data->L);
  270. lua_settable(data->L, -3);
  271. lua_pop(data->L, 1);
  272. }
  273. if (state->level == 1) {
  274. data->complete = 1;
  275. }
  276. break;
  277. }
  278. }
  279. static int sjson_decoder_int(lua_State *L, int argno) {
  280. int nlevels = DEFAULT_DEPTH;
  281. if (lua_type(L, argno) == LUA_TTABLE) {
  282. lua_getfield(L, argno, "depth");
  283. nlevels = lua_tointeger(L, argno);
  284. if (nlevels == 0) {
  285. nlevels = DEFAULT_DEPTH;
  286. }
  287. if (nlevels < 4) {
  288. nlevels = 4;
  289. }
  290. if (nlevels > 1000) {
  291. nlevels = 1000;
  292. }
  293. lua_pop(L, 1);
  294. }
  295. JSN_DATA *data = (JSN_DATA *) lua_newuserdata(L, sizeof(JSN_DATA) + jsonsl_get_size(nlevels));
  296. //
  297. // Associate its metatable
  298. luaL_getmetatable(L, "sjson.decoder");
  299. lua_setmetatable(L, -2);
  300. jsonsl_t jsn = jsonsl_init((jsonsl_t) (data + 1), nlevels);
  301. int i;
  302. for (i = 0; i < jsn->levels_max; i++) {
  303. jsn->stack[i].lua_object_ref = LUA_NOREF;
  304. }
  305. data->jsn = jsn;
  306. data->result_ref = LUA_NOREF;
  307. data->null_ref = LUA_REFNIL;
  308. data->metatable = LUA_NOREF;
  309. data->hkey_ref = LUA_NOREF;
  310. data->pos_ref = LUA_NOREF;
  311. data->buffer_ref = LUA_NOREF;
  312. data->complete = 0;
  313. data->error = NULL;
  314. data->L = L;
  315. data->buffer_len = 0;
  316. data->min_needed = data->min_available = jsn->pos;
  317. lua_pushlightuserdata(L, 0);
  318. data->null_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  319. // This may throw...
  320. lua_newtable(L);
  321. data->result_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  322. if (lua_type(L, argno) == LUA_TTABLE) {
  323. luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref);
  324. data->null_ref = LUA_NOREF;
  325. lua_getfield(L, argno, "null");
  326. data->null_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  327. lua_getfield(L, argno, "metatable");
  328. lua_pushvalue(L, -1);
  329. data->metatable = luaL_ref(L, LUA_REGISTRYINDEX);
  330. if (!lua_isnil(L, -1)) {
  331. lua_getfield(L, -1, "checkpath");
  332. if (!lua_isnil(L, -1)) {
  333. lua_newtable(L);
  334. data->pos_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  335. }
  336. lua_pop(L, 1); // Throw away the checkpath value
  337. }
  338. lua_pop(L, 1); // Throw away the metatable
  339. }
  340. jsonsl_enable_all_callbacks(data->jsn);
  341. jsn->action_callback = NULL;
  342. jsn->action_callback_PUSH = create_new_element;
  343. jsn->action_callback_POP = cleanup_closing_element;
  344. jsn->error_callback = error_callback;
  345. jsn->data = data;
  346. jsn->max_callback_level = nlevels;
  347. return 1;
  348. }
  349. static int sjson_decoder(lua_State *L) {
  350. return sjson_decoder_int(L, 1);
  351. }
  352. static int sjson_decoder_result_int(lua_State *L, JSN_DATA *data) {
  353. if (!data->complete) {
  354. luaL_error(L, "decode not complete");
  355. }
  356. lua_rawgeti(L, LUA_REGISTRYINDEX, data->result_ref);
  357. lua_rawgeti(L, -1, 1);
  358. lua_remove(L, -2);
  359. return 1;
  360. }
  361. static int sjson_decoder_result(lua_State *L) {
  362. JSN_DATA *data = (JSN_DATA *)luaL_checkudata(L, 1, "sjson.decoder");
  363. return sjson_decoder_result_int(L, data);
  364. }
  365. static void sjson_free_working_data(lua_State *L, JSN_DATA *data) {
  366. jsonsl_t jsn = data->jsn;
  367. int i;
  368. for (i = 0; i < jsn->levels_max; i++) {
  369. luaL_unref(L, LUA_REGISTRYINDEX, jsn->stack[i].lua_object_ref);
  370. jsn->stack[i].lua_object_ref = LUA_NOREF;
  371. }
  372. luaL_unref(L, LUA_REGISTRYINDEX, data->metatable);
  373. data->metatable = LUA_NOREF;
  374. luaL_unref(L, LUA_REGISTRYINDEX, data->hkey_ref);
  375. data->hkey_ref = LUA_NOREF;
  376. luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref);
  377. data->null_ref = LUA_NOREF;
  378. luaL_unref(L, LUA_REGISTRYINDEX, data->pos_ref);
  379. data->pos_ref = LUA_NOREF;
  380. luaL_unref(L, LUA_REGISTRYINDEX, data->buffer_ref);
  381. data->buffer_ref = LUA_NOREF;
  382. }
  383. static int sjson_decoder_write_int(lua_State *L, int udata_pos, int string_pos) {
  384. JSN_DATA *data = (JSN_DATA *)luaL_checkudata(L, udata_pos, "sjson.decoder");
  385. size_t len;
  386. const char *str = luaL_checklstring(L, string_pos, &len);
  387. if (data->error) {
  388. luaL_error(L, "JSON parse error: previous call");
  389. }
  390. if (!data->complete) {
  391. data->L = L;
  392. // Merge into any existing buffer and deal with discard
  393. if (data->buffer_ref != LUA_NOREF) {
  394. luaL_Buffer b;
  395. luaL_buffinit(L, &b);
  396. lua_rawgeti(L, LUA_REGISTRYINDEX, data->buffer_ref);
  397. size_t prev_len;
  398. const char *prev_buffer = luaL_checklstring(L, -1, &prev_len);
  399. lua_pop(L, 1); // But string still referenced so it cannot move
  400. int discard = data->min_needed - data->min_available;
  401. prev_buffer += discard;
  402. prev_len -= discard;
  403. if (prev_len > 0) {
  404. luaL_addlstring(&b, prev_buffer, prev_len);
  405. }
  406. data->min_available += discard;
  407. luaL_unref(L, LUA_REGISTRYINDEX, data->buffer_ref);
  408. data->buffer_ref = LUA_NOREF;
  409. lua_pushvalue(L, string_pos);
  410. luaL_addvalue(&b);
  411. luaL_pushresult(&b);
  412. } else {
  413. lua_pushvalue(L, string_pos);
  414. }
  415. size_t blen;
  416. data->buffer = luaL_checklstring(L, -1, &blen);
  417. data->buffer_len = blen;
  418. data->buffer_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  419. jsonsl_feed(data->jsn, str, len);
  420. if (data->error) {
  421. luaL_error(L, "JSON parse error: %s", data->error);
  422. }
  423. }
  424. if (data->complete) {
  425. // We no longer need the buffer
  426. sjson_free_working_data(L, data);
  427. return sjson_decoder_result_int(L, data);
  428. }
  429. return 0;
  430. }
  431. static int sjson_decoder_write(lua_State *L) {
  432. return sjson_decoder_write_int(L, 1, 2);
  433. }
  434. static int sjson_decode(lua_State *L) {
  435. int push_count = sjson_decoder_int(L, 2);
  436. if (push_count != 1) {
  437. luaL_error(L, "Internal error in sjson.deocder");
  438. }
  439. luaL_checkudata(L, -1, "sjson.decoder");
  440. push_count = sjson_decoder_write_int(L, -1, 1);
  441. if (push_count != 1) {
  442. luaL_error(L, "Incomplete JSON object passed to sjson.decode");
  443. }
  444. // Now we have two items on the stack -- the udata and the result
  445. lua_remove(L, -2);
  446. return 1;
  447. }
  448. static int sjson_decoder_destructor(lua_State *L) {
  449. JSN_DATA *data = (JSN_DATA *)luaL_checkudata(L, 1, "sjson.decoder");
  450. sjson_free_working_data(L, data);
  451. data->jsn = NULL;
  452. luaL_unref(L, LUA_REGISTRYINDEX, data->result_ref);
  453. data->result_ref = LUA_NOREF;
  454. DBG_PRINTF("Destructor called\n");
  455. return 0;
  456. }
  457. //
  458. //--------------------------------- ENCODER BELOW
  459. //
  460. //
  461. //
  462. //#undef DBG_PRINTF
  463. //#define DBG_PRINTF printf
  464. typedef struct {
  465. int lua_object_ref;
  466. // for arrays
  467. // 0 -> [
  468. // 1 -> first element
  469. // 2 -> ,
  470. // 3 -> second element
  471. // 4 -> ]
  472. // for objects
  473. // 0 -> { firstkey :
  474. // 1 -> first value
  475. // 2 -> , secondkey :
  476. // 3 -> second value
  477. // 4 -> }
  478. short offset;
  479. // -1 for objects
  480. // 0 -> n maximum integer key = n
  481. short size;
  482. int lua_key_ref;
  483. } ENC_DATA_STATE;
  484. typedef struct {
  485. ENC_DATA_STATE *stack;
  486. int nlevels;
  487. int level;
  488. int current_str_ref;
  489. int null_ref;
  490. int offset;
  491. } ENC_DATA;
  492. static int sjson_encoder_get_table_size(lua_State *L, int argno) {
  493. // Returns -1 for object, otherwise the maximum integer key value found.
  494. lua_pushvalue(L, argno);
  495. // stack now contains: -1 => table
  496. lua_pushnil(L);
  497. // stack now contains: -1 => nil; -2 => table
  498. //
  499. int maxkey = 0;
  500. while (lua_next(L, -2)) {
  501. lua_pop(L, 1);
  502. // stack now contains: -1 => key; -2 => table
  503. if (lua_type(L, -1) == LUA_TNUMBER) {
  504. int val = lua_tointeger(L, -1);
  505. if (val > maxkey) {
  506. maxkey = val;
  507. } else if (val <= 0) {
  508. maxkey = -1;
  509. lua_pop(L, 1);
  510. break;
  511. }
  512. } else {
  513. maxkey = -1;
  514. lua_pop(L, 1);
  515. break;
  516. }
  517. }
  518. lua_pop(L, 1);
  519. return maxkey;
  520. }
  521. static void enc_pop_stack(lua_State *L, ENC_DATA *data) {
  522. if (data->level < 0) {
  523. luaL_error(L, "encoder stack underflow");
  524. }
  525. ENC_DATA_STATE *state = &data->stack[data->level];
  526. luaL_unref(L, LUA_REGISTRYINDEX, state->lua_object_ref);
  527. state->lua_object_ref = LUA_NOREF;
  528. luaL_unref(L, LUA_REGISTRYINDEX, state->lua_key_ref);
  529. state->lua_key_ref = LUA_REFNIL;
  530. data->level--;
  531. }
  532. static void enc_push_stack(lua_State *L, ENC_DATA *data, int argno) {
  533. if (++data->level >= data->nlevels) {
  534. luaL_error(L, "encoder stack overflow");
  535. }
  536. lua_pushvalue(L, argno);
  537. ENC_DATA_STATE *state = &data->stack[data->level];
  538. state->lua_object_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  539. state->size = sjson_encoder_get_table_size(L, argno);
  540. state->offset = 0; // We haven't started on this one yet
  541. }
  542. static int sjson_encoder(lua_State *L) {
  543. int nlevels = DEFAULT_DEPTH;
  544. int argno = 1;
  545. // Validate first arg is a table
  546. luaL_checktype(L, argno++, LUA_TTABLE);
  547. if (lua_type(L, argno) == LUA_TTABLE) {
  548. lua_getfield(L, argno, "depth");
  549. nlevels = lua_tointeger(L, argno);
  550. if (nlevels == 0) {
  551. nlevels = DEFAULT_DEPTH;
  552. }
  553. if (nlevels < 4) {
  554. nlevels = 4;
  555. }
  556. if (nlevels > 1000) {
  557. nlevels = 1000;
  558. }
  559. lua_pop(L, 1);
  560. }
  561. ENC_DATA *data = (ENC_DATA *) lua_newuserdata(L, sizeof(ENC_DATA) + nlevels * sizeof(ENC_DATA_STATE));
  562. // Associate its metatable
  563. luaL_getmetatable(L, "sjson.encoder");
  564. lua_setmetatable(L, -2);
  565. data->nlevels = nlevels;
  566. data->level = -1;
  567. data->stack = (ENC_DATA_STATE *) (data + 1);
  568. data->current_str_ref = LUA_NOREF;
  569. int i;
  570. for (i = 0; i < nlevels; i++) {
  571. data->stack[i].lua_object_ref = LUA_NOREF;
  572. data->stack[i].lua_key_ref = LUA_REFNIL;
  573. }
  574. enc_push_stack(L, data, 1);
  575. data->null_ref = LUA_REFNIL;
  576. if (lua_type(L, argno) == LUA_TTABLE) {
  577. luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref);
  578. data->null_ref = LUA_NOREF;
  579. lua_getfield(L, argno, "null");
  580. data->null_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  581. }
  582. return 1;
  583. }
  584. static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const char *prefix, const char *suffix) {
  585. luaL_Buffer b;
  586. luaL_buffinit(L, &b);
  587. luaL_addstring(&b, prefix);
  588. int type = lua_type(L, argno);
  589. if (type == LUA_TSTRING) {
  590. // Check to see if it is the NULL value
  591. if (data->null_ref != LUA_REFNIL) {
  592. lua_rawgeti(L, LUA_REGISTRYINDEX, data->null_ref);
  593. if (lua_equal(L, -1, -2)) {
  594. type = LUA_TNIL;
  595. }
  596. lua_pop(L, 1);
  597. }
  598. }
  599. switch (type) {
  600. default:
  601. luaL_error(L, "Cannot encode type %d", type);
  602. break;
  603. case LUA_TLIGHTUSERDATA:
  604. case LUA_TNIL:
  605. luaL_addstring(&b, "null");
  606. break;
  607. case LUA_TBOOLEAN:
  608. luaL_addstring(&b, lua_toboolean(L, argno) ? "true" : "false");
  609. break;
  610. case LUA_TNUMBER:
  611. {
  612. lua_pushvalue(L, argno);
  613. size_t len;
  614. const char *str = lua_tolstring(L, -1, &len);
  615. char value[len + 1];
  616. strcpy(value, str);
  617. lua_pop(L, 1);
  618. if (strcmp(value, "-Infinity") == 0 || strcmp(value, "NaN") == 0 || strcmp(value, "Infinity") == 0) {
  619. luaL_addstring(&b, "null"); // According to ECMA-262 section 24.5.2 Note 4
  620. } else {
  621. luaL_addstring(&b, value);
  622. }
  623. break;
  624. }
  625. case LUA_TSTRING:
  626. {
  627. luaL_addchar(&b, '"');
  628. size_t len;
  629. const char *str = lua_tolstring(L, argno, &len);
  630. while (len > 0) {
  631. if ((*str & 0xff) < 0x20) {
  632. char value[8];
  633. value[0] = '\\';
  634. char *d = value + 1;
  635. switch(*str) {
  636. case '\f':
  637. *d++ = 'f';
  638. break;
  639. case '\n':
  640. *d++ = 'n';
  641. break;
  642. case '\t':
  643. *d++ = 't';
  644. break;
  645. case '\r':
  646. *d++ = 'r';
  647. break;
  648. case '\b':
  649. *d++ = 'b';
  650. break;
  651. default:
  652. *d++ = 'u';
  653. *d++ = '0';
  654. *d++ = '0';
  655. *d++ = "0123456789abcdef"[(*str >> 4) & 0xf];
  656. *d++ = "0123456789abcdef"[(*str ) & 0xf];
  657. break;
  658. }
  659. *d = '\0';
  660. luaL_addstring(&b, value);
  661. } else if (*str == '"') {
  662. luaL_addstring(&b, "\\\"");
  663. } else {
  664. luaL_addchar(&b, *str);
  665. }
  666. str++;
  667. len--;
  668. }
  669. luaL_addchar(&b, '"');
  670. break;
  671. }
  672. }
  673. luaL_addstring(&b, suffix);
  674. luaL_pushresult(&b);
  675. }
  676. static int sjson_encoder_next_value_is_table(lua_State *L) {
  677. int count = 10;
  678. while ((lua_isfunction(L, -1)
  679. ) && count-- > 0) {
  680. // call it and use the return value
  681. lua_call(L, 0, 1); // Expecting replacement value
  682. }
  683. return (lua_type(L, -1) == LUA_TTABLE);
  684. }
  685. static void sjson_encoder_make_next_chunk(lua_State *L, ENC_DATA *data) {
  686. if (data->level < 0) {
  687. return;
  688. }
  689. luaL_Buffer b;
  690. luaL_buffinit(L, &b);
  691. // Ending condition
  692. while (data->level >= 0 /* && !b.lvl */) {
  693. ENC_DATA_STATE *state = &data->stack[data->level];
  694. int finished = 0;
  695. if (state->size >= 0) {
  696. if (state->offset == 0) {
  697. // start of object or whatever
  698. luaL_addchar(&b, '[');
  699. }
  700. if (state->offset == state->size << 1) {
  701. luaL_addchar(&b, ']');
  702. finished = 1;
  703. } else if ((state->offset & 1) == 0) {
  704. if (state->offset > 0) {
  705. luaL_addchar(&b, ',');
  706. }
  707. } else {
  708. // output the value
  709. lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_object_ref);
  710. lua_rawgeti(L, -1, (state->offset >> 1) + 1);
  711. if (sjson_encoder_next_value_is_table(L)) {
  712. enc_push_stack(L, data, -1);
  713. lua_pop(L, 2);
  714. state->offset++;
  715. continue;
  716. }
  717. encode_lua_object(L, data, -1, "", "");
  718. lua_remove(L, -2);
  719. lua_remove(L, -2);
  720. luaL_addvalue(&b);
  721. }
  722. state->offset++;
  723. } else {
  724. lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_object_ref);
  725. // stack now contains: -1 => table
  726. lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_key_ref);
  727. // stack now contains: -1 => nil or key; -2 => table
  728. if (lua_next(L, -2)) {
  729. // save the key
  730. if (state->offset & 1) {
  731. luaL_unref(L, LUA_REGISTRYINDEX, state->lua_key_ref);
  732. state->lua_key_ref = LUA_NOREF;
  733. // Duplicate the key
  734. lua_pushvalue(L, -2);
  735. state->lua_key_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  736. }
  737. if ((state->offset & 1) == 0) {
  738. // copy the key so that lua_tostring does not modify the original
  739. lua_pushvalue(L, -2);
  740. // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
  741. // key
  742. lua_tostring(L, -1);
  743. encode_lua_object(L, data, -1, state->offset ? "," : "{", ":");
  744. lua_remove(L, -2);
  745. lua_remove(L, -2);
  746. lua_remove(L, -2);
  747. lua_remove(L, -2);
  748. } else {
  749. if (sjson_encoder_next_value_is_table(L)) {
  750. enc_push_stack(L, data, -1);
  751. lua_pop(L, 3);
  752. state->offset++;
  753. continue;
  754. }
  755. encode_lua_object(L, data, -1, "", "");
  756. lua_remove(L, -2);
  757. lua_remove(L, -2);
  758. lua_remove(L, -2);
  759. }
  760. luaL_addvalue(&b);
  761. } else {
  762. lua_pop(L, 1);
  763. // We have got to the end
  764. luaL_addchar(&b, '}');
  765. finished = 1;
  766. }
  767. state->offset++;
  768. }
  769. if (finished) {
  770. enc_pop_stack(L, data);
  771. }
  772. }
  773. luaL_pushresult(&b);
  774. data->current_str_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  775. data->offset = 0;
  776. }
  777. static int sjson_encoder_read_int(lua_State *L, ENC_DATA *data, int readsize) {
  778. luaL_Buffer b;
  779. luaL_buffinit(L, &b);
  780. size_t len;
  781. do {
  782. // Fill the buffer with (up to) readsize characters
  783. if (data->current_str_ref != LUA_NOREF) {
  784. // this is not allowed
  785. lua_rawgeti(L, LUA_REGISTRYINDEX, data->current_str_ref);
  786. const char *str = lua_tolstring(L, -1, &len);
  787. lua_pop(L, 1); // Note that we still have the string referenced so it can't go away
  788. int amnt = len - data->offset;;
  789. if (amnt > readsize) {
  790. amnt = readsize;
  791. }
  792. luaL_addlstring(&b, str + data->offset, amnt);
  793. data->offset += amnt;
  794. readsize -= amnt;
  795. if (data->offset == len) {
  796. luaL_unref(L, LUA_REGISTRYINDEX, data->current_str_ref);
  797. data->current_str_ref = LUA_NOREF;
  798. }
  799. }
  800. if (readsize > 0) {
  801. // Make the next chunk
  802. sjson_encoder_make_next_chunk(L, data);
  803. }
  804. } while (readsize > 0 && data->current_str_ref != LUA_NOREF);
  805. luaL_pushresult(&b);
  806. lua_tolstring(L, -1, &len);
  807. if (len == 0) {
  808. // we have got to the end
  809. lua_pop(L, 1);
  810. return 0;
  811. }
  812. return 1;
  813. }
  814. static int sjson_encoder_read(lua_State *L) {
  815. ENC_DATA *data = (ENC_DATA *)luaL_checkudata(L, 1, "sjson.encoder");
  816. int readsize = 1024;
  817. if (lua_type(L, 2) == LUA_TNUMBER) {
  818. readsize = lua_tointeger(L, 2);
  819. if (readsize < 1) {
  820. readsize = 1;
  821. }
  822. }
  823. return sjson_encoder_read_int(L, data, readsize);
  824. }
  825. static int sjson_encode(lua_State *L) {
  826. sjson_encoder(L);
  827. ENC_DATA *data = (ENC_DATA *)luaL_checkudata(L, -1, "sjson.encoder");
  828. int rc = sjson_encoder_read_int(L, data, 1000000);
  829. lua_remove(L, -(rc + 1));
  830. return rc;
  831. }
  832. static int sjson_encoder_destructor(lua_State *L) {
  833. ENC_DATA *data = (ENC_DATA *)luaL_checkudata(L, 1, "sjson.encoder");
  834. int i;
  835. for (i = 0; i < data->nlevels; i++) {
  836. luaL_unref(L, LUA_REGISTRYINDEX, data->stack[i].lua_object_ref);
  837. luaL_unref(L, LUA_REGISTRYINDEX, data->stack[i].lua_key_ref);
  838. }
  839. luaL_unref(L, LUA_REGISTRYINDEX, data->null_ref);
  840. luaL_unref(L, LUA_REGISTRYINDEX, data->current_str_ref);
  841. DBG_PRINTF("Destructor called\n");
  842. return 0;
  843. }
  844. LROT_BEGIN(sjson_encoder_map, NULL, LROT_MASK_GC_INDEX)
  845. LROT_FUNCENTRY( __gc, sjson_encoder_destructor )
  846. LROT_TABENTRY( __index, sjson_encoder_map )
  847. LROT_FUNCENTRY( read, sjson_encoder_read )
  848. LROT_END(sjson_encoder_map, NULL, LROT_MASK_GC_INDEX)
  849. LROT_BEGIN(sjson_decoder_map, NULL, LROT_MASK_GC_INDEX)
  850. LROT_FUNCENTRY( __gc, sjson_decoder_destructor )
  851. LROT_TABENTRY( __index, sjson_decoder_map )
  852. LROT_FUNCENTRY( write, sjson_decoder_write )
  853. LROT_FUNCENTRY( result, sjson_decoder_result )
  854. LROT_END(sjson_decoder_map, NULL, LROT_MASK_GC_INDEX)
  855. LROT_BEGIN(sjson, NULL, 0)
  856. LROT_FUNCENTRY( encode, sjson_encode )
  857. LROT_FUNCENTRY( decode, sjson_decode )
  858. LROT_FUNCENTRY( encoder, sjson_encoder )
  859. LROT_FUNCENTRY( decoder, sjson_decoder )
  860. LROT_END(sjson, NULL, 0)
  861. LUALIB_API int luaopen_sjson (lua_State *L) {
  862. luaL_rometatable(L, "sjson.decoder", LROT_TABLEREF(sjson_decoder_map));
  863. luaL_rometatable(L, "sjson.encoder", LROT_TABLEREF(sjson_encoder_map));
  864. return 1;
  865. }
  866. NODEMCU_MODULE(SJSON, "sjson", sjson, luaopen_sjson);