blob: be2fcea8555e412e05187dae29971537313f1174 [file] [log] [blame]
Mark Slee89e2bb82007-03-01 00:20:36 +00001#
David Reissea2cba82009-03-30 21:35:00 +00002# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
Mark Slee89e2bb82007-03-01 00:20:36 +000019
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +090020from thrift.Thrift import TException, TType, TFrozenDict
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090021import six
22
23from ..compat import binary_to_str, str_to_binary
Mark Sleecde2b612006-09-03 21:13:07 +000024
Mark Slee92195ae2007-02-21 05:16:30 +000025
Bryan Duxbury69720412012-01-03 17:32:30 +000026class TProtocolException(TException):
Mark Slee92195ae2007-02-21 05:16:30 +000027 """Custom Protocol Exception class"""
28
29 UNKNOWN = 0
30 INVALID_DATA = 1
31 NEGATIVE_SIZE = 2
32 SIZE_LIMIT = 3
Mark Slee808454e2007-06-20 21:51:57 +000033 BAD_VERSION = 4
Jens Geyer6d1a83a2014-05-03 00:49:05 +020034 NOT_IMPLEMENTED = 5
35 DEPTH_LIMIT = 6
Mark Slee92195ae2007-02-21 05:16:30 +000036
37 def __init__(self, type=UNKNOWN, message=None):
38 TException.__init__(self, message)
39 self.type = type
40
Mark Sleecde2b612006-09-03 21:13:07 +000041
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090042class TProtocolBase(object):
Mark Sleecde2b612006-09-03 21:13:07 +000043 """Base class for Thrift protocol driver."""
44
Aditya Agarwal5c468192007-02-06 01:14:33 +000045 def __init__(self, trans):
46 self.trans = trans
Mark Slee4ac459f2006-10-25 21:39:01 +000047
Roger Meierad8154a2012-12-18 21:02:16 +010048 def writeMessageBegin(self, name, ttype, seqid):
Mark Sleecde2b612006-09-03 21:13:07 +000049 pass
50
Mark Slee4ac459f2006-10-25 21:39:01 +000051 def writeMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000052 pass
53
Mark Slee4ac459f2006-10-25 21:39:01 +000054 def writeStructBegin(self, name):
Mark Sleecde2b612006-09-03 21:13:07 +000055 pass
56
Mark Slee4ac459f2006-10-25 21:39:01 +000057 def writeStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000058 pass
59
Roger Meierad8154a2012-12-18 21:02:16 +010060 def writeFieldBegin(self, name, ttype, fid):
Mark Sleecde2b612006-09-03 21:13:07 +000061 pass
62
Mark Slee4ac459f2006-10-25 21:39:01 +000063 def writeFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000064 pass
65
Mark Slee4ac459f2006-10-25 21:39:01 +000066 def writeFieldStop(self):
Mark Sleecde2b612006-09-03 21:13:07 +000067 pass
68
Mark Slee4ac459f2006-10-25 21:39:01 +000069 def writeMapBegin(self, ktype, vtype, size):
Mark Sleecde2b612006-09-03 21:13:07 +000070 pass
71
Mark Slee4ac459f2006-10-25 21:39:01 +000072 def writeMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000073 pass
74
Mark Slee4ac459f2006-10-25 21:39:01 +000075 def writeListBegin(self, etype, size):
Mark Sleecde2b612006-09-03 21:13:07 +000076 pass
77
Mark Slee4ac459f2006-10-25 21:39:01 +000078 def writeListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000079 pass
80
Mark Slee4ac459f2006-10-25 21:39:01 +000081 def writeSetBegin(self, etype, size):
Mark Sleecde2b612006-09-03 21:13:07 +000082 pass
83
Mark Slee4ac459f2006-10-25 21:39:01 +000084 def writeSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000085 pass
86
Roger Meierad8154a2012-12-18 21:02:16 +010087 def writeBool(self, bool_val):
Mark Sleecde2b612006-09-03 21:13:07 +000088 pass
89
Mark Slee4ac459f2006-10-25 21:39:01 +000090 def writeByte(self, byte):
Mark Sleecde2b612006-09-03 21:13:07 +000091 pass
92
Mark Slee4ac459f2006-10-25 21:39:01 +000093 def writeI16(self, i16):
Mark Sleecde2b612006-09-03 21:13:07 +000094 pass
95
Mark Slee4ac459f2006-10-25 21:39:01 +000096 def writeI32(self, i32):
Mark Sleecde2b612006-09-03 21:13:07 +000097 pass
98
Mark Slee4ac459f2006-10-25 21:39:01 +000099 def writeI64(self, i64):
Mark Sleecde2b612006-09-03 21:13:07 +0000100 pass
101
Mark Slee4ac459f2006-10-25 21:39:01 +0000102 def writeDouble(self, dub):
Mark Sleec98d0502006-09-06 02:42:25 +0000103 pass
104
Roger Meierad8154a2012-12-18 21:02:16 +0100105 def writeString(self, str_val):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900106 self.writeBinary(str_to_binary(str_val))
107
108 def writeBinary(self, str_val):
Mark Sleecde2b612006-09-03 21:13:07 +0000109 pass
110
Mark Slee4ac459f2006-10-25 21:39:01 +0000111 def readMessageBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000112 pass
113
Mark Slee4ac459f2006-10-25 21:39:01 +0000114 def readMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000115 pass
116
Mark Slee4ac459f2006-10-25 21:39:01 +0000117 def readStructBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000118 pass
119
Mark Slee4ac459f2006-10-25 21:39:01 +0000120 def readStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000121 pass
122
Mark Slee4ac459f2006-10-25 21:39:01 +0000123 def readFieldBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000124 pass
125
Mark Slee4ac459f2006-10-25 21:39:01 +0000126 def readFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000127 pass
128
Mark Slee4ac459f2006-10-25 21:39:01 +0000129 def readMapBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000130 pass
131
Mark Slee4ac459f2006-10-25 21:39:01 +0000132 def readMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000133 pass
134
Mark Slee4ac459f2006-10-25 21:39:01 +0000135 def readListBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000136 pass
137
Mark Slee4ac459f2006-10-25 21:39:01 +0000138 def readListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000139 pass
140
Mark Slee4ac459f2006-10-25 21:39:01 +0000141 def readSetBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000142 pass
143
Mark Slee4ac459f2006-10-25 21:39:01 +0000144 def readSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000145 pass
146
Mark Slee4ac459f2006-10-25 21:39:01 +0000147 def readBool(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000148 pass
149
Mark Slee4ac459f2006-10-25 21:39:01 +0000150 def readByte(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000151 pass
152
Mark Slee4ac459f2006-10-25 21:39:01 +0000153 def readI16(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000154 pass
155
Mark Slee4ac459f2006-10-25 21:39:01 +0000156 def readI32(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000157 pass
158
Mark Slee4ac459f2006-10-25 21:39:01 +0000159 def readI64(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000160 pass
161
Mark Slee4ac459f2006-10-25 21:39:01 +0000162 def readDouble(self):
Mark Sleec98d0502006-09-06 02:42:25 +0000163 pass
164
Mark Slee4ac459f2006-10-25 21:39:01 +0000165 def readString(self):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900166 return binary_to_str(self.readBinary())
167
168 def readBinary(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000169 pass
170
Roger Meierad8154a2012-12-18 21:02:16 +0100171 def skip(self, ttype):
172 if ttype == TType.STOP:
Mark Sleecde2b612006-09-03 21:13:07 +0000173 return
Roger Meierad8154a2012-12-18 21:02:16 +0100174 elif ttype == TType.BOOL:
Mark Slee4ac459f2006-10-25 21:39:01 +0000175 self.readBool()
Roger Meierad8154a2012-12-18 21:02:16 +0100176 elif ttype == TType.BYTE:
Mark Slee4ac459f2006-10-25 21:39:01 +0000177 self.readByte()
Roger Meierad8154a2012-12-18 21:02:16 +0100178 elif ttype == TType.I16:
Mark Slee4ac459f2006-10-25 21:39:01 +0000179 self.readI16()
Roger Meierad8154a2012-12-18 21:02:16 +0100180 elif ttype == TType.I32:
Mark Slee4ac459f2006-10-25 21:39:01 +0000181 self.readI32()
Roger Meierad8154a2012-12-18 21:02:16 +0100182 elif ttype == TType.I64:
Mark Slee4ac459f2006-10-25 21:39:01 +0000183 self.readI64()
Roger Meierad8154a2012-12-18 21:02:16 +0100184 elif ttype == TType.DOUBLE:
Mark Slee4ac459f2006-10-25 21:39:01 +0000185 self.readDouble()
Roger Meierad8154a2012-12-18 21:02:16 +0100186 elif ttype == TType.STRING:
Mark Slee4ac459f2006-10-25 21:39:01 +0000187 self.readString()
Roger Meierad8154a2012-12-18 21:02:16 +0100188 elif ttype == TType.STRUCT:
Mark Slee4ac459f2006-10-25 21:39:01 +0000189 name = self.readStructBegin()
Mark Sleecde2b612006-09-03 21:13:07 +0000190 while True:
Roger Meierad8154a2012-12-18 21:02:16 +0100191 (name, ttype, id) = self.readFieldBegin()
192 if ttype == TType.STOP:
Mark Sleecde2b612006-09-03 21:13:07 +0000193 break
Roger Meierad8154a2012-12-18 21:02:16 +0100194 self.skip(ttype)
Mark Slee4ac459f2006-10-25 21:39:01 +0000195 self.readFieldEnd()
196 self.readStructEnd()
Roger Meierad8154a2012-12-18 21:02:16 +0100197 elif ttype == TType.MAP:
Mark Slee4ac459f2006-10-25 21:39:01 +0000198 (ktype, vtype, size) = self.readMapBegin()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900199 for i in range(size):
Mark Slee4ac459f2006-10-25 21:39:01 +0000200 self.skip(ktype)
201 self.skip(vtype)
202 self.readMapEnd()
Roger Meierad8154a2012-12-18 21:02:16 +0100203 elif ttype == TType.SET:
Mark Slee4ac459f2006-10-25 21:39:01 +0000204 (etype, size) = self.readSetBegin()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900205 for i in range(size):
Mark Slee4ac459f2006-10-25 21:39:01 +0000206 self.skip(etype)
207 self.readSetEnd()
Roger Meierad8154a2012-12-18 21:02:16 +0100208 elif ttype == TType.LIST:
Mark Slee4ac459f2006-10-25 21:39:01 +0000209 (etype, size) = self.readListBegin()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900210 for i in range(size):
Mark Slee4ac459f2006-10-25 21:39:01 +0000211 self.skip(etype)
212 self.readListEnd()
Mark Sleecde2b612006-09-03 21:13:07 +0000213
Bryan Duxbury69720412012-01-03 17:32:30 +0000214 # tuple of: ( 'reader method' name, is_container bool, 'writer_method' name )
Roger Meierf4eec7a2011-09-11 18:16:21 +0000215 _TTYPE_HANDLERS = (
Bryan Duxbury69720412012-01-03 17:32:30 +0000216 (None, None, False), # 0 TType.STOP
217 (None, None, False), # 1 TType.VOID # TODO: handle void?
218 ('readBool', 'writeBool', False), # 2 TType.BOOL
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900219 ('readByte', 'writeByte', False), # 3 TType.BYTE and I08
Bryan Duxbury69720412012-01-03 17:32:30 +0000220 ('readDouble', 'writeDouble', False), # 4 TType.DOUBLE
221 (None, None, False), # 5 undefined
222 ('readI16', 'writeI16', False), # 6 TType.I16
223 (None, None, False), # 7 undefined
224 ('readI32', 'writeI32', False), # 8 TType.I32
225 (None, None, False), # 9 undefined
226 ('readI64', 'writeI64', False), # 10 TType.I64
227 ('readString', 'writeString', False), # 11 TType.STRING and UTF7
228 ('readContainerStruct', 'writeContainerStruct', True), # 12 *.STRUCT
229 ('readContainerMap', 'writeContainerMap', True), # 13 TType.MAP
230 ('readContainerSet', 'writeContainerSet', True), # 14 TType.SET
231 ('readContainerList', 'writeContainerList', True), # 15 TType.LIST
232 (None, None, False), # 16 TType.UTF8 # TODO: handle utf8 types?
233 (None, None, False) # 17 TType.UTF16 # TODO: handle utf16 types?
Roger Meierf4eec7a2011-09-11 18:16:21 +0000234 )
235
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900236 def _ttype_handlers(self, ttype, spec):
237 if spec == 'BINARY':
238 if ttype != TType.STRING:
239 raise TProtocolException(type=TProtocolException.INVALID_DATA,
240 message='Invalid binary field type %d' % ttype)
241 return ('readBinary', 'writeBinary', False)
242 return self._TTYPE_HANDLERS[ttype]
243
Roger Meierf4eec7a2011-09-11 18:16:21 +0000244 def readFieldByTType(self, ttype, spec):
245 try:
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900246 (r_handler, w_handler, is_container) = self._ttype_handlers(ttype, spec)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000247 except IndexError:
248 raise TProtocolException(type=TProtocolException.INVALID_DATA,
249 message='Invalid field type %d' % (ttype))
250 if r_handler is None:
251 raise TProtocolException(type=TProtocolException.INVALID_DATA,
252 message='Invalid field type %d' % (ttype))
253 reader = getattr(self, r_handler)
254 if not is_container:
255 return reader()
256 return reader(spec)
257
258 def readContainerList(self, spec):
259 results = []
260 ttype, tspec = spec[0], spec[1]
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900261 is_immutable = spec[2]
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900262 r_handler = self._ttype_handlers(ttype, spec)[0]
Roger Meierf4eec7a2011-09-11 18:16:21 +0000263 reader = getattr(self, r_handler)
264 (list_type, list_len) = self.readListBegin()
265 if tspec is None:
266 # list values are simple types
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900267 for idx in range(list_len):
Roger Meierf4eec7a2011-09-11 18:16:21 +0000268 results.append(reader())
269 else:
270 # this is like an inlined readFieldByTType
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900271 container_reader = self._ttype_handlers(list_type, tspec)[0]
Roger Meierf4eec7a2011-09-11 18:16:21 +0000272 val_reader = getattr(self, container_reader)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900273 for idx in range(list_len):
Roger Meierf4eec7a2011-09-11 18:16:21 +0000274 val = val_reader(tspec)
275 results.append(val)
276 self.readListEnd()
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900277 return tuple(results) if is_immutable else results
Roger Meierf4eec7a2011-09-11 18:16:21 +0000278
279 def readContainerSet(self, spec):
280 results = set()
281 ttype, tspec = spec[0], spec[1]
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900282 is_immutable = spec[2]
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900283 r_handler = self._ttype_handlers(ttype, spec)[0]
Roger Meierf4eec7a2011-09-11 18:16:21 +0000284 reader = getattr(self, r_handler)
285 (set_type, set_len) = self.readSetBegin()
286 if tspec is None:
287 # set members are simple types
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900288 for idx in range(set_len):
Roger Meierf4eec7a2011-09-11 18:16:21 +0000289 results.add(reader())
290 else:
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900291 container_reader = self._ttype_handlers(set_type, tspec)[0]
Roger Meierf4eec7a2011-09-11 18:16:21 +0000292 val_reader = getattr(self, container_reader)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900293 for idx in range(set_len):
Bryan Duxbury69720412012-01-03 17:32:30 +0000294 results.add(val_reader(tspec))
Roger Meierf4eec7a2011-09-11 18:16:21 +0000295 self.readSetEnd()
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900296 return frozenset(results) if is_immutable else results
Roger Meierf4eec7a2011-09-11 18:16:21 +0000297
298 def readContainerStruct(self, spec):
299 (obj_class, obj_spec) = spec
300 obj = obj_class()
301 obj.read(self)
302 return obj
Bryan Duxbury69720412012-01-03 17:32:30 +0000303
Roger Meierf4eec7a2011-09-11 18:16:21 +0000304 def readContainerMap(self, spec):
305 results = dict()
306 key_ttype, key_spec = spec[0], spec[1]
307 val_ttype, val_spec = spec[2], spec[3]
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900308 is_immutable = spec[4]
Roger Meierf4eec7a2011-09-11 18:16:21 +0000309 (map_ktype, map_vtype, map_len) = self.readMapBegin()
Bryan Duxbury69720412012-01-03 17:32:30 +0000310 # TODO: compare types we just decoded with thrift_spec and
311 # abort/skip if types disagree
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900312 key_reader = getattr(self, self._ttype_handlers(key_ttype, key_spec)[0])
313 val_reader = getattr(self, self._ttype_handlers(val_ttype, val_spec)[0])
Roger Meierf4eec7a2011-09-11 18:16:21 +0000314 # list values are simple types
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900315 for idx in range(map_len):
Roger Meierf4eec7a2011-09-11 18:16:21 +0000316 if key_spec is None:
317 k_val = key_reader()
318 else:
319 k_val = self.readFieldByTType(key_ttype, key_spec)
320 if val_spec is None:
321 v_val = val_reader()
322 else:
323 v_val = self.readFieldByTType(val_ttype, val_spec)
Bryan Duxbury69720412012-01-03 17:32:30 +0000324 # this raises a TypeError with unhashable keys types
325 # i.e. this fails: d=dict(); d[[0,1]] = 2
Roger Meierf4eec7a2011-09-11 18:16:21 +0000326 results[k_val] = v_val
327 self.readMapEnd()
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900328 return TFrozenDict(results) if is_immutable else results
Roger Meierf4eec7a2011-09-11 18:16:21 +0000329
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900330 def readStruct(self, obj, thrift_spec, is_immutable=False):
331 if is_immutable:
332 fields = {}
Roger Meierf4eec7a2011-09-11 18:16:21 +0000333 self.readStructBegin()
334 while True:
335 (fname, ftype, fid) = self.readFieldBegin()
336 if ftype == TType.STOP:
337 break
338 try:
339 field = thrift_spec[fid]
340 except IndexError:
341 self.skip(ftype)
342 else:
343 if field is not None and ftype == field[1]:
344 fname = field[2]
345 fspec = field[3]
346 val = self.readFieldByTType(ftype, fspec)
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900347 if is_immutable:
348 fields[fname] = val
349 else:
350 setattr(obj, fname, val)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000351 else:
352 self.skip(ftype)
353 self.readFieldEnd()
354 self.readStructEnd()
Nobuaki Sukegawae841b3d2015-11-17 11:01:17 +0900355 if is_immutable:
356 return obj(**fields)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000357
358 def writeContainerStruct(self, val, spec):
359 val.write(self)
360
361 def writeContainerList(self, val, spec):
362 self.writeListBegin(spec[0], len(val))
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900363 r_handler, w_handler, is_container = self._ttype_handlers(spec[0], spec)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000364 e_writer = getattr(self, w_handler)
365 if not is_container:
366 for elem in val:
367 e_writer(elem)
368 else:
369 for elem in val:
370 e_writer(elem, spec[1])
371 self.writeListEnd()
372
373 def writeContainerSet(self, val, spec):
374 self.writeSetBegin(spec[0], len(val))
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900375 r_handler, w_handler, is_container = self._ttype_handlers(spec[0], spec)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000376 e_writer = getattr(self, w_handler)
377 if not is_container:
378 for elem in val:
379 e_writer(elem)
380 else:
381 for elem in val:
382 e_writer(elem, spec[1])
383 self.writeSetEnd()
384
385 def writeContainerMap(self, val, spec):
386 k_type = spec[0]
387 v_type = spec[2]
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900388 ignore, ktype_name, k_is_container = self._ttype_handlers(k_type, spec)
389 ignore, vtype_name, v_is_container = self._ttype_handlers(v_type, spec)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000390 k_writer = getattr(self, ktype_name)
391 v_writer = getattr(self, vtype_name)
392 self.writeMapBegin(k_type, v_type, len(val))
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900393 for m_key, m_val in six.iteritems(val):
Roger Meierf4eec7a2011-09-11 18:16:21 +0000394 if not k_is_container:
395 k_writer(m_key)
396 else:
397 k_writer(m_key, spec[1])
398 if not v_is_container:
399 v_writer(m_val)
400 else:
401 v_writer(m_val, spec[3])
402 self.writeMapEnd()
403
404 def writeStruct(self, obj, thrift_spec):
405 self.writeStructBegin(obj.__class__.__name__)
406 for field in thrift_spec:
407 if field is None:
408 continue
409 fname = field[2]
410 val = getattr(obj, fname)
411 if val is None:
412 # skip writing out unset fields
413 continue
414 fid = field[0]
415 ftype = field[1]
416 fspec = field[3]
417 # get the writer method for this value
418 self.writeFieldBegin(fname, ftype, fid)
419 self.writeFieldByTType(ftype, val, fspec)
420 self.writeFieldEnd()
421 self.writeFieldStop()
422 self.writeStructEnd()
423
424 def writeFieldByTType(self, ttype, val, spec):
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900425 r_handler, w_handler, is_container = self._ttype_handlers(ttype, spec)
Roger Meierf4eec7a2011-09-11 18:16:21 +0000426 writer = getattr(self, w_handler)
427 if is_container:
428 writer(val, spec)
429 else:
430 writer(val)
431
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900432
Konrad Grochowski93fea152014-10-02 16:29:14 +0200433def checkIntegerLimits(i, bits):
Konrad Grochowski07218672014-10-09 12:18:25 +0200434 if bits == 8 and (i < -128 or i > 127):
Konrad Grochowski93fea152014-10-02 16:29:14 +0200435 raise TProtocolException(TProtocolException.INVALID_DATA,
Konrad Grochowskid5f3be52014-10-08 15:32:21 +0200436 "i8 requires -128 <= number <= 127")
Konrad Grochowski07218672014-10-09 12:18:25 +0200437 elif bits == 16 and (i < -32768 or i > 32767):
Konrad Grochowskid5f3be52014-10-08 15:32:21 +0200438 raise TProtocolException(TProtocolException.INVALID_DATA,
439 "i16 requires -32768 <= number <= 32767")
Konrad Grochowski07218672014-10-09 12:18:25 +0200440 elif bits == 32 and (i < -2147483648 or i > 2147483647):
Konrad Grochowskid5f3be52014-10-08 15:32:21 +0200441 raise TProtocolException(TProtocolException.INVALID_DATA,
442 "i32 requires -2147483648 <= number <= 2147483647")
Konrad Grochowski07218672014-10-09 12:18:25 +0200443 elif bits == 64 and (i < -9223372036854775808 or i > 9223372036854775807):
Konrad Grochowskid5f3be52014-10-08 15:32:21 +0200444 raise TProtocolException(TProtocolException.INVALID_DATA,
445 "i64 requires -9223372036854775808 <= number <= 9223372036854775807")
Bryan Duxbury69720412012-01-03 17:32:30 +0000446
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900447
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +0900448class TProtocolFactory(object):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000449 def getProtocol(self, trans):
Mark Slee4ac459f2006-10-25 21:39:01 +0000450 pass