• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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