@@ -33,10 +33,9 @@ local function field_type(field)
33
33
return realtype
34
34
end
35
35
36
- local decode , decode_field , decode_unknown_field
37
- local encode
36
+ local decode , encode
38
37
39
- function decode_unknown_field (t , dec , wiretype , tag )
38
+ local function decode_unknown_field (t , dec , wiretype , tag )
40
39
local value = dec :fetch (wiretype )
41
40
local uf = t .unknown_fields
42
41
if not uf then
@@ -53,7 +52,7 @@ function decode_unknown_field(t, dec, wiretype, tag)
53
52
end
54
53
end
55
54
56
- function decode_field (t , dec , wiretype , tag , field )
55
+ local function decode_field (t , dec , wiretype , tag , field )
57
56
local value
58
57
if field .scalar then
59
58
value = dec :fetch (wiretype , field .type_name )
@@ -68,7 +67,7 @@ function decode_field(t, dec, wiretype, tag, field)
68
67
else
69
68
local len = dec :fetch " varint"
70
69
local old = dec :len (dec :pos () + len - 1 )
71
- value = decode (dec , ftype )
70
+ value = decode (dec , ftype , table.concat ( field . type_name , " . " ) )
72
71
dec :len (old )
73
72
end
74
73
end
@@ -83,8 +82,9 @@ function decode_field(t, dec, wiretype, tag, field)
83
82
end
84
83
end
85
84
86
- function decode (dec , ptype )
85
+ function decode (dec , ptype , tn )
87
86
local t = {}
87
+ local pos = dec :pos ()
88
88
while not dec :finished () do
89
89
local tag , wiretype = dec :tag ()
90
90
local field = ptype [tag ]
@@ -94,52 +94,131 @@ function decode(dec, ptype)
94
94
decode_unknown_field (t , dec , wiretype , tag )
95
95
end
96
96
end
97
+ local size = dec :pos () - pos
97
98
return t
98
99
end
99
100
101
+ local buffer_pool = {}
102
+ local buffer_used = setmetatable ({}, { __mode = " k" })
103
+
104
+
105
+ --[[
106
+ function buffer.new()
107
+ local t = {}
108
+ function t:add(tag, type, value)
109
+ t[#t+1] = ("[%s %d %s]\n"):format(type, tag, tostring(value))
110
+ end
111
+ function t:tag(tag, wiretype)
112
+ t[#t+1] = ("[%s %d "):format(wiretype, tag)
113
+ end
114
+ function t:varint(n)
115
+ t[#t+1] = ("%d]\n"):format(n)
116
+ end
117
+ function t:bytes(s)
118
+ if type(s) == "table" then
119
+ s = table.concat(s)
120
+ t[#t+1] = ("\n"..s.."]"):gsub("\n", "\n "):gsub(" ]%s*$", "]\n")
121
+ else
122
+ t[#t+1] = ("'%s'\n]\n"):format(s)
123
+ end
124
+ end
125
+ function t:clear(len, result)
126
+ if result then
127
+ result = table.concat(t)
128
+ end
129
+ for k, v in ipairs(t) do
130
+ t[k] = nil
131
+ end
132
+ return result
133
+ end
134
+ return t
135
+ end
136
+ --]]
137
+
138
+ local function get_buffer ()
139
+ local buff = next (buffer_pool )
140
+ if buff then
141
+ buffer_pool [buff ] = nil
142
+ else
143
+ buff = buffer .new ()
144
+ end
145
+ buffer_used [buff ] = true
146
+ return buff
147
+ end
148
+
149
+ local function put_buffer (buff )
150
+ buffer_used [buff ] = nil
151
+ buffer_pool [buff ] = true
152
+ end
153
+
154
+ local function encode_message (buff , tag , msg , ftype )
155
+ local inner = get_buffer ()
156
+ inner :clear ()
157
+ encode (inner , msg , ftype )
158
+ buff :tag (tag , " bytes" )
159
+ buff :bytes (inner )
160
+ inner :clear ()
161
+ put_buffer (inner )
162
+ end
163
+
164
+ local function encode_enum (buff , tag , enum , ftype )
165
+ local value = assert (ftype .map [enum ])
166
+ buff :tag (tag , " varint" )
167
+ buff :varint (value )
168
+ end
169
+
170
+ local function encode_field (buff , tag , v , ptype )
171
+ -- print(("encode_field(%d, %s)"):format(tag,
172
+ -- require"serpent".block(v)))
173
+ local field = ptype [tag ]
174
+ if not field then return end
175
+
176
+ if field .scalar then
177
+ -- TODO packed repeated
178
+ if field .repeated then
179
+ for k ,v in ipairs (v ) do
180
+ buff :add (tag , field .type_name , v )
181
+ end
182
+ else
183
+ buff :add (tag , field .type_name , v )
184
+ end
185
+ return
186
+ end
187
+
188
+ local ftype = field_type (field )
189
+ if ftype .type == " message" then
190
+ if not inner_buff then
191
+ inner_buff = buffer .new ()
192
+ end
193
+ if not field .repeated then
194
+ encode_message (buff , tag , v , ftype )
195
+ else
196
+ for _ , v in ipairs (v ) do
197
+ encode_message (buff , tag , v , ftype )
198
+ end
199
+ end
200
+ return
201
+ end
202
+
203
+ if ftype .type == " enum" then
204
+ if not field .repeated then
205
+ encode_enum (buff , tag , v , ftype )
206
+ else
207
+ for _ , v in ipairs (v ) do
208
+ encode_enum (buff , tag , v , ftype )
209
+ end
210
+ end
211
+ return
212
+ end
213
+
214
+ error (" unknown type: " .. ftype .type )
215
+ end
216
+
100
217
function encode (buff , t , ptype )
101
- lvl = lvl or 1
102
- local lvls = (" " ):rep (lvl )
103
- local inner_buff
104
218
for k ,v in pairs (t ) do
105
219
local tag = ptype .map [k ]
106
- local field = ptype [tag ]
107
- if field then
108
- if field .scalar then
109
- if field .repeated then
110
- for k ,v in ipairs (v ) do
111
- buff :add (tag , field .type_name , v )
112
- end
113
- else
114
- buff :add (tag , field .type_name , v )
115
- end
116
- else
117
- local ftype = field_type (field )
118
- if ftype .type == " message" then
119
- if not inner_buff then
120
- inner_buff = buffer .new ()
121
- end
122
- if field .repeated then
123
- for k ,v in ipairs (v ) do
124
- inner_buff :clear ()
125
- encode (inner_buff , v , ftype )
126
- buff :tag (tag , " bytes" )
127
- buff :bytes (inner_buff )
128
- end
129
- else
130
- inner_buff :clear ()
131
- encode (inner_buff , v , ftype )
132
- buff :tag (tag , " bytes" )
133
- buff :bytes (inner_buff )
134
- end
135
- elseif ftype .type == " enum" then
136
- local value = ftype .map [v ]
137
- if value then
138
- buff :tag (tag , " varint" )
139
- buff :varint (value )
140
- end
141
- end
142
- end
220
+ if tag then
221
+ encode_field (buff , tag , v , ptype )
143
222
end
144
223
end
145
224
end
@@ -153,12 +232,14 @@ function pb.decode(s, ptype)
153
232
return res
154
233
end
155
234
156
- local buff = buffer .new ()
157
235
function pb .encode (t , ptype )
158
236
local realtype = qualitied_type (ptype )
237
+ local buff = get_buffer ()
159
238
buff :clear ()
160
239
encode (buff , t , realtype )
161
- return buff :clear (nil , true )
240
+ local res = buff :clear (nil , true )
241
+ put_buffer (buff )
242
+ return res
162
243
end
163
244
164
245
---- --------------------------------------------------------
0 commit comments