sjson.c 27 KB

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