local Serializedo local recurse local function _Serialize(value) local kind = type(value) if kind == "boolean" then if value then return "by" else return "bn" end elseif not value then return "-" elseif kind == "number" then local v = tostring(value) return "#" .. string.char(string.len(v)) .. v elseif kind == "string" then local len = string.len(value) if len <= 127 then return "s" .. string.char(len) .. value else return "S" .. string.char(math.floor(len / 128)) .. string.char(math.mod(len, 128)) .. value end elseif kind == "function" then local v = string.dump(value) local len = string.len(v) if len <= 127 then return "f" .. string.char(len) .. v else return "F" .. string.char(math.floor(len / 128)) .. string.char(math.mod(len, 128)) .. v end elseif kind == "table" then if recurse[value] then for k in pairs(recurse) do recurse[k] = nil end AceComm:error("Cannot serialize a recursive table") return end recurse[value] = true local t = Compost and Compost:Acquire() or {} for k,v in pairs(value) do table.insert(t, _Serialize(k)) table.insert(t, _Serialize(v)) end if not notFirst then for k in pairs(recurse) do recurse[k] = nil end end local s = table.concat(t) local len = string.len(s) if len <= 127 then return "t" .. string.char(len) .. s else return "T" .. string.char(math.floor(len / 128)) .. string.char(math.mod(len, 128)) .. s end if Compost then Compost:Reclaim(t) end t = nil end end function Serialize(value) if not recurse then recurse = {} end local chunk = _Serialize(value) for k in pairs(recurse) do recurse[k] = nil end return chunk endendlocal Deserializedo local byte_b = string.byte('b') local byte_nil = string.byte('-') local byte_num = string.byte('#') local byte_s = string.byte('s') local byte_S = string.byte('S') local byte_f = string.byte('f') local byte_F = string.byte('F') local byte_t = string.byte('t') local byte_T = string.byte('T') local function _Deserialize(value, position) if not position then position = 1 end local x = string.byte(value, position) if x == byte_b then local v = string.byte(value, position + 1) if v == "n" then return false, position + 1 else return true, position + 1 end elseif x == byte_nil then return nil, position elseif x == byte_s then local len = string.byte(value, position + 1) return string.sub(value, position + 2, position + 1 + len), position + 1 + len elseif x == byte_S then local len = string.byte(value, position + 1) * 128 + string.byte(value, position + 2) return string.sub(value, position + 3, position + 2 + len), position + 2 + len elseif x == byte_num then local len = string.byte(value, position + 1) return tonumber(string.sub(value, position + 2, position + 1 + len)), position + 1 + len elseif x == byte_f then local len = string.byte(value, position + 1) return loadstring(string.sub(value, position + 2, position + 1 + len)), position + 1 + len elseif x == byte_F then local len = string.byte(value, position + 1) * 128 + string.byte(value, position + 2) return loadstring(string.sub(value, position + 3, position + 2 + len)), position + 2 + len elseif x == byte_t or x == byte_T then local finish local start if x == byte_t then local len = string.byte(value, position + 1) finish = position + 1 + len start = position + 2 else local len = string.byte(value, position + 1) * 128 + string.byte(value, position + 2) finish = position + 2 + len start = position + 3 end local t = Compost and Compost:Acquire() or {} local curr = start - 1 while curr < finish do local key, l = Deserialize(value, curr + 1) local value, m = Deserialize(value, l + 1) curr = m t[key] = value end return t, finish else error("Improper serialized value provided") end end function Deserialize(value) local ret,msg = pcall(_Deserialize, value) if not ret then if msg == "Improper serialized value provided" then return nil else error(msg, 2) end else return msg end endend