blob: fde15c3d8efb934a380739490b2cbfd20a869b7c [file] [log] [blame]
Austin Schuhe89fa2d2019-08-14 20:24:23 -07001local m = {}
2local mt = {}
3
4local mt_name = "flatbuffers.view.mt"
5
6local N = require("flatbuffers.numTypes")
7local binaryarray = require("flatbuffers.binaryarray")
8
Austin Schuh272c6132020-11-14 16:37:52 -08009local function enforceOffset(off)
10 if off < 0 or off > 42949672951 then
11 error("Offset is not valid")
12 end
13end
14
15local unpack = string.unpack
16local function unPackUoffset(bytes, off)
17 return unpack("<I4", bytes.str, off + 1)
18end
19
20local function unPackVoffset(bytes, off)
21 return unpack("<I2", bytes.str, off + 1)
22end
23
Austin Schuhe89fa2d2019-08-14 20:24:23 -070024function m.New(buf, pos)
Austin Schuh272c6132020-11-14 16:37:52 -080025 enforceOffset(pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070026 -- need to convert from a string buffer into
27 -- a binary array
28
29 local o = {
30 bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
Austin Schuh272c6132020-11-14 16:37:52 -080031 pos = pos,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070032 }
33 setmetatable(o, {__index = mt, __metatable = mt_name})
34 return o
35end
36
37function mt:Offset(vtableOffset)
Austin Schuh272c6132020-11-14 16:37:52 -080038 local vtable = self.vtable
39 if not vtable then
40 vtable = self.pos - self:Get(N.SOffsetT, self.pos)
41 self.vtable = vtable
42 self.vtableEnd = self:Get(N.VOffsetT, vtable)
43 end
44 if vtableOffset < self.vtableEnd then
45 return unPackVoffset(self.bytes, vtable + vtableOffset)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070046 end
47 return 0
48end
49
50function mt:Indirect(off)
Austin Schuh272c6132020-11-14 16:37:52 -080051 enforceOffset(off)
52 return off + unPackUoffset(self.bytes, off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070053end
54
55function mt:String(off)
Austin Schuh272c6132020-11-14 16:37:52 -080056 enforceOffset(off)
57 off = off + unPackUoffset(self.bytes, off)
58 local start = off + 4
59 local length = unPackUoffset(self.bytes, off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070060 return self.bytes:Slice(start, start+length)
61end
62
63function mt:VectorLen(off)
Austin Schuh272c6132020-11-14 16:37:52 -080064 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070065 off = off + self.pos
Austin Schuh272c6132020-11-14 16:37:52 -080066 off = off + unPackUoffset(self.bytes, off)
67 return unPackUoffset(self.bytes, off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070068end
69
70function mt:Vector(off)
Austin Schuh272c6132020-11-14 16:37:52 -080071 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070072 off = off + self.pos
Austin Schuh272c6132020-11-14 16:37:52 -080073 return off + self:Get(N.UOffsetT, off) + 4
Austin Schuhe89fa2d2019-08-14 20:24:23 -070074end
75
76function mt:Union(t2, off)
77 assert(getmetatable(t2) == mt_name)
Austin Schuh272c6132020-11-14 16:37:52 -080078 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070079 off = off + self.pos
80 t2.pos = off + self:Get(N.UOffsetT, off)
81 t2.bytes = self.bytes
82end
83
84function mt:Get(flags, off)
Austin Schuh272c6132020-11-14 16:37:52 -080085 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070086 return flags:Unpack(self.bytes, off)
87end
88
89function mt:GetSlot(slot, d, validatorFlags)
90 N.VOffsetT:EnforceNumber(slot)
91 if validatorFlags then
92 validatorFlags:EnforceNumber(d)
93 end
94 local off = self:Offset(slot)
95 if off == 0 then
96 return d
97 end
98 return self:Get(validatorFlags, self.pos + off)
99end
100
101function mt:GetVOffsetTSlot(slot, d)
Austin Schuh272c6132020-11-14 16:37:52 -0800102 N.VOffsetT:EnforceNumbers(slot, d)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700103 local off = self:Offset(slot)
104 if off == 0 then
105 return d
106 end
107 return off
108end
109
110return m