~ubuntu-branches/debian/squeeze/protobuf/squeeze

« back to all changes in this revision

Viewing changes to python/google/protobuf/internal/type_checkers.py

  • Committer: Bazaar Package Importer
  • Author(s): Julien Cristau
  • Date: 2009-06-02 16:19:00 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090602161900-vm176i3ryt35yk91
Tags: 2.0.3-2.2
* Non-maintainer upload.
* Fix FTBFS from -2.1: don't fail when we can't clean up the java build,
  such as when openjdk isn't installed.
* Disable parallel builds, because libtool is made of fail (if binary-arch
  and build-indep run concurrently, we relink a library while it's being
  used; that doesn't work so well).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 google.protobuf.internal import decoder
 
49
from google.protobuf.internal import encoder
 
50
from google.protobuf.internal import wire_format
 
51
from google.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
    }