All pastes #105710 Raw Edit

ckknight

public lua v1 · immutable
#105710 ·published 2006-07-29 21:21 UTC
rendered paste body
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