1local compat = require("flatbuffers.compat") 2-- locals for slightly faster access 3local string_pack = compat.string_pack 4local string_unpack = compat.string_unpack 5 6 7local m = {} -- the module table 8 9local mt = {} -- the module metatable 10 11-- given a binary array, set a metamethod to return its length 12-- (e.g., #binaryArray, calls this) 13function mt:__len() 14 return self.size 15end 16 17-- Create a new binary array of an initial size 18function m.New(sizeOrString) 19 -- the array storage itself 20 local o = {} 21 22 if type(sizeOrString) == "string" then 23 o.str = sizeOrString 24 o.size = #sizeOrString 25 elseif type(sizeOrString) == "number" then 26 o.data = {} 27 o.size = sizeOrString 28 else 29 error("Expect a integer size value or string to construct a binary array") 30 end 31 -- set the inheritance 32 setmetatable(o, {__index = mt, __len = mt.__len}) 33 return o 34end 35 36-- Get a slice of the binary array from start to end position 37function mt:Slice(startPos, endPos) 38 startPos = startPos or 0 39 endPos = endPos or self.size 40 local d = self.data 41 if d then 42 -- if the self.data is defined, we are building the buffer 43 -- in a Lua table 44 45 -- new table to store the slice components 46 local b = {} 47 48 -- starting with the startPos, put all 49 -- values into the new table to be concat later 50 -- updated the startPos based on the size of the 51 -- value 52 while startPos < endPos do 53 local v = d[startPos] 54 if not v or v == "" then 55 v = '/0' 56 end 57 table.insert(b, v) 58 startPos = startPos + #v 59 end 60 61 -- combine the table of strings into one string 62 -- this is faster than doing a bunch of concats by themselves 63 return table.concat(b) 64 else 65 -- n.b start/endPos are 0-based incoming, so need to convert 66 -- correctly. in python a slice includes start -> end - 1 67 return self.str:sub(startPos+1, endPos) 68 end 69end 70 71-- Grow the binary array to a new size, placing the exisiting data 72-- at then end of the new array 73function mt:Grow(newsize) 74 -- the new table to store the data 75 local newT = {} 76 77 -- the offset to be applied to existing entries 78 local offset = newsize - self.size 79 80 -- loop over all the current entries and 81 -- add them to the new table at the correct 82 -- offset location 83 local d = self.data 84 for i,data in pairs(d) do 85 newT[i + offset] = data 86 end 87 88 -- update this storage with the new table and size 89 self.data = newT 90 self.size = newsize 91end 92 93-- memorization for padding strings 94local pads = {} 95 96-- pad the binary with n \0 bytes at the starting position 97function mt:Pad(n, startPos) 98 -- use memorization to avoid creating a bunch of strings 99 -- all the time 100 local s = pads[n] 101 if not s then 102 s = string.rep('\0', n) 103 pads[n] = s 104 end 105 106 -- store the padding string at the start position in the 107 -- Lua table 108 self.data[startPos] = s 109end 110 111-- Sets the binary array value at the specified position 112function mt:Set(value, position) 113 self.data[position] = value 114end 115 116-- Pack the data into a binary representation 117function m.Pack(fmt, ...) 118 return string_pack(fmt, ...) 119end 120 121-- Unpack the data from a binary representation in 122-- a Lua value 123function m.Unpack(fmt, s, pos) 124 return string_unpack(fmt, s.str, pos + 1) 125end 126 127-- Return the binary array module 128return m