lua-seri.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /*
  2. modify from https://github.com/cloudwu/lua-serialize
  3. */
  4. #define LUA_LIB
  5. #include "skynet_malloc.h"
  6. #include <lua.h>
  7. #include <lauxlib.h>
  8. #include <stdlib.h>
  9. #include <stdint.h>
  10. #include <assert.h>
  11. #include <string.h>
  12. #define TYPE_NIL 0
  13. #define TYPE_BOOLEAN 1
  14. // hibits 0 false 1 true
  15. #define TYPE_NUMBER 2
  16. // hibits 0 : 0 , 1: byte, 2:word, 4: dword, 6: qword, 8 : double
  17. #define TYPE_NUMBER_ZERO 0
  18. #define TYPE_NUMBER_BYTE 1
  19. #define TYPE_NUMBER_WORD 2
  20. #define TYPE_NUMBER_DWORD 4
  21. #define TYPE_NUMBER_QWORD 6
  22. #define TYPE_NUMBER_REAL 8
  23. #define TYPE_USERDATA 3
  24. #define TYPE_SHORT_STRING 4
  25. // hibits 0~31 : len
  26. #define TYPE_LONG_STRING 5
  27. #define TYPE_TABLE 6
  28. #define MAX_COOKIE 32
  29. #define COMBINE_TYPE(t,v) ((t) | (v) << 3)
  30. #define BLOCK_SIZE 128
  31. #define MAX_DEPTH 32
  32. struct block {
  33. struct block * next;
  34. char buffer[BLOCK_SIZE];
  35. };
  36. struct write_block {
  37. struct block * head;
  38. struct block * current;
  39. int len;
  40. int ptr;
  41. };
  42. struct read_block {
  43. char * buffer;
  44. int len;
  45. int ptr;
  46. };
  47. inline static struct block *
  48. blk_alloc(void) {
  49. struct block *b = skynet_malloc(sizeof(struct block));
  50. b->next = NULL;
  51. return b;
  52. }
  53. inline static void
  54. wb_push(struct write_block *b, const void *buf, int sz) {
  55. const char * buffer = buf;
  56. if (b->ptr == BLOCK_SIZE) {
  57. _again:
  58. b->current = b->current->next = blk_alloc();
  59. b->ptr = 0;
  60. }
  61. if (b->ptr <= BLOCK_SIZE - sz) {
  62. memcpy(b->current->buffer + b->ptr, buffer, sz);
  63. b->ptr+=sz;
  64. b->len+=sz;
  65. } else {
  66. int copy = BLOCK_SIZE - b->ptr;
  67. memcpy(b->current->buffer + b->ptr, buffer, copy);
  68. buffer += copy;
  69. b->len += copy;
  70. sz -= copy;
  71. goto _again;
  72. }
  73. }
  74. static void
  75. wb_init(struct write_block *wb , struct block *b) {
  76. wb->head = b;
  77. assert(b->next == NULL);
  78. wb->len = 0;
  79. wb->current = wb->head;
  80. wb->ptr = 0;
  81. }
  82. static void
  83. wb_free(struct write_block *wb) {
  84. struct block *blk = wb->head;
  85. blk = blk->next; // the first block is on stack
  86. while (blk) {
  87. struct block * next = blk->next;
  88. skynet_free(blk);
  89. blk = next;
  90. }
  91. wb->head = NULL;
  92. wb->current = NULL;
  93. wb->ptr = 0;
  94. wb->len = 0;
  95. }
  96. static void
  97. rball_init(struct read_block * rb, char * buffer, int size) {
  98. rb->buffer = buffer;
  99. rb->len = size;
  100. rb->ptr = 0;
  101. }
  102. static const void *
  103. rb_read(struct read_block *rb, int sz) {
  104. if (rb->len < sz) {
  105. return NULL;
  106. }
  107. int ptr = rb->ptr;
  108. rb->ptr += sz;
  109. rb->len -= sz;
  110. return rb->buffer + ptr;
  111. }
  112. static inline void
  113. wb_nil(struct write_block *wb) {
  114. uint8_t n = TYPE_NIL;
  115. wb_push(wb, &n, 1);
  116. }
  117. static inline void
  118. wb_boolean(struct write_block *wb, int boolean) {
  119. uint8_t n = COMBINE_TYPE(TYPE_BOOLEAN , boolean ? 1 : 0);
  120. wb_push(wb, &n, 1);
  121. }
  122. static inline void
  123. wb_integer(struct write_block *wb, lua_Integer v) {
  124. int type = TYPE_NUMBER;
  125. if (v == 0) {
  126. uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_ZERO);
  127. wb_push(wb, &n, 1);
  128. } else if (v != (int32_t)v) {
  129. uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_QWORD);
  130. int64_t v64 = v;
  131. wb_push(wb, &n, 1);
  132. wb_push(wb, &v64, sizeof(v64));
  133. } else if (v < 0) {
  134. int32_t v32 = (int32_t)v;
  135. uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_DWORD);
  136. wb_push(wb, &n, 1);
  137. wb_push(wb, &v32, sizeof(v32));
  138. } else if (v<0x100) {
  139. uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_BYTE);
  140. wb_push(wb, &n, 1);
  141. uint8_t byte = (uint8_t)v;
  142. wb_push(wb, &byte, sizeof(byte));
  143. } else if (v<0x10000) {
  144. uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_WORD);
  145. wb_push(wb, &n, 1);
  146. uint16_t word = (uint16_t)v;
  147. wb_push(wb, &word, sizeof(word));
  148. } else {
  149. uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_DWORD);
  150. wb_push(wb, &n, 1);
  151. uint32_t v32 = (uint32_t)v;
  152. wb_push(wb, &v32, sizeof(v32));
  153. }
  154. }
  155. static inline void
  156. wb_real(struct write_block *wb, double v) {
  157. uint8_t n = COMBINE_TYPE(TYPE_NUMBER , TYPE_NUMBER_REAL);
  158. wb_push(wb, &n, 1);
  159. wb_push(wb, &v, sizeof(v));
  160. }
  161. static inline void
  162. wb_pointer(struct write_block *wb, void *v) {
  163. uint8_t n = TYPE_USERDATA;
  164. wb_push(wb, &n, 1);
  165. wb_push(wb, &v, sizeof(v));
  166. }
  167. static inline void
  168. wb_string(struct write_block *wb, const char *str, int len) {
  169. if (len < MAX_COOKIE) {
  170. uint8_t n = COMBINE_TYPE(TYPE_SHORT_STRING, len);
  171. wb_push(wb, &n, 1);
  172. if (len > 0) {
  173. wb_push(wb, str, len);
  174. }
  175. } else {
  176. uint8_t n;
  177. if (len < 0x10000) {
  178. n = COMBINE_TYPE(TYPE_LONG_STRING, 2);
  179. wb_push(wb, &n, 1);
  180. uint16_t x = (uint16_t) len;
  181. wb_push(wb, &x, 2);
  182. } else {
  183. n = COMBINE_TYPE(TYPE_LONG_STRING, 4);
  184. wb_push(wb, &n, 1);
  185. uint32_t x = (uint32_t) len;
  186. wb_push(wb, &x, 4);
  187. }
  188. wb_push(wb, str, len);
  189. }
  190. }
  191. static void pack_one(lua_State *L, struct write_block *b, int index, int depth);
  192. static int
  193. wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) {
  194. int array_size = lua_rawlen(L,index);
  195. if (array_size >= MAX_COOKIE-1) {
  196. uint8_t n = COMBINE_TYPE(TYPE_TABLE, MAX_COOKIE-1);
  197. wb_push(wb, &n, 1);
  198. wb_integer(wb, array_size);
  199. } else {
  200. uint8_t n = COMBINE_TYPE(TYPE_TABLE, array_size);
  201. wb_push(wb, &n, 1);
  202. }
  203. int i;
  204. for (i=1;i<=array_size;i++) {
  205. lua_rawgeti(L,index,i);
  206. pack_one(L, wb, -1, depth);
  207. lua_pop(L,1);
  208. }
  209. return array_size;
  210. }
  211. static void
  212. wb_table_hash(lua_State *L, struct write_block * wb, int index, int depth, int array_size) {
  213. lua_pushnil(L);
  214. while (lua_next(L, index) != 0) {
  215. if (lua_type(L,-2) == LUA_TNUMBER) {
  216. if (lua_isinteger(L, -2)) {
  217. lua_Integer x = lua_tointeger(L,-2);
  218. if (x>0 && x<=array_size) {
  219. lua_pop(L,1);
  220. continue;
  221. }
  222. }
  223. }
  224. pack_one(L,wb,-2,depth);
  225. pack_one(L,wb,-1,depth);
  226. lua_pop(L, 1);
  227. }
  228. wb_nil(wb);
  229. }
  230. static int
  231. wb_table_metapairs(lua_State *L, struct write_block *wb, int index, int depth) {
  232. uint8_t n = COMBINE_TYPE(TYPE_TABLE, 0);
  233. wb_push(wb, &n, 1);
  234. lua_pushvalue(L, index);
  235. if (lua_pcall(L, 1, 3,0) != LUA_OK)
  236. return 1;
  237. for(;;) {
  238. lua_pushvalue(L, -2);
  239. lua_pushvalue(L, -2);
  240. lua_copy(L, -5, -3);
  241. if (lua_pcall(L, 2, 2, 0) != LUA_OK)
  242. return 1;
  243. int type = lua_type(L, -2);
  244. if (type == LUA_TNIL) {
  245. lua_pop(L, 4);
  246. break;
  247. }
  248. pack_one(L, wb, -2, depth);
  249. pack_one(L, wb, -1, depth);
  250. lua_pop(L, 1);
  251. }
  252. wb_nil(wb);
  253. return 0;
  254. }
  255. static int
  256. wb_table(lua_State *L, struct write_block *wb, int index, int depth) {
  257. if (!lua_checkstack(L, LUA_MINSTACK)) {
  258. lua_pushstring(L, "out of memory");
  259. return 1;
  260. }
  261. if (index < 0) {
  262. index = lua_gettop(L) + index + 1;
  263. }
  264. if (luaL_getmetafield(L, index, "__pairs") != LUA_TNIL) {
  265. return wb_table_metapairs(L, wb, index, depth);
  266. } else {
  267. int array_size = wb_table_array(L, wb, index, depth);
  268. wb_table_hash(L, wb, index, depth, array_size);
  269. return 0;
  270. }
  271. }
  272. static void
  273. pack_one(lua_State *L, struct write_block *b, int index, int depth) {
  274. if (depth > MAX_DEPTH) {
  275. wb_free(b);
  276. luaL_error(L, "serialize can't pack too depth table");
  277. }
  278. int type = lua_type(L,index);
  279. switch(type) {
  280. case LUA_TNIL:
  281. wb_nil(b);
  282. break;
  283. case LUA_TNUMBER: {
  284. if (lua_isinteger(L, index)) {
  285. lua_Integer x = lua_tointeger(L,index);
  286. wb_integer(b, x);
  287. } else {
  288. lua_Number n = lua_tonumber(L,index);
  289. wb_real(b,n);
  290. }
  291. break;
  292. }
  293. case LUA_TBOOLEAN:
  294. wb_boolean(b, lua_toboolean(L,index));
  295. break;
  296. case LUA_TSTRING: {
  297. size_t sz = 0;
  298. const char *str = lua_tolstring(L,index,&sz);
  299. wb_string(b, str, (int)sz);
  300. break;
  301. }
  302. case LUA_TLIGHTUSERDATA:
  303. wb_pointer(b, lua_touserdata(L,index));
  304. break;
  305. case LUA_TTABLE: {
  306. if (index < 0) {
  307. index = lua_gettop(L) + index + 1;
  308. }
  309. if (wb_table(L, b, index, depth+1)) {
  310. wb_free(b);
  311. lua_error(L);
  312. }
  313. break;
  314. }
  315. default:
  316. wb_free(b);
  317. luaL_error(L, "Unsupport type %s to serialize", lua_typename(L, type));
  318. }
  319. }
  320. static void
  321. pack_from(lua_State *L, struct write_block *b, int from) {
  322. int n = lua_gettop(L) - from;
  323. int i;
  324. for (i=1;i<=n;i++) {
  325. pack_one(L, b , from + i, 0);
  326. }
  327. }
  328. static inline void
  329. invalid_stream_line(lua_State *L, struct read_block *rb, int line) {
  330. int len = rb->len;
  331. luaL_error(L, "Invalid serialize stream %d (line:%d)", len, line);
  332. }
  333. #define invalid_stream(L,rb) invalid_stream_line(L,rb,__LINE__)
  334. static lua_Integer
  335. get_integer(lua_State *L, struct read_block *rb, int cookie) {
  336. switch (cookie) {
  337. case TYPE_NUMBER_ZERO:
  338. return 0;
  339. case TYPE_NUMBER_BYTE: {
  340. uint8_t n;
  341. const uint8_t * pn = (const uint8_t *)rb_read(rb,sizeof(n));
  342. if (pn == NULL)
  343. invalid_stream(L,rb);
  344. n = *pn;
  345. return n;
  346. }
  347. case TYPE_NUMBER_WORD: {
  348. uint16_t n;
  349. const void * pn = rb_read(rb,sizeof(n));
  350. if (pn == NULL)
  351. invalid_stream(L,rb);
  352. memcpy(&n, pn, sizeof(n));
  353. return n;
  354. }
  355. case TYPE_NUMBER_DWORD: {
  356. int32_t n;
  357. const void * pn = rb_read(rb,sizeof(n));
  358. if (pn == NULL)
  359. invalid_stream(L,rb);
  360. memcpy(&n, pn, sizeof(n));
  361. return n;
  362. }
  363. case TYPE_NUMBER_QWORD: {
  364. int64_t n;
  365. const void * pn = rb_read(rb,sizeof(n));
  366. if (pn == NULL)
  367. invalid_stream(L,rb);
  368. memcpy(&n, pn, sizeof(n));
  369. return n;
  370. }
  371. default:
  372. invalid_stream(L,rb);
  373. return 0;
  374. }
  375. }
  376. static double
  377. get_real(lua_State *L, struct read_block *rb) {
  378. double n;
  379. const void * pn = rb_read(rb,sizeof(n));
  380. if (pn == NULL)
  381. invalid_stream(L,rb);
  382. memcpy(&n, pn, sizeof(n));
  383. return n;
  384. }
  385. static void *
  386. get_pointer(lua_State *L, struct read_block *rb) {
  387. void * userdata = 0;
  388. const void * v = rb_read(rb,sizeof(userdata));
  389. if (v == NULL) {
  390. invalid_stream(L,rb);
  391. }
  392. memcpy(&userdata, v, sizeof(userdata));
  393. return userdata;
  394. }
  395. static void
  396. get_buffer(lua_State *L, struct read_block *rb, int len) {
  397. const char * p = (const char *)rb_read(rb,len);
  398. if (p == NULL) {
  399. invalid_stream(L,rb);
  400. }
  401. lua_pushlstring(L,p,len);
  402. }
  403. static void unpack_one(lua_State *L, struct read_block *rb);
  404. static void
  405. unpack_table(lua_State *L, struct read_block *rb, int array_size) {
  406. if (array_size == MAX_COOKIE-1) {
  407. uint8_t type;
  408. const uint8_t * t = (const uint8_t *)rb_read(rb, sizeof(type));
  409. if (t==NULL) {
  410. invalid_stream(L,rb);
  411. }
  412. type = *t;
  413. int cookie = type >> 3;
  414. if ((type & 7) != TYPE_NUMBER || cookie == TYPE_NUMBER_REAL) {
  415. invalid_stream(L,rb);
  416. }
  417. array_size = get_integer(L,rb,cookie);
  418. }
  419. luaL_checkstack(L,LUA_MINSTACK,NULL);
  420. lua_createtable(L,array_size,0);
  421. int i;
  422. for (i=1;i<=array_size;i++) {
  423. unpack_one(L,rb);
  424. lua_rawseti(L,-2,i);
  425. }
  426. for (;;) {
  427. unpack_one(L,rb);
  428. if (lua_isnil(L,-1)) {
  429. lua_pop(L,1);
  430. return;
  431. }
  432. unpack_one(L,rb);
  433. lua_rawset(L,-3);
  434. }
  435. }
  436. static void
  437. push_value(lua_State *L, struct read_block *rb, int type, int cookie) {
  438. switch(type) {
  439. case TYPE_NIL:
  440. lua_pushnil(L);
  441. break;
  442. case TYPE_BOOLEAN:
  443. lua_pushboolean(L,cookie);
  444. break;
  445. case TYPE_NUMBER:
  446. if (cookie == TYPE_NUMBER_REAL) {
  447. lua_pushnumber(L,get_real(L,rb));
  448. } else {
  449. lua_pushinteger(L, get_integer(L, rb, cookie));
  450. }
  451. break;
  452. case TYPE_USERDATA:
  453. lua_pushlightuserdata(L,get_pointer(L,rb));
  454. break;
  455. case TYPE_SHORT_STRING:
  456. get_buffer(L,rb,cookie);
  457. break;
  458. case TYPE_LONG_STRING: {
  459. if (cookie == 2) {
  460. const void * plen = rb_read(rb, 2);
  461. if (plen == NULL) {
  462. invalid_stream(L,rb);
  463. }
  464. uint16_t n;
  465. memcpy(&n, plen, sizeof(n));
  466. get_buffer(L,rb,n);
  467. } else {
  468. if (cookie != 4) {
  469. invalid_stream(L,rb);
  470. }
  471. const void * plen = rb_read(rb, 4);
  472. if (plen == NULL) {
  473. invalid_stream(L,rb);
  474. }
  475. uint32_t n;
  476. memcpy(&n, plen, sizeof(n));
  477. get_buffer(L,rb,n);
  478. }
  479. break;
  480. }
  481. case TYPE_TABLE: {
  482. unpack_table(L,rb,cookie);
  483. break;
  484. }
  485. default: {
  486. invalid_stream(L,rb);
  487. break;
  488. }
  489. }
  490. }
  491. static void
  492. unpack_one(lua_State *L, struct read_block *rb) {
  493. uint8_t type;
  494. const uint8_t * t = (const uint8_t *)rb_read(rb, sizeof(type));
  495. if (t==NULL) {
  496. invalid_stream(L, rb);
  497. }
  498. type = *t;
  499. push_value(L, rb, type & 0x7, type>>3);
  500. }
  501. static void
  502. seri(lua_State *L, struct block *b, int len) {
  503. uint8_t * buffer = skynet_malloc(len);
  504. uint8_t * ptr = buffer;
  505. int sz = len;
  506. while(len>0) {
  507. if (len >= BLOCK_SIZE) {
  508. memcpy(ptr, b->buffer, BLOCK_SIZE);
  509. ptr += BLOCK_SIZE;
  510. len -= BLOCK_SIZE;
  511. b = b->next;
  512. } else {
  513. memcpy(ptr, b->buffer, len);
  514. break;
  515. }
  516. }
  517. lua_pushlightuserdata(L, buffer);
  518. lua_pushinteger(L, sz);
  519. }
  520. int
  521. luaseri_unpack(lua_State *L) {
  522. if (lua_isnoneornil(L,1)) {
  523. return 0;
  524. }
  525. void * buffer;
  526. int len;
  527. if (lua_type(L,1) == LUA_TSTRING) {
  528. size_t sz;
  529. buffer = (void *)lua_tolstring(L,1,&sz);
  530. len = (int)sz;
  531. } else {
  532. buffer = lua_touserdata(L,1);
  533. len = luaL_checkinteger(L,2);
  534. }
  535. if (len == 0) {
  536. return 0;
  537. }
  538. if (buffer == NULL) {
  539. return luaL_error(L, "deserialize null pointer");
  540. }
  541. lua_settop(L,1);
  542. struct read_block rb;
  543. rball_init(&rb, buffer, len);
  544. int i;
  545. for (i=0;;i++) {
  546. if (i%8==7) {
  547. luaL_checkstack(L,LUA_MINSTACK,NULL);
  548. }
  549. uint8_t type = 0;
  550. const uint8_t * t = (const uint8_t *)rb_read(&rb, sizeof(type));
  551. if (t==NULL)
  552. break;
  553. type = *t;
  554. push_value(L, &rb, type & 0x7, type>>3);
  555. }
  556. // Need not free buffer
  557. return lua_gettop(L) - 1;
  558. }
  559. LUAMOD_API int
  560. luaseri_pack(lua_State *L) {
  561. struct block temp;
  562. temp.next = NULL;
  563. struct write_block wb;
  564. wb_init(&wb, &temp);
  565. pack_from(L,&wb,0);
  566. assert(wb.head == &temp);
  567. seri(L, &temp, wb.len);
  568. wb_free(&wb);
  569. return 2;
  570. }