blob: 433f25c851fb5a2d6bdd35a5c13751b9146f7256 [file] [log] [blame]
James Kuszmaul8e62b022022-03-22 09:33:25 -07001local compat = require("flatbuffers.compat")
2local string_unpack = compat.string_unpack
3
4
Austin Schuhe89fa2d2019-08-14 20:24:23 -07005local m = {}
6local mt = {}
7
8local mt_name = "flatbuffers.view.mt"
9
10local N = require("flatbuffers.numTypes")
11local binaryarray = require("flatbuffers.binaryarray")
12
Austin Schuh272c6132020-11-14 16:37:52 -080013local function enforceOffset(off)
14 if off < 0 or off > 42949672951 then
15 error("Offset is not valid")
16 end
17end
18
Austin Schuh272c6132020-11-14 16:37:52 -080019local function unPackUoffset(bytes, off)
James Kuszmaul8e62b022022-03-22 09:33:25 -070020 return string_unpack("<I4", bytes.str, off + 1)
Austin Schuh272c6132020-11-14 16:37:52 -080021end
22
23local function unPackVoffset(bytes, off)
James Kuszmaul8e62b022022-03-22 09:33:25 -070024 return string_unpack("<I2", bytes.str, off + 1)
Austin Schuh272c6132020-11-14 16:37:52 -080025end
26
Austin Schuhe89fa2d2019-08-14 20:24:23 -070027function m.New(buf, pos)
Austin Schuh272c6132020-11-14 16:37:52 -080028 enforceOffset(pos)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070029 -- need to convert from a string buffer into
30 -- a binary array
31
32 local o = {
33 bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
Austin Schuh272c6132020-11-14 16:37:52 -080034 pos = pos,
Austin Schuhe89fa2d2019-08-14 20:24:23 -070035 }
36 setmetatable(o, {__index = mt, __metatable = mt_name})
37 return o
38end
39
40function mt:Offset(vtableOffset)
Austin Schuh272c6132020-11-14 16:37:52 -080041 local vtable = self.vtable
42 if not vtable then
43 vtable = self.pos - self:Get(N.SOffsetT, self.pos)
44 self.vtable = vtable
45 self.vtableEnd = self:Get(N.VOffsetT, vtable)
46 end
47 if vtableOffset < self.vtableEnd then
48 return unPackVoffset(self.bytes, vtable + vtableOffset)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070049 end
50 return 0
51end
52
53function mt:Indirect(off)
Austin Schuh272c6132020-11-14 16:37:52 -080054 enforceOffset(off)
55 return off + unPackUoffset(self.bytes, off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070056end
57
58function mt:String(off)
Austin Schuh272c6132020-11-14 16:37:52 -080059 enforceOffset(off)
60 off = off + unPackUoffset(self.bytes, off)
61 local start = off + 4
62 local length = unPackUoffset(self.bytes, off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070063 return self.bytes:Slice(start, start+length)
64end
65
66function mt:VectorLen(off)
Austin Schuh272c6132020-11-14 16:37:52 -080067 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070068 off = off + self.pos
Austin Schuh272c6132020-11-14 16:37:52 -080069 off = off + unPackUoffset(self.bytes, off)
70 return unPackUoffset(self.bytes, off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070071end
72
73function mt:Vector(off)
Austin Schuh272c6132020-11-14 16:37:52 -080074 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070075 off = off + self.pos
Austin Schuh272c6132020-11-14 16:37:52 -080076 return off + self:Get(N.UOffsetT, off) + 4
Austin Schuhe89fa2d2019-08-14 20:24:23 -070077end
78
James Kuszmaul8e62b022022-03-22 09:33:25 -070079function mt:VectorAsString(off, start, stop)
80 local o = self:Offset(off)
81 if o ~= 0 then
82 start = start or 1
83 stop = stop or self:VectorLen(o)
84 local a = self:Vector(o) + start - 1
85 return self.bytes:Slice(a, a + stop - start + 1)
86 end
87 return nil
88end
89
Austin Schuhe89fa2d2019-08-14 20:24:23 -070090function mt:Union(t2, off)
91 assert(getmetatable(t2) == mt_name)
Austin Schuh272c6132020-11-14 16:37:52 -080092 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -070093 off = off + self.pos
94 t2.pos = off + self:Get(N.UOffsetT, off)
95 t2.bytes = self.bytes
96end
97
98function mt:Get(flags, off)
Austin Schuh272c6132020-11-14 16:37:52 -080099 enforceOffset(off)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700100 return flags:Unpack(self.bytes, off)
101end
102
103function mt:GetSlot(slot, d, validatorFlags)
104 N.VOffsetT:EnforceNumber(slot)
105 if validatorFlags then
106 validatorFlags:EnforceNumber(d)
107 end
108 local off = self:Offset(slot)
109 if off == 0 then
110 return d
111 end
112 return self:Get(validatorFlags, self.pos + off)
113end
114
115function mt:GetVOffsetTSlot(slot, d)
Austin Schuh272c6132020-11-14 16:37:52 -0800116 N.VOffsetT:EnforceNumbers(slot, d)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700117 local off = self:Offset(slot)
118 if off == 0 then
119 return d
120 end
121 return off
122end
123
124return m