This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Isaac's profile picture

Unserialization doesn't work

Started by Isaac, 08 June 2015 - 04:32 PM
Isaac #1
Posted 08 June 2015 - 06:32 PM
Today I tried to get information from a table stored in a file. I put the table here: http://pastebin.com/Fi9LsNfk (I pasted it here for convenience)


{
  stone = {
	letter = "#",
	color = 256,
  },
  air = {
	letter = "-",
	color = 32768,
	dord = 0,
  },
  gold = {
	letter = "@",
	color = 16,
	dord = 5,
  },
  iron = {
	letter = "@",
	color = colors.white ,
	dord = 15,
  },
  diamond = {
	letter = "*",
	color = colors.lightBlue ,
	dord = 1,
  },
}

When I do:

sMats = file.readAll()
print(sMats)

It prints the serialized table as intended, but when I do this:

tMats = textutils.unserialize(sMats)

The unserialization doesn't work and it returns nil. The strange thing is that it works with other tables but not this one. If I recreate the table though the lua console, serialize it, and save it in a file, I get the exact same file, but unserializing the contents works, but if I do a small modification to the file, whatever it is, the string won't unserialize. This is really annoying as I'll want to modify that file often. I really don't understand what's wrong, so I came here for help.
KingofGamesYami #2
Posted 08 June 2015 - 08:29 PM
I tested this in Mimic, this is really, really weird. I pulled the source code from textutils to see what might be the problem, copied the function and edited it like this:


function unserialize( s )
    local func = loadstring( "return "..s )
    if func then
        local ok, result = pcall( func )
        if ok then
            return result
        end
    end
    return nil
end

…which worked. I'm not sure what the "load" function is, because it's not defined within textutils but it's also not global (at least in Mimic). If someone knows what the load function does, or has the source code, I'd like to see it because it is screwing up for this table.
Lyqyd #3
Posted 08 June 2015 - 08:31 PM
It's likely the color entries that are using colors.white and such. I don't think the environment that tables are unserialized in has the colors API. Try replacing those with the numeric values.

You should also be able to catch the second return value from unserialize, which should be an error message if it fails. If I recall correctly, anyway.
Bomb Bloke #4
Posted 09 June 2015 - 12:58 AM
I'm not sure what the "load" function is, because it's not defined within textutils but it's also not global (at least in Mimic). If someone knows what the load function does, or has the source code, I'd like to see it because it is screwing up for this table.

Do you mean loadstring()? That simply compiles a function out of whatever string you pass to it.
KingofGamesYami #5
Posted 09 June 2015 - 03:53 AM
No, I mean load. I modified my function to use loadstring. The original, unaltered unserialize:


function unserialize( s )
    local func = load( "return "..s, "unserialize", "t", {} ) --#this line here, what is it?
    if func then
        local ok, result = pcall( func )
        if ok then
            return result
        end
    end
    return nil
end
Lyqyd #6
Posted 09 June 2015 - 04:19 AM
See the Lua 5.2 Reference Manual. The function is also present in Lua 5.1, but accepts different arguments.
MKlegoman357 #7
Posted 09 June 2015 - 10:51 AM
The problem here is that in textutils.unserialize tables have no access to any APIs or functions. 'load' as seen in the KingofGamesYami post is used there because in Lua 5.2 there is no 'loadstring' and that piece of code was taken from the CC 1.74 pre-release which added partial support for Lua 5.2.