3 # Protocol Buffers - Google's data interchange format
4 # Copyright 2008 Google Inc. All rights reserved.
5 # http://code.google.com/p/protobuf/
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are
11 # * Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following disclaimer
15 # in the documentation and/or other materials provided with the
17 # * Neither the name of Google Inc. nor the names of its
18 # contributors may be used to endorse or promote products derived from
19 # this software without specific prior written permission.
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 """Test for google.protobuf.internal.wire_format."""
35 __author__ = 'robinson@google.com (Will Robinson)'
38 from google.protobuf import message
39 from google.protobuf.internal import wire_format
42 class WireFormatTest(unittest.TestCase):
44 def testPackTag(self):
47 self.assertEqual((field_number << 3) | tag_type,
48 wire_format.PackTag(field_number, tag_type))
49 PackTag = wire_format.PackTag
51 self.assertRaises(message.EncodeError, PackTag, field_number, 6)
53 self.assertRaises(message.EncodeError, PackTag, field_number, -1)
55 def testUnpackTag(self):
56 # Test field numbers that will require various varint sizes.
57 for expected_field_number in (1, 15, 16, 2047, 2048):
58 for expected_wire_type in range(6): # Highest-numbered wiretype is 5.
59 field_number, wire_type = wire_format.UnpackTag(
60 wire_format.PackTag(expected_field_number, expected_wire_type))
61 self.assertEqual(expected_field_number, field_number)
62 self.assertEqual(expected_wire_type, wire_type)
64 self.assertRaises(TypeError, wire_format.UnpackTag, None)
65 self.assertRaises(TypeError, wire_format.UnpackTag, 'abc')
66 self.assertRaises(TypeError, wire_format.UnpackTag, 0.0)
67 self.assertRaises(TypeError, wire_format.UnpackTag, object())
69 def testZigZagEncode(self):
70 Z = wire_format.ZigZagEncode
71 self.assertEqual(0, Z(0))
72 self.assertEqual(1, Z(-1))
73 self.assertEqual(2, Z(1))
74 self.assertEqual(3, Z(-2))
75 self.assertEqual(4, Z(2))
76 self.assertEqual(0xfffffffe, Z(0x7fffffff))
77 self.assertEqual(0xffffffff, Z(-0x80000000))
78 self.assertEqual(0xfffffffffffffffe, Z(0x7fffffffffffffff))
79 self.assertEqual(0xffffffffffffffff, Z(-0x8000000000000000))
81 self.assertRaises(TypeError, Z, None)
82 self.assertRaises(TypeError, Z, 'abcd')
83 self.assertRaises(TypeError, Z, 0.0)
84 self.assertRaises(TypeError, Z, object())
86 def testZigZagDecode(self):
87 Z = wire_format.ZigZagDecode
88 self.assertEqual(0, Z(0))
89 self.assertEqual(-1, Z(1))
90 self.assertEqual(1, Z(2))
91 self.assertEqual(-2, Z(3))
92 self.assertEqual(2, Z(4))
93 self.assertEqual(0x7fffffff, Z(0xfffffffe))
94 self.assertEqual(-0x80000000, Z(0xffffffff))
95 self.assertEqual(0x7fffffffffffffff, Z(0xfffffffffffffffe))
96 self.assertEqual(-0x8000000000000000, Z(0xffffffffffffffff))
98 self.assertRaises(TypeError, Z, None)
99 self.assertRaises(TypeError, Z, 'abcd')
100 self.assertRaises(TypeError, Z, 0.0)
101 self.assertRaises(TypeError, Z, object())
103 def NumericByteSizeTestHelper(self, byte_size_fn, value, expected_value_size):
104 # Use field numbers that cause various byte sizes for the tag information.
105 for field_number, tag_bytes in ((15, 1), (16, 2), (2047, 2), (2048, 3)):
106 expected_size = expected_value_size + tag_bytes
107 actual_size = byte_size_fn(field_number, value)
108 self.assertEqual(expected_size, actual_size,
109 'byte_size_fn: %s, field_number: %d, value: %r\n'
110 'Expected: %d, Actual: %d'% (
111 byte_size_fn, field_number, value, expected_size, actual_size))
113 def testByteSizeFunctions(self):
114 # Test all numeric *ByteSize() functions.
117 [wire_format.Int32ByteSize, 0, 1],
118 [wire_format.Int32ByteSize, 127, 1],
119 [wire_format.Int32ByteSize, 128, 2],
120 [wire_format.Int32ByteSize, -1, 10],
122 [wire_format.Int64ByteSize, 0, 1],
123 [wire_format.Int64ByteSize, 127, 1],
124 [wire_format.Int64ByteSize, 128, 2],
125 [wire_format.Int64ByteSize, -1, 10],
127 [wire_format.UInt32ByteSize, 0, 1],
128 [wire_format.UInt32ByteSize, 127, 1],
129 [wire_format.UInt32ByteSize, 128, 2],
130 [wire_format.UInt32ByteSize, wire_format.UINT32_MAX, 5],
132 [wire_format.UInt64ByteSize, 0, 1],
133 [wire_format.UInt64ByteSize, 127, 1],
134 [wire_format.UInt64ByteSize, 128, 2],
135 [wire_format.UInt64ByteSize, wire_format.UINT64_MAX, 10],
137 [wire_format.SInt32ByteSize, 0, 1],
138 [wire_format.SInt32ByteSize, -1, 1],
139 [wire_format.SInt32ByteSize, 1, 1],
140 [wire_format.SInt32ByteSize, -63, 1],
141 [wire_format.SInt32ByteSize, 63, 1],
142 [wire_format.SInt32ByteSize, -64, 1],
143 [wire_format.SInt32ByteSize, 64, 2],
145 [wire_format.SInt64ByteSize, 0, 1],
146 [wire_format.SInt64ByteSize, -1, 1],
147 [wire_format.SInt64ByteSize, 1, 1],
148 [wire_format.SInt64ByteSize, -63, 1],
149 [wire_format.SInt64ByteSize, 63, 1],
150 [wire_format.SInt64ByteSize, -64, 1],
151 [wire_format.SInt64ByteSize, 64, 2],
153 [wire_format.Fixed32ByteSize, 0, 4],
154 [wire_format.Fixed32ByteSize, wire_format.UINT32_MAX, 4],
156 [wire_format.Fixed64ByteSize, 0, 8],
157 [wire_format.Fixed64ByteSize, wire_format.UINT64_MAX, 8],
158 # SFixed32ByteSize().
159 [wire_format.SFixed32ByteSize, 0, 4],
160 [wire_format.SFixed32ByteSize, wire_format.INT32_MIN, 4],
161 [wire_format.SFixed32ByteSize, wire_format.INT32_MAX, 4],
162 # SFixed64ByteSize().
163 [wire_format.SFixed64ByteSize, 0, 8],
164 [wire_format.SFixed64ByteSize, wire_format.INT64_MIN, 8],
165 [wire_format.SFixed64ByteSize, wire_format.INT64_MAX, 8],
167 [wire_format.FloatByteSize, 0.0, 4],
168 [wire_format.FloatByteSize, 1000000000.0, 4],
169 [wire_format.FloatByteSize, -1000000000.0, 4],
171 [wire_format.DoubleByteSize, 0.0, 8],
172 [wire_format.DoubleByteSize, 1000000000.0, 8],
173 [wire_format.DoubleByteSize, -1000000000.0, 8],
175 [wire_format.BoolByteSize, False, 1],
176 [wire_format.BoolByteSize, True, 1],
178 [wire_format.EnumByteSize, 0, 1],
179 [wire_format.EnumByteSize, 127, 1],
180 [wire_format.EnumByteSize, 128, 2],
181 [wire_format.EnumByteSize, wire_format.UINT32_MAX, 5],
183 for args in NUMERIC_ARGS:
184 self.NumericByteSizeTestHelper(*args)
186 # Test strings and bytes.
187 for byte_size_fn in (wire_format.StringByteSize, wire_format.BytesByteSize):
188 # 1 byte for tag, 1 byte for length, 3 bytes for contents.
189 self.assertEqual(5, byte_size_fn(10, 'abc'))
190 # 2 bytes for tag, 1 byte for length, 3 bytes for contents.
191 self.assertEqual(6, byte_size_fn(16, 'abc'))
192 # 2 bytes for tag, 2 bytes for length, 128 bytes for contents.
193 self.assertEqual(132, byte_size_fn(16, 'a' * 128))
195 # Test UTF-8 string byte size calculation.
196 # 1 byte for tag, 1 byte for length, 8 bytes for content.
197 self.assertEqual(10, wire_format.StringByteSize(
198 5, unicode('\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82', 'utf-8')))
200 class MockMessage(object):
201 def __init__(self, byte_size):
202 self.byte_size = byte_size
204 return self.byte_size
206 message_byte_size = 10
207 mock_message = MockMessage(byte_size=message_byte_size)
209 # (2 * 1) bytes for begin and end tags, plus message_byte_size.
210 self.assertEqual(2 + message_byte_size,
211 wire_format.GroupByteSize(1, mock_message))
212 # (2 * 2) bytes for begin and end tags, plus message_byte_size.
213 self.assertEqual(4 + message_byte_size,
214 wire_format.GroupByteSize(16, mock_message))
217 # 1 byte for tag, plus 1 byte for length, plus contents.
218 self.assertEqual(2 + mock_message.byte_size,
219 wire_format.MessageByteSize(1, mock_message))
220 # 2 bytes for tag, plus 1 byte for length, plus contents.
221 self.assertEqual(3 + mock_message.byte_size,
222 wire_format.MessageByteSize(16, mock_message))
223 # 2 bytes for tag, plus 2 bytes for length, plus contents.
224 mock_message.byte_size = 128
225 self.assertEqual(4 + mock_message.byte_size,
226 wire_format.MessageByteSize(16, mock_message))
229 # Test message set item byte size.
230 # 4 bytes for tags, plus 1 byte for length, plus 1 byte for type_id,
232 mock_message.byte_size = 10
233 self.assertEqual(mock_message.byte_size + 6,
234 wire_format.MessageSetItemByteSize(1, mock_message))
236 # 4 bytes for tags, plus 2 bytes for length, plus 1 byte for type_id,
238 mock_message.byte_size = 128
239 self.assertEqual(mock_message.byte_size + 7,
240 wire_format.MessageSetItemByteSize(1, mock_message))
242 # 4 bytes for tags, plus 2 bytes for length, plus 2 byte for type_id,
244 self.assertEqual(mock_message.byte_size + 8,
245 wire_format.MessageSetItemByteSize(128, mock_message))
248 self.assertRaises(message.EncodeError,
249 wire_format.UInt64ByteSize, 1, 1 << 128)
252 if __name__ == '__main__':