Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: third_party/google/protobuf/internal/encoder.py

Issue 1153333003: Added tools to retrieve CQ builders from a CQ config (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Addressed comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Protocol Buffers - Google's data interchange format
2 # Copyright 2008 Google Inc. All rights reserved.
3 # http://code.google.com/p/protobuf/
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions are
7 # met:
8 #
9 # * Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # * Redistributions in binary form must reproduce the above
12 # copyright notice, this list of conditions and the following disclaimer
13 # in the documentation and/or other materials provided with the
14 # distribution.
15 # * Neither the name of Google Inc. nor the names of its
16 # contributors may be used to endorse or promote products derived from
17 # this software without specific prior written permission.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #PY25 compatible for GAE.
32 #
33 # Copyright 2009 Google Inc. All Rights Reserved.
34
35 """Code for encoding protocol message primitives.
36
37 Contains the logic for encoding every logical protocol field type
38 into one of the 5 physical wire types.
39
40 This code is designed to push the Python interpreter's performance to the
41 limits.
42
43 The basic idea is that at startup time, for every field (i.e. every
44 FieldDescriptor) we construct two functions: a "sizer" and an "encoder". The
45 sizer takes a value of this field's type and computes its byte size. The
46 encoder takes a writer function and a value. It encodes the value into byte
47 strings and invokes the writer function to write those strings. Typically the
48 writer function is the write() method of a cStringIO.
49
50 We try to do as much work as possible when constructing the writer and the
51 sizer rather than when calling them. In particular:
52 * We copy any needed global functions to local variables, so that we do not need
53 to do costly global table lookups at runtime.
54 * Similarly, we try to do any attribute lookups at startup time if possible.
55 * Every field's tag is encoded to bytes at startup, since it can't change at
56 runtime.
57 * Whatever component of the field size we can compute at startup, we do.
58 * We *avoid* sharing code if doing so would make the code slower and not sharing
59 does not burden us too much. For example, encoders for repeated fields do
60 not just call the encoders for singular fields in a loop because this would
61 add an extra function call overhead for every loop iteration; instead, we
62 manually inline the single-value encoder into the loop.
63 * If a Python function lacks a return statement, Python actually generates
64 instructions to pop the result of the last statement off the stack, push
65 None onto the stack, and then return that. If we really don't care what
66 value is returned, then we can save two instructions by returning the
67 result of the last statement. It looks funny but it helps.
68 * We assume that type and bounds checking has happened at a higher level.
69 """
70
71 __author__ = 'kenton@google.com (Kenton Varda)'
72
73 import struct
74 import sys ##PY25
75 _PY2 = sys.version_info[0] < 3 ##PY25
76 from google.protobuf.internal import wire_format
77
78
79 # This will overflow and thus become IEEE-754 "infinity". We would use
80 # "float('inf')" but it doesn't work on Windows pre-Python-2.6.
81 _POS_INF = 1e10000
82 _NEG_INF = -_POS_INF
83
84
85 def _VarintSize(value):
86 """Compute the size of a varint value."""
87 if value <= 0x7f: return 1
88 if value <= 0x3fff: return 2
89 if value <= 0x1fffff: return 3
90 if value <= 0xfffffff: return 4
91 if value <= 0x7ffffffff: return 5
92 if value <= 0x3ffffffffff: return 6
93 if value <= 0x1ffffffffffff: return 7
94 if value <= 0xffffffffffffff: return 8
95 if value <= 0x7fffffffffffffff: return 9
96 return 10
97
98
99 def _SignedVarintSize(value):
100 """Compute the size of a signed varint value."""
101 if value < 0: return 10
102 if value <= 0x7f: return 1
103 if value <= 0x3fff: return 2
104 if value <= 0x1fffff: return 3
105 if value <= 0xfffffff: return 4
106 if value <= 0x7ffffffff: return 5
107 if value <= 0x3ffffffffff: return 6
108 if value <= 0x1ffffffffffff: return 7
109 if value <= 0xffffffffffffff: return 8
110 if value <= 0x7fffffffffffffff: return 9
111 return 10
112
113
114 def _TagSize(field_number):
115 """Returns the number of bytes required to serialize a tag with this field
116 number."""
117 # Just pass in type 0, since the type won't affect the tag+type size.
118 return _VarintSize(wire_format.PackTag(field_number, 0))
119
120
121 # --------------------------------------------------------------------
122 # In this section we define some generic sizers. Each of these functions
123 # takes parameters specific to a particular field type, e.g. int32 or fixed64.
124 # It returns another function which in turn takes parameters specific to a
125 # particular field, e.g. the field number and whether it is repeated or packed.
126 # Look at the next section to see how these are used.
127
128
129 def _SimpleSizer(compute_value_size):
130 """A sizer which uses the function compute_value_size to compute the size of
131 each value. Typically compute_value_size is _VarintSize."""
132
133 def SpecificSizer(field_number, is_repeated, is_packed):
134 tag_size = _TagSize(field_number)
135 if is_packed:
136 local_VarintSize = _VarintSize
137 def PackedFieldSize(value):
138 result = 0
139 for element in value:
140 result += compute_value_size(element)
141 return result + local_VarintSize(result) + tag_size
142 return PackedFieldSize
143 elif is_repeated:
144 def RepeatedFieldSize(value):
145 result = tag_size * len(value)
146 for element in value:
147 result += compute_value_size(element)
148 return result
149 return RepeatedFieldSize
150 else:
151 def FieldSize(value):
152 return tag_size + compute_value_size(value)
153 return FieldSize
154
155 return SpecificSizer
156
157
158 def _ModifiedSizer(compute_value_size, modify_value):
159 """Like SimpleSizer, but modify_value is invoked on each value before it is
160 passed to compute_value_size. modify_value is typically ZigZagEncode."""
161
162 def SpecificSizer(field_number, is_repeated, is_packed):
163 tag_size = _TagSize(field_number)
164 if is_packed:
165 local_VarintSize = _VarintSize
166 def PackedFieldSize(value):
167 result = 0
168 for element in value:
169 result += compute_value_size(modify_value(element))
170 return result + local_VarintSize(result) + tag_size
171 return PackedFieldSize
172 elif is_repeated:
173 def RepeatedFieldSize(value):
174 result = tag_size * len(value)
175 for element in value:
176 result += compute_value_size(modify_value(element))
177 return result
178 return RepeatedFieldSize
179 else:
180 def FieldSize(value):
181 return tag_size + compute_value_size(modify_value(value))
182 return FieldSize
183
184 return SpecificSizer
185
186
187 def _FixedSizer(value_size):
188 """Like _SimpleSizer except for a fixed-size field. The input is the size
189 of one value."""
190
191 def SpecificSizer(field_number, is_repeated, is_packed):
192 tag_size = _TagSize(field_number)
193 if is_packed:
194 local_VarintSize = _VarintSize
195 def PackedFieldSize(value):
196 result = len(value) * value_size
197 return result + local_VarintSize(result) + tag_size
198 return PackedFieldSize
199 elif is_repeated:
200 element_size = value_size + tag_size
201 def RepeatedFieldSize(value):
202 return len(value) * element_size
203 return RepeatedFieldSize
204 else:
205 field_size = value_size + tag_size
206 def FieldSize(value):
207 return field_size
208 return FieldSize
209
210 return SpecificSizer
211
212
213 # ====================================================================
214 # Here we declare a sizer constructor for each field type. Each "sizer
215 # constructor" is a function that takes (field_number, is_repeated, is_packed)
216 # as parameters and returns a sizer, which in turn takes a field value as
217 # a parameter and returns its encoded size.
218
219
220 Int32Sizer = Int64Sizer = EnumSizer = _SimpleSizer(_SignedVarintSize)
221
222 UInt32Sizer = UInt64Sizer = _SimpleSizer(_VarintSize)
223
224 SInt32Sizer = SInt64Sizer = _ModifiedSizer(
225 _SignedVarintSize, wire_format.ZigZagEncode)
226
227 Fixed32Sizer = SFixed32Sizer = FloatSizer = _FixedSizer(4)
228 Fixed64Sizer = SFixed64Sizer = DoubleSizer = _FixedSizer(8)
229
230 BoolSizer = _FixedSizer(1)
231
232
233 def StringSizer(field_number, is_repeated, is_packed):
234 """Returns a sizer for a string field."""
235
236 tag_size = _TagSize(field_number)
237 local_VarintSize = _VarintSize
238 local_len = len
239 assert not is_packed
240 if is_repeated:
241 def RepeatedFieldSize(value):
242 result = tag_size * len(value)
243 for element in value:
244 l = local_len(element.encode('utf-8'))
245 result += local_VarintSize(l) + l
246 return result
247 return RepeatedFieldSize
248 else:
249 def FieldSize(value):
250 l = local_len(value.encode('utf-8'))
251 return tag_size + local_VarintSize(l) + l
252 return FieldSize
253
254
255 def BytesSizer(field_number, is_repeated, is_packed):
256 """Returns a sizer for a bytes field."""
257
258 tag_size = _TagSize(field_number)
259 local_VarintSize = _VarintSize
260 local_len = len
261 assert not is_packed
262 if is_repeated:
263 def RepeatedFieldSize(value):
264 result = tag_size * len(value)
265 for element in value:
266 l = local_len(element)
267 result += local_VarintSize(l) + l
268 return result
269 return RepeatedFieldSize
270 else:
271 def FieldSize(value):
272 l = local_len(value)
273 return tag_size + local_VarintSize(l) + l
274 return FieldSize
275
276
277 def GroupSizer(field_number, is_repeated, is_packed):
278 """Returns a sizer for a group field."""
279
280 tag_size = _TagSize(field_number) * 2
281 assert not is_packed
282 if is_repeated:
283 def RepeatedFieldSize(value):
284 result = tag_size * len(value)
285 for element in value:
286 result += element.ByteSize()
287 return result
288 return RepeatedFieldSize
289 else:
290 def FieldSize(value):
291 return tag_size + value.ByteSize()
292 return FieldSize
293
294
295 def MessageSizer(field_number, is_repeated, is_packed):
296 """Returns a sizer for a message field."""
297
298 tag_size = _TagSize(field_number)
299 local_VarintSize = _VarintSize
300 assert not is_packed
301 if is_repeated:
302 def RepeatedFieldSize(value):
303 result = tag_size * len(value)
304 for element in value:
305 l = element.ByteSize()
306 result += local_VarintSize(l) + l
307 return result
308 return RepeatedFieldSize
309 else:
310 def FieldSize(value):
311 l = value.ByteSize()
312 return tag_size + local_VarintSize(l) + l
313 return FieldSize
314
315
316 # --------------------------------------------------------------------
317 # MessageSet is special.
318
319
320 def MessageSetItemSizer(field_number):
321 """Returns a sizer for extensions of MessageSet.
322
323 The message set message looks like this:
324 message MessageSet {
325 repeated group Item = 1 {
326 required int32 type_id = 2;
327 required string message = 3;
328 }
329 }
330 """
331 static_size = (_TagSize(1) * 2 + _TagSize(2) + _VarintSize(field_number) +
332 _TagSize(3))
333 local_VarintSize = _VarintSize
334
335 def FieldSize(value):
336 l = value.ByteSize()
337 return static_size + local_VarintSize(l) + l
338
339 return FieldSize
340
341
342 # ====================================================================
343 # Encoders!
344
345
346 def _VarintEncoder():
347 """Return an encoder for a basic varint value (does not include tag)."""
348
349 local_chr = _PY2 and chr or (lambda x: bytes((x,))) ##PY25
350 ##!PY25 local_chr = chr if bytes is str else lambda x: bytes((x,))
351 def EncodeVarint(write, value):
352 bits = value & 0x7f
353 value >>= 7
354 while value:
355 write(local_chr(0x80|bits))
356 bits = value & 0x7f
357 value >>= 7
358 return write(local_chr(bits))
359
360 return EncodeVarint
361
362
363 def _SignedVarintEncoder():
364 """Return an encoder for a basic signed varint value (does not include
365 tag)."""
366
367 local_chr = _PY2 and chr or (lambda x: bytes((x,))) ##PY25
368 ##!PY25 local_chr = chr if bytes is str else lambda x: bytes((x,))
369 def EncodeSignedVarint(write, value):
370 if value < 0:
371 value += (1 << 64)
372 bits = value & 0x7f
373 value >>= 7
374 while value:
375 write(local_chr(0x80|bits))
376 bits = value & 0x7f
377 value >>= 7
378 return write(local_chr(bits))
379
380 return EncodeSignedVarint
381
382
383 _EncodeVarint = _VarintEncoder()
384 _EncodeSignedVarint = _SignedVarintEncoder()
385
386
387 def _VarintBytes(value):
388 """Encode the given integer as a varint and return the bytes. This is only
389 called at startup time so it doesn't need to be fast."""
390
391 pieces = []
392 _EncodeVarint(pieces.append, value)
393 return "".encode("latin1").join(pieces) ##PY25
394 ##!PY25 return b"".join(pieces)
395
396
397 def TagBytes(field_number, wire_type):
398 """Encode the given tag and return the bytes. Only called at startup."""
399
400 return _VarintBytes(wire_format.PackTag(field_number, wire_type))
401
402 # --------------------------------------------------------------------
403 # As with sizers (see above), we have a number of common encoder
404 # implementations.
405
406
407 def _SimpleEncoder(wire_type, encode_value, compute_value_size):
408 """Return a constructor for an encoder for fields of a particular type.
409
410 Args:
411 wire_type: The field's wire type, for encoding tags.
412 encode_value: A function which encodes an individual value, e.g.
413 _EncodeVarint().
414 compute_value_size: A function which computes the size of an individual
415 value, e.g. _VarintSize().
416 """
417
418 def SpecificEncoder(field_number, is_repeated, is_packed):
419 if is_packed:
420 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
421 local_EncodeVarint = _EncodeVarint
422 def EncodePackedField(write, value):
423 write(tag_bytes)
424 size = 0
425 for element in value:
426 size += compute_value_size(element)
427 local_EncodeVarint(write, size)
428 for element in value:
429 encode_value(write, element)
430 return EncodePackedField
431 elif is_repeated:
432 tag_bytes = TagBytes(field_number, wire_type)
433 def EncodeRepeatedField(write, value):
434 for element in value:
435 write(tag_bytes)
436 encode_value(write, element)
437 return EncodeRepeatedField
438 else:
439 tag_bytes = TagBytes(field_number, wire_type)
440 def EncodeField(write, value):
441 write(tag_bytes)
442 return encode_value(write, value)
443 return EncodeField
444
445 return SpecificEncoder
446
447
448 def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
449 """Like SimpleEncoder but additionally invokes modify_value on every value
450 before passing it to encode_value. Usually modify_value is ZigZagEncode."""
451
452 def SpecificEncoder(field_number, is_repeated, is_packed):
453 if is_packed:
454 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
455 local_EncodeVarint = _EncodeVarint
456 def EncodePackedField(write, value):
457 write(tag_bytes)
458 size = 0
459 for element in value:
460 size += compute_value_size(modify_value(element))
461 local_EncodeVarint(write, size)
462 for element in value:
463 encode_value(write, modify_value(element))
464 return EncodePackedField
465 elif is_repeated:
466 tag_bytes = TagBytes(field_number, wire_type)
467 def EncodeRepeatedField(write, value):
468 for element in value:
469 write(tag_bytes)
470 encode_value(write, modify_value(element))
471 return EncodeRepeatedField
472 else:
473 tag_bytes = TagBytes(field_number, wire_type)
474 def EncodeField(write, value):
475 write(tag_bytes)
476 return encode_value(write, modify_value(value))
477 return EncodeField
478
479 return SpecificEncoder
480
481
482 def _StructPackEncoder(wire_type, format):
483 """Return a constructor for an encoder for a fixed-width field.
484
485 Args:
486 wire_type: The field's wire type, for encoding tags.
487 format: The format string to pass to struct.pack().
488 """
489
490 value_size = struct.calcsize(format)
491
492 def SpecificEncoder(field_number, is_repeated, is_packed):
493 local_struct_pack = struct.pack
494 if is_packed:
495 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
496 local_EncodeVarint = _EncodeVarint
497 def EncodePackedField(write, value):
498 write(tag_bytes)
499 local_EncodeVarint(write, len(value) * value_size)
500 for element in value:
501 write(local_struct_pack(format, element))
502 return EncodePackedField
503 elif is_repeated:
504 tag_bytes = TagBytes(field_number, wire_type)
505 def EncodeRepeatedField(write, value):
506 for element in value:
507 write(tag_bytes)
508 write(local_struct_pack(format, element))
509 return EncodeRepeatedField
510 else:
511 tag_bytes = TagBytes(field_number, wire_type)
512 def EncodeField(write, value):
513 write(tag_bytes)
514 return write(local_struct_pack(format, value))
515 return EncodeField
516
517 return SpecificEncoder
518
519
520 def _FloatingPointEncoder(wire_type, format):
521 """Return a constructor for an encoder for float fields.
522
523 This is like StructPackEncoder, but catches errors that may be due to
524 passing non-finite floating-point values to struct.pack, and makes a
525 second attempt to encode those values.
526
527 Args:
528 wire_type: The field's wire type, for encoding tags.
529 format: The format string to pass to struct.pack().
530 """
531
532 b = _PY2 and (lambda x:x) or (lambda x:x.encode('latin1')) ##PY25
533 value_size = struct.calcsize(format)
534 if value_size == 4:
535 def EncodeNonFiniteOrRaise(write, value):
536 # Remember that the serialized form uses little-endian byte order.
537 if value == _POS_INF:
538 write(b('\x00\x00\x80\x7F')) ##PY25
539 ##!PY25 write(b'\x00\x00\x80\x7F')
540 elif value == _NEG_INF:
541 write(b('\x00\x00\x80\xFF')) ##PY25
542 ##!PY25 write(b'\x00\x00\x80\xFF')
543 elif value != value: # NaN
544 write(b('\x00\x00\xC0\x7F')) ##PY25
545 ##!PY25 write(b'\x00\x00\xC0\x7F')
546 else:
547 raise
548 elif value_size == 8:
549 def EncodeNonFiniteOrRaise(write, value):
550 if value == _POS_INF:
551 write(b('\x00\x00\x00\x00\x00\x00\xF0\x7F')) ##PY25
552 ##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF0\x7F')
553 elif value == _NEG_INF:
554 write(b('\x00\x00\x00\x00\x00\x00\xF0\xFF')) ##PY25
555 ##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF0\xFF')
556 elif value != value: # NaN
557 write(b('\x00\x00\x00\x00\x00\x00\xF8\x7F')) ##PY25
558 ##!PY25 write(b'\x00\x00\x00\x00\x00\x00\xF8\x7F')
559 else:
560 raise
561 else:
562 raise ValueError('Can\'t encode floating-point values that are '
563 '%d bytes long (only 4 or 8)' % value_size)
564
565 def SpecificEncoder(field_number, is_repeated, is_packed):
566 local_struct_pack = struct.pack
567 if is_packed:
568 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
569 local_EncodeVarint = _EncodeVarint
570 def EncodePackedField(write, value):
571 write(tag_bytes)
572 local_EncodeVarint(write, len(value) * value_size)
573 for element in value:
574 # This try/except block is going to be faster than any code that
575 # we could write to check whether element is finite.
576 try:
577 write(local_struct_pack(format, element))
578 except SystemError:
579 EncodeNonFiniteOrRaise(write, element)
580 return EncodePackedField
581 elif is_repeated:
582 tag_bytes = TagBytes(field_number, wire_type)
583 def EncodeRepeatedField(write, value):
584 for element in value:
585 write(tag_bytes)
586 try:
587 write(local_struct_pack(format, element))
588 except SystemError:
589 EncodeNonFiniteOrRaise(write, element)
590 return EncodeRepeatedField
591 else:
592 tag_bytes = TagBytes(field_number, wire_type)
593 def EncodeField(write, value):
594 write(tag_bytes)
595 try:
596 write(local_struct_pack(format, value))
597 except SystemError:
598 EncodeNonFiniteOrRaise(write, value)
599 return EncodeField
600
601 return SpecificEncoder
602
603
604 # ====================================================================
605 # Here we declare an encoder constructor for each field type. These work
606 # very similarly to sizer constructors, described earlier.
607
608
609 Int32Encoder = Int64Encoder = EnumEncoder = _SimpleEncoder(
610 wire_format.WIRETYPE_VARINT, _EncodeSignedVarint, _SignedVarintSize)
611
612 UInt32Encoder = UInt64Encoder = _SimpleEncoder(
613 wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize)
614
615 SInt32Encoder = SInt64Encoder = _ModifiedEncoder(
616 wire_format.WIRETYPE_VARINT, _EncodeVarint, _VarintSize,
617 wire_format.ZigZagEncode)
618
619 # Note that Python conveniently guarantees that when using the '<' prefix on
620 # formats, they will also have the same size across all platforms (as opposed
621 # to without the prefix, where their sizes depend on the C compiler's basic
622 # type sizes).
623 Fixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<I')
624 Fixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<Q')
625 SFixed32Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED32, '<i')
626 SFixed64Encoder = _StructPackEncoder(wire_format.WIRETYPE_FIXED64, '<q')
627 FloatEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED32, '<f')
628 DoubleEncoder = _FloatingPointEncoder(wire_format.WIRETYPE_FIXED64, '<d')
629
630
631 def BoolEncoder(field_number, is_repeated, is_packed):
632 """Returns an encoder for a boolean field."""
633
634 ##!PY25 false_byte = b'\x00'
635 ##!PY25 true_byte = b'\x01'
636 false_byte = '\x00'.encode('latin1') ##PY25
637 true_byte = '\x01'.encode('latin1') ##PY25
638 if is_packed:
639 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
640 local_EncodeVarint = _EncodeVarint
641 def EncodePackedField(write, value):
642 write(tag_bytes)
643 local_EncodeVarint(write, len(value))
644 for element in value:
645 if element:
646 write(true_byte)
647 else:
648 write(false_byte)
649 return EncodePackedField
650 elif is_repeated:
651 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
652 def EncodeRepeatedField(write, value):
653 for element in value:
654 write(tag_bytes)
655 if element:
656 write(true_byte)
657 else:
658 write(false_byte)
659 return EncodeRepeatedField
660 else:
661 tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
662 def EncodeField(write, value):
663 write(tag_bytes)
664 if value:
665 return write(true_byte)
666 return write(false_byte)
667 return EncodeField
668
669
670 def StringEncoder(field_number, is_repeated, is_packed):
671 """Returns an encoder for a string field."""
672
673 tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
674 local_EncodeVarint = _EncodeVarint
675 local_len = len
676 assert not is_packed
677 if is_repeated:
678 def EncodeRepeatedField(write, value):
679 for element in value:
680 encoded = element.encode('utf-8')
681 write(tag)
682 local_EncodeVarint(write, local_len(encoded))
683 write(encoded)
684 return EncodeRepeatedField
685 else:
686 def EncodeField(write, value):
687 encoded = value.encode('utf-8')
688 write(tag)
689 local_EncodeVarint(write, local_len(encoded))
690 return write(encoded)
691 return EncodeField
692
693
694 def BytesEncoder(field_number, is_repeated, is_packed):
695 """Returns an encoder for a bytes field."""
696
697 tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
698 local_EncodeVarint = _EncodeVarint
699 local_len = len
700 assert not is_packed
701 if is_repeated:
702 def EncodeRepeatedField(write, value):
703 for element in value:
704 write(tag)
705 local_EncodeVarint(write, local_len(element))
706 write(element)
707 return EncodeRepeatedField
708 else:
709 def EncodeField(write, value):
710 write(tag)
711 local_EncodeVarint(write, local_len(value))
712 return write(value)
713 return EncodeField
714
715
716 def GroupEncoder(field_number, is_repeated, is_packed):
717 """Returns an encoder for a group field."""
718
719 start_tag = TagBytes(field_number, wire_format.WIRETYPE_START_GROUP)
720 end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP)
721 assert not is_packed
722 if is_repeated:
723 def EncodeRepeatedField(write, value):
724 for element in value:
725 write(start_tag)
726 element._InternalSerialize(write)
727 write(end_tag)
728 return EncodeRepeatedField
729 else:
730 def EncodeField(write, value):
731 write(start_tag)
732 value._InternalSerialize(write)
733 return write(end_tag)
734 return EncodeField
735
736
737 def MessageEncoder(field_number, is_repeated, is_packed):
738 """Returns an encoder for a message field."""
739
740 tag = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
741 local_EncodeVarint = _EncodeVarint
742 assert not is_packed
743 if is_repeated:
744 def EncodeRepeatedField(write, value):
745 for element in value:
746 write(tag)
747 local_EncodeVarint(write, element.ByteSize())
748 element._InternalSerialize(write)
749 return EncodeRepeatedField
750 else:
751 def EncodeField(write, value):
752 write(tag)
753 local_EncodeVarint(write, value.ByteSize())
754 return value._InternalSerialize(write)
755 return EncodeField
756
757
758 # --------------------------------------------------------------------
759 # As before, MessageSet is special.
760
761
762 def MessageSetItemEncoder(field_number):
763 """Encoder for extensions of MessageSet.
764
765 The message set message looks like this:
766 message MessageSet {
767 repeated group Item = 1 {
768 required int32 type_id = 2;
769 required string message = 3;
770 }
771 }
772 """
773 start_bytes = "".encode("latin1").join([ ##PY25
774 ##!PY25 start_bytes = b"".join([
775 TagBytes(1, wire_format.WIRETYPE_START_GROUP),
776 TagBytes(2, wire_format.WIRETYPE_VARINT),
777 _VarintBytes(field_number),
778 TagBytes(3, wire_format.WIRETYPE_LENGTH_DELIMITED)])
779 end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP)
780 local_EncodeVarint = _EncodeVarint
781
782 def EncodeField(write, value):
783 write(start_bytes)
784 local_EncodeVarint(write, value.ByteSize())
785 value._InternalSerialize(write)
786 return write(end_bytes)
787
788 return EncodeField
OLDNEW
« no previous file with comments | « third_party/google/protobuf/internal/decoder.py ('k') | third_party/google/protobuf/internal/enum_type_wrapper.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698