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

View File

@ -30,6 +30,7 @@ local buf = nil
local buf_is_writable = true local buf_is_writable = true
local writable_buf = nil local writable_buf = nil
local writable_buf_size = nil local writable_buf_size = nil
local includeMetatables = true -- togglable with bitser.includeMetatables(false)
local SEEN_LEN = {} local SEEN_LEN = {}
local function Buffer_prereserve(min_size) local function Buffer_prereserve(min_size)
@ -198,7 +199,7 @@ local function write_table(value, seen)
classkey = classkey_registry[classname] classkey = classkey_registry[classname]
Buffer_write_byte(242) Buffer_write_byte(242)
serialize_value(classname, seen) serialize_value(classname, seen)
elseif metatable then elseif includeMetatables and metatable then
Buffer_write_byte(253) Buffer_write_byte(253)
else else
Buffer_write_byte(240) Buffer_write_byte(240)
@ -221,7 +222,7 @@ local function write_table(value, seen)
serialize_value(v, seen) serialize_value(v, seen)
end end
end end
if metatable and not classname then if includeMetatables and metatable and not classname then
serialize_value(metatable, seen) serialize_value(metatable, seen)
end end
end end
@ -323,7 +324,9 @@ local function deserialize_value(seen)
v[key] = deserialize_value(seen) v[key] = deserialize_value(seen)
end end
if t == 253 then if t == 253 then
setmetatable(v, deserialize_value(seen)) if includeMetatables then
setmetatable(v, deserialize_value(seen))
end
end end
return v return v
elseif t == 241 then elseif t == 241 then
@ -434,6 +437,8 @@ end, loads = function(str)
end end
Buffer_newReader(str) Buffer_newReader(str)
return deserialize_value({}) return deserialize_value({})
end, includeMetatables = function(bool)
includeMetatables = not not bool
end, register = function(name, resource) end, register = function(name, resource)
assert(not resource_registry[name], name .. " already registered") assert(not resource_registry[name], name .. " already registered")
resource_registry[name] = resource 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() 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)}) test_serdeser({ffi.new('double', 42.5), ffi.new('double', 12), ffi.new('double', 0.01)})
end) 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"}}) local t = setmetatable({foo="foo"}, {__index = {bar="bar"}})
test_serdeser(t) test_serdeser(t)
assert.are.same(getmetatable(t), getmetatable(serdeser(t))) assert.are.same(getmetatable(t), getmetatable(serdeser(t)))
assert.are.same(serdeser(t).bar, "bar") assert.are.same(serdeser(t).bar, "bar")
end) 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) end)