bakpakin / binser Goto Github PK
View Code? Open in Web Editor NEWCustomizable Lua Serializer
License: MIT License
Customizable Lua Serializer
License: MIT License
The README says that binser "does not [...] use the Lua parser to read expressions" and that "[t]his makes it safe."
But the deserializer uses loadstring()
for functions.
Doesn't this mean that binser is in fact not safe? Perhaps deserialize()
could take an argument to enable the non-safe behavior of deserializing functions?
Hi,
I am trying to use binser to serialize data from lua. Based on the readme, it looks perfect, as I need to be able to include binary data into the files. That said, I have no clue how to do that, based on the readme I'd guess that I'd use registerResource
to achieve that but I can't really make sense of it based on the readme. Can someone provide me with a full example of how to do that i.e. with an image?
Thank you!
I'm trying to serialize a rather complex and large table. Good news is, binser is really fast to do so.
Bad news is there's some self-referencing that it doesn't seem to recognize.
I have a hierarchy like so:
level -> grid[x][y] -> units[x] -> actions[i] -> data -> level
Where level
should be equal to data.level
. I get two copies of the same level
.
I was using most likely b403348
The serialized and deserialized values are a bit different, though this is nothing that important.
local binser = require("binser")
local tbl = {1/0, 0/0, -(1/0), -(0/0), math.huge, -math.huge}
local data = binser.deserialize(binser.serialize(tbl))
print(table.unpack(data))
print(table.unpack(tbl))
-- output:
inf -nan(ind) -inf -nan(ind) inf -inf
inf -nan(ind) -inf nan inf -inf
A similar issue was fixed here: gvx/Smallfolk#3
ps. I dont suppose its a one line change to make \0
not appear in the serialized sequence?
Assuming it does appear in it.
Otherwise Ill encode the output string not to be able to represent the null character.
Lua 5.4.0 on Arch Linux
Current readPath and writePath follow a pattern that if the file does not exist it wraps the io.open return value in an assert which then calls Lua's error stack. In one instance this caused me to have to write my own file handling. It would be nice if readFile and writeFile would return nil or an error so I could handle it myself.
A contrived example of the case:
binser = require("binser")
t = { data = "someData"}
data = binser.readFile("myfile")
if data then
data[#data + 1] = t
end
binser.writeFile("myFile", table.unpack(data))
In my opinion, what I would like to see from readFile/writeFile might be something like this:
local function readFile(path)
local file, err = io.open(path, "rb")
if not file then return nil end
-- assert(file, err)
local str = file:read("*all")
file:close()
return deserialize(str)
end
I usually hate to bother people with my specific game's code, but I've had a bit of issue getting binser to operate correctly here. So, in this example love file I am able to use binser to register a quad userdata, save the table that contains instances of a class that contains a quad (f5), manipulate those objects in some way (f6), and then load them back (f7).
On lines 90 of main.lua we wrap the quad's userdata and register it, on line 312 we register the table that contains the instances of the 'static' objects, and on line 1300 we do the actual save/manip/restore.
I had to manipulate binser so that it did not attempt to serialize a key/value pair of nil/nil by adding:
if k~=nil then
ret[k] = v
else
print(k, v)
end
to line 309 of binser.lua
I was under the impression that I should be able to serialize a plain table no problems so I think I might be off on the wrong foot trying to register or serialize the tables the way I am.
Hi
I am trying to use binser in my hobby project with Lua 5.3. It is failing as math.frexp() and math.ldexp() no longer exist in 5.3 version, as they are deprecated. Is there any plan to update binser to 5.3?
Thank you very much.
This is just some feedback, but from user stand point the vararg return is very inconvenient.
TL;DR
To process the return values from deserialize a new function needs to be created OR must assume there are no nils and they must be tabled like {binser.deserialize(str)}
to for
loop them. Also this is complicated more by the fact that deserialize can error out and pcall is needed.
To process the results you must loop them through unless you expect an exact amount of results like 3 and store them in variables.
Looping the results must be done either by select
or making a table of the results and using select("#", ...)
to get the amount of results. Doing so requires another function to be made so you can actually use the vararg variable at all ...
.
In addition to this, the serialize and deserialize functions can error out.
Lets assume you want to load game data and want to handle any errors from deserializing.
To do that you would need to wrap the deserialize in a pcall
, which returns true or false and then error message or the function return value.
Below I made the easiest way to do this, which requires the result of pcall to be directly passed to another function that processes the results. Otherwise I could table all the return values and test if index 1 has true or false and then continue or possibly remove that value.
local process_varargs(process, success, ...)
assert(process, success) -- assert or some other error handler
for i = 1, select("#", ...) do
process(select(i, ...))
end
return true
end
process_varargs(process, pcall(binser.deserialize, str))
If the table and len was returned directly from deserialize without unpacking, it would be very easy to unpack the table if needed and otherwise it would be easy to handle the table and it would also be more efficient. For example
local success, results, len = pcall(binser.deserialize, str)
assert(success, results) -- assert or some other error handler
for i = 1, len do
process(results[i])
end
Hi,
Just to let you know that the doc for deserialize
and deserializedN
in the README are missing the index
argument.
In README
local function deserialize(str)
in the source
local function deserialize(str, index)
For instance the following code will not work as expected if the user doesnt know about the second index
argument.
binser.deserialize(love.filesystem.read('myfile.ser'))
Sorry for the very stupid question. I'm trying to print a simple table like so :
grid = {}
for i = 1, x do
for j = 1, y do
grid[i] = {}
grid[i][j] = 1
end
end
print(binser.s(grid))
All this gives as an output is :
�+���'����'����'����'����'����'����'����'����'����'����'����'����'����'����'����'��
What I'm doing wrong?
Can someone please provide an example how to deserialize the Employee "joe" metatable in the example on Templates.
I don't get it. (^_^;)
binser sometimes optimistically works with bytes at indexes that may be past end of input. E.g.
local binser = require "binser"
binser.deserialize("\128")
binser.lua:347: attempt to perform arithmetic on a nil value
stack traceback:
binser.lua:347: in upvalue 'deserialize_value'
binser.lua:455: in function 'binser.deserialize'
(...tail calls...)
[C]: in ?
(this is on fix-next branch)
This technically fits the "binser throws on malformed input" contract but makes it impossible to distinguish deseriazation failures due to bad input from regular Lua errors (bugs happen, don't want to silence/misinterpret them). It would be even nicer if there was a way to get nil + error message on malformed input.
Please add instruction to this function, i waste 3 days to find a way to DECODE serialized files.
Writing is simple
local mydata = binser.serialize(uammokey,uicekey,ubombkey,udropkey,uleftkey,urightkey,uupkey,udownkey)
sourcewrite(mydata, "keyboardsettings");
But READING is real hardcore.
keyboardloadingdata=sourceread ("keyboardsettings");
if (keyboardloadingdata~=0) then
ua= binser.deserialize (keyboardloadingdata)
uammokey =ua[1];--split("!") ;
uicekey = ua[2];
ubombkey = ua[3];
udropkey = ua[4];
uleftkey = ua[5];
urightkey = ua[6];
uupkey = ua[7];
udownkey = ua[8];
uunpackkey = ua[9];
end
i tries reads data wrong methods like this
uammokey, uice, ubomb,uleft...= ua
In the current LOVE game I am building, I use the rotLove library, which uses 30log classes. I've managed to serialize my own 30log classes, but I'm getting an error when I try to load now - an error I was not getting until I added rotLove's game scheduler and engine to my game state to be serialized.
S to save, Shift-Q to quit
truesteel.love.zip
It would be nice to have a field (e.g. binser.version = "0.0-6"
) so that programs depending on binser could show its version in their --version
message. This makes it easy to identify user environment when investigating issues.
(Side note: IIRC rockspec revisions are supposed to be for metadata/dependency/build instruction updates and should not point to different sources, perhaps something semver-like could be used like 0.0.6?)
minimal code example:
local mt = {}
binser.register(mt, "foo")
binser.unregister("foo")
binser.register(mt, "bar") -- Error: Resource already registered
Good day,
This currently fairly simple code will return me an error when I try to to deserialize.
binser = require "includes/binser"
local player = {}
--
function love.load()
if love.filesystem.exists( 'Save.lua' ) then
player = binser.d(love.filesystem.load('Save.lua'))
else
player[1] = "foo"
player[2] = "bar"
end
end
--
function love.quit()
love.filesystem.write( 'Save.lua', binser.s(player) )
end
actual error:
content of save file:
Thank you.
0.0 will become 0.25
Hi,
i tried today the binser but i get this error message: (number has no integer representation)
So my table contains a few floating point values since can distinguish between them since lua 5.3.
Is Lua 5.3 fully supported with floating point values ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.