static struct block * wb_close(struct write_block *b) { b->current = b->head; b->ptr = 0; wb_push(b, &b->len, sizeof(b->len)); b->current = NULL; return b->head; }
static int wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) { int array_size = lua_rawlen(L,index); if (array_size >= MAX_COOKIE-1) { uint8_t n = COMBINE_TYPE(TYPE_TABLE, MAX_COOKIE-1); wb_push(wb, &n, 1); wb_integer(wb, array_size); } else { uint8_t n = COMBINE_TYPE(TYPE_TABLE, array_size); wb_push(wb, &n, 1); } int i; for (i=1;i<=array_size;i++) { lua_rawgeti(L,index,i); pack_one(L, wb, -1, depth); lua_pop(L,1); } return array_size; }
static void wb_init(struct write_block *wb , struct block *b) { if (b==NULL) { wb->head = blk_alloc(); wb->len = 0; wb->current = wb->head; wb->ptr = 0; wb_push(wb, &wb->len, sizeof(wb->len)); } else { wb->head = b; int * plen = (int *)b->buffer; int sz = *plen; wb->len = sz; while (b->next) { sz -= BLOCK_SIZE; b = b->next; } wb->current = b; wb->ptr = sz; } }
static void wb_table_metapairs(lua_State *L, struct write_block *wb, int index, int depth) { uint8_t n = COMBINE_TYPE(TYPE_TABLE, 0); wb_push(wb, &n, 1); lua_pushvalue(L, index); lua_call(L, 1, 3); for(;;) { lua_pushvalue(L, -2); lua_pushvalue(L, -2); lua_copy(L, -5, -3); lua_call(L, 2, 2); int type = lua_type(L, -2); if (type == LUA_TNIL) { lua_pop(L, 4); break; } pack_one(L, wb, -2, depth); pack_one(L, wb, -1, depth); lua_pop(L, 1); } wb_nil(wb); }
static inline void wb_string(struct write_block *wb, const char *str, int len) { if (len < MAX_COOKIE) { uint8_t n = COMBINE_TYPE(TYPE_SHORT_STRING, len); wb_push(wb, &n, 1); if (len > 0) { wb_push(wb, str, len); } } else { uint8_t n; if (len < 0x10000) { n = COMBINE_TYPE(TYPE_LONG_STRING, 2); wb_push(wb, &n, 1); uint16_t x = (uint16_t) len; wb_push(wb, &x, 2); } else { n = COMBINE_TYPE(TYPE_LONG_STRING, 4); wb_push(wb, &n, 1); uint32_t x = (uint32_t) len; wb_push(wb, &x, 4); } wb_push(wb, str, len); } }
static inline void wb_pointer(struct write_block *wb, void *v) { uint8_t n = TYPE_USERDATA; wb_push(wb, &n, 1); wb_push(wb, &v, sizeof(v)); }
static inline void wb_real(struct write_block *wb, double v) { uint8_t n = COMBINE_TYPE(TYPE_NUMBER , TYPE_NUMBER_REAL); wb_push(wb, &n, 1); wb_push(wb, &v, sizeof(v)); }
static inline void wb_integer(struct write_block *wb, lua_Integer v) { int type = TYPE_NUMBER; if (v == 0) { uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_ZERO); wb_push(wb, &n, 1); } else if (v != (int32_t)v) { uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_QWORD); int64_t v64 = v; wb_push(wb, &n, 1); wb_push(wb, &v64, sizeof(v64)); } else if (v < 0) { int32_t v32 = (int32_t)v; uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_DWORD); wb_push(wb, &n, 1); wb_push(wb, &v32, sizeof(v32)); } else if (v<0x100) { uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_BYTE); wb_push(wb, &n, 1); uint8_t byte = (uint8_t)v; wb_push(wb, &byte, sizeof(byte)); } else if (v<0x10000) { uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_WORD); wb_push(wb, &n, 1); uint16_t word = (uint16_t)v; wb_push(wb, &word, sizeof(word)); } else { uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_DWORD); wb_push(wb, &n, 1); uint32_t v32 = (uint32_t)v; wb_push(wb, &v32, sizeof(v32)); } }
static inline void wb_boolean(struct write_block *wb, int boolean) { uint8_t n = COMBINE_TYPE(TYPE_BOOLEAN , boolean ? 1 : 0); wb_push(wb, &n, 1); }
static inline void wb_nil(struct write_block *wb) { uint8_t n = TYPE_NIL; wb_push(wb, &n, 1); }