static void mar_decode_value (lua_State *L, const char *buf, size_t len, const char **p, size_t *idx) { size_t l; char val_type = **p; mar_incr_ptr(MAR_CHR); switch (val_type) { case LUA_TBOOLEAN: lua_pushboolean(L, *(char*)*p); mar_incr_ptr(MAR_CHR); break; case LUA_TNUMBER: lua_pushnumber(L, *(lua_Number*)*p); mar_incr_ptr(MAR_I64); break; case LUA_TLIGHTUSERDATA: { void * ptr=(void*)*(void**)*p; lua_pushlightuserdata(L, ptr); mar_incr_ptr(MAR_I64); } break; case LUA_TSTRING: mar_next_len(l, uint32_t); lua_pushlstring(L, *p, l); mar_incr_ptr(l); break; case LUA_TTABLE: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TVAL) { mar_next_len(l, uint32_t); lua_newtable(L); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_decode_table(L, *p, l, idx); mar_incr_ptr(l); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { luaL_error(L, "bad encoded data"); } break; } case LUA_TFUNCTION: { size_t nups; int i; mar_Buffer dec_buf; char tag = *(char*)*p; mar_incr_ptr(1); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else { mar_next_len(l, uint32_t); dec_buf.data = (char*)*p; dec_buf.size = l; dec_buf.head = l; dec_buf.seek = 0; lua_load(L, (lua_Reader)buf_read, &dec_buf, "=marshal" #if LUA_VERSION_NUM > 501 ,NULL #endif ); mar_incr_ptr(l); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); nups = lua_objlen(L, -1); for (i=1; i <= nups; i++) { lua_rawgeti(L, -1, i); #if LUA_VERSION_NUM > 501 if(lua_type(L,-1)==LUA_TSTRING) { size_t len=0; const char * s=lua_tolstring(L,-1,&len); if(!strncmp(s,LEDA_ENV_MARKER,sizeof(LEDA_ENV_MARKER))) { lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); lua_remove(L,-2); } } #endif lua_setupvalue(L, -3, i); } lua_pop(L, 1); mar_incr_ptr(l); } break; } case LUA_TUSERDATA: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { /* tag == MAR_TVAL */ lua_pushnil(L); } break; } case LUA_TNIL: case LUA_TTHREAD: lua_pushnil(L); break; default: luaL_error(L, "bad code"); } }
static void mar_decode_value (lua_State *L, const char *buf, size_t len, const char **p, size_t *idx) { size_t l; char val_type = **p; mar_incr_ptr(MAR_CHR); switch (val_type) { case LUA_TBOOLEAN: lua_pushboolean(L, *(char*)*p); mar_incr_ptr(MAR_CHR); break; case LUA_TNUMBER: lua_pushnumber(L, *(lua_Number*)*p); mar_incr_ptr(MAR_I64); break; case LUA_TSTRING: mar_next_len(l, uint32_t); lua_pushlstring(L, *p, l); mar_incr_ptr(l); break; case LUA_TTABLE: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TVAL) { mar_next_len(l, uint32_t); lua_newtable(L); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_decode_table(L, *p, l, idx); mar_incr_ptr(l); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { luaL_error(L, "bad encoded data"); } break; } case LUA_TFUNCTION: { size_t nups; int i; mar_Buffer dec_buf; char tag = *(char*)*p; mar_incr_ptr(1); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else { mar_next_len(l, uint32_t); dec_buf.data = (char*)*p; dec_buf.size = l; dec_buf.head = l; dec_buf.seek = 0; lua_load(L, (lua_Reader)buf_read, &dec_buf, "=marshal"); mar_incr_ptr(l); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); nups = lua_objlen(L, -1); for (i=1; i <= nups; i++) { lua_rawgeti(L, -1, i); lua_setupvalue(L, -3, i); } lua_pop(L, 1); mar_incr_ptr(l); } break; } case LUA_TUSERDATA: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { /* tag == MAR_TVAL */ lua_pushnil(L); } break; } case LUA_TNIL: case LUA_TTHREAD: lua_pushnil(L); break; default: luaL_error(L, "bad code"); } }