blob: b58095a00079e34abdcaa64c5813402805e51ece [file] [log] [blame]
Roger Meierf4eec7a2011-09-11 18:16:21 +00001#
2# 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#
19
James E. King IIIe44f6a92019-02-07 17:11:21 -050020from .TProtocol import TType, TProtocolBase, TProtocolException, TProtocolFactory, checkIntegerLimits
David Reissabafd792010-09-27 17:28:15 +000021from struct import pack, unpack
Carel Combrinka715bdf2025-10-30 07:44:21 +010022import uuid
David Reissabafd792010-09-27 17:28:15 +000023
24__all__ = ['TCompactProtocol', 'TCompactProtocolFactory']
25
26CLEAR = 0
27FIELD_WRITE = 1
28VALUE_WRITE = 2
29CONTAINER_WRITE = 3
30BOOL_WRITE = 4
31FIELD_READ = 5
32CONTAINER_READ = 6
33VALUE_READ = 7
34BOOL_READ = 8
35
Bryan Duxbury69720412012-01-03 17:32:30 +000036
David Reissabafd792010-09-27 17:28:15 +000037def make_helper(v_from, container):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090038 def helper(func):
39 def nested(self, *args, **kwargs):
40 assert self.state in (v_from, container), (self.state, v_from, container)
41 return func(self, *args, **kwargs)
42 return nested
43 return helper
James E. King, III0ad20bd2017-09-30 15:44:16 -070044
45
David Reissabafd792010-09-27 17:28:15 +000046writer = make_helper(VALUE_WRITE, CONTAINER_WRITE)
47reader = make_helper(VALUE_READ, CONTAINER_READ)
48
Bryan Duxbury69720412012-01-03 17:32:30 +000049
David Reissabafd792010-09-27 17:28:15 +000050def makeZigZag(n, bits):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090051 checkIntegerLimits(n, bits)
52 return (n << 1) ^ (n >> (bits - 1))
David Reissabafd792010-09-27 17:28:15 +000053
Bryan Duxbury69720412012-01-03 17:32:30 +000054
David Reissabafd792010-09-27 17:28:15 +000055def fromZigZag(n):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090056 return (n >> 1) ^ -(n & 1)
David Reissabafd792010-09-27 17:28:15 +000057
Bryan Duxbury69720412012-01-03 17:32:30 +000058
David Reissabafd792010-09-27 17:28:15 +000059def writeVarint(trans, n):
James E. King IIIf15b4152019-01-31 13:01:56 -050060 assert n >= 0, "Input to TCompactProtocol writeVarint cannot be negative!"
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090061 out = bytearray()
62 while True:
63 if n & ~0x7f == 0:
64 out.append(n)
65 break
66 else:
67 out.append((n & 0xff) | 0x80)
68 n = n >> 7
69 trans.write(bytes(out))
David Reissabafd792010-09-27 17:28:15 +000070
Bryan Duxbury69720412012-01-03 17:32:30 +000071
David Reissabafd792010-09-27 17:28:15 +000072def readVarint(trans):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090073 result = 0
74 shift = 0
75 while True:
76 x = trans.readAll(1)
77 byte = ord(x)
78 result |= (byte & 0x7f) << shift
79 if byte >> 7 == 0:
80 return result
81 shift += 7
David Reissabafd792010-09-27 17:28:15 +000082
Bryan Duxbury69720412012-01-03 17:32:30 +000083
Carel Combrinka715bdf2025-10-30 07:44:21 +010084# As per TCompactProtocol.tcc
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +090085class CompactType(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090086 STOP = 0x00
87 TRUE = 0x01
88 FALSE = 0x02
89 BYTE = 0x03
90 I16 = 0x04
91 I32 = 0x05
92 I64 = 0x06
93 DOUBLE = 0x07
94 BINARY = 0x08
95 LIST = 0x09
96 SET = 0x0A
97 MAP = 0x0B
98 STRUCT = 0x0C
Carel Combrinka715bdf2025-10-30 07:44:21 +010099 UUID = 0x0D
David Reissabafd792010-09-27 17:28:15 +0000100
James E. King, III0ad20bd2017-09-30 15:44:16 -0700101
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900102CTYPES = {
103 TType.STOP: CompactType.STOP,
104 TType.BOOL: CompactType.TRUE, # used for collection
105 TType.BYTE: CompactType.BYTE,
106 TType.I16: CompactType.I16,
107 TType.I32: CompactType.I32,
108 TType.I64: CompactType.I64,
109 TType.DOUBLE: CompactType.DOUBLE,
110 TType.STRING: CompactType.BINARY,
111 TType.STRUCT: CompactType.STRUCT,
112 TType.LIST: CompactType.LIST,
113 TType.SET: CompactType.SET,
114 TType.MAP: CompactType.MAP,
Carel Combrinka715bdf2025-10-30 07:44:21 +0100115 TType.UUID: CompactType.UUID,
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900116}
David Reissabafd792010-09-27 17:28:15 +0000117
118TTYPES = {}
119for k, v in CTYPES.items():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900120 TTYPES[v] = k
David Reissabafd792010-09-27 17:28:15 +0000121TTYPES[CompactType.FALSE] = TType.BOOL
122del k
123del v
124
Bryan Duxbury69720412012-01-03 17:32:30 +0000125
David Reissabafd792010-09-27 17:28:15 +0000126class TCompactProtocol(TProtocolBase):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900127 """Compact implementation of the Thrift protocol driver."""
David Reissabafd792010-09-27 17:28:15 +0000128
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900129 PROTOCOL_ID = 0x82
130 VERSION = 1
131 VERSION_MASK = 0x1f
132 TYPE_MASK = 0xe0
133 TYPE_BITS = 0x07
134 TYPE_SHIFT_AMOUNT = 5
David Reissabafd792010-09-27 17:28:15 +0000135
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900136 def __init__(self, trans,
137 string_length_limit=None,
138 container_length_limit=None):
139 TProtocolBase.__init__(self, trans)
140 self.state = CLEAR
141 self.__last_fid = 0
142 self.__bool_fid = None
143 self.__bool_value = None
144 self.__structs = []
145 self.__containers = []
146 self.string_length_limit = string_length_limit
147 self.container_length_limit = container_length_limit
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900148
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900149 def _check_string_length(self, length):
150 self._check_length(self.string_length_limit, length)
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900151
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900152 def _check_container_length(self, length):
153 self._check_length(self.container_length_limit, length)
David Reissabafd792010-09-27 17:28:15 +0000154
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900155 def __writeVarint(self, n):
156 writeVarint(self.trans, n)
David Reissabafd792010-09-27 17:28:15 +0000157
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900158 def writeMessageBegin(self, name, type, seqid):
159 assert self.state == CLEAR
160 self.__writeUByte(self.PROTOCOL_ID)
161 self.__writeUByte(self.VERSION | (type << self.TYPE_SHIFT_AMOUNT))
James E. King IIIf15b4152019-01-31 13:01:56 -0500162 # The sequence id is a signed 32-bit integer but the compact protocol
163 # writes this out as a "var int" which is always positive, and attempting
164 # to write a negative number results in an infinite loop, so we may
165 # need to do some conversion here...
James E. King III53bd0e62019-01-31 17:11:04 -0500166 tseqid = seqid
James E. King IIIf15b4152019-01-31 13:01:56 -0500167 if tseqid < 0:
168 tseqid = 2147483648 + (2147483648 + tseqid)
169 self.__writeVarint(tseqid)
Alexandre Detiste3494e1c2025-02-19 21:53:40 +0100170 self.__writeBinary(bytes(name, 'utf-8'))
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900171 self.state = VALUE_WRITE
David Reissabafd792010-09-27 17:28:15 +0000172
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900173 def writeMessageEnd(self):
174 assert self.state == VALUE_WRITE
175 self.state = CLEAR
David Reissabafd792010-09-27 17:28:15 +0000176
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900177 def writeStructBegin(self, name):
178 assert self.state in (CLEAR, CONTAINER_WRITE, VALUE_WRITE), self.state
179 self.__structs.append((self.state, self.__last_fid))
180 self.state = FIELD_WRITE
181 self.__last_fid = 0
David Reissabafd792010-09-27 17:28:15 +0000182
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900183 def writeStructEnd(self):
184 assert self.state == FIELD_WRITE
185 self.state, self.__last_fid = self.__structs.pop()
David Reissabafd792010-09-27 17:28:15 +0000186
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900187 def writeFieldStop(self):
188 self.__writeByte(0)
David Reissabafd792010-09-27 17:28:15 +0000189
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900190 def __writeFieldHeader(self, type, fid):
191 delta = fid - self.__last_fid
192 if 0 < delta <= 15:
193 self.__writeUByte(delta << 4 | type)
194 else:
195 self.__writeByte(type)
196 self.__writeI16(fid)
197 self.__last_fid = fid
David Reissabafd792010-09-27 17:28:15 +0000198
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900199 def writeFieldBegin(self, name, type, fid):
200 assert self.state == FIELD_WRITE, self.state
201 if type == TType.BOOL:
202 self.state = BOOL_WRITE
203 self.__bool_fid = fid
204 else:
205 self.state = VALUE_WRITE
206 self.__writeFieldHeader(CTYPES[type], fid)
David Reissabafd792010-09-27 17:28:15 +0000207
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900208 def writeFieldEnd(self):
209 assert self.state in (VALUE_WRITE, BOOL_WRITE), self.state
210 self.state = FIELD_WRITE
David Reissabafd792010-09-27 17:28:15 +0000211
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900212 def __writeUByte(self, byte):
213 self.trans.write(pack('!B', byte))
David Reissabafd792010-09-27 17:28:15 +0000214
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900215 def __writeByte(self, byte):
216 self.trans.write(pack('!b', byte))
David Reissabafd792010-09-27 17:28:15 +0000217
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900218 def __writeI16(self, i16):
219 self.__writeVarint(makeZigZag(i16, 16))
David Reissabafd792010-09-27 17:28:15 +0000220
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900221 def __writeSize(self, i32):
222 self.__writeVarint(i32)
David Reissabafd792010-09-27 17:28:15 +0000223
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900224 def writeCollectionBegin(self, etype, size):
225 assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state
226 if size <= 14:
227 self.__writeUByte(size << 4 | CTYPES[etype])
228 else:
229 self.__writeUByte(0xf0 | CTYPES[etype])
230 self.__writeSize(size)
231 self.__containers.append(self.state)
232 self.state = CONTAINER_WRITE
233 writeSetBegin = writeCollectionBegin
234 writeListBegin = writeCollectionBegin
David Reissabafd792010-09-27 17:28:15 +0000235
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900236 def writeMapBegin(self, ktype, vtype, size):
237 assert self.state in (VALUE_WRITE, CONTAINER_WRITE), self.state
238 if size == 0:
239 self.__writeByte(0)
240 else:
241 self.__writeSize(size)
242 self.__writeUByte(CTYPES[ktype] << 4 | CTYPES[vtype])
243 self.__containers.append(self.state)
244 self.state = CONTAINER_WRITE
David Reissabafd792010-09-27 17:28:15 +0000245
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900246 def writeCollectionEnd(self):
247 assert self.state == CONTAINER_WRITE, self.state
248 self.state = self.__containers.pop()
249 writeMapEnd = writeCollectionEnd
250 writeSetEnd = writeCollectionEnd
251 writeListEnd = writeCollectionEnd
David Reissabafd792010-09-27 17:28:15 +0000252
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900253 def writeBool(self, bool):
254 if self.state == BOOL_WRITE:
255 if bool:
256 ctype = CompactType.TRUE
257 else:
258 ctype = CompactType.FALSE
259 self.__writeFieldHeader(ctype, self.__bool_fid)
260 elif self.state == CONTAINER_WRITE:
261 if bool:
262 self.__writeByte(CompactType.TRUE)
263 else:
264 self.__writeByte(CompactType.FALSE)
265 else:
266 raise AssertionError("Invalid state in compact protocol")
David Reissabafd792010-09-27 17:28:15 +0000267
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900268 writeByte = writer(__writeByte)
269 writeI16 = writer(__writeI16)
David Reissabafd792010-09-27 17:28:15 +0000270
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900271 @writer
272 def writeI32(self, i32):
273 self.__writeVarint(makeZigZag(i32, 32))
David Reissabafd792010-09-27 17:28:15 +0000274
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900275 @writer
276 def writeI64(self, i64):
277 self.__writeVarint(makeZigZag(i64, 64))
David Reissabafd792010-09-27 17:28:15 +0000278
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900279 @writer
280 def writeDouble(self, dub):
281 self.trans.write(pack('<d', dub))
David Reissabafd792010-09-27 17:28:15 +0000282
Carel Combrinka715bdf2025-10-30 07:44:21 +0100283 @writer
284 def writeUuid(self, uuid):
285 self.trans.write(uuid.bytes)
286
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900287 def __writeBinary(self, s):
288 self.__writeSize(len(s))
289 self.trans.write(s)
290 writeBinary = writer(__writeBinary)
David Reissabafd792010-09-27 17:28:15 +0000291
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900292 def readFieldBegin(self):
293 assert self.state == FIELD_READ, self.state
294 type = self.__readUByte()
295 if type & 0x0f == TType.STOP:
296 return (None, 0, 0)
297 delta = type >> 4
298 if delta == 0:
299 fid = self.__readI16()
300 else:
301 fid = self.__last_fid + delta
302 self.__last_fid = fid
303 type = type & 0x0f
304 if type == CompactType.TRUE:
305 self.state = BOOL_READ
306 self.__bool_value = True
307 elif type == CompactType.FALSE:
308 self.state = BOOL_READ
309 self.__bool_value = False
310 else:
311 self.state = VALUE_READ
312 return (None, self.__getTType(type), fid)
David Reissabafd792010-09-27 17:28:15 +0000313
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900314 def readFieldEnd(self):
315 assert self.state in (VALUE_READ, BOOL_READ), self.state
316 self.state = FIELD_READ
David Reissabafd792010-09-27 17:28:15 +0000317
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900318 def __readUByte(self):
319 result, = unpack('!B', self.trans.readAll(1))
320 return result
David Reissabafd792010-09-27 17:28:15 +0000321
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900322 def __readByte(self):
323 result, = unpack('!b', self.trans.readAll(1))
324 return result
David Reissabafd792010-09-27 17:28:15 +0000325
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900326 def __readVarint(self):
327 return readVarint(self.trans)
David Reissabafd792010-09-27 17:28:15 +0000328
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900329 def __readZigZag(self):
330 return fromZigZag(self.__readVarint())
David Reissabafd792010-09-27 17:28:15 +0000331
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900332 def __readSize(self):
333 result = self.__readVarint()
334 if result < 0:
335 raise TProtocolException("Length < 0")
336 return result
David Reissabafd792010-09-27 17:28:15 +0000337
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900338 def readMessageBegin(self):
339 assert self.state == CLEAR
340 proto_id = self.__readUByte()
341 if proto_id != self.PROTOCOL_ID:
342 raise TProtocolException(TProtocolException.BAD_VERSION,
343 'Bad protocol id in the message: %d' % proto_id)
344 ver_type = self.__readUByte()
345 type = (ver_type >> self.TYPE_SHIFT_AMOUNT) & self.TYPE_BITS
346 version = ver_type & self.VERSION_MASK
347 if version != self.VERSION:
348 raise TProtocolException(TProtocolException.BAD_VERSION,
349 'Bad version: %d (expect %d)' % (version, self.VERSION))
350 seqid = self.__readVarint()
James E. King IIIf15b4152019-01-31 13:01:56 -0500351 # the sequence is a compact "var int" which is treaded as unsigned,
352 # however the sequence is actually signed...
353 if seqid > 2147483647:
354 seqid = -2147483648 - (2147483648 - seqid)
Alexandre Detiste3494e1c2025-02-19 21:53:40 +0100355 name = self.__readBinary().decode('utf-8')
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900356 return (name, type, seqid)
David Reissabafd792010-09-27 17:28:15 +0000357
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900358 def readMessageEnd(self):
359 assert self.state == CLEAR
360 assert len(self.__structs) == 0
David Reissabafd792010-09-27 17:28:15 +0000361
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900362 def readStructBegin(self):
363 assert self.state in (CLEAR, CONTAINER_READ, VALUE_READ), self.state
364 self.__structs.append((self.state, self.__last_fid))
365 self.state = FIELD_READ
366 self.__last_fid = 0
David Reissabafd792010-09-27 17:28:15 +0000367
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900368 def readStructEnd(self):
369 assert self.state == FIELD_READ
370 self.state, self.__last_fid = self.__structs.pop()
David Reissabafd792010-09-27 17:28:15 +0000371
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900372 def readCollectionBegin(self):
373 assert self.state in (VALUE_READ, CONTAINER_READ), self.state
374 size_type = self.__readUByte()
375 size = size_type >> 4
376 type = self.__getTType(size_type)
377 if size == 15:
378 size = self.__readSize()
379 self._check_container_length(size)
380 self.__containers.append(self.state)
381 self.state = CONTAINER_READ
382 return type, size
383 readSetBegin = readCollectionBegin
384 readListBegin = readCollectionBegin
David Reissabafd792010-09-27 17:28:15 +0000385
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900386 def readMapBegin(self):
387 assert self.state in (VALUE_READ, CONTAINER_READ), self.state
388 size = self.__readSize()
389 self._check_container_length(size)
390 types = 0
391 if size > 0:
392 types = self.__readUByte()
393 vtype = self.__getTType(types)
394 ktype = self.__getTType(types >> 4)
395 self.__containers.append(self.state)
396 self.state = CONTAINER_READ
397 return (ktype, vtype, size)
David Reissabafd792010-09-27 17:28:15 +0000398
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900399 def readCollectionEnd(self):
400 assert self.state == CONTAINER_READ, self.state
401 self.state = self.__containers.pop()
402 readSetEnd = readCollectionEnd
403 readListEnd = readCollectionEnd
404 readMapEnd = readCollectionEnd
David Reissabafd792010-09-27 17:28:15 +0000405
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900406 def readBool(self):
407 if self.state == BOOL_READ:
408 return self.__bool_value == CompactType.TRUE
409 elif self.state == CONTAINER_READ:
410 return self.__readByte() == CompactType.TRUE
411 else:
412 raise AssertionError("Invalid state in compact protocol: %d" %
413 self.state)
David Reissabafd792010-09-27 17:28:15 +0000414
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900415 readByte = reader(__readByte)
416 __readI16 = __readZigZag
417 readI16 = reader(__readZigZag)
418 readI32 = reader(__readZigZag)
419 readI64 = reader(__readZigZag)
David Reissabafd792010-09-27 17:28:15 +0000420
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900421 @reader
422 def readDouble(self):
423 buff = self.trans.readAll(8)
424 val, = unpack('<d', buff)
425 return val
David Reissabafd792010-09-27 17:28:15 +0000426
Carel Combrinka715bdf2025-10-30 07:44:21 +0100427 @reader
428 def readUuid(self):
429 buff = self.trans.readAll(16)
430 val = uuid.UUID(bytes=buff)
431 return val
432
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900433 def __readBinary(self):
434 size = self.__readSize()
435 self._check_string_length(size)
436 return self.trans.readAll(size)
437 readBinary = reader(__readBinary)
David Reissabafd792010-09-27 17:28:15 +0000438
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900439 def __getTType(self, byte):
440 return TTYPES[byte & 0x0f]
David Reissabafd792010-09-27 17:28:15 +0000441
442
James E. King IIIe44f6a92019-02-07 17:11:21 -0500443class TCompactProtocolFactory(TProtocolFactory):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900444 def __init__(self,
445 string_length_limit=None,
446 container_length_limit=None):
447 self.string_length_limit = string_length_limit
448 self.container_length_limit = container_length_limit
David Reissabafd792010-09-27 17:28:15 +0000449
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900450 def getProtocol(self, trans):
451 return TCompactProtocol(trans,
452 self.string_length_limit,
453 self.container_length_limit)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900454
455
456class TCompactProtocolAccelerated(TCompactProtocol):
457 """C-Accelerated version of TCompactProtocol.
458
459 This class does not override any of TCompactProtocol's methods,
460 but the generated code recognizes it directly and will call into
461 our C module to do the encoding, bypassing this object entirely.
462 We inherit from TCompactProtocol so that the normal TCompactProtocol
463 encoding can happen if the fastbinary module doesn't work for some
464 reason.
465 To disable this behavior, pass fallback=False constructor argument.
466
467 In order to take advantage of the C module, just use
468 TCompactProtocolAccelerated instead of TCompactProtocol.
469 """
470 pass
471
472 def __init__(self, *args, **kwargs):
473 fallback = kwargs.pop('fallback', True)
474 super(TCompactProtocolAccelerated, self).__init__(*args, **kwargs)
475 try:
476 from thrift.protocol import fastbinary
477 except ImportError:
478 if not fallback:
479 raise
480 else:
481 self._fast_decode = fastbinary.decode_compact
482 self._fast_encode = fastbinary.encode_compact
483
484
James E. King IIIe44f6a92019-02-07 17:11:21 -0500485class TCompactProtocolAcceleratedFactory(TProtocolFactory):
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900486 def __init__(self,
487 string_length_limit=None,
488 container_length_limit=None,
489 fallback=True):
490 self.string_length_limit = string_length_limit
491 self.container_length_limit = container_length_limit
492 self._fallback = fallback
493
494 def getProtocol(self, trans):
495 return TCompactProtocolAccelerated(
496 trans,
497 string_length_limit=self.string_length_limit,
498 container_length_limit=self.container_length_limit,
499 fallback=self._fallback)