PtokaX forum

Development Section => Your Developing Problems => Topic started by: bastya_elvtars on 25 February, 2007, 16:58:28

Title: SaveTable woes
Post by: bastya_elvtars on 25 February, 2007, 16:58:28
Hey peeps, I have this (http://lua-users.org/wiki/SaveTableToFile) code and it saves an array in a weird format:
Code (lua) Select
return {{[1] = {2},},
{[1] = [[music]],[2] = [[bastya@home]],[3] = [[02/24/2007]],[4] = [[something]],},
}


Can somebody please explain why it writes {[1] = {2},}, out? It breaks the entire thing.
Title: Re: SaveTable woes
Post by: bastya_elvtars on 25 February, 2007, 17:42:31
There is not even such stuff in my array. The array consists of tabloes as values:
Code (lua) Select
AllStuff=
{
  {[1] = [[music]],[2] = [[bastya@home]],[3] = [[02/24/2007]],[4] = [[something]],}
  {[1] = [[music]],[2] = [[bastya@home]],[3] = [[02/24/2007]],[4] = [[something2]],}
}

OK, found the problem, tables saved by this method should be loaded like this: mytbl=table.load("file") - I have just called table.load("file"), completely ignored the return thing. That table inside is used internally by the routine.

BTW does anyone know who wrote this? I think chill did, but unsure...
Title: Re: SaveTable woes
Post by: plop on 25 February, 2007, 20:05:42
is it freshstuff 3?
then it could be me, older versions were made by chill.

plop
Title: Re: SaveTable woes
Post by: bastya_elvtars on 25 February, 2007, 20:41:20
No, this code is from the lua-users wiki. There is no information on the author.
Title: Re: SaveTable woes
Post by: CHILLCODE? on 26 February, 2007, 12:01:38
this code is meant to save also tables where you have an index as a table e.g.

t = { "test" }
t2 = {} t2[t] = { "test" }

and it encloses the strings, so you don't have to worry about what you save and speacial chars as \r or \n are saved properly, these make problems if you only save it with  sting.format( "%q", string ).

So in your case you only need a simple serialize function, but if you one day have cyclic references in the table or tables as index, you will not be able to use any normal serialize script anymore. So this script basically saves anything that can be saved. As said I had some help from the pickle.lua script that you will also find on the wiki, but that one has a bug since it shows you a quite different table after loading again, I tried this code with lots of tables and never could find any differences between the saved and the loaded one, and thats what you want. But this script will need more time in your case to save and load, since you could also use a simple serialize.

Ahm and yup I wrote it with help from the pickle.lua script as said :)
Title: Re: SaveTable woes
Post by: bastya_elvtars on 26 February, 2007, 13:55:22
Quote from: CHILLCODE? on 26 February, 2007, 12:01:38
But this script will need more time in your case to save and load, since you could also use a simple serialize.

Yes, I need it for exact data persistence (especially multiline).

Quote from: CHILLCODE? on 26 February, 2007, 12:01:38
Ahm and yup I wrote it with help from the pickle.lua script as said :)
OK, then pickle is free to use, how about this, may I use it? :-)
Title: Re: SaveTable woes
Post by: CHILLCODE? on 26 February, 2007, 14:48:16
sure its free, else it wouldn't have no use :), I think anything posted on the lua wiki page is for free usage.
Title: Re: SaveTable woes
Post by: bastya_elvtars on 07 March, 2007, 00:23:55
Quote from: CHILLCODE? on 26 February, 2007, 14:48:16
sure its free, else it wouldn't have no use :), I think anything posted on the lua wiki page is for free usage.

Thanks! :)
Found a bug: it goes mad when I try to save strings starting or ending with square brackets. I have circuvented it, but will look into a real solution.
Title: Re: SaveTable woes
Post by: CHILLCODE? on 07 March, 2007, 14:42:51
hey can you give me the entrie that fucks up or the table even

I tried the script with this code and I thaught it was okey, also shows some breaktes

Code (lua) Select

function Main()

print( "Serialise Test" )

t = {}

t.a = 1
t.b = 2
t.c = {}
-- self reference
t.c.a = t
--should change t.a to 4
t.c.a.a = 4

t.func = function() end

-- table as index
t.f = {  [{ a = 5, b = 7, }] = "[[ hellooooo ]] ]]", [{ 1,2,3, m = 5, 5,6,7 }] = { a = 1 }, }

t.i = { [{ [{ a = 10 }] = 6, }] = 4 }

t.enc = "[[ [=[ hello world"

t.x = "[ [ \"hello \r\n world \'] ]]"

-- references
t.c.d = t.c.a

print( "Before Save\n\n" )
for i,v in pairs( t) do
print( i, v )
end
for i,v in pairs( t.f) do
if type( i ) == "table" then
print( table.maxn( i ) )
for i2,v2 in pairs( i) do
print( "\t", i2, v2 )
end
else
print( i, v )
end
end

table.save( t, "t.txt" )

t = table.load( "t.txt" )

print("\n\nAfter Save\n\n" )

for i,v in pairs( t) do
print( i, v )
end
for i,v in pairs( t.f) do
if type( i ) == "table" then
print( table.maxn( i ) )
for i2,v2 in pairs( i) do
print( "\t", i2, v2 )
end
else
print( i, v )
end
end

table.save( t, "t2.txt" )
io.read()
end
Main()


so if you could just tell me what the item looks like that messes up I'll try and fix it
Title: Re: SaveTable woes
Post by: bastya_elvtars on 07 March, 2007, 14:57:45
Code (lua) Select
{[1] = [[music]],[2] = [[(TGA-OP)Darkstar?]],[3] = [[11/07/2004]],[4] = [[andrea bocelli - andrea [2004]]],},
Title: Re: SaveTable woes
Post by: CHILLCODE? on 09 March, 2007, 13:59:42
hey how could I miss that, ah well thx a lot, i fixed it hopefully now :)

Code (lua) Select

--[[
TABLE.SAVE 0.4

table.save( table, file ) 0.4
Save Table to File
Functions, Userdata and indices of these will not be saved
Strings will be converted to enclosed long brakets, makes it easier to save regardingly special chars,
now hopefull for sure thx to 'bastya_elvtars'
References are preserved

table.load( file )
returns a previously saved table

]]--

function table.save( t, sfile )
local tables = {}
table.insert( tables, t )
local lookup = { [t] = 1 }
local file = io.open( sfile, "w" )
file:write( "return {" )
for i,v in ipairs( tables ) do
table.pickle( v, file, tables, lookup )
end
file:write( "}" )
file:close()
end

function table.pickle( t, file, tables, lookup )
file:write( "{" )
for i,v in pairs( t) do
-- escape functions
if type( v ) ~= "function" and type( v ) ~= "userdata" then
-- handle index
if type( i ) == "table" then
if not lookup[i] then
table.insert( tables, i )
lookup[i] = table.maxn( tables )
end
file:write( "[{"..lookup[i].."}] = " )
else
local index = ( type( i ) == "string" and "[ "..string.enclose( i, 50 ).." ]" ) or string.format( "[%d]", i )
file:write( index.." = " )
end
-- handle value
if type( v ) == "table" then
if not lookup[v] then
table.insert( tables, v )
lookup[v] = table.maxn( tables )
end
file:write( "{"..lookup[v].."}," )
else
local value =  ( type( v ) == "string" and string.enclose( v, 50 ) ) or tostring( v )
file:write( value.."," )
end
end
end
file:write( "},\n" )
end

-- enclose string by long brakets ( string, maxlevel )
function string.enclose( s, maxlevel )
s = "["..s.."]"
local level = 0
while 1 do
if maxlevel and level == maxlevel then
error( "error: maxlevel too low, "..maxlevel )
--
elseif string.find( s, "%["..string.rep( "=", level ).."%[" ) or string.find( s, "]"..string.rep( "=", level ).."]" ) then
level = level + 1
else
return "["..string.rep( "=", level )..s..string.rep( "=", level ).."]"
end
end
end

function table.load( sfile )
local tables = dofile( sfile )
if tables then
local tcopy = {}
table.unpickle( tables[1], tables, tcopy )
return tcopy
end
end

function table.unpickle( t, tables, tcopy, pickled )
pickled = pickled or {}
pickled[t] = tcopy
for i,v in pairs( t ) do
local i2 = i
if type( i ) == "table" then
local pointer = tables[ i[1] ]
if pickled[pointer] then
i2 = pickled[pointer]
else
i2 = {}
table.unpickle( pointer, tables, i2, pickled )
end
end
local v2 = v
if type( v ) == "table" then
local pointer = tables[ v[1] ]
if pickled[pointer] then
v2 = pickled[pointer]
else
v2 = {}
table.unpickle( pointer, tables, v2, pickled )
end
end
tcopy[i2] = v2
end
end
Title: Re: SaveTable woes
Post by: bastya_elvtars on 09 March, 2007, 15:57:25
It works fine. Thank you.