blob: 433f25c851fb5a2d6bdd35a5c13751b9146f7256 [file] [log] [blame]
local compat = require("flatbuffers.compat")
local string_unpack = compat.string_unpack
local m = {}
local mt = {}
local mt_name = "flatbuffers.view.mt"
local N = require("flatbuffers.numTypes")
local binaryarray = require("flatbuffers.binaryarray")
local function enforceOffset(off)
if off < 0 or off > 42949672951 then
error("Offset is not valid")
end
end
local function unPackUoffset(bytes, off)
return string_unpack("<I4", bytes.str, off + 1)
end
local function unPackVoffset(bytes, off)
return string_unpack("<I2", bytes.str, off + 1)
end
function m.New(buf, pos)
enforceOffset(pos)
-- need to convert from a string buffer into
-- a binary array
local o = {
bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
pos = pos,
}
setmetatable(o, {__index = mt, __metatable = mt_name})
return o
end
function mt:Offset(vtableOffset)
local vtable = self.vtable
if not vtable then
vtable = self.pos - self:Get(N.SOffsetT, self.pos)
self.vtable = vtable
self.vtableEnd = self:Get(N.VOffsetT, vtable)
end
if vtableOffset < self.vtableEnd then
return unPackVoffset(self.bytes, vtable + vtableOffset)
end
return 0
end
function mt:Indirect(off)
enforceOffset(off)
return off + unPackUoffset(self.bytes, off)
end
function mt:String(off)
enforceOffset(off)
off = off + unPackUoffset(self.bytes, off)
local start = off + 4
local length = unPackUoffset(self.bytes, off)
return self.bytes:Slice(start, start+length)
end
function mt:VectorLen(off)
enforceOffset(off)
off = off + self.pos
off = off + unPackUoffset(self.bytes, off)
return unPackUoffset(self.bytes, off)
end
function mt:Vector(off)
enforceOffset(off)
off = off + self.pos
return off + self:Get(N.UOffsetT, off) + 4
end
function mt:VectorAsString(off, start, stop)
local o = self:Offset(off)
if o ~= 0 then
start = start or 1
stop = stop or self:VectorLen(o)
local a = self:Vector(o) + start - 1
return self.bytes:Slice(a, a + stop - start + 1)
end
return nil
end
function mt:Union(t2, off)
assert(getmetatable(t2) == mt_name)
enforceOffset(off)
off = off + self.pos
t2.pos = off + self:Get(N.UOffsetT, off)
t2.bytes = self.bytes
end
function mt:Get(flags, off)
enforceOffset(off)
return flags:Unpack(self.bytes, off)
end
function mt:GetSlot(slot, d, validatorFlags)
N.VOffsetT:EnforceNumber(slot)
if validatorFlags then
validatorFlags:EnforceNumber(d)
end
local off = self:Offset(slot)
if off == 0 then
return d
end
return self:Get(validatorFlags, self.pos + off)
end
function mt:GetVOffsetTSlot(slot, d)
N.VOffsetT:EnforceNumbers(slot, d)
local off = self:Offset(slot)
if off == 0 then
return d
end
return off
end
return m