1local compat = require("flatbuffers.compat") 2local string_unpack = compat.string_unpack 3 4 5local m = {} 6local mt = {} 7 8local mt_name = "flatbuffers.view.mt" 9 10local N = require("flatbuffers.numTypes") 11local binaryarray = require("flatbuffers.binaryarray") 12 13local function enforceOffset(off) 14 if off < 0 or off > 42949672951 then 15 error("Offset is not valid") 16 end 17end 18 19local function unPackUoffset(bytes, off) 20 return string_unpack("<I4", bytes.str, off + 1) 21end 22 23local function unPackVoffset(bytes, off) 24 return string_unpack("<I2", bytes.str, off + 1) 25end 26 27function m.New(buf, pos) 28 enforceOffset(pos) 29 -- 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, 34 pos = pos, 35 } 36 setmetatable(o, {__index = mt, __metatable = mt_name}) 37 return o 38end 39 40function mt:Offset(vtableOffset) 41 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) 49 end 50 return 0 51end 52 53function mt:Indirect(off) 54 enforceOffset(off) 55 return off + unPackUoffset(self.bytes, off) 56end 57 58function mt:String(off) 59 enforceOffset(off) 60 off = off + unPackUoffset(self.bytes, off) 61 local start = off + 4 62 local length = unPackUoffset(self.bytes, off) 63 return self.bytes:Slice(start, start+length) 64end 65 66function mt:VectorLen(off) 67 enforceOffset(off) 68 off = off + self.pos 69 off = off + unPackUoffset(self.bytes, off) 70 return unPackUoffset(self.bytes, off) 71end 72 73function mt:Vector(off) 74 enforceOffset(off) 75 off = off + self.pos 76 return off + self:Get(N.UOffsetT, off) + 4 77end 78 79function 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 90function mt:Union(t2, off) 91 assert(getmetatable(t2) == mt_name) 92 enforceOffset(off) 93 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) 99 enforceOffset(off) 100 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) 116 N.VOffsetT:EnforceNumbers(slot, d) 117 local off = self:Offset(slot) 118 if off == 0 then 119 return d 120 end 121 return off 122end 123 124return m