All pastes #519986 Raw Edit

serialise/deserialise

public lua v1 · immutable
#519986 ·published 2007-05-29 20:27 UTC
rendered paste body
// Helper functions for serialise functionslocal function SerialiseChunk( chunk, tables )	local type = type( chunk )		if		type == "number"  then return 'N:'..chunk	elseif	type == "string"  then return 'S:"'..chunk..'"'	elseif	type == "boolean" then return 'B:'..tostring( chunk ):sub( 1,1 )	elseif	type == "Entity"  then if chunk == GetWorldEntity() then return 'E:W' elseif chunk == NULL then return 'E:N' else return 'E:'..chunk:EntIndex()  end	elseif	type == "Vector"  then return 'V:'..chunk.x.."|"..chunk.y.."|"..chunk.z	elseif	type == "Angle"   then return 'A:'..chunk.pitch.."|"..chunk.yaw.."|"..chunk.roll	elseif	type == "Player"  then return 'P:'..chunk:UniqueID()	elseif	type == "table"	 then		local ID = tostring( chunk ):sub( 8 )		if !tables[ID] then tables[ID] = true tables[ID] = SerialiseTableKeyValues( chunk, tables ) end		return 'T:'..ID	endendlocal function DeSerialiseChunk( chunk, tables )	local type = chunk:sub(1,1)		if		type == "N" then return chunk:sub(3)	elseif	type == "S" then return chunk:sub( 4, -2 )	elseif	type == "B" then return chunk:sub(3) == "t"	elseif	type == "E" then local ent = chunk:sub(3) if ent == "W" then return GetWorldEntity() elseif ent == "N" then return NULL else return Entity( ent )  end	elseif	type == "V" then return Vector( string.Explode( '|', chunk:sub(3) ) )	elseif	type == "A" then return Angle( string.Explode( '|', chunk:sub(3) ) )	elseif	type == "P" then return player.GetByUniqueID( chunk:sub(3) )	elseif	type == "T" then 		local ID = chunk:sub(3)		local t = {}		if !tables[ID] then tables[ID] = {} end		table.insert( tables[ID], t )		return t	endendfunction SerialiseTableKeyValues( tbl, tables )	local temp = {}	local DoKeys = true //!table.IsSequential( tbl )	for k,v in pairs( tbl ) doprint(k,v)		local str = SerialiseChunk( v, tables )		if DoKeys then str = SerialiseChunk( k, tables ) .."=".. str end		table.insert( temp, str )	end	return tempend/*---------------------------------------------------------   Name:	table.serialise( table )   table.deserialise( table )   Desc:	Converts an arbitrary table containing vectors, angles, bools, players, entities, etc  to & from a compact string.	(will handle circular references)---------------------------------------------------------*/function table.serialise( t )	local tables	= {}	local str		= ""		local headID = tostring(t):sub(8)	local head	 = SerialiseTableKeyValues( t, tables )	local str	 = headID.."{".. table.concat( tables[ headID ], ";" ) ..";}"		for k,v in pairs( tables ) do		str = str..k.."{".. table.concat( v, ";" ) ..";}"	end	return strendfunction table.deserialise( str )	local tables = {}	local subtables	= {}	local head = nil	// I'm not too good at regex, so there's probably a more efficient/reliable way of doing this	for ID,tbl in string.gmatch(str, "(........)[\{](.-)[\}]") do  // Get each table block		tables[ID] = {}		for k,v in string.gmatch(tbl, "\(.-)[\=](.-)[\;]") do	// Split each table block into k/v pairs			k = DeSerialiseChunk( k, subtables )	// deserialise each k/v pair			v = DeSerialiseChunk( v, subtables )			tables[ID][k] = v		end		//the first table will be the head		if !head then head = tables[ID] end	end	// Restore table references	for ID,tbls in pairs( subtables ) do		for _,tbl in pairs( tbls ) do					print( tbl, tables[ID], ID )			table.Merge( tbl, tables[ID] )		end	end	return headend