blob: db4ea31820451db70de59600f6965fdec6e69223 [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 Sukegawa760511f2015-11-06 21:24:16 +090020from .TProtocol import TType, TProtocolBase, TProtocolException
Mark Sleecde2b612006-09-03 21:13:07 +000021from struct import pack, unpack
22
Mark Sleecde2b612006-09-03 21:13:07 +000023
Bryan Duxbury69720412012-01-03 17:32:30 +000024class TBinaryProtocol(TProtocolBase):
Mark Sleecde2b612006-09-03 21:13:07 +000025 """Binary implementation of the Thrift protocol driver."""
26
Mark Slee9b36ef32007-10-02 04:44:48 +000027 # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be
28 # positive, converting this into a long. If we hardcode the int value
29 # instead it'll stay in 32 bit-land.
30
31 # VERSION_MASK = 0xffff0000
32 VERSION_MASK = -65536
33
34 # VERSION_1 = 0x80010000
35 VERSION_1 = -2147418112
36
37 TYPE_MASK = 0x000000ff
Mark Slee808454e2007-06-20 21:51:57 +000038
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +090039 def __init__(self, trans, strictRead=False, strictWrite=True, **kwargs):
Aditya Agarwal5c468192007-02-06 01:14:33 +000040 TProtocolBase.__init__(self, trans)
Mark Slee808454e2007-06-20 21:51:57 +000041 self.strictRead = strictRead
42 self.strictWrite = strictWrite
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +090043 self.string_length_limit = kwargs.get('string_length_limit', None)
44 self.container_length_limit = kwargs.get('container_length_limit', None)
45
46 def _check_string_length(self, length):
47 self._check_length(self.string_length_limit, length)
48
49 def _check_container_length(self, length):
50 self._check_length(self.container_length_limit, length)
Mark Sleecde2b612006-09-03 21:13:07 +000051
Mark Slee4ac459f2006-10-25 21:39:01 +000052 def writeMessageBegin(self, name, type, seqid):
Mark Slee808454e2007-06-20 21:51:57 +000053 if self.strictWrite:
Mark Slee552410c2007-06-22 01:03:55 +000054 self.writeI32(TBinaryProtocol.VERSION_1 | type)
Mark Slee808454e2007-06-20 21:51:57 +000055 self.writeString(name)
56 self.writeI32(seqid)
57 else:
58 self.writeString(name)
59 self.writeByte(type)
60 self.writeI32(seqid)
Mark Slee4ac459f2006-10-25 21:39:01 +000061
62 def writeMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000063 pass
64
Mark Slee4ac459f2006-10-25 21:39:01 +000065 def writeStructBegin(self, name):
Mark Sleecde2b612006-09-03 21:13:07 +000066 pass
67
Mark Slee4ac459f2006-10-25 21:39:01 +000068 def writeStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000069 pass
70
Mark Slee4ac459f2006-10-25 21:39:01 +000071 def writeFieldBegin(self, name, type, id):
72 self.writeByte(type)
73 self.writeI16(id)
Mark Sleecde2b612006-09-03 21:13:07 +000074
Mark Slee4ac459f2006-10-25 21:39:01 +000075 def writeFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000076 pass
77
Mark Slee4ac459f2006-10-25 21:39:01 +000078 def writeFieldStop(self):
Bryan Duxbury69720412012-01-03 17:32:30 +000079 self.writeByte(TType.STOP)
Mark Sleecde2b612006-09-03 21:13:07 +000080
Mark Slee4ac459f2006-10-25 21:39:01 +000081 def writeMapBegin(self, ktype, vtype, size):
82 self.writeByte(ktype)
83 self.writeByte(vtype)
84 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000085
Mark Slee4ac459f2006-10-25 21:39:01 +000086 def writeMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000087 pass
88
Mark Slee4ac459f2006-10-25 21:39:01 +000089 def writeListBegin(self, etype, size):
90 self.writeByte(etype)
91 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000092
Mark Slee4ac459f2006-10-25 21:39:01 +000093 def writeListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000094 pass
95
Mark Slee4ac459f2006-10-25 21:39:01 +000096 def writeSetBegin(self, etype, size):
97 self.writeByte(etype)
98 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000099
Mark Slee4ac459f2006-10-25 21:39:01 +0000100 def writeSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000101 pass
102
Mark Slee4ac459f2006-10-25 21:39:01 +0000103 def writeBool(self, bool):
Mark Sleecde2b612006-09-03 21:13:07 +0000104 if bool:
Mark Slee4ac459f2006-10-25 21:39:01 +0000105 self.writeByte(1)
Mark Sleecde2b612006-09-03 21:13:07 +0000106 else:
Mark Slee4ac459f2006-10-25 21:39:01 +0000107 self.writeByte(0)
David Reiss382fc302007-08-25 18:01:30 +0000108
Mark Slee4ac459f2006-10-25 21:39:01 +0000109 def writeByte(self, byte):
Mark Sleecde2b612006-09-03 21:13:07 +0000110 buff = pack("!b", byte)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000111 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000112
Mark Slee4ac459f2006-10-25 21:39:01 +0000113 def writeI16(self, i16):
Mark Sleecde2b612006-09-03 21:13:07 +0000114 buff = pack("!h", i16)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000115 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000116
Mark Slee4ac459f2006-10-25 21:39:01 +0000117 def writeI32(self, i32):
Mark Sleecde2b612006-09-03 21:13:07 +0000118 buff = pack("!i", i32)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000119 self.trans.write(buff)
David Reiss382fc302007-08-25 18:01:30 +0000120
Mark Slee4ac459f2006-10-25 21:39:01 +0000121 def writeI64(self, i64):
Mark Sleec9676562006-09-05 17:34:52 +0000122 buff = pack("!q", i64)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000123 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000124
Mark Slee4ac459f2006-10-25 21:39:01 +0000125 def writeDouble(self, dub):
Mark Sleec98d0502006-09-06 02:42:25 +0000126 buff = pack("!d", dub)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000127 self.trans.write(buff)
Mark Sleec98d0502006-09-06 02:42:25 +0000128
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900129 def writeBinary(self, str):
Mark Slee4ac459f2006-10-25 21:39:01 +0000130 self.writeI32(len(str))
Aditya Agarwal5c468192007-02-06 01:14:33 +0000131 self.trans.write(str)
Mark Sleecde2b612006-09-03 21:13:07 +0000132
Mark Slee4ac459f2006-10-25 21:39:01 +0000133 def readMessageBegin(self):
Mark Slee808454e2007-06-20 21:51:57 +0000134 sz = self.readI32()
135 if sz < 0:
Mark Slee552410c2007-06-22 01:03:55 +0000136 version = sz & TBinaryProtocol.VERSION_MASK
137 if version != TBinaryProtocol.VERSION_1:
Bryan Duxbury69720412012-01-03 17:32:30 +0000138 raise TProtocolException(
139 type=TProtocolException.BAD_VERSION,
140 message='Bad version in readMessageBegin: %d' % (sz))
Mark Slee9b36ef32007-10-02 04:44:48 +0000141 type = sz & TBinaryProtocol.TYPE_MASK
Mark Slee808454e2007-06-20 21:51:57 +0000142 name = self.readString()
143 seqid = self.readI32()
144 else:
145 if self.strictRead:
Bryan Duxbury69720412012-01-03 17:32:30 +0000146 raise TProtocolException(type=TProtocolException.BAD_VERSION,
147 message='No protocol version header')
Mark Slee808454e2007-06-20 21:51:57 +0000148 name = self.trans.readAll(sz)
149 type = self.readByte()
150 seqid = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000151 return (name, type, seqid)
152
Mark Slee4ac459f2006-10-25 21:39:01 +0000153 def readMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000154 pass
155
Mark Slee4ac459f2006-10-25 21:39:01 +0000156 def readStructBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000157 pass
158
Mark Slee4ac459f2006-10-25 21:39:01 +0000159 def readStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000160 pass
161
Mark Slee4ac459f2006-10-25 21:39:01 +0000162 def readFieldBegin(self):
163 type = self.readByte()
Mark Sleecde2b612006-09-03 21:13:07 +0000164 if type == TType.STOP:
165 return (None, type, 0)
Mark Slee4ac459f2006-10-25 21:39:01 +0000166 id = self.readI16()
Mark Sleecde2b612006-09-03 21:13:07 +0000167 return (None, type, id)
168
Mark Slee4ac459f2006-10-25 21:39:01 +0000169 def readFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000170 pass
171
Mark Slee4ac459f2006-10-25 21:39:01 +0000172 def readMapBegin(self):
173 ktype = self.readByte()
174 vtype = self.readByte()
175 size = self.readI32()
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900176 self._check_container_length(size)
Mark Sleecde2b612006-09-03 21:13:07 +0000177 return (ktype, vtype, size)
178
Mark Slee4ac459f2006-10-25 21:39:01 +0000179 def readMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000180 pass
181
Mark Slee4ac459f2006-10-25 21:39:01 +0000182 def readListBegin(self):
183 etype = self.readByte()
184 size = self.readI32()
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900185 self._check_container_length(size)
Mark Sleecde2b612006-09-03 21:13:07 +0000186 return (etype, size)
187
Mark Slee4ac459f2006-10-25 21:39:01 +0000188 def readListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000189 pass
190
Mark Slee4ac459f2006-10-25 21:39:01 +0000191 def readSetBegin(self):
192 etype = self.readByte()
193 size = self.readI32()
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900194 self._check_container_length(size)
Mark Sleecde2b612006-09-03 21:13:07 +0000195 return (etype, size)
196
Mark Slee4ac459f2006-10-25 21:39:01 +0000197 def readSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000198 pass
199
Mark Slee4ac459f2006-10-25 21:39:01 +0000200 def readBool(self):
201 byte = self.readByte()
Mark Sleecde2b612006-09-03 21:13:07 +0000202 if byte == 0:
203 return False
204 return True
205
Mark Slee4ac459f2006-10-25 21:39:01 +0000206 def readByte(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000207 buff = self.trans.readAll(1)
Mark Sleecde2b612006-09-03 21:13:07 +0000208 val, = unpack('!b', buff)
209 return val
210
Mark Slee4ac459f2006-10-25 21:39:01 +0000211 def readI16(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000212 buff = self.trans.readAll(2)
Mark Sleecde2b612006-09-03 21:13:07 +0000213 val, = unpack('!h', buff)
214 return val
215
Mark Slee4ac459f2006-10-25 21:39:01 +0000216 def readI32(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000217 buff = self.trans.readAll(4)
Mark Sleecde2b612006-09-03 21:13:07 +0000218 val, = unpack('!i', buff)
219 return val
220
Mark Slee4ac459f2006-10-25 21:39:01 +0000221 def readI64(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000222 buff = self.trans.readAll(8)
Mark Sleec9676562006-09-05 17:34:52 +0000223 val, = unpack('!q', buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000224 return val
225
Mark Slee4ac459f2006-10-25 21:39:01 +0000226 def readDouble(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000227 buff = self.trans.readAll(8)
Mark Sleec98d0502006-09-06 02:42:25 +0000228 val, = unpack('!d', buff)
229 return val
230
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900231 def readBinary(self):
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900232 size = self.readI32()
233 self._check_string_length(size)
234 s = self.trans.readAll(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900235 return s
Mark Slee4ac459f2006-10-25 21:39:01 +0000236
David Reiss382fc302007-08-25 18:01:30 +0000237
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +0900238class TBinaryProtocolFactory(object):
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900239 def __init__(self, strictRead=False, strictWrite=True, **kwargs):
Mark Slee808454e2007-06-20 21:51:57 +0000240 self.strictRead = strictRead
241 self.strictWrite = strictWrite
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900242 self.string_length_limit = kwargs.get('string_length_limit', None)
243 self.container_length_limit = kwargs.get('container_length_limit', None)
Mark Slee808454e2007-06-20 21:51:57 +0000244
Aditya Agarwal5c468192007-02-06 01:14:33 +0000245 def getProtocol(self, trans):
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900246 prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite,
247 string_length_limit=self.string_length_limit,
248 container_length_limit=self.container_length_limit)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000249 return prot
David Reiss382fc302007-08-25 18:01:30 +0000250
251
252class TBinaryProtocolAccelerated(TBinaryProtocol):
David Reiss382fc302007-08-25 18:01:30 +0000253 """C-Accelerated version of TBinaryProtocol.
254
255 This class does not override any of TBinaryProtocol's methods,
256 but the generated code recognizes it directly and will call into
257 our C module to do the encoding, bypassing this object entirely.
258 We inherit from TBinaryProtocol so that the normal TBinaryProtocol
259 encoding can happen if the fastbinary module doesn't work for some
David Reiss5db3e922007-08-30 23:07:45 +0000260 reason. (TODO(dreiss): Make this happen sanely in more cases.)
David Reiss382fc302007-08-25 18:01:30 +0000261
262 In order to take advantage of the C module, just use
263 TBinaryProtocolAccelerated instead of TBinaryProtocol.
264
265 NOTE: This code was contributed by an external developer.
266 The internal Thrift team has reviewed and tested it,
267 but we cannot guarantee that it is production-ready.
268 Please feel free to report bugs and/or success stories
269 to the public mailing list.
270 """
David Reiss382fc302007-08-25 18:01:30 +0000271 pass
272
273
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +0900274class TBinaryProtocolAcceleratedFactory(object):
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900275 def __init__(self,
276 string_length_limit=None,
277 container_length_limit=None):
278 self.string_length_limit = string_length_limit
279 self.container_length_limit = container_length_limit
280
David Reiss382fc302007-08-25 18:01:30 +0000281 def getProtocol(self, trans):
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900282 return TBinaryProtocolAccelerated(
283 trans,
284 string_length_limit=self.string_length_limit,
285 container_length_limit=self.container_length_limit)