diff options
author | Shawn O. Pearce <sop@google.com> | 2009-01-26 10:55:39 -0800 |
---|---|---|
committer | Shawn O. Pearce <sop@google.com> | 2009-01-26 10:55:39 -0800 |
commit | 370e3fa6660fa2eb675199104cde9e9d02063cfd (patch) | |
tree | 5ff9e8399be3a6ba7db48f20c00c86989634445f /froofle/protobuf/internal | |
parent | b54a392c9a267a06058b663377282c9dcec6878e (diff) | |
download | git-repo-370e3fa6660fa2eb675199104cde9e9d02063cfd.tar.gz |
Remove the protobuf based HTTP upload code path
Now that Gerrit2 has been released and the only supported upload
protocol is direct git push over SSH we no longer need the large
and complex protobuf client library, or the upload chunking logic
in gerrit_upload.py.
Signed-off-by: Shawn O. Pearce <sop@google.com>
Diffstat (limited to 'froofle/protobuf/internal')
-rw-r--r-- | froofle/protobuf/internal/__init__.py | 0 | ||||
-rw-r--r-- | froofle/protobuf/internal/decoder.py | 209 | ||||
-rw-r--r-- | froofle/protobuf/internal/encoder.py | 206 | ||||
-rw-r--r-- | froofle/protobuf/internal/input_stream.py | 326 | ||||
-rw-r--r-- | froofle/protobuf/internal/message_listener.py | 69 | ||||
-rw-r--r-- | froofle/protobuf/internal/output_stream.py | 125 | ||||
-rw-r--r-- | froofle/protobuf/internal/type_checkers.py | 268 | ||||
-rw-r--r-- | froofle/protobuf/internal/wire_format.py | 236 |
8 files changed, 0 insertions, 1439 deletions
diff --git a/froofle/protobuf/internal/__init__.py b/froofle/protobuf/internal/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/froofle/protobuf/internal/__init__.py +++ /dev/null | |||
diff --git a/froofle/protobuf/internal/decoder.py b/froofle/protobuf/internal/decoder.py deleted file mode 100644 index 2dd4c96e..00000000 --- a/froofle/protobuf/internal/decoder.py +++ /dev/null | |||
@@ -1,209 +0,0 @@ | |||
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 | """Class for decoding protocol buffer primitives. | ||
32 | |||
33 | Contains the logic for decoding every logical protocol field type | ||
34 | from one of the 5 physical wire types. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import struct | ||
40 | from froofle.protobuf import message | ||
41 | from froofle.protobuf.internal import input_stream | ||
42 | from froofle.protobuf.internal import wire_format | ||
43 | |||
44 | |||
45 | |||
46 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
47 | # that the interface is strongly inspired by WireFormat from the C++ proto2 | ||
48 | # implementation. | ||
49 | |||
50 | |||
51 | class Decoder(object): | ||
52 | |||
53 | """Decodes logical protocol buffer fields from the wire.""" | ||
54 | |||
55 | def __init__(self, s): | ||
56 | """Initializes the decoder to read from s. | ||
57 | |||
58 | Args: | ||
59 | s: An immutable sequence of bytes, which must be accessible | ||
60 | via the Python buffer() primitive (i.e., buffer(s)). | ||
61 | """ | ||
62 | self._stream = input_stream.InputStream(s) | ||
63 | |||
64 | def EndOfStream(self): | ||
65 | """Returns true iff we've reached the end of the bytes we're reading.""" | ||
66 | return self._stream.EndOfStream() | ||
67 | |||
68 | def Position(self): | ||
69 | """Returns the 0-indexed position in |s|.""" | ||
70 | return self._stream.Position() | ||
71 | |||
72 | def ReadFieldNumberAndWireType(self): | ||
73 | """Reads a tag from the wire. Returns a (field_number, wire_type) pair.""" | ||
74 | tag_and_type = self.ReadUInt32() | ||
75 | return wire_format.UnpackTag(tag_and_type) | ||
76 | |||
77 | def SkipBytes(self, bytes): | ||
78 | """Skips the specified number of bytes on the wire.""" | ||
79 | self._stream.SkipBytes(bytes) | ||
80 | |||
81 | # Note that the Read*() methods below are not exactly symmetrical with the | ||
82 | # corresponding Encoder.Append*() methods. Those Encoder methods first | ||
83 | # encode a tag, but the Read*() methods below assume that the tag has already | ||
84 | # been read, and that the client wishes to read a field of the specified type | ||
85 | # starting at the current position. | ||
86 | |||
87 | def ReadInt32(self): | ||
88 | """Reads and returns a signed, varint-encoded, 32-bit integer.""" | ||
89 | return self._stream.ReadVarint32() | ||
90 | |||
91 | def ReadInt64(self): | ||
92 | """Reads and returns a signed, varint-encoded, 64-bit integer.""" | ||
93 | return self._stream.ReadVarint64() | ||
94 | |||
95 | def ReadUInt32(self): | ||
96 | """Reads and returns an signed, varint-encoded, 32-bit integer.""" | ||
97 | return self._stream.ReadVarUInt32() | ||
98 | |||
99 | def ReadUInt64(self): | ||
100 | """Reads and returns an signed, varint-encoded,64-bit integer.""" | ||
101 | return self._stream.ReadVarUInt64() | ||
102 | |||
103 | def ReadSInt32(self): | ||
104 | """Reads and returns a signed, zigzag-encoded, varint-encoded, | ||
105 | 32-bit integer.""" | ||
106 | return wire_format.ZigZagDecode(self._stream.ReadVarUInt32()) | ||
107 | |||
108 | def ReadSInt64(self): | ||
109 | """Reads and returns a signed, zigzag-encoded, varint-encoded, | ||
110 | 64-bit integer.""" | ||
111 | return wire_format.ZigZagDecode(self._stream.ReadVarUInt64()) | ||
112 | |||
113 | def ReadFixed32(self): | ||
114 | """Reads and returns an unsigned, fixed-width, 32-bit integer.""" | ||
115 | return self._stream.ReadLittleEndian32() | ||
116 | |||
117 | def ReadFixed64(self): | ||
118 | """Reads and returns an unsigned, fixed-width, 64-bit integer.""" | ||
119 | return self._stream.ReadLittleEndian64() | ||
120 | |||
121 | def ReadSFixed32(self): | ||
122 | """Reads and returns a signed, fixed-width, 32-bit integer.""" | ||
123 | value = self._stream.ReadLittleEndian32() | ||
124 | if value >= (1 << 31): | ||
125 | value -= (1 << 32) | ||
126 | return value | ||
127 | |||
128 | def ReadSFixed64(self): | ||
129 | """Reads and returns a signed, fixed-width, 64-bit integer.""" | ||
130 | value = self._stream.ReadLittleEndian64() | ||
131 | if value >= (1 << 63): | ||
132 | value -= (1 << 64) | ||
133 | return value | ||
134 | |||
135 | def ReadFloat(self): | ||
136 | """Reads and returns a 4-byte floating-point number.""" | ||
137 | serialized = self._stream.ReadBytes(4) | ||
138 | return struct.unpack('f', serialized)[0] | ||
139 | |||
140 | def ReadDouble(self): | ||
141 | """Reads and returns an 8-byte floating-point number.""" | ||
142 | serialized = self._stream.ReadBytes(8) | ||
143 | return struct.unpack('d', serialized)[0] | ||
144 | |||
145 | def ReadBool(self): | ||
146 | """Reads and returns a bool.""" | ||
147 | i = self._stream.ReadVarUInt32() | ||
148 | return bool(i) | ||
149 | |||
150 | def ReadEnum(self): | ||
151 | """Reads and returns an enum value.""" | ||
152 | return self._stream.ReadVarUInt32() | ||
153 | |||
154 | def ReadString(self): | ||
155 | """Reads and returns a length-delimited string.""" | ||
156 | bytes = self.ReadBytes() | ||
157 | return unicode(bytes, 'utf-8') | ||
158 | |||
159 | def ReadBytes(self): | ||
160 | """Reads and returns a length-delimited byte sequence.""" | ||
161 | length = self._stream.ReadVarUInt32() | ||
162 | return self._stream.ReadBytes(length) | ||
163 | |||
164 | def ReadMessageInto(self, msg): | ||
165 | """Calls msg.MergeFromString() to merge | ||
166 | length-delimited serialized message data into |msg|. | ||
167 | |||
168 | REQUIRES: The decoder must be positioned at the serialized "length" | ||
169 | prefix to a length-delmiited serialized message. | ||
170 | |||
171 | POSTCONDITION: The decoder is positioned just after the | ||
172 | serialized message, and we have merged those serialized | ||
173 | contents into |msg|. | ||
174 | """ | ||
175 | length = self._stream.ReadVarUInt32() | ||
176 | sub_buffer = self._stream.GetSubBuffer(length) | ||
177 | num_bytes_used = msg.MergeFromString(sub_buffer) | ||
178 | if num_bytes_used != length: | ||
179 | raise message.DecodeError( | ||
180 | 'Submessage told to deserialize from %d-byte encoding, ' | ||
181 | 'but used only %d bytes' % (length, num_bytes_used)) | ||
182 | self._stream.SkipBytes(num_bytes_used) | ||
183 | |||
184 | def ReadGroupInto(self, expected_field_number, group): | ||
185 | """Calls group.MergeFromString() to merge | ||
186 | END_GROUP-delimited serialized message data into |group|. | ||
187 | We'll raise an exception if we don't find an END_GROUP | ||
188 | tag immediately after the serialized message contents. | ||
189 | |||
190 | REQUIRES: The decoder is positioned just after the START_GROUP | ||
191 | tag for this group. | ||
192 | |||
193 | POSTCONDITION: The decoder is positioned just after the | ||
194 | END_GROUP tag for this group, and we have merged | ||
195 | the contents of the group into |group|. | ||
196 | """ | ||
197 | sub_buffer = self._stream.GetSubBuffer() # No a priori length limit. | ||
198 | num_bytes_used = group.MergeFromString(sub_buffer) | ||
199 | if num_bytes_used < 0: | ||
200 | raise message.DecodeError('Group message reported negative bytes read.') | ||
201 | self._stream.SkipBytes(num_bytes_used) | ||
202 | field_number, field_type = self.ReadFieldNumberAndWireType() | ||
203 | if field_type != wire_format.WIRETYPE_END_GROUP: | ||
204 | raise message.DecodeError('Group message did not end with an END_GROUP.') | ||
205 | if field_number != expected_field_number: | ||
206 | raise message.DecodeError('END_GROUP tag had field ' | ||
207 | 'number %d, was expecting field number %d' % ( | ||
208 | field_number, expected_field_number)) | ||
209 | # We're now positioned just after the END_GROUP tag. Perfect. | ||
diff --git a/froofle/protobuf/internal/encoder.py b/froofle/protobuf/internal/encoder.py deleted file mode 100644 index 8b924b3e..00000000 --- a/froofle/protobuf/internal/encoder.py +++ /dev/null | |||
@@ -1,206 +0,0 @@ | |||
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 | """Class for encoding protocol message primitives. | ||
32 | |||
33 | Contains the logic for encoding every logical protocol field type | ||
34 | into one of the 5 physical wire types. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import struct | ||
40 | from froofle.protobuf import message | ||
41 | from froofle.protobuf.internal import wire_format | ||
42 | from froofle.protobuf.internal import output_stream | ||
43 | |||
44 | |||
45 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
46 | # that the interface is strongly inspired by WireFormat from the C++ proto2 | ||
47 | # implementation. | ||
48 | |||
49 | |||
50 | class Encoder(object): | ||
51 | |||
52 | """Encodes logical protocol buffer fields to the wire format.""" | ||
53 | |||
54 | def __init__(self): | ||
55 | self._stream = output_stream.OutputStream() | ||
56 | |||
57 | def ToString(self): | ||
58 | """Returns all values encoded in this object as a string.""" | ||
59 | return self._stream.ToString() | ||
60 | |||
61 | # All the Append*() methods below first append a tag+type pair to the buffer | ||
62 | # before appending the specified value. | ||
63 | |||
64 | def AppendInt32(self, field_number, value): | ||
65 | """Appends a 32-bit integer to our buffer, varint-encoded.""" | ||
66 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
67 | self._stream.AppendVarint32(value) | ||
68 | |||
69 | def AppendInt64(self, field_number, value): | ||
70 | """Appends a 64-bit integer to our buffer, varint-encoded.""" | ||
71 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
72 | self._stream.AppendVarint64(value) | ||
73 | |||
74 | def AppendUInt32(self, field_number, unsigned_value): | ||
75 | """Appends an unsigned 32-bit integer to our buffer, varint-encoded.""" | ||
76 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
77 | self._stream.AppendVarUInt32(unsigned_value) | ||
78 | |||
79 | def AppendUInt64(self, field_number, unsigned_value): | ||
80 | """Appends an unsigned 64-bit integer to our buffer, varint-encoded.""" | ||
81 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
82 | self._stream.AppendVarUInt64(unsigned_value) | ||
83 | |||
84 | def AppendSInt32(self, field_number, value): | ||
85 | """Appends a 32-bit integer to our buffer, zigzag-encoded and then | ||
86 | varint-encoded. | ||
87 | """ | ||
88 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
89 | zigzag_value = wire_format.ZigZagEncode(value) | ||
90 | self._stream.AppendVarUInt32(zigzag_value) | ||
91 | |||
92 | def AppendSInt64(self, field_number, value): | ||
93 | """Appends a 64-bit integer to our buffer, zigzag-encoded and then | ||
94 | varint-encoded. | ||
95 | """ | ||
96 | self._AppendTag(field_number, wire_format.WIRETYPE_VARINT) | ||
97 | zigzag_value = wire_format.ZigZagEncode(value) | ||
98 | self._stream.AppendVarUInt64(zigzag_value) | ||
99 | |||
100 | def AppendFixed32(self, field_number, unsigned_value): | ||
101 | """Appends an unsigned 32-bit integer to our buffer, in little-endian | ||
102 | byte-order. | ||
103 | """ | ||
104 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32) | ||
105 | self._stream.AppendLittleEndian32(unsigned_value) | ||
106 | |||
107 | def AppendFixed64(self, field_number, unsigned_value): | ||
108 | """Appends an unsigned 64-bit integer to our buffer, in little-endian | ||
109 | byte-order. | ||
110 | """ | ||
111 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64) | ||
112 | self._stream.AppendLittleEndian64(unsigned_value) | ||
113 | |||
114 | def AppendSFixed32(self, field_number, value): | ||
115 | """Appends a signed 32-bit integer to our buffer, in little-endian | ||
116 | byte-order. | ||
117 | """ | ||
118 | sign = (value & 0x80000000) and -1 or 0 | ||
119 | if value >> 32 != sign: | ||
120 | raise message.EncodeError('SFixed32 out of range: %d' % value) | ||
121 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32) | ||
122 | self._stream.AppendLittleEndian32(value & 0xffffffff) | ||
123 | |||
124 | def AppendSFixed64(self, field_number, value): | ||
125 | """Appends a signed 64-bit integer to our buffer, in little-endian | ||
126 | byte-order. | ||
127 | """ | ||
128 | sign = (value & 0x8000000000000000) and -1 or 0 | ||
129 | if value >> 64 != sign: | ||
130 | raise message.EncodeError('SFixed64 out of range: %d' % value) | ||
131 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64) | ||
132 | self._stream.AppendLittleEndian64(value & 0xffffffffffffffff) | ||
133 | |||
134 | def AppendFloat(self, field_number, value): | ||
135 | """Appends a floating-point number to our buffer.""" | ||
136 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED32) | ||
137 | self._stream.AppendRawBytes(struct.pack('f', value)) | ||
138 | |||
139 | def AppendDouble(self, field_number, value): | ||
140 | """Appends a double-precision floating-point number to our buffer.""" | ||
141 | self._AppendTag(field_number, wire_format.WIRETYPE_FIXED64) | ||
142 | self._stream.AppendRawBytes(struct.pack('d', value)) | ||
143 | |||
144 | def AppendBool(self, field_number, value): | ||
145 | """Appends a boolean to our buffer.""" | ||
146 | self.AppendInt32(field_number, value) | ||
147 | |||
148 | def AppendEnum(self, field_number, value): | ||
149 | """Appends an enum value to our buffer.""" | ||
150 | self.AppendInt32(field_number, value) | ||
151 | |||
152 | def AppendString(self, field_number, value): | ||
153 | """Appends a length-prefixed unicode string, encoded as UTF-8 to our buffer, | ||
154 | with the length varint-encoded. | ||
155 | """ | ||
156 | self.AppendBytes(field_number, value.encode('utf-8')) | ||
157 | |||
158 | def AppendBytes(self, field_number, value): | ||
159 | """Appends a length-prefixed sequence of bytes to our buffer, with the | ||
160 | length varint-encoded. | ||
161 | """ | ||
162 | self._AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) | ||
163 | self._stream.AppendVarUInt32(len(value)) | ||
164 | self._stream.AppendRawBytes(value) | ||
165 | |||
166 | # TODO(robinson): For AppendGroup() and AppendMessage(), we'd really like to | ||
167 | # avoid the extra string copy here. We can do so if we widen the Message | ||
168 | # interface to be able to serialize to a stream in addition to a string. The | ||
169 | # challenge when thinking ahead to the Python/C API implementation of Message | ||
170 | # is finding a stream-like Python thing to which we can write raw bytes | ||
171 | # from C. I'm not sure such a thing exists(?). (array.array is pretty much | ||
172 | # what we want, but it's not directly exposed in the Python/C API). | ||
173 | |||
174 | def AppendGroup(self, field_number, group): | ||
175 | """Appends a group to our buffer. | ||
176 | """ | ||
177 | self._AppendTag(field_number, wire_format.WIRETYPE_START_GROUP) | ||
178 | self._stream.AppendRawBytes(group.SerializeToString()) | ||
179 | self._AppendTag(field_number, wire_format.WIRETYPE_END_GROUP) | ||
180 | |||
181 | def AppendMessage(self, field_number, msg): | ||
182 | """Appends a nested message to our buffer. | ||
183 | """ | ||
184 | self._AppendTag(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED) | ||
185 | self._stream.AppendVarUInt32(msg.ByteSize()) | ||
186 | self._stream.AppendRawBytes(msg.SerializeToString()) | ||
187 | |||
188 | def AppendMessageSetItem(self, field_number, msg): | ||
189 | """Appends an item using the message set wire format. | ||
190 | |||
191 | The message set message looks like this: | ||
192 | message MessageSet { | ||
193 | repeated group Item = 1 { | ||
194 | required int32 type_id = 2; | ||
195 | required string message = 3; | ||
196 | } | ||
197 | } | ||
198 | """ | ||
199 | self._AppendTag(1, wire_format.WIRETYPE_START_GROUP) | ||
200 | self.AppendInt32(2, field_number) | ||
201 | self.AppendMessage(3, msg) | ||
202 | self._AppendTag(1, wire_format.WIRETYPE_END_GROUP) | ||
203 | |||
204 | def _AppendTag(self, field_number, wire_type): | ||
205 | """Appends a tag containing field number and wire type information.""" | ||
206 | self._stream.AppendVarUInt32(wire_format.PackTag(field_number, wire_type)) | ||
diff --git a/froofle/protobuf/internal/input_stream.py b/froofle/protobuf/internal/input_stream.py deleted file mode 100644 index 26a26dcf..00000000 --- a/froofle/protobuf/internal/input_stream.py +++ /dev/null | |||
@@ -1,326 +0,0 @@ | |||
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 | """InputStream is the primitive interface for reading bits from the wire. | ||
32 | |||
33 | All protocol buffer deserialization can be expressed in terms of | ||
34 | the InputStream primitives provided here. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import struct | ||
40 | from array import array | ||
41 | from froofle.protobuf import message | ||
42 | from froofle.protobuf.internal import wire_format | ||
43 | |||
44 | |||
45 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
46 | # that the interface is strongly inspired by CodedInputStream from the C++ | ||
47 | # proto2 implementation. | ||
48 | |||
49 | |||
50 | class InputStreamBuffer(object): | ||
51 | |||
52 | """Contains all logic for reading bits, and dealing with stream position. | ||
53 | |||
54 | If an InputStream method ever raises an exception, the stream is left | ||
55 | in an indeterminate state and is not safe for further use. | ||
56 | """ | ||
57 | |||
58 | def __init__(self, s): | ||
59 | # What we really want is something like array('B', s), where elements we | ||
60 | # read from the array are already given to us as one-byte integers. BUT | ||
61 | # using array() instead of buffer() would force full string copies to result | ||
62 | # from each GetSubBuffer() call. | ||
63 | # | ||
64 | # So, if the N serialized bytes of a single protocol buffer object are | ||
65 | # split evenly between 2 child messages, and so on recursively, using | ||
66 | # array('B', s) instead of buffer() would incur an additional N*logN bytes | ||
67 | # copied during deserialization. | ||
68 | # | ||
69 | # The higher constant overhead of having to ord() for every byte we read | ||
70 | # from the buffer in _ReadVarintHelper() could definitely lead to worse | ||
71 | # performance in many real-world scenarios, even if the asymptotic | ||
72 | # complexity is better. However, our real answer is that the mythical | ||
73 | # Python/C extension module output mode for the protocol compiler will | ||
74 | # be blazing-fast and will eliminate most use of this class anyway. | ||
75 | self._buffer = buffer(s) | ||
76 | self._pos = 0 | ||
77 | |||
78 | def EndOfStream(self): | ||
79 | """Returns true iff we're at the end of the stream. | ||
80 | If this returns true, then a call to any other InputStream method | ||
81 | will raise an exception. | ||
82 | """ | ||
83 | return self._pos >= len(self._buffer) | ||
84 | |||
85 | def Position(self): | ||
86 | """Returns the current position in the stream, or equivalently, the | ||
87 | number of bytes read so far. | ||
88 | """ | ||
89 | return self._pos | ||
90 | |||
91 | def GetSubBuffer(self, size=None): | ||
92 | """Returns a sequence-like object that represents a portion of our | ||
93 | underlying sequence. | ||
94 | |||
95 | Position 0 in the returned object corresponds to self.Position() | ||
96 | in this stream. | ||
97 | |||
98 | If size is specified, then the returned object ends after the | ||
99 | next "size" bytes in this stream. If size is not specified, | ||
100 | then the returned object ends at the end of this stream. | ||
101 | |||
102 | We guarantee that the returned object R supports the Python buffer | ||
103 | interface (and thus that the call buffer(R) will work). | ||
104 | |||
105 | Note that the returned buffer is read-only. | ||
106 | |||
107 | The intended use for this method is for nested-message and nested-group | ||
108 | deserialization, where we want to make a recursive MergeFromString() | ||
109 | call on the portion of the original sequence that contains the serialized | ||
110 | nested message. (And we'd like to do so without making unnecessary string | ||
111 | copies). | ||
112 | |||
113 | REQUIRES: size is nonnegative. | ||
114 | """ | ||
115 | # Note that buffer() doesn't perform any actual string copy. | ||
116 | if size is None: | ||
117 | return buffer(self._buffer, self._pos) | ||
118 | else: | ||
119 | if size < 0: | ||
120 | raise message.DecodeError('Negative size %d' % size) | ||
121 | return buffer(self._buffer, self._pos, size) | ||
122 | |||
123 | def SkipBytes(self, num_bytes): | ||
124 | """Skip num_bytes bytes ahead, or go to the end of the stream, whichever | ||
125 | comes first. | ||
126 | |||
127 | REQUIRES: num_bytes is nonnegative. | ||
128 | """ | ||
129 | if num_bytes < 0: | ||
130 | raise message.DecodeError('Negative num_bytes %d' % num_bytes) | ||
131 | self._pos += num_bytes | ||
132 | self._pos = min(self._pos, len(self._buffer)) | ||
133 | |||
134 | def ReadBytes(self, size): | ||
135 | """Reads up to 'size' bytes from the stream, stopping early | ||
136 | only if we reach the end of the stream. Returns the bytes read | ||
137 | as a string. | ||
138 | """ | ||
139 | if size < 0: | ||
140 | raise message.DecodeError('Negative size %d' % size) | ||
141 | s = (self._buffer[self._pos : self._pos + size]) | ||
142 | self._pos += len(s) # Only advance by the number of bytes actually read. | ||
143 | return s | ||
144 | |||
145 | def ReadLittleEndian32(self): | ||
146 | """Interprets the next 4 bytes of the stream as a little-endian | ||
147 | encoded, unsiged 32-bit integer, and returns that integer. | ||
148 | """ | ||
149 | try: | ||
150 | i = struct.unpack(wire_format.FORMAT_UINT32_LITTLE_ENDIAN, | ||
151 | self._buffer[self._pos : self._pos + 4]) | ||
152 | self._pos += 4 | ||
153 | return i[0] # unpack() result is a 1-element tuple. | ||
154 | except struct.error, e: | ||
155 | raise message.DecodeError(e) | ||
156 | |||
157 | def ReadLittleEndian64(self): | ||
158 | """Interprets the next 8 bytes of the stream as a little-endian | ||
159 | encoded, unsiged 64-bit integer, and returns that integer. | ||
160 | """ | ||
161 | try: | ||
162 | i = struct.unpack(wire_format.FORMAT_UINT64_LITTLE_ENDIAN, | ||
163 | self._buffer[self._pos : self._pos + 8]) | ||
164 | self._pos += 8 | ||
165 | return i[0] # unpack() result is a 1-element tuple. | ||
166 | except struct.error, e: | ||
167 | raise message.DecodeError(e) | ||
168 | |||
169 | def ReadVarint32(self): | ||
170 | """Reads a varint from the stream, interprets this varint | ||
171 | as a signed, 32-bit integer, and returns the integer. | ||
172 | """ | ||
173 | i = self.ReadVarint64() | ||
174 | if not wire_format.INT32_MIN <= i <= wire_format.INT32_MAX: | ||
175 | raise message.DecodeError('Value out of range for int32: %d' % i) | ||
176 | return int(i) | ||
177 | |||
178 | def ReadVarUInt32(self): | ||
179 | """Reads a varint from the stream, interprets this varint | ||
180 | as an unsigned, 32-bit integer, and returns the integer. | ||
181 | """ | ||
182 | i = self.ReadVarUInt64() | ||
183 | if i > wire_format.UINT32_MAX: | ||
184 | raise message.DecodeError('Value out of range for uint32: %d' % i) | ||
185 | return i | ||
186 | |||
187 | def ReadVarint64(self): | ||
188 | """Reads a varint from the stream, interprets this varint | ||
189 | as a signed, 64-bit integer, and returns the integer. | ||
190 | """ | ||
191 | i = self.ReadVarUInt64() | ||
192 | if i > wire_format.INT64_MAX: | ||
193 | i -= (1 << 64) | ||
194 | return i | ||
195 | |||
196 | def ReadVarUInt64(self): | ||
197 | """Reads a varint from the stream, interprets this varint | ||
198 | as an unsigned, 64-bit integer, and returns the integer. | ||
199 | """ | ||
200 | i = self._ReadVarintHelper() | ||
201 | if not 0 <= i <= wire_format.UINT64_MAX: | ||
202 | raise message.DecodeError('Value out of range for uint64: %d' % i) | ||
203 | return i | ||
204 | |||
205 | def _ReadVarintHelper(self): | ||
206 | """Helper for the various varint-reading methods above. | ||
207 | Reads an unsigned, varint-encoded integer from the stream and | ||
208 | returns this integer. | ||
209 | |||
210 | Does no bounds checking except to ensure that we read at most as many bytes | ||
211 | as could possibly be present in a varint-encoded 64-bit number. | ||
212 | """ | ||
213 | result = 0 | ||
214 | shift = 0 | ||
215 | while 1: | ||
216 | if shift >= 64: | ||
217 | raise message.DecodeError('Too many bytes when decoding varint.') | ||
218 | try: | ||
219 | b = ord(self._buffer[self._pos]) | ||
220 | except IndexError: | ||
221 | raise message.DecodeError('Truncated varint.') | ||
222 | self._pos += 1 | ||
223 | result |= ((b & 0x7f) << shift) | ||
224 | shift += 7 | ||
225 | if not (b & 0x80): | ||
226 | return result | ||
227 | |||
228 | class InputStreamArray(object): | ||
229 | def __init__(self, s): | ||
230 | self._buffer = array('B', s) | ||
231 | self._pos = 0 | ||
232 | |||
233 | def EndOfStream(self): | ||
234 | return self._pos >= len(self._buffer) | ||
235 | |||
236 | def Position(self): | ||
237 | return self._pos | ||
238 | |||
239 | def GetSubBuffer(self, size=None): | ||
240 | if size is None: | ||
241 | return self._buffer[self._pos : ].tostring() | ||
242 | else: | ||
243 | if size < 0: | ||
244 | raise message.DecodeError('Negative size %d' % size) | ||
245 | return self._buffer[self._pos : self._pos + size].tostring() | ||
246 | |||
247 | def SkipBytes(self, num_bytes): | ||
248 | if num_bytes < 0: | ||
249 | raise message.DecodeError('Negative num_bytes %d' % num_bytes) | ||
250 | self._pos += num_bytes | ||
251 | self._pos = min(self._pos, len(self._buffer)) | ||
252 | |||
253 | def ReadBytes(self, size): | ||
254 | if size < 0: | ||
255 | raise message.DecodeError('Negative size %d' % size) | ||
256 | s = self._buffer[self._pos : self._pos + size].tostring() | ||
257 | self._pos += len(s) # Only advance by the number of bytes actually read. | ||
258 | return s | ||
259 | |||
260 | def ReadLittleEndian32(self): | ||
261 | try: | ||
262 | i = struct.unpack(wire_format.FORMAT_UINT32_LITTLE_ENDIAN, | ||
263 | self._buffer[self._pos : self._pos + 4]) | ||
264 | self._pos += 4 | ||
265 | return i[0] # unpack() result is a 1-element tuple. | ||
266 | except struct.error, e: | ||
267 | raise message.DecodeError(e) | ||
268 | |||
269 | def ReadLittleEndian64(self): | ||
270 | try: | ||
271 | i = struct.unpack(wire_format.FORMAT_UINT64_LITTLE_ENDIAN, | ||
272 | self._buffer[self._pos : self._pos + 8]) | ||
273 | self._pos += 8 | ||
274 | return i[0] # unpack() result is a 1-element tuple. | ||
275 | except struct.error, e: | ||
276 | raise message.DecodeError(e) | ||
277 | |||
278 | def ReadVarint32(self): | ||
279 | i = self.ReadVarint64() | ||
280 | if not wire_format.INT32_MIN <= i <= wire_format.INT32_MAX: | ||
281 | raise message.DecodeError('Value out of range for int32: %d' % i) | ||
282 | return int(i) | ||
283 | |||
284 | def ReadVarUInt32(self): | ||
285 | i = self.ReadVarUInt64() | ||
286 | if i > wire_format.UINT32_MAX: | ||
287 | raise message.DecodeError('Value out of range for uint32: %d' % i) | ||
288 | return i | ||
289 | |||
290 | def ReadVarint64(self): | ||
291 | i = self.ReadVarUInt64() | ||
292 | if i > wire_format.INT64_MAX: | ||
293 | i -= (1 << 64) | ||
294 | return i | ||
295 | |||
296 | def ReadVarUInt64(self): | ||
297 | i = self._ReadVarintHelper() | ||
298 | if not 0 <= i <= wire_format.UINT64_MAX: | ||
299 | raise message.DecodeError('Value out of range for uint64: %d' % i) | ||
300 | return i | ||
301 | |||
302 | def _ReadVarintHelper(self): | ||
303 | result = 0 | ||
304 | shift = 0 | ||
305 | while 1: | ||
306 | if shift >= 64: | ||
307 | raise message.DecodeError('Too many bytes when decoding varint.') | ||
308 | try: | ||
309 | b = self._buffer[self._pos] | ||
310 | except IndexError: | ||
311 | raise message.DecodeError('Truncated varint.') | ||
312 | self._pos += 1 | ||
313 | result |= ((b & 0x7f) << shift) | ||
314 | shift += 7 | ||
315 | if not (b & 0x80): | ||
316 | return result | ||
317 | |||
318 | try: | ||
319 | buffer("") | ||
320 | InputStream = InputStreamBuffer | ||
321 | except NotImplementedError: | ||
322 | # Google App Engine: dev_appserver.py | ||
323 | InputStream = InputStreamArray | ||
324 | except RuntimeError: | ||
325 | # Google App Engine: production | ||
326 | InputStream = InputStreamArray | ||
diff --git a/froofle/protobuf/internal/message_listener.py b/froofle/protobuf/internal/message_listener.py deleted file mode 100644 index 43978952..00000000 --- a/froofle/protobuf/internal/message_listener.py +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
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 | """Defines a listener interface for observing certain | ||
32 | state transitions on Message objects. | ||
33 | |||
34 | Also defines a null implementation of this interface. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | |||
40 | class MessageListener(object): | ||
41 | |||
42 | """Listens for transitions to nonempty and for invalidations of cached | ||
43 | byte sizes. Meant to be registered via Message._SetListener(). | ||
44 | """ | ||
45 | |||
46 | def TransitionToNonempty(self): | ||
47 | """Called the *first* time that this message becomes nonempty. | ||
48 | Implementations are free (but not required) to call this method multiple | ||
49 | times after the message has become nonempty. | ||
50 | """ | ||
51 | raise NotImplementedError | ||
52 | |||
53 | def ByteSizeDirty(self): | ||
54 | """Called *every* time the cached byte size value | ||
55 | for this object is invalidated (transitions from being | ||
56 | "clean" to "dirty"). | ||
57 | """ | ||
58 | raise NotImplementedError | ||
59 | |||
60 | |||
61 | class NullMessageListener(object): | ||
62 | |||
63 | """No-op MessageListener implementation.""" | ||
64 | |||
65 | def TransitionToNonempty(self): | ||
66 | pass | ||
67 | |||
68 | def ByteSizeDirty(self): | ||
69 | pass | ||
diff --git a/froofle/protobuf/internal/output_stream.py b/froofle/protobuf/internal/output_stream.py deleted file mode 100644 index f62cd1c4..00000000 --- a/froofle/protobuf/internal/output_stream.py +++ /dev/null | |||
@@ -1,125 +0,0 @@ | |||
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 | """OutputStream is the primitive interface for sticking bits on the wire. | ||
32 | |||
33 | All protocol buffer serialization can be expressed in terms of | ||
34 | the OutputStream primitives provided here. | ||
35 | """ | ||
36 | |||
37 | __author__ = 'robinson@google.com (Will Robinson)' | ||
38 | |||
39 | import array | ||
40 | import struct | ||
41 | from froofle.protobuf import message | ||
42 | from froofle.protobuf.internal import wire_format | ||
43 | |||
44 | |||
45 | |||
46 | # Note that much of this code is ported from //net/proto/ProtocolBuffer, and | ||
47 | # that the interface is strongly inspired by CodedOutputStream from the C++ | ||
48 | # proto2 implementation. | ||
49 | |||
50 | |||
51 | class OutputStream(object): | ||
52 | |||
53 | """Contains all logic for writing bits, and ToString() to get the result.""" | ||
54 | |||
55 | def __init__(self): | ||
56 | self._buffer = array.array('B') | ||
57 | |||
58 | def AppendRawBytes(self, raw_bytes): | ||
59 | """Appends raw_bytes to our internal buffer.""" | ||
60 | self._buffer.fromstring(raw_bytes) | ||
61 | |||
62 | def AppendLittleEndian32(self, unsigned_value): | ||
63 | """Appends an unsigned 32-bit integer to the internal buffer, | ||
64 | in little-endian byte order. | ||
65 | """ | ||
66 | if not 0 <= unsigned_value <= wire_format.UINT32_MAX: | ||
67 | raise message.EncodeError( | ||
68 | 'Unsigned 32-bit out of range: %d' % unsigned_value) | ||
69 | self._buffer.fromstring(struct.pack( | ||
70 | wire_format.FORMAT_UINT32_LITTLE_ENDIAN, unsigned_value)) | ||
71 | |||
72 | def AppendLittleEndian64(self, unsigned_value): | ||
73 | """Appends an unsigned 64-bit integer to the internal buffer, | ||
74 | in little-endian byte order. | ||
75 | """ | ||
76 | if not 0 <= unsigned_value <= wire_format.UINT64_MAX: | ||
77 | raise message.EncodeError( | ||
78 | 'Unsigned 64-bit out of range: %d' % unsigned_value) | ||
79 | self._buffer.fromstring(struct.pack( | ||
80 | wire_format.FORMAT_UINT64_LITTLE_ENDIAN, unsigned_value)) | ||
81 | |||
82 | def AppendVarint32(self, value): | ||
83 | """Appends a signed 32-bit integer to the internal buffer, | ||
84 | encoded as a varint. (Note that a negative varint32 will | ||
85 | always require 10 bytes of space.) | ||
86 | """ | ||
87 | if not wire_format.INT32_MIN <= value <= wire_format.INT32_MAX: | ||
88 | raise message.EncodeError('Value out of range: %d' % value) | ||
89 | self.AppendVarint64(value) | ||
90 | |||
91 | def AppendVarUInt32(self, value): | ||
92 | """Appends an unsigned 32-bit integer to the internal buffer, | ||
93 | encoded as a varint. | ||
94 | """ | ||
95 | if not 0 <= value <= wire_format.UINT32_MAX: | ||
96 | raise message.EncodeError('Value out of range: %d' % value) | ||
97 | self.AppendVarUInt64(value) | ||
98 | |||
99 | def AppendVarint64(self, value): | ||
100 | """Appends a signed 64-bit integer to the internal buffer, | ||
101 | encoded as a varint. | ||
102 | """ | ||
103 | if not wire_format.INT64_MIN <= value <= wire_format.INT64_MAX: | ||
104 | raise message.EncodeError('Value out of range: %d' % value) | ||
105 | if value < 0: | ||
106 | value += (1 << 64) | ||
107 | self.AppendVarUInt64(value) | ||
108 | |||
109 | def AppendVarUInt64(self, unsigned_value): | ||
110 | """Appends an unsigned 64-bit integer to the internal buffer, | ||
111 | encoded as a varint. | ||
112 | """ | ||
113 | if not 0 <= unsigned_value <= wire_format.UINT64_MAX: | ||
114 | raise message.EncodeError('Value out of range: %d' % unsigned_value) | ||
115 | while True: | ||
116 | bits = unsigned_value & 0x7f | ||
117 | unsigned_value >>= 7 | ||
118 | if not unsigned_value: | ||
119 | self._buffer.append(bits) | ||
120 | break | ||
121 | self._buffer.append(0x80|bits) | ||
122 | |||
123 | def ToString(self): | ||
124 | """Returns a string containing the bytes in our internal buffer.""" | ||
125 | return self._buffer.tostring() | ||
diff --git a/froofle/protobuf/internal/type_checkers.py b/froofle/protobuf/internal/type_checkers.py deleted file mode 100644 index aaf7a844..00000000 --- a/froofle/protobuf/internal/type_checkers.py +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
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 | """Provides type checking routines. | ||
32 | |||
33 | This module defines type checking utilities in the forms of dictionaries: | ||
34 | |||
35 | VALUE_CHECKERS: A dictionary of field types and a value validation object. | ||
36 | TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing | ||
37 | function. | ||
38 | TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization | ||
39 | function. | ||
40 | FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their | ||
41 | coresponding wire types. | ||
42 | TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization | ||
43 | function. | ||
44 | """ | ||
45 | |||
46 | __author__ = 'robinson@google.com (Will Robinson)' | ||
47 | |||
48 | from froofle.protobuf.internal import decoder | ||
49 | from froofle.protobuf.internal import encoder | ||
50 | from froofle.protobuf.internal import wire_format | ||
51 | from froofle.protobuf import descriptor | ||
52 | |||
53 | _FieldDescriptor = descriptor.FieldDescriptor | ||
54 | |||
55 | |||
56 | def GetTypeChecker(cpp_type, field_type): | ||
57 | """Returns a type checker for a message field of the specified types. | ||
58 | |||
59 | Args: | ||
60 | cpp_type: C++ type of the field (see descriptor.py). | ||
61 | field_type: Protocol message field type (see descriptor.py). | ||
62 | |||
63 | Returns: | ||
64 | An instance of TypeChecker which can be used to verify the types | ||
65 | of values assigned to a field of the specified type. | ||
66 | """ | ||
67 | if (cpp_type == _FieldDescriptor.CPPTYPE_STRING and | ||
68 | field_type == _FieldDescriptor.TYPE_STRING): | ||
69 | return UnicodeValueChecker() | ||
70 | return _VALUE_CHECKERS[cpp_type] | ||
71 | |||
72 | |||
73 | # None of the typecheckers below make any attempt to guard against people | ||
74 | # subclassing builtin types and doing weird things. We're not trying to | ||
75 | # protect against malicious clients here, just people accidentally shooting | ||
76 | # themselves in the foot in obvious ways. | ||
77 | |||
78 | class TypeChecker(object): | ||
79 | |||
80 | """Type checker used to catch type errors as early as possible | ||
81 | when the client is setting scalar fields in protocol messages. | ||
82 | """ | ||
83 | |||
84 | def __init__(self, *acceptable_types): | ||
85 | self._acceptable_types = acceptable_types | ||
86 | |||
87 | def CheckValue(self, proposed_value): | ||
88 | if not isinstance(proposed_value, self._acceptable_types): | ||
89 | message = ('%.1024r has type %s, but expected one of: %s' % | ||
90 | (proposed_value, type(proposed_value), self._acceptable_types)) | ||
91 | raise TypeError(message) | ||
92 | |||
93 | |||
94 | # IntValueChecker and its subclasses perform integer type-checks | ||
95 | # and bounds-checks. | ||
96 | class IntValueChecker(object): | ||
97 | |||
98 | """Checker used for integer fields. Performs type-check and range check.""" | ||
99 | |||
100 | def CheckValue(self, proposed_value): | ||
101 | if not isinstance(proposed_value, (int, long)): | ||
102 | message = ('%.1024r has type %s, but expected one of: %s' % | ||
103 | (proposed_value, type(proposed_value), (int, long))) | ||
104 | raise TypeError(message) | ||
105 | if not self._MIN <= proposed_value <= self._MAX: | ||
106 | raise ValueError('Value out of range: %d' % proposed_value) | ||
107 | |||
108 | |||
109 | class UnicodeValueChecker(object): | ||
110 | |||
111 | """Checker used for string fields.""" | ||
112 | |||
113 | def CheckValue(self, proposed_value): | ||
114 | if not isinstance(proposed_value, (str, unicode)): | ||
115 | message = ('%.1024r has type %s, but expected one of: %s' % | ||
116 | (proposed_value, type(proposed_value), (str, unicode))) | ||
117 | raise TypeError(message) | ||
118 | |||
119 | # If the value is of type 'str' make sure that it is in 7-bit ASCII | ||
120 | # encoding. | ||
121 | if isinstance(proposed_value, str): | ||
122 | try: | ||
123 | unicode(proposed_value, 'ascii') | ||
124 | except UnicodeDecodeError: | ||
125 | raise ValueError('%.1024r isn\'t in 7-bit ASCII encoding.' | ||
126 | % (proposed_value)) | ||
127 | |||
128 | |||
129 | class Int32ValueChecker(IntValueChecker): | ||
130 | # We're sure to use ints instead of longs here since comparison may be more | ||
131 | # efficient. | ||
132 | _MIN = -2147483648 | ||
133 | _MAX = 2147483647 | ||
134 | |||
135 | |||
136 | class Uint32ValueChecker(IntValueChecker): | ||
137 | _MIN = 0 | ||
138 | _MAX = (1 << 32) - 1 | ||
139 | |||
140 | |||
141 | class Int64ValueChecker(IntValueChecker): | ||
142 | _MIN = -(1 << 63) | ||
143 | _MAX = (1 << 63) - 1 | ||
144 | |||
145 | |||
146 | class Uint64ValueChecker(IntValueChecker): | ||
147 | _MIN = 0 | ||
148 | _MAX = (1 << 64) - 1 | ||
149 | |||
150 | |||
151 | # Type-checkers for all scalar CPPTYPEs. | ||
152 | _VALUE_CHECKERS = { | ||
153 | _FieldDescriptor.CPPTYPE_INT32: Int32ValueChecker(), | ||
154 | _FieldDescriptor.CPPTYPE_INT64: Int64ValueChecker(), | ||
155 | _FieldDescriptor.CPPTYPE_UINT32: Uint32ValueChecker(), | ||
156 | _FieldDescriptor.CPPTYPE_UINT64: Uint64ValueChecker(), | ||
157 | _FieldDescriptor.CPPTYPE_DOUBLE: TypeChecker( | ||
158 | float, int, long), | ||
159 | _FieldDescriptor.CPPTYPE_FLOAT: TypeChecker( | ||
160 | float, int, long), | ||
161 | _FieldDescriptor.CPPTYPE_BOOL: TypeChecker(bool, int), | ||
162 | _FieldDescriptor.CPPTYPE_ENUM: Int32ValueChecker(), | ||
163 | _FieldDescriptor.CPPTYPE_STRING: TypeChecker(str), | ||
164 | } | ||
165 | |||
166 | |||
167 | # Map from field type to a function F, such that F(field_num, value) | ||
168 | # gives the total byte size for a value of the given type. This | ||
169 | # byte size includes tag information and any other additional space | ||
170 | # associated with serializing "value". | ||
171 | TYPE_TO_BYTE_SIZE_FN = { | ||
172 | _FieldDescriptor.TYPE_DOUBLE: wire_format.DoubleByteSize, | ||
173 | _FieldDescriptor.TYPE_FLOAT: wire_format.FloatByteSize, | ||
174 | _FieldDescriptor.TYPE_INT64: wire_format.Int64ByteSize, | ||
175 | _FieldDescriptor.TYPE_UINT64: wire_format.UInt64ByteSize, | ||
176 | _FieldDescriptor.TYPE_INT32: wire_format.Int32ByteSize, | ||
177 | _FieldDescriptor.TYPE_FIXED64: wire_format.Fixed64ByteSize, | ||
178 | _FieldDescriptor.TYPE_FIXED32: wire_format.Fixed32ByteSize, | ||
179 | _FieldDescriptor.TYPE_BOOL: wire_format.BoolByteSize, | ||
180 | _FieldDescriptor.TYPE_STRING: wire_format.StringByteSize, | ||
181 | _FieldDescriptor.TYPE_GROUP: wire_format.GroupByteSize, | ||
182 | _FieldDescriptor.TYPE_MESSAGE: wire_format.MessageByteSize, | ||
183 | _FieldDescriptor.TYPE_BYTES: wire_format.BytesByteSize, | ||
184 | _FieldDescriptor.TYPE_UINT32: wire_format.UInt32ByteSize, | ||
185 | _FieldDescriptor.TYPE_ENUM: wire_format.EnumByteSize, | ||
186 | _FieldDescriptor.TYPE_SFIXED32: wire_format.SFixed32ByteSize, | ||
187 | _FieldDescriptor.TYPE_SFIXED64: wire_format.SFixed64ByteSize, | ||
188 | _FieldDescriptor.TYPE_SINT32: wire_format.SInt32ByteSize, | ||
189 | _FieldDescriptor.TYPE_SINT64: wire_format.SInt64ByteSize | ||
190 | } | ||
191 | |||
192 | |||
193 | # Maps from field type to an unbound Encoder method F, such that | ||
194 | # F(encoder, field_number, value) will append the serialization | ||
195 | # of a value of this type to the encoder. | ||
196 | _Encoder = encoder.Encoder | ||
197 | TYPE_TO_SERIALIZE_METHOD = { | ||
198 | _FieldDescriptor.TYPE_DOUBLE: _Encoder.AppendDouble, | ||
199 | _FieldDescriptor.TYPE_FLOAT: _Encoder.AppendFloat, | ||
200 | _FieldDescriptor.TYPE_INT64: _Encoder.AppendInt64, | ||
201 | _FieldDescriptor.TYPE_UINT64: _Encoder.AppendUInt64, | ||
202 | _FieldDescriptor.TYPE_INT32: _Encoder.AppendInt32, | ||
203 | _FieldDescriptor.TYPE_FIXED64: _Encoder.AppendFixed64, | ||
204 | _FieldDescriptor.TYPE_FIXED32: _Encoder.AppendFixed32, | ||
205 | _FieldDescriptor.TYPE_BOOL: _Encoder.AppendBool, | ||
206 | _FieldDescriptor.TYPE_STRING: _Encoder.AppendString, | ||
207 | _FieldDescriptor.TYPE_GROUP: _Encoder.AppendGroup, | ||
208 | _FieldDescriptor.TYPE_MESSAGE: _Encoder.AppendMessage, | ||
209 | _FieldDescriptor.TYPE_BYTES: _Encoder.AppendBytes, | ||
210 | _FieldDescriptor.TYPE_UINT32: _Encoder.AppendUInt32, | ||
211 | _FieldDescriptor.TYPE_ENUM: _Encoder.AppendEnum, | ||
212 | _FieldDescriptor.TYPE_SFIXED32: _Encoder.AppendSFixed32, | ||
213 | _FieldDescriptor.TYPE_SFIXED64: _Encoder.AppendSFixed64, | ||
214 | _FieldDescriptor.TYPE_SINT32: _Encoder.AppendSInt32, | ||
215 | _FieldDescriptor.TYPE_SINT64: _Encoder.AppendSInt64, | ||
216 | } | ||
217 | |||
218 | |||
219 | # Maps from field type to expected wiretype. | ||
220 | FIELD_TYPE_TO_WIRE_TYPE = { | ||
221 | _FieldDescriptor.TYPE_DOUBLE: wire_format.WIRETYPE_FIXED64, | ||
222 | _FieldDescriptor.TYPE_FLOAT: wire_format.WIRETYPE_FIXED32, | ||
223 | _FieldDescriptor.TYPE_INT64: wire_format.WIRETYPE_VARINT, | ||
224 | _FieldDescriptor.TYPE_UINT64: wire_format.WIRETYPE_VARINT, | ||
225 | _FieldDescriptor.TYPE_INT32: wire_format.WIRETYPE_VARINT, | ||
226 | _FieldDescriptor.TYPE_FIXED64: wire_format.WIRETYPE_FIXED64, | ||
227 | _FieldDescriptor.TYPE_FIXED32: wire_format.WIRETYPE_FIXED32, | ||
228 | _FieldDescriptor.TYPE_BOOL: wire_format.WIRETYPE_VARINT, | ||
229 | _FieldDescriptor.TYPE_STRING: | ||
230 | wire_format.WIRETYPE_LENGTH_DELIMITED, | ||
231 | _FieldDescriptor.TYPE_GROUP: wire_format.WIRETYPE_START_GROUP, | ||
232 | _FieldDescriptor.TYPE_MESSAGE: | ||
233 | wire_format.WIRETYPE_LENGTH_DELIMITED, | ||
234 | _FieldDescriptor.TYPE_BYTES: | ||
235 | wire_format.WIRETYPE_LENGTH_DELIMITED, | ||
236 | _FieldDescriptor.TYPE_UINT32: wire_format.WIRETYPE_VARINT, | ||
237 | _FieldDescriptor.TYPE_ENUM: wire_format.WIRETYPE_VARINT, | ||
238 | _FieldDescriptor.TYPE_SFIXED32: wire_format.WIRETYPE_FIXED32, | ||
239 | _FieldDescriptor.TYPE_SFIXED64: wire_format.WIRETYPE_FIXED64, | ||
240 | _FieldDescriptor.TYPE_SINT32: wire_format.WIRETYPE_VARINT, | ||
241 | _FieldDescriptor.TYPE_SINT64: wire_format.WIRETYPE_VARINT, | ||
242 | } | ||
243 | |||
244 | |||
245 | # Maps from field type to an unbound Decoder method F, | ||
246 | # such that F(decoder) will read a field of the requested type. | ||
247 | # | ||
248 | # Note that Message and Group are intentionally missing here. | ||
249 | # They're handled by _RecursivelyMerge(). | ||
250 | _Decoder = decoder.Decoder | ||
251 | TYPE_TO_DESERIALIZE_METHOD = { | ||
252 | _FieldDescriptor.TYPE_DOUBLE: _Decoder.ReadDouble, | ||
253 | _FieldDescriptor.TYPE_FLOAT: _Decoder.ReadFloat, | ||
254 | _FieldDescriptor.TYPE_INT64: _Decoder.ReadInt64, | ||
255 | _FieldDescriptor.TYPE_UINT64: _Decoder.ReadUInt64, | ||
256 | _FieldDescriptor.TYPE_INT32: _Decoder.ReadInt32, | ||
257 | _FieldDescriptor.TYPE_FIXED64: _Decoder.ReadFixed64, | ||
258 | _FieldDescriptor.TYPE_FIXED32: _Decoder.ReadFixed32, | ||
259 | _FieldDescriptor.TYPE_BOOL: _Decoder.ReadBool, | ||
260 | _FieldDescriptor.TYPE_STRING: _Decoder.ReadString, | ||
261 | _FieldDescriptor.TYPE_BYTES: _Decoder.ReadBytes, | ||
262 | _FieldDescriptor.TYPE_UINT32: _Decoder.ReadUInt32, | ||
263 | _FieldDescriptor.TYPE_ENUM: _Decoder.ReadEnum, | ||
264 | _FieldDescriptor.TYPE_SFIXED32: _Decoder.ReadSFixed32, | ||
265 | _FieldDescriptor.TYPE_SFIXED64: _Decoder.ReadSFixed64, | ||
266 | _FieldDescriptor.TYPE_SINT32: _Decoder.ReadSInt32, | ||
267 | _FieldDescriptor.TYPE_SINT64: _Decoder.ReadSInt64, | ||
268 | } | ||
diff --git a/froofle/protobuf/internal/wire_format.py b/froofle/protobuf/internal/wire_format.py deleted file mode 100644 index 4d823c8d..00000000 --- a/froofle/protobuf/internal/wire_format.py +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
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 | """Constants and static functions to support protocol buffer wire format.""" | ||
32 | |||
33 | __author__ = 'robinson@google.com (Will Robinson)' | ||
34 | |||
35 | import struct | ||
36 | from froofle.protobuf import message | ||
37 | |||
38 | |||
39 | TAG_TYPE_BITS = 3 # Number of bits used to hold type info in a proto tag. | ||
40 | _TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1 # 0x7 | ||
41 | |||
42 | # These numbers identify the wire type of a protocol buffer value. | ||
43 | # We use the least-significant TAG_TYPE_BITS bits of the varint-encoded | ||
44 | # tag-and-type to store one of these WIRETYPE_* constants. | ||
45 | # These values must match WireType enum in //net/proto2/public/wire_format.h. | ||
46 | WIRETYPE_VARINT = 0 | ||
47 | WIRETYPE_FIXED64 = 1 | ||
48 | WIRETYPE_LENGTH_DELIMITED = 2 | ||
49 | WIRETYPE_START_GROUP = 3 | ||
50 | WIRETYPE_END_GROUP = 4 | ||
51 | WIRETYPE_FIXED32 = 5 | ||
52 | _WIRETYPE_MAX = 5 | ||
53 | |||
54 | |||
55 | # Bounds for various integer types. | ||
56 | INT32_MAX = int((1 << 31) - 1) | ||
57 | INT32_MIN = int(-(1 << 31)) | ||
58 | UINT32_MAX = (1 << 32) - 1 | ||
59 | |||
60 | INT64_MAX = (1 << 63) - 1 | ||
61 | INT64_MIN = -(1 << 63) | ||
62 | UINT64_MAX = (1 << 64) - 1 | ||
63 | |||
64 | # "struct" format strings that will encode/decode the specified formats. | ||
65 | FORMAT_UINT32_LITTLE_ENDIAN = '<I' | ||
66 | FORMAT_UINT64_LITTLE_ENDIAN = '<Q' | ||
67 | |||
68 | |||
69 | # We'll have to provide alternate implementations of AppendLittleEndian*() on | ||
70 | # any architectures where these checks fail. | ||
71 | if struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4: | ||
72 | raise AssertionError('Format "I" is not a 32-bit number.') | ||
73 | if struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8: | ||
74 | raise AssertionError('Format "Q" is not a 64-bit number.') | ||
75 | |||
76 | |||
77 | def PackTag(field_number, wire_type): | ||
78 | """Returns an unsigned 32-bit integer that encodes the field number and | ||
79 | wire type information in standard protocol message wire format. | ||
80 | |||
81 | Args: | ||
82 | field_number: Expected to be an integer in the range [1, 1 << 29) | ||
83 | wire_type: One of the WIRETYPE_* constants. | ||
84 | """ | ||
85 | if not 0 <= wire_type <= _WIRETYPE_MAX: | ||
86 | raise message.EncodeError('Unknown wire type: %d' % wire_type) | ||
87 | return (field_number << TAG_TYPE_BITS) | wire_type | ||
88 | |||
89 | |||
90 | def UnpackTag(tag): | ||
91 | """The inverse of PackTag(). Given an unsigned 32-bit number, | ||
92 | returns a (field_number, wire_type) tuple. | ||
93 | """ | ||
94 | return (tag >> TAG_TYPE_BITS), (tag & _TAG_TYPE_MASK) | ||
95 | |||
96 | |||
97 | def ZigZagEncode(value): | ||
98 | """ZigZag Transform: Encodes signed integers so that they can be | ||
99 | effectively used with varint encoding. See wire_format.h for | ||
100 | more details. | ||
101 | """ | ||
102 | if value >= 0: | ||
103 | return value << 1 | ||
104 | return (value << 1) ^ (~0) | ||
105 | |||
106 | |||
107 | def ZigZagDecode(value): | ||
108 | """Inverse of ZigZagEncode().""" | ||
109 | if not value & 0x1: | ||
110 | return value >> 1 | ||
111 | return (value >> 1) ^ (~0) | ||
112 | |||
113 | |||
114 | |||
115 | # The *ByteSize() functions below return the number of bytes required to | ||
116 | # serialize "field number + type" information and then serialize the value. | ||
117 | |||
118 | |||
119 | def Int32ByteSize(field_number, int32): | ||
120 | return Int64ByteSize(field_number, int32) | ||
121 | |||
122 | |||
123 | def Int64ByteSize(field_number, int64): | ||
124 | # Have to convert to uint before calling UInt64ByteSize(). | ||
125 | return UInt64ByteSize(field_number, 0xffffffffffffffff & int64) | ||
126 | |||
127 | |||
128 | def UInt32ByteSize(field_number, uint32): | ||
129 | return UInt64ByteSize(field_number, uint32) | ||
130 | |||
131 | |||
132 | def UInt64ByteSize(field_number, uint64): | ||
133 | return _TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64) | ||
134 | |||
135 | |||
136 | def SInt32ByteSize(field_number, int32): | ||
137 | return UInt32ByteSize(field_number, ZigZagEncode(int32)) | ||
138 | |||
139 | |||
140 | def SInt64ByteSize(field_number, int64): | ||
141 | return UInt64ByteSize(field_number, ZigZagEncode(int64)) | ||
142 | |||
143 | |||
144 | def Fixed32ByteSize(field_number, fixed32): | ||
145 | return _TagByteSize(field_number) + 4 | ||
146 | |||
147 | |||
148 | def Fixed64ByteSize(field_number, fixed64): | ||
149 | return _TagByteSize(field_number) + 8 | ||
150 | |||
151 | |||
152 | def SFixed32ByteSize(field_number, sfixed32): | ||
153 | return _TagByteSize(field_number) + 4 | ||
154 | |||
155 | |||
156 | def SFixed64ByteSize(field_number, sfixed64): | ||
157 | return _TagByteSize(field_number) + 8 | ||
158 | |||
159 | |||
160 | def FloatByteSize(field_number, flt): | ||
161 | return _TagByteSize(field_number) + 4 | ||
162 | |||
163 | |||
164 | def DoubleByteSize(field_number, double): | ||
165 | return _TagByteSize(field_number) + 8 | ||
166 | |||
167 | |||
168 | def BoolByteSize(field_number, b): | ||
169 | return _TagByteSize(field_number) + 1 | ||
170 | |||
171 | |||
172 | def EnumByteSize(field_number, enum): | ||
173 | return UInt32ByteSize(field_number, enum) | ||
174 | |||
175 | |||
176 | def StringByteSize(field_number, string): | ||
177 | return BytesByteSize(field_number, string.encode('utf-8')) | ||
178 | |||
179 | |||
180 | def BytesByteSize(field_number, b): | ||
181 | return (_TagByteSize(field_number) | ||
182 | + _VarUInt64ByteSizeNoTag(len(b)) | ||
183 | + len(b)) | ||
184 | |||
185 | |||
186 | def GroupByteSize(field_number, message): | ||
187 | return (2 * _TagByteSize(field_number) # START and END group. | ||
188 | + message.ByteSize()) | ||
189 | |||
190 | |||
191 | def MessageByteSize(field_number, message): | ||
192 | return (_TagByteSize(field_number) | ||
193 | + _VarUInt64ByteSizeNoTag(message.ByteSize()) | ||
194 | + message.ByteSize()) | ||
195 | |||
196 | |||
197 | def MessageSetItemByteSize(field_number, msg): | ||
198 | # First compute the sizes of the tags. | ||
199 | # There are 2 tags for the beginning and ending of the repeated group, that | ||
200 | # is field number 1, one with field number 2 (type_id) and one with field | ||
201 | # number 3 (message). | ||
202 | total_size = (2 * _TagByteSize(1) + _TagByteSize(2) + _TagByteSize(3)) | ||
203 | |||
204 | # Add the number of bytes for type_id. | ||
205 | total_size += _VarUInt64ByteSizeNoTag(field_number) | ||
206 | |||
207 | message_size = msg.ByteSize() | ||
208 | |||
209 | # The number of bytes for encoding the length of the message. | ||
210 | total_size += _VarUInt64ByteSizeNoTag(message_size) | ||
211 | |||
212 | # The size of the message. | ||
213 | total_size += message_size | ||
214 | return total_size | ||
215 | |||
216 | |||
217 | # Private helper functions for the *ByteSize() functions above. | ||
218 | |||
219 | |||
220 | def _TagByteSize(field_number): | ||
221 | """Returns the bytes required to serialize a tag with this field number.""" | ||
222 | # Just pass in type 0, since the type won't affect the tag+type size. | ||
223 | return _VarUInt64ByteSizeNoTag(PackTag(field_number, 0)) | ||
224 | |||
225 | |||
226 | def _VarUInt64ByteSizeNoTag(uint64): | ||
227 | """Returns the bytes required to serialize a single varint. | ||
228 | uint64 must be unsigned. | ||
229 | """ | ||
230 | if uint64 > UINT64_MAX: | ||
231 | raise message.EncodeError('Value out of range: %d' % uint64) | ||
232 | bytes = 1 | ||
233 | while uint64 > 0x7f: | ||
234 | bytes += 1 | ||
235 | uint64 >>= 7 | ||
236 | return bytes | ||