megagrump / moonblob

Binary serialization for moonscript + LuaJIT

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

A 'debug' mode where type metadata is added even in the binary case

nikki93 opened this issue · comments

Could be useful to enable a global 'debug' mode where methods like :string and :number etc. add type metadata in the serialized form, so that the deserializer would error if there is a mismatch. Could even go the extra mile and add hint keys that it'd check for a match (eg. :number(100, 'health')) but ignore in non-debug mode.

I'm mostly using this in a multiplayer game scenario and if there are bugs where the receiver isn't gleaning the format properly from the message this would help. I'm just thinking ahead though and haven't hit concrete cases of this yet.

Here's a quick and easy way to add type information to every value written, and check the type when reading:

DEBUG = true -- the global debug flag

local function writeChecked(self, value, type)
  if DEBUG then
    self:string(type)
  end
  return self[type](self, value)
end

local function readChecked(self, type)
  if DEBUG then
    assert(type == self:string(), "Mismatching types in data")
  end
  return self[type](self)
end

Usage:

local w = BlobWriter()
writeChecked(w, "hello", "string")
writeChecked(w, "world", "string")

local r = BlobReader(w:tostring())
local hello = readChecked(r, "string") -- okay
local world = readChecked(r, "u32") -- error: type mismatch

This works for all supported data types, not just Lua types. Note that the overhead for type information can be significant with this approach, but it also has a low probability for giving false positives. Shorter type identifiers with low overhead, for example single byte values, could lead to situations where user data is mistaken for type information, making it even harder to find mistakes in your code.

Doing this correctly and in an efficient way is not trivial. Introducing some kind of schema definition might be the way to go here.