summaryrefslogtreecommitdiffstats
path: root/froofle/protobuf/internal
diff options
context:
space:
mode:
Diffstat (limited to 'froofle/protobuf/internal')
-rw-r--r--froofle/protobuf/internal/__init__.py0
-rw-r--r--froofle/protobuf/internal/decoder.py209
-rw-r--r--froofle/protobuf/internal/encoder.py206
-rw-r--r--froofle/protobuf/internal/input_stream.py326
-rw-r--r--froofle/protobuf/internal/message_listener.py69
-rw-r--r--froofle/protobuf/internal/output_stream.py125
-rw-r--r--froofle/protobuf/internal/type_checkers.py268
-rw-r--r--froofle/protobuf/internal/wire_format.py236
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
33Contains the logic for decoding every logical protocol field type
34from one of the 5 physical wire types.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import struct
40from froofle.protobuf import message
41from froofle.protobuf.internal import input_stream
42from 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
51class 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
33Contains the logic for encoding every logical protocol field type
34into one of the 5 physical wire types.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import struct
40from froofle.protobuf import message
41from froofle.protobuf.internal import wire_format
42from 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
50class 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
33All protocol buffer deserialization can be expressed in terms of
34the InputStream primitives provided here.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import struct
40from array import array
41from froofle.protobuf import message
42from 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
50class 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
228class 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
318try:
319 buffer("")
320 InputStream = InputStreamBuffer
321except NotImplementedError:
322 # Google App Engine: dev_appserver.py
323 InputStream = InputStreamArray
324except 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
32state transitions on Message objects.
33
34Also defines a null implementation of this interface.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39
40class 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
61class 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
33All protocol buffer serialization can be expressed in terms of
34the OutputStream primitives provided here.
35"""
36
37__author__ = 'robinson@google.com (Will Robinson)'
38
39import array
40import struct
41from froofle.protobuf import message
42from 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
51class 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
33This module defines type checking utilities in the forms of dictionaries:
34
35VALUE_CHECKERS: A dictionary of field types and a value validation object.
36TYPE_TO_BYTE_SIZE_FN: A dictionary with field types and a size computing
37 function.
38TYPE_TO_SERIALIZE_METHOD: A dictionary with field types and serialization
39 function.
40FIELD_TYPE_TO_WIRE_TYPE: A dictionary with field typed and their
41 coresponding wire types.
42TYPE_TO_DESERIALIZE_METHOD: A dictionary with field types and deserialization
43 function.
44"""
45
46__author__ = 'robinson@google.com (Will Robinson)'
47
48from froofle.protobuf.internal import decoder
49from froofle.protobuf.internal import encoder
50from froofle.protobuf.internal import wire_format
51from froofle.protobuf import descriptor
52
53_FieldDescriptor = descriptor.FieldDescriptor
54
55
56def 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
78class 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.
96class 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
109class 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
129class 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
136class Uint32ValueChecker(IntValueChecker):
137 _MIN = 0
138 _MAX = (1 << 32) - 1
139
140
141class Int64ValueChecker(IntValueChecker):
142 _MIN = -(1 << 63)
143 _MAX = (1 << 63) - 1
144
145
146class 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".
171TYPE_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
197TYPE_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.
220FIELD_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
251TYPE_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
35import struct
36from froofle.protobuf import message
37
38
39TAG_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.
46WIRETYPE_VARINT = 0
47WIRETYPE_FIXED64 = 1
48WIRETYPE_LENGTH_DELIMITED = 2
49WIRETYPE_START_GROUP = 3
50WIRETYPE_END_GROUP = 4
51WIRETYPE_FIXED32 = 5
52_WIRETYPE_MAX = 5
53
54
55# Bounds for various integer types.
56INT32_MAX = int((1 << 31) - 1)
57INT32_MIN = int(-(1 << 31))
58UINT32_MAX = (1 << 32) - 1
59
60INT64_MAX = (1 << 63) - 1
61INT64_MIN = -(1 << 63)
62UINT64_MAX = (1 << 64) - 1
63
64# "struct" format strings that will encode/decode the specified formats.
65FORMAT_UINT32_LITTLE_ENDIAN = '<I'
66FORMAT_UINT64_LITTLE_ENDIAN = '<Q'
67
68
69# We'll have to provide alternate implementations of AppendLittleEndian*() on
70# any architectures where these checks fail.
71if struct.calcsize(FORMAT_UINT32_LITTLE_ENDIAN) != 4:
72 raise AssertionError('Format "I" is not a 32-bit number.')
73if struct.calcsize(FORMAT_UINT64_LITTLE_ENDIAN) != 8:
74 raise AssertionError('Format "Q" is not a 64-bit number.')
75
76
77def 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
90def 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
97def 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
107def 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
119def Int32ByteSize(field_number, int32):
120 return Int64ByteSize(field_number, int32)
121
122
123def Int64ByteSize(field_number, int64):
124 # Have to convert to uint before calling UInt64ByteSize().
125 return UInt64ByteSize(field_number, 0xffffffffffffffff & int64)
126
127
128def UInt32ByteSize(field_number, uint32):
129 return UInt64ByteSize(field_number, uint32)
130
131
132def UInt64ByteSize(field_number, uint64):
133 return _TagByteSize(field_number) + _VarUInt64ByteSizeNoTag(uint64)
134
135
136def SInt32ByteSize(field_number, int32):
137 return UInt32ByteSize(field_number, ZigZagEncode(int32))
138
139
140def SInt64ByteSize(field_number, int64):
141 return UInt64ByteSize(field_number, ZigZagEncode(int64))
142
143
144def Fixed32ByteSize(field_number, fixed32):
145 return _TagByteSize(field_number) + 4
146
147
148def Fixed64ByteSize(field_number, fixed64):
149 return _TagByteSize(field_number) + 8
150
151
152def SFixed32ByteSize(field_number, sfixed32):
153 return _TagByteSize(field_number) + 4
154
155
156def SFixed64ByteSize(field_number, sfixed64):
157 return _TagByteSize(field_number) + 8
158
159
160def FloatByteSize(field_number, flt):
161 return _TagByteSize(field_number) + 4
162
163
164def DoubleByteSize(field_number, double):
165 return _TagByteSize(field_number) + 8
166
167
168def BoolByteSize(field_number, b):
169 return _TagByteSize(field_number) + 1
170
171
172def EnumByteSize(field_number, enum):
173 return UInt32ByteSize(field_number, enum)
174
175
176def StringByteSize(field_number, string):
177 return BytesByteSize(field_number, string.encode('utf-8'))
178
179
180def BytesByteSize(field_number, b):
181 return (_TagByteSize(field_number)
182 + _VarUInt64ByteSizeNoTag(len(b))
183 + len(b))
184
185
186def GroupByteSize(field_number, message):
187 return (2 * _TagByteSize(field_number) # START and END group.
188 + message.ByteSize())
189
190
191def MessageByteSize(field_number, message):
192 return (_TagByteSize(field_number)
193 + _VarUInt64ByteSizeNoTag(message.ByteSize())
194 + message.ByteSize())
195
196
197def 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
220def _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
226def _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