diff options
Diffstat (limited to 'vendor/godobuf/addons/protobuf/protobuf_core.gd')
-rw-r--r-- | vendor/godobuf/addons/protobuf/protobuf_core.gd | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/vendor/godobuf/addons/protobuf/protobuf_core.gd b/vendor/godobuf/addons/protobuf/protobuf_core.gd new file mode 100644 index 0000000..7098413 --- /dev/null +++ b/vendor/godobuf/addons/protobuf/protobuf_core.gd | |||
@@ -0,0 +1,668 @@ | |||
1 | # | ||
2 | # BSD 3-Clause License | ||
3 | # | ||
4 | # Copyright (c) 2018 - 2023, Oleg Malyavkin | ||
5 | # All rights reserved. | ||
6 | # | ||
7 | # Redistribution and use in source and binary forms, with or without | ||
8 | # modification, are permitted provided that the following conditions are met: | ||
9 | # | ||
10 | # * Redistributions of source code must retain the above copyright notice, this | ||
11 | # list of conditions and the following disclaimer. | ||
12 | # | ||
13 | # * Redistributions in binary form must reproduce the above copyright notice, | ||
14 | # this list of conditions and the following disclaimer in the documentation | ||
15 | # and/or other materials provided with the distribution. | ||
16 | # | ||
17 | # * Neither the name of the copyright holder nor the names of its | ||
18 | # contributors may be used to endorse or promote products derived from | ||
19 | # this software without specific prior written permission. | ||
20 | # | ||
21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
22 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
23 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
25 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
27 | # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
29 | # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
30 | # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
31 | |||
32 | # DEBUG_TAB redefine this " " if you need, example: const DEBUG_TAB = "\t" | ||
33 | |||
34 | const PROTO_VERSION = 0 | ||
35 | |||
36 | const DEBUG_TAB : String = " " | ||
37 | |||
38 | enum PB_ERR { | ||
39 | NO_ERRORS = 0, | ||
40 | VARINT_NOT_FOUND = -1, | ||
41 | REPEATED_COUNT_NOT_FOUND = -2, | ||
42 | REPEATED_COUNT_MISMATCH = -3, | ||
43 | LENGTHDEL_SIZE_NOT_FOUND = -4, | ||
44 | LENGTHDEL_SIZE_MISMATCH = -5, | ||
45 | PACKAGE_SIZE_MISMATCH = -6, | ||
46 | UNDEFINED_STATE = -7, | ||
47 | PARSE_INCOMPLETE = -8, | ||
48 | REQUIRED_FIELDS = -9 | ||
49 | } | ||
50 | |||
51 | enum PB_DATA_TYPE { | ||
52 | INT32 = 0, | ||
53 | SINT32 = 1, | ||
54 | UINT32 = 2, | ||
55 | INT64 = 3, | ||
56 | SINT64 = 4, | ||
57 | UINT64 = 5, | ||
58 | BOOL = 6, | ||
59 | ENUM = 7, | ||
60 | FIXED32 = 8, | ||
61 | SFIXED32 = 9, | ||
62 | FLOAT = 10, | ||
63 | FIXED64 = 11, | ||
64 | SFIXED64 = 12, | ||
65 | DOUBLE = 13, | ||
66 | STRING = 14, | ||
67 | BYTES = 15, | ||
68 | MESSAGE = 16, | ||
69 | MAP = 17 | ||
70 | } | ||
71 | |||
72 | const DEFAULT_VALUES_2 = { | ||
73 | PB_DATA_TYPE.INT32: null, | ||
74 | PB_DATA_TYPE.SINT32: null, | ||
75 | PB_DATA_TYPE.UINT32: null, | ||
76 | PB_DATA_TYPE.INT64: null, | ||
77 | PB_DATA_TYPE.SINT64: null, | ||
78 | PB_DATA_TYPE.UINT64: null, | ||
79 | PB_DATA_TYPE.BOOL: null, | ||
80 | PB_DATA_TYPE.ENUM: null, | ||
81 | PB_DATA_TYPE.FIXED32: null, | ||
82 | PB_DATA_TYPE.SFIXED32: null, | ||
83 | PB_DATA_TYPE.FLOAT: null, | ||
84 | PB_DATA_TYPE.FIXED64: null, | ||
85 | PB_DATA_TYPE.SFIXED64: null, | ||
86 | PB_DATA_TYPE.DOUBLE: null, | ||
87 | PB_DATA_TYPE.STRING: null, | ||
88 | PB_DATA_TYPE.BYTES: null, | ||
89 | PB_DATA_TYPE.MESSAGE: null, | ||
90 | PB_DATA_TYPE.MAP: null | ||
91 | } | ||
92 | |||
93 | const DEFAULT_VALUES_3 = { | ||
94 | PB_DATA_TYPE.INT32: 0, | ||
95 | PB_DATA_TYPE.SINT32: 0, | ||
96 | PB_DATA_TYPE.UINT32: 0, | ||
97 | PB_DATA_TYPE.INT64: 0, | ||
98 | PB_DATA_TYPE.SINT64: 0, | ||
99 | PB_DATA_TYPE.UINT64: 0, | ||
100 | PB_DATA_TYPE.BOOL: false, | ||
101 | PB_DATA_TYPE.ENUM: 0, | ||
102 | PB_DATA_TYPE.FIXED32: 0, | ||
103 | PB_DATA_TYPE.SFIXED32: 0, | ||
104 | PB_DATA_TYPE.FLOAT: 0.0, | ||
105 | PB_DATA_TYPE.FIXED64: 0, | ||
106 | PB_DATA_TYPE.SFIXED64: 0, | ||
107 | PB_DATA_TYPE.DOUBLE: 0.0, | ||
108 | PB_DATA_TYPE.STRING: "", | ||
109 | PB_DATA_TYPE.BYTES: [], | ||
110 | PB_DATA_TYPE.MESSAGE: null, | ||
111 | PB_DATA_TYPE.MAP: [] | ||
112 | } | ||
113 | |||
114 | enum PB_TYPE { | ||
115 | VARINT = 0, | ||
116 | FIX64 = 1, | ||
117 | LENGTHDEL = 2, | ||
118 | STARTGROUP = 3, | ||
119 | ENDGROUP = 4, | ||
120 | FIX32 = 5, | ||
121 | UNDEFINED = 8 | ||
122 | } | ||
123 | |||
124 | enum PB_RULE { | ||
125 | OPTIONAL = 0, | ||
126 | REQUIRED = 1, | ||
127 | REPEATED = 2, | ||
128 | RESERVED = 3 | ||
129 | } | ||
130 | |||
131 | enum PB_SERVICE_STATE { | ||
132 | FILLED = 0, | ||
133 | UNFILLED = 1 | ||
134 | } | ||
135 | |||
136 | class PBField: | ||
137 | func _init(a_name : String, a_type : int, a_rule : int, a_tag : int, packed : bool, a_value = null): | ||
138 | name = a_name | ||
139 | type = a_type | ||
140 | rule = a_rule | ||
141 | tag = a_tag | ||
142 | option_packed = packed | ||
143 | value = a_value | ||
144 | |||
145 | var name : String | ||
146 | var type : int | ||
147 | var rule : int | ||
148 | var tag : int | ||
149 | var option_packed : bool | ||
150 | var value | ||
151 | var is_map_field : bool = false | ||
152 | var option_default : bool = false | ||
153 | |||
154 | class PBTypeTag: | ||
155 | var ok : bool = false | ||
156 | var type : int | ||
157 | var tag : int | ||
158 | var offset : int | ||
159 | |||
160 | class PBServiceField: | ||
161 | var field : PBField | ||
162 | var func_ref = null | ||
163 | var state : int = PB_SERVICE_STATE.UNFILLED | ||
164 | |||
165 | class PBPacker: | ||
166 | static func convert_signed(n : int) -> int: | ||
167 | if n < -2147483648: | ||
168 | return (n << 1) ^ (n >> 63) | ||
169 | else: | ||
170 | return (n << 1) ^ (n >> 31) | ||
171 | |||
172 | static func deconvert_signed(n : int) -> int: | ||
173 | if n & 0x01: | ||
174 | return ~(n >> 1) | ||
175 | else: | ||
176 | return (n >> 1) | ||
177 | |||
178 | static func pack_varint(value) -> PackedByteArray: | ||
179 | var varint : PackedByteArray = PackedByteArray() | ||
180 | if typeof(value) == TYPE_BOOL: | ||
181 | if value: | ||
182 | value = 1 | ||
183 | else: | ||
184 | value = 0 | ||
185 | for _i in range(9): | ||
186 | var b = value & 0x7F | ||
187 | value >>= 7 | ||
188 | if value: | ||
189 | varint.append(b | 0x80) | ||
190 | else: | ||
191 | varint.append(b) | ||
192 | break | ||
193 | if varint.size() == 9 && (varint[8] & 0x80 != 0): | ||
194 | varint.append(0x01) | ||
195 | return varint | ||
196 | |||
197 | static func pack_bytes(value, count : int, data_type : int) -> PackedByteArray: | ||
198 | var bytes : PackedByteArray = PackedByteArray() | ||
199 | if data_type == PB_DATA_TYPE.FLOAT: | ||
200 | var spb : StreamPeerBuffer = StreamPeerBuffer.new() | ||
201 | spb.put_float(value) | ||
202 | bytes = spb.get_data_array() | ||
203 | elif data_type == PB_DATA_TYPE.DOUBLE: | ||
204 | var spb : StreamPeerBuffer = StreamPeerBuffer.new() | ||
205 | spb.put_double(value) | ||
206 | bytes = spb.get_data_array() | ||
207 | else: | ||
208 | for _i in range(count): | ||
209 | bytes.append(value & 0xFF) | ||
210 | value >>= 8 | ||
211 | return bytes | ||
212 | |||
213 | static func unpack_bytes(bytes : PackedByteArray, index : int, count : int, data_type : int): | ||
214 | if data_type == PB_DATA_TYPE.FLOAT: | ||
215 | return bytes.decode_float(index) | ||
216 | elif data_type == PB_DATA_TYPE.DOUBLE: | ||
217 | return bytes.decode_double(index) | ||
218 | else: | ||
219 | # Convert to big endian | ||
220 | var slice: PackedByteArray = bytes.slice(index, index + count) | ||
221 | slice.reverse() | ||
222 | return slice | ||
223 | |||
224 | static func unpack_varint(varint_bytes) -> int: | ||
225 | var value : int = 0 | ||
226 | var i: int = varint_bytes.size() - 1 | ||
227 | while i > -1: | ||
228 | value = (value << 7) | (varint_bytes[i] & 0x7F) | ||
229 | i -= 1 | ||
230 | return value | ||
231 | |||
232 | static func pack_type_tag(type : int, tag : int) -> PackedByteArray: | ||
233 | return pack_varint((tag << 3) | type) | ||
234 | |||
235 | static func isolate_varint(bytes : PackedByteArray, index : int) -> PackedByteArray: | ||
236 | var i: int = index | ||
237 | while i <= index + 10: # Protobuf varint max size is 10 bytes | ||
238 | if !(bytes[i] & 0x80): | ||
239 | return bytes.slice(index, i + 1) | ||
240 | i += 1 | ||
241 | return [] # Unreachable | ||
242 | |||
243 | static func unpack_type_tag(bytes : PackedByteArray, index : int) -> PBTypeTag: | ||
244 | var varint_bytes : PackedByteArray = isolate_varint(bytes, index) | ||
245 | var result : PBTypeTag = PBTypeTag.new() | ||
246 | if varint_bytes.size() != 0: | ||
247 | result.ok = true | ||
248 | result.offset = varint_bytes.size() | ||
249 | var unpacked : int = unpack_varint(varint_bytes) | ||
250 | result.type = unpacked & 0x07 | ||
251 | result.tag = unpacked >> 3 | ||
252 | return result | ||
253 | |||
254 | static func pack_length_delimeted(type : int, tag : int, bytes : PackedByteArray) -> PackedByteArray: | ||
255 | var result : PackedByteArray = pack_type_tag(type, tag) | ||
256 | result.append_array(pack_varint(bytes.size())) | ||
257 | result.append_array(bytes) | ||
258 | return result | ||
259 | |||
260 | static func pb_type_from_data_type(data_type : int) -> int: | ||
261 | if data_type == PB_DATA_TYPE.INT32 || data_type == PB_DATA_TYPE.SINT32 || data_type == PB_DATA_TYPE.UINT32 || data_type == PB_DATA_TYPE.INT64 || data_type == PB_DATA_TYPE.SINT64 || data_type == PB_DATA_TYPE.UINT64 || data_type == PB_DATA_TYPE.BOOL || data_type == PB_DATA_TYPE.ENUM: | ||
262 | return PB_TYPE.VARINT | ||
263 | elif data_type == PB_DATA_TYPE.FIXED32 || data_type == PB_DATA_TYPE.SFIXED32 || data_type == PB_DATA_TYPE.FLOAT: | ||
264 | return PB_TYPE.FIX32 | ||
265 | elif data_type == PB_DATA_TYPE.FIXED64 || data_type == PB_DATA_TYPE.SFIXED64 || data_type == PB_DATA_TYPE.DOUBLE: | ||
266 | return PB_TYPE.FIX64 | ||
267 | elif data_type == PB_DATA_TYPE.STRING || data_type == PB_DATA_TYPE.BYTES || data_type == PB_DATA_TYPE.MESSAGE || data_type == PB_DATA_TYPE.MAP: | ||
268 | return PB_TYPE.LENGTHDEL | ||
269 | else: | ||
270 | return PB_TYPE.UNDEFINED | ||
271 | |||
272 | static func pack_field(field : PBField) -> PackedByteArray: | ||
273 | var type : int = pb_type_from_data_type(field.type) | ||
274 | var type_copy : int = type | ||
275 | if field.rule == PB_RULE.REPEATED && field.option_packed: | ||
276 | type = PB_TYPE.LENGTHDEL | ||
277 | var head : PackedByteArray = pack_type_tag(type, field.tag) | ||
278 | var data : PackedByteArray = PackedByteArray() | ||
279 | if type == PB_TYPE.VARINT: | ||
280 | var value | ||
281 | if field.rule == PB_RULE.REPEATED: | ||
282 | for v in field.value: | ||
283 | data.append_array(head) | ||
284 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
285 | value = convert_signed(v) | ||
286 | else: | ||
287 | value = v | ||
288 | data.append_array(pack_varint(value)) | ||
289 | return data | ||
290 | else: | ||
291 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
292 | value = convert_signed(field.value) | ||
293 | else: | ||
294 | value = field.value | ||
295 | data = pack_varint(value) | ||
296 | elif type == PB_TYPE.FIX32: | ||
297 | if field.rule == PB_RULE.REPEATED: | ||
298 | for v in field.value: | ||
299 | data.append_array(head) | ||
300 | data.append_array(pack_bytes(v, 4, field.type)) | ||
301 | return data | ||
302 | else: | ||
303 | data.append_array(pack_bytes(field.value, 4, field.type)) | ||
304 | elif type == PB_TYPE.FIX64: | ||
305 | if field.rule == PB_RULE.REPEATED: | ||
306 | for v in field.value: | ||
307 | data.append_array(head) | ||
308 | data.append_array(pack_bytes(v, 8, field.type)) | ||
309 | return data | ||
310 | else: | ||
311 | data.append_array(pack_bytes(field.value, 8, field.type)) | ||
312 | elif type == PB_TYPE.LENGTHDEL: | ||
313 | if field.rule == PB_RULE.REPEATED: | ||
314 | if type_copy == PB_TYPE.VARINT: | ||
315 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
316 | var signed_value : int | ||
317 | for v in field.value: | ||
318 | signed_value = convert_signed(v) | ||
319 | data.append_array(pack_varint(signed_value)) | ||
320 | else: | ||
321 | for v in field.value: | ||
322 | data.append_array(pack_varint(v)) | ||
323 | return pack_length_delimeted(type, field.tag, data) | ||
324 | elif type_copy == PB_TYPE.FIX32: | ||
325 | for v in field.value: | ||
326 | data.append_array(pack_bytes(v, 4, field.type)) | ||
327 | return pack_length_delimeted(type, field.tag, data) | ||
328 | elif type_copy == PB_TYPE.FIX64: | ||
329 | for v in field.value: | ||
330 | data.append_array(pack_bytes(v, 8, field.type)) | ||
331 | return pack_length_delimeted(type, field.tag, data) | ||
332 | elif field.type == PB_DATA_TYPE.STRING: | ||
333 | for v in field.value: | ||
334 | var obj = v.to_utf8_buffer() | ||
335 | data.append_array(pack_length_delimeted(type, field.tag, obj)) | ||
336 | return data | ||
337 | elif field.type == PB_DATA_TYPE.BYTES: | ||
338 | for v in field.value: | ||
339 | data.append_array(pack_length_delimeted(type, field.tag, v)) | ||
340 | return data | ||
341 | elif typeof(field.value[0]) == TYPE_OBJECT: | ||
342 | for v in field.value: | ||
343 | var obj : PackedByteArray = v.to_bytes() | ||
344 | data.append_array(pack_length_delimeted(type, field.tag, obj)) | ||
345 | return data | ||
346 | else: | ||
347 | if field.type == PB_DATA_TYPE.STRING: | ||
348 | var str_bytes : PackedByteArray = field.value.to_utf8_buffer() | ||
349 | if PROTO_VERSION == 2 || (PROTO_VERSION == 3 && str_bytes.size() > 0): | ||
350 | data.append_array(str_bytes) | ||
351 | return pack_length_delimeted(type, field.tag, data) | ||
352 | if field.type == PB_DATA_TYPE.BYTES: | ||
353 | if PROTO_VERSION == 2 || (PROTO_VERSION == 3 && field.value.size() > 0): | ||
354 | data.append_array(field.value) | ||
355 | return pack_length_delimeted(type, field.tag, data) | ||
356 | elif typeof(field.value) == TYPE_OBJECT: | ||
357 | var obj : PackedByteArray = field.value.to_bytes() | ||
358 | if obj.size() > 0: | ||
359 | data.append_array(obj) | ||
360 | return pack_length_delimeted(type, field.tag, data) | ||
361 | else: | ||
362 | pass | ||
363 | if data.size() > 0: | ||
364 | head.append_array(data) | ||
365 | return head | ||
366 | else: | ||
367 | return data | ||
368 | |||
369 | static func skip_unknown_field(bytes : PackedByteArray, offset : int, type : int) -> int: | ||
370 | if type == PB_TYPE.VARINT: | ||
371 | return offset + isolate_varint(bytes, offset).size() | ||
372 | if type == PB_TYPE.FIX64: | ||
373 | return offset + 8 | ||
374 | if type == PB_TYPE.LENGTHDEL: | ||
375 | var length_bytes : PackedByteArray = isolate_varint(bytes, offset) | ||
376 | var length : int = unpack_varint(length_bytes) | ||
377 | return offset + length_bytes.size() + length | ||
378 | if type == PB_TYPE.FIX32: | ||
379 | return offset + 4 | ||
380 | return PB_ERR.UNDEFINED_STATE | ||
381 | |||
382 | static func unpack_field(bytes : PackedByteArray, offset : int, field : PBField, type : int, message_func_ref) -> int: | ||
383 | if field.rule == PB_RULE.REPEATED && type != PB_TYPE.LENGTHDEL && field.option_packed: | ||
384 | var count = isolate_varint(bytes, offset) | ||
385 | if count.size() > 0: | ||
386 | offset += count.size() | ||
387 | count = unpack_varint(count) | ||
388 | if type == PB_TYPE.VARINT: | ||
389 | var val | ||
390 | var counter = offset + count | ||
391 | while offset < counter: | ||
392 | val = isolate_varint(bytes, offset) | ||
393 | if val.size() > 0: | ||
394 | offset += val.size() | ||
395 | val = unpack_varint(val) | ||
396 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
397 | val = deconvert_signed(val) | ||
398 | elif field.type == PB_DATA_TYPE.BOOL: | ||
399 | if val: | ||
400 | val = true | ||
401 | else: | ||
402 | val = false | ||
403 | field.value.append(val) | ||
404 | else: | ||
405 | return PB_ERR.REPEATED_COUNT_MISMATCH | ||
406 | return offset | ||
407 | elif type == PB_TYPE.FIX32 || type == PB_TYPE.FIX64: | ||
408 | var type_size | ||
409 | if type == PB_TYPE.FIX32: | ||
410 | type_size = 4 | ||
411 | else: | ||
412 | type_size = 8 | ||
413 | var val | ||
414 | var counter = offset + count | ||
415 | while offset < counter: | ||
416 | if (offset + type_size) > bytes.size(): | ||
417 | return PB_ERR.REPEATED_COUNT_MISMATCH | ||
418 | val = unpack_bytes(bytes, offset, type_size, field.type) | ||
419 | offset += type_size | ||
420 | field.value.append(val) | ||
421 | return offset | ||
422 | else: | ||
423 | return PB_ERR.REPEATED_COUNT_NOT_FOUND | ||
424 | else: | ||
425 | if type == PB_TYPE.VARINT: | ||
426 | var val = isolate_varint(bytes, offset) | ||
427 | if val.size() > 0: | ||
428 | offset += val.size() | ||
429 | val = unpack_varint(val) | ||
430 | if field.type == PB_DATA_TYPE.SINT32 || field.type == PB_DATA_TYPE.SINT64: | ||
431 | val = deconvert_signed(val) | ||
432 | elif field.type == PB_DATA_TYPE.BOOL: | ||
433 | if val: | ||
434 | val = true | ||
435 | else: | ||
436 | val = false | ||
437 | if field.rule == PB_RULE.REPEATED: | ||
438 | field.value.append(val) | ||
439 | else: | ||
440 | field.value = val | ||
441 | else: | ||
442 | return PB_ERR.VARINT_NOT_FOUND | ||
443 | return offset | ||
444 | elif type == PB_TYPE.FIX32 || type == PB_TYPE.FIX64: | ||
445 | var type_size | ||
446 | if type == PB_TYPE.FIX32: | ||
447 | type_size = 4 | ||
448 | else: | ||
449 | type_size = 8 | ||
450 | var val | ||
451 | if (offset + type_size) > bytes.size(): | ||
452 | return PB_ERR.REPEATED_COUNT_MISMATCH | ||
453 | val = unpack_bytes(bytes, offset, type_size, field.type) | ||
454 | offset += type_size | ||
455 | if field.rule == PB_RULE.REPEATED: | ||
456 | field.value.append(val) | ||
457 | else: | ||
458 | field.value = val | ||
459 | return offset | ||
460 | elif type == PB_TYPE.LENGTHDEL: | ||
461 | var inner_size = isolate_varint(bytes, offset) | ||
462 | if inner_size.size() > 0: | ||
463 | offset += inner_size.size() | ||
464 | inner_size = unpack_varint(inner_size) | ||
465 | if inner_size >= 0: | ||
466 | if inner_size + offset > bytes.size(): | ||
467 | return PB_ERR.LENGTHDEL_SIZE_MISMATCH | ||
468 | if message_func_ref != null: | ||
469 | var message = message_func_ref.call() | ||
470 | if inner_size > 0: | ||
471 | var sub_offset = message.from_bytes(bytes, offset, inner_size + offset) | ||
472 | if sub_offset > 0: | ||
473 | if sub_offset - offset >= inner_size: | ||
474 | offset = sub_offset | ||
475 | return offset | ||
476 | else: | ||
477 | return PB_ERR.LENGTHDEL_SIZE_MISMATCH | ||
478 | return sub_offset | ||
479 | else: | ||
480 | return offset | ||
481 | elif field.type == PB_DATA_TYPE.STRING: | ||
482 | var str_bytes : PackedByteArray = bytes.slice(offset, inner_size + offset) | ||
483 | if field.rule == PB_RULE.REPEATED: | ||
484 | field.value.append(str_bytes.get_string_from_utf8()) | ||
485 | else: | ||
486 | field.value = str_bytes.get_string_from_utf8() | ||
487 | return offset + inner_size | ||
488 | elif field.type == PB_DATA_TYPE.BYTES: | ||
489 | var val_bytes : PackedByteArray = bytes.slice(offset, inner_size + offset) | ||
490 | if field.rule == PB_RULE.REPEATED: | ||
491 | field.value.append(val_bytes) | ||
492 | else: | ||
493 | field.value = val_bytes | ||
494 | return offset + inner_size | ||
495 | else: | ||
496 | return PB_ERR.LENGTHDEL_SIZE_NOT_FOUND | ||
497 | else: | ||
498 | return PB_ERR.LENGTHDEL_SIZE_NOT_FOUND | ||
499 | return PB_ERR.UNDEFINED_STATE | ||
500 | |||
501 | static func unpack_message(data, bytes : PackedByteArray, offset : int, limit : int) -> int: | ||
502 | while true: | ||
503 | var tt : PBTypeTag = unpack_type_tag(bytes, offset) | ||
504 | if tt.ok: | ||
505 | offset += tt.offset | ||
506 | if data.has(tt.tag): | ||
507 | var service : PBServiceField = data[tt.tag] | ||
508 | var type : int = pb_type_from_data_type(service.field.type) | ||
509 | if type == tt.type || (tt.type == PB_TYPE.LENGTHDEL && service.field.rule == PB_RULE.REPEATED && service.field.option_packed): | ||
510 | var res : int = unpack_field(bytes, offset, service.field, type, service.func_ref) | ||
511 | if res > 0: | ||
512 | service.state = PB_SERVICE_STATE.FILLED | ||
513 | offset = res | ||
514 | if offset == limit: | ||
515 | return offset | ||
516 | elif offset > limit: | ||
517 | return PB_ERR.PACKAGE_SIZE_MISMATCH | ||
518 | elif res < 0: | ||
519 | return res | ||
520 | else: | ||
521 | break | ||
522 | else: | ||
523 | var res : int = skip_unknown_field(bytes, offset, tt.type) | ||
524 | if res > 0: | ||
525 | offset = res | ||
526 | if offset == limit: | ||
527 | return offset | ||
528 | elif offset > limit: | ||
529 | return PB_ERR.PACKAGE_SIZE_MISMATCH | ||
530 | elif res < 0: | ||
531 | return res | ||
532 | else: | ||
533 | break | ||
534 | else: | ||
535 | return offset | ||
536 | return PB_ERR.UNDEFINED_STATE | ||
537 | |||
538 | static func pack_message(data) -> PackedByteArray: | ||
539 | var DEFAULT_VALUES | ||
540 | if PROTO_VERSION == 2: | ||
541 | DEFAULT_VALUES = DEFAULT_VALUES_2 | ||
542 | elif PROTO_VERSION == 3: | ||
543 | DEFAULT_VALUES = DEFAULT_VALUES_3 | ||
544 | var result : PackedByteArray = PackedByteArray() | ||
545 | var keys : Array = data.keys() | ||
546 | keys.sort() | ||
547 | for i in keys: | ||
548 | if data[i].field.value != null: | ||
549 | if data[i].state == PB_SERVICE_STATE.UNFILLED \ | ||
550 | && !data[i].field.is_map_field \ | ||
551 | && typeof(data[i].field.value) == typeof(DEFAULT_VALUES[data[i].field.type]) \ | ||
552 | && data[i].field.value == DEFAULT_VALUES[data[i].field.type]: | ||
553 | continue | ||
554 | elif data[i].field.rule == PB_RULE.REPEATED && data[i].field.value.size() == 0: | ||
555 | continue | ||
556 | result.append_array(pack_field(data[i].field)) | ||
557 | elif data[i].field.rule == PB_RULE.REQUIRED: | ||
558 | print("Error: required field is not filled: Tag:", data[i].field.tag) | ||
559 | return PackedByteArray() | ||
560 | return result | ||
561 | |||
562 | static func check_required(data) -> bool: | ||
563 | var keys : Array = data.keys() | ||
564 | for i in keys: | ||
565 | if data[i].field.rule == PB_RULE.REQUIRED && data[i].state == PB_SERVICE_STATE.UNFILLED: | ||
566 | return false | ||
567 | return true | ||
568 | |||
569 | static func construct_map(key_values): | ||
570 | var result = {} | ||
571 | for kv in key_values: | ||
572 | result[kv.get_key()] = kv.get_value() | ||
573 | return result | ||
574 | |||
575 | static func tabulate(text : String, nesting : int) -> String: | ||
576 | var tab : String = "" | ||
577 | for _i in range(nesting): | ||
578 | tab += DEBUG_TAB | ||
579 | return tab + text | ||
580 | |||
581 | static func value_to_string(value, field : PBField, nesting : int) -> String: | ||
582 | var result : String = "" | ||
583 | var text : String | ||
584 | if field.type == PB_DATA_TYPE.MESSAGE: | ||
585 | result += "{" | ||
586 | nesting += 1 | ||
587 | text = message_to_string(value.data, nesting) | ||
588 | if text != "": | ||
589 | result += "\n" + text | ||
590 | nesting -= 1 | ||
591 | result += tabulate("}", nesting) | ||
592 | else: | ||
593 | nesting -= 1 | ||
594 | result += "}" | ||
595 | elif field.type == PB_DATA_TYPE.BYTES: | ||
596 | result += "<" | ||
597 | for i in range(value.size()): | ||
598 | result += str(value[i]) | ||
599 | if i != (value.size() - 1): | ||
600 | result += ", " | ||
601 | result += ">" | ||
602 | elif field.type == PB_DATA_TYPE.STRING: | ||
603 | result += "\"" + value + "\"" | ||
604 | elif field.type == PB_DATA_TYPE.ENUM: | ||
605 | result += "ENUM::" + str(value) | ||
606 | else: | ||
607 | result += str(value) | ||
608 | return result | ||
609 | |||
610 | static func field_to_string(field : PBField, nesting : int) -> String: | ||
611 | var result : String = tabulate(field.name + ": ", nesting) | ||
612 | if field.type == PB_DATA_TYPE.MAP: | ||
613 | if field.value.size() > 0: | ||
614 | result += "(\n" | ||
615 | nesting += 1 | ||
616 | for i in range(field.value.size()): | ||
617 | var local_key_value = field.value[i].data[1].field | ||
618 | result += tabulate(value_to_string(local_key_value.value, local_key_value, nesting), nesting) + ": " | ||
619 | local_key_value = field.value[i].data[2].field | ||
620 | result += value_to_string(local_key_value.value, local_key_value, nesting) | ||
621 | if i != (field.value.size() - 1): | ||
622 | result += "," | ||
623 | result += "\n" | ||
624 | nesting -= 1 | ||
625 | result += tabulate(")", nesting) | ||
626 | else: | ||
627 | result += "()" | ||
628 | elif field.rule == PB_RULE.REPEATED: | ||
629 | if field.value.size() > 0: | ||
630 | result += "[\n" | ||
631 | nesting += 1 | ||
632 | for i in range(field.value.size()): | ||
633 | result += tabulate(str(i) + ": ", nesting) | ||
634 | result += value_to_string(field.value[i], field, nesting) | ||
635 | if i != (field.value.size() - 1): | ||
636 | result += "," | ||
637 | result += "\n" | ||
638 | nesting -= 1 | ||
639 | result += tabulate("]", nesting) | ||
640 | else: | ||
641 | result += "[]" | ||
642 | else: | ||
643 | result += value_to_string(field.value, field, nesting) | ||
644 | result += ";\n" | ||
645 | return result | ||
646 | |||
647 | static func message_to_string(data, nesting : int = 0) -> String: | ||
648 | var DEFAULT_VALUES | ||
649 | if PROTO_VERSION == 2: | ||
650 | DEFAULT_VALUES = DEFAULT_VALUES_2 | ||
651 | elif PROTO_VERSION == 3: | ||
652 | DEFAULT_VALUES = DEFAULT_VALUES_3 | ||
653 | var result : String = "" | ||
654 | var keys : Array = data.keys() | ||
655 | keys.sort() | ||
656 | for i in keys: | ||
657 | if data[i].field.value != null: | ||
658 | if data[i].state == PB_SERVICE_STATE.UNFILLED \ | ||
659 | && !data[i].field.is_map_field \ | ||
660 | && typeof(data[i].field.value) == typeof(DEFAULT_VALUES[data[i].field.type]) \ | ||
661 | && data[i].field.value == DEFAULT_VALUES[data[i].field.type]: | ||
662 | continue | ||
663 | elif data[i].field.rule == PB_RULE.REPEATED && data[i].field.value.size() == 0: | ||
664 | continue | ||
665 | result += field_to_string(data[i].field, nesting) | ||
666 | elif data[i].field.rule == PB_RULE.REQUIRED: | ||
667 | result += data[i].field.name + ": " + "error" | ||
668 | return result | ||