/* * serialize(obj, totable) * - obj: object to serialize * - totable: if true, returns a string buffer containing the serialized object instead of a buffer * returns a string buffer (table) or a string containing obj serialization */ static int serialize(lua_State *L) { //printf("\r\nserialize"); int buffer = 0; if (lua_isboolean(L, 2)) { buffer = lua_toboolean(L, 2); } lua_settop(L, 1); // Object 1 lua_newtable(L); // CacheTable 2 lua_newtable(L); // OutTable 3 luaL_Buffer frame; uint16_t key = 0; int indice = 0; serialize_value(L, 1, &frame, &indice, &key); if (buffer) { lua_settop(L, 3); // return OutTable } else { concat_table(L, 3, &frame); // return table.concat(OutTable) (SerializedObject) } //printf("\r\nendserialize"); return 1; }
static String HHVM_FUNCTION(wddx_serialize_value, const Variant& var, const Variant& comment) { auto wddxPacket = req::make<WddxPacket>(comment, false, false); wddxPacket->serialize_value(var); return wddxPacket->packet_end(); }
static void serialize_value(lua_State *L, int pos, luaL_Buffer* frame, int* indice, uint16_t* key) { if (!lua_checkstack(L, 2)) { luaL_error(L, "cannot serialize: stack won't grow"); } uint8_t type = get_luatobin_type(L, pos); switch (type) { case BIN_NIL: { //printf("(nil[1])"); lua_pushlstring(L, (char *) &type, 1); write_object(L, indice); break; } case BIN_BOOLEAN: { //printf("(boolean[2])"); int boolean = lua_toboolean(L, pos); luaL_buffinit(L, frame); luaL_addchar(frame, type); luaL_addchar(frame, boolean & 0xFF); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_DOUBLE: { double number = lua_tonumber(L, pos); luaL_buffinit(L, frame); luaL_addchar(frame, type); //printf("(number[%d])", sizeof(number)); if (sendian.double_) hton(&number, sizeof(number), sendian.double_); luaL_addlstring(frame, (char*) &number, sizeof(number)); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_INTEGER: { int32_t number = lua_tointeger(L, pos); luaL_buffinit(L, frame); luaL_addchar(frame, type); //printf("(number[%d])", sizeof(number)); if (sendian.int32_) hton(&number, sizeof(number), sendian.int32_); luaL_addlstring(frame, (char*) &number, sizeof(number)); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_STRING: { uint16_t cached = verify_cache(L, pos, key); if (cached != 0) { //printf("(stringref[%d])", cached); luaL_buffinit(L, frame); luaL_addchar(frame, BIN_REF); if (sendian.int16_) hton(&cached, sizeof(cached), sendian.int16_); luaL_addlstring(frame, (char*) &cached, sizeof(cached)); luaL_pushresult(frame); write_object(L, indice); break; } size_t s; const char* string = lua_tolstring(L, pos, &s); if (s >= 0xFFFF) luaL_error(L, "cannot serialize: string length > 65k"); uint16_t size = (uint16_t) s; luaL_buffinit(L, frame); luaL_addchar(frame, type); uint16_t nsize = size; if (sendian.int16_) hton(&nsize, sizeof(nsize), sendian.int16_); luaL_addlstring(frame, (char*) &nsize, sizeof(nsize)); //printf("(string[%d][%d])", *key, size); luaL_addlstring(frame, string, size); luaL_pushresult(frame); write_object(L, indice); break; } case BIN_FUNCTION: { uint16_t cached = verify_cache(L, pos, key); if (cached != 0) { //printf("(functionref[%d])", cached); luaL_buffinit(L, frame); luaL_addchar(frame, BIN_REF); if (sendian.int16_) hton(&cached, sizeof(cached), sendian.int16_); luaL_addlstring(frame, (char*) &cached, sizeof(cached)); luaL_pushresult(frame); write_object(L, indice); break; } serialize_function(L, frame, pos); size_t s; const char* string = lua_tolstring(L, -1, &s); if (s >= 0xFFFF) luaL_error(L, "cannot serialize: function length > 65k"); uint16_t size = (uint16_t) s; luaL_buffinit(L, frame); luaL_addchar(frame, type); uint16_t nsize = size; if (sendian.int16_) hton(&nsize, sizeof(nsize), sendian.int16_); luaL_addlstring(frame, (char*) &nsize, sizeof(nsize)); //printf("(function[%d][%d])", *key, size); luaL_addlstring(frame, string, size); luaL_pushresult(frame); write_object(L, indice); lua_pop(L, 1); // remove the serialized function break; } case BIN_TABLE: { uint16_t cached = verify_cache(L, pos, key); if (cached != 0) { //printf("(tableref[%d])", cached); luaL_buffinit(L, frame); luaL_addchar(frame, BIN_REF); if (sendian.int16_) hton(&cached, sizeof(cached), sendian.int16_); luaL_addlstring(frame, (char*) &cached, sizeof(cached)); luaL_pushresult(frame); write_object(L, indice); break; } // reserved for table header (as size cannot be calculated beforehand) *indice = *indice + 1; int header = *indice; //printf("{table="); int top; size_t s = 0; lua_pushnil(L); while (lua_next(L, pos) != 0) { top = lua_gettop(L); serialize_value(L, top - 1, frame, indice, key); serialize_value(L, top, frame, indice, key); lua_pop(L, 1); s++; } if (s >= 0xFFFF) luaL_error(L, "cannot serialize: table length > 65k"); uint16_t size = (uint16_t) s; luaL_buffinit(L, frame); luaL_addchar(frame, type); uint16_t nsize = size; if (sendian.int16_) hton(&nsize, sizeof(nsize), sendian.int16_); luaL_addlstring(frame, (char*) &nsize, sizeof(nsize)); luaL_pushresult(frame); // set table header lua_rawseti(L, 3, header); //printf("[%d]}", size); break; } default: luaL_error(L, "cannot serialize: unsupported type (%d)", lua_type(L, pos)); } }