metatables: feature to toggle (de)serializing them. Fix #21. (#22)

This commit is contained in:
Adrien Bertrand 2021-02-14 13:53:02 -05:00 committed by GitHub
parent 66042a5b09
commit 1d3ebe04cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 4 deletions

View File

@ -7,6 +7,7 @@
* [`bitser.loads`](#loads)
* [`bitser.loadData`](#loaddata)
* [`bitser.loadLoveFile`](#loadlovefile)
* [`bitser.includeMetatables`](#includeMetatables)
* [`bitser.register`](#register)
* [`bitser.registerClass`](#registerclass)
* [`bitser.unregister`](#unregister)
@ -148,6 +149,14 @@ Only useful if you're running [LÖVE](https://love2d.org/).
See also: [`bitser.dumpLoveFile`](#dumplovefile).
## includeMetatables
Controls whether bitser will (de)serialize metatables. true by default.
```lua
bitser.includeMetatables(bool)
```
## register
```lua

View File

@ -30,6 +30,7 @@ local buf = nil
local buf_is_writable = true
local writable_buf = nil
local writable_buf_size = nil
local includeMetatables = true -- togglable with bitser.includeMetatables(false)
local SEEN_LEN = {}
local function Buffer_prereserve(min_size)
@ -198,7 +199,7 @@ local function write_table(value, seen)
classkey = classkey_registry[classname]
Buffer_write_byte(242)
serialize_value(classname, seen)
elseif metatable then
elseif includeMetatables and metatable then
Buffer_write_byte(253)
else
Buffer_write_byte(240)
@ -221,7 +222,7 @@ local function write_table(value, seen)
serialize_value(v, seen)
end
end
if metatable and not classname then
if includeMetatables and metatable and not classname then
serialize_value(metatable, seen)
end
end
@ -323,7 +324,9 @@ local function deserialize_value(seen)
v[key] = deserialize_value(seen)
end
if t == 253 then
setmetatable(v, deserialize_value(seen))
if includeMetatables then
setmetatable(v, deserialize_value(seen))
end
end
return v
elseif t == 241 then
@ -434,6 +437,8 @@ end, loads = function(str)
end
Buffer_newReader(str)
return deserialize_value({})
end, includeMetatables = function(bool)
includeMetatables = not not bool
end, register = function(name, resource)
assert(not resource_registry[name], name .. " already registered")
resource_registry[name] = resource

View File

@ -334,10 +334,18 @@ describe("bitser", function()
it("can read and write simple multiple cdata of the same ctype without getting confused", function()
test_serdeser({ffi.new('double', 42.5), ffi.new('double', 12), ffi.new('double', 0.01)})
end)
it("can read and write metatables", function()
it("can read and write metatables by default", function()
local t = setmetatable({foo="foo"}, {__index = {bar="bar"}})
test_serdeser(t)
assert.are.same(getmetatable(t), getmetatable(serdeser(t)))
assert.are.same(serdeser(t).bar, "bar")
end)
it("ignores metatables if the feature is explicitly disabled", function()
bitser.includeMetatables(false)
local t = setmetatable({foo="foo"}, {__index = {bar="bar"}})
test_serdeser(t)
assert.is_nil(getmetatable(serdeser(t)))
assert.is_nil(serdeser(t).bar)
bitser.includeMetatables(true) -- revert back to default for potential other tests
end)
end)