blob: 4d723753e4b5bc7039bd596ac3f3f15a53d93fe1 [file] [log] [blame]
James Kuszmaul8e62b022022-03-22 09:33:25 -07001local compat = require("flatbuffers.compat")
2-- locals for slightly faster access
3local string_pack = compat.string_pack
4local string_unpack = compat.string_unpack
5
6
Austin Schuhe89fa2d2019-08-14 20:24:23 -07007local 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
James Kuszmaul8e62b022022-03-22 09:33:25 -070053 local v = d[startPos]
54 if not v or v == "" then
55 v = '/0'
56 end
Austin Schuhe89fa2d2019-08-14 20:24:23 -070057 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
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700116-- Pack the data into a binary representation
117function m.Pack(fmt, ...)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700118 return string_pack(fmt, ...)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700119end
120
121-- Unpack the data from a binary representation in
122-- a Lua value
123function m.Unpack(fmt, s, pos)
James Kuszmaul8e62b022022-03-22 09:33:25 -0700124 return string_unpack(fmt, s.str, pos + 1)
Austin Schuhe89fa2d2019-08-14 20:24:23 -0700125end
126
127-- Return the binary array module
128return m