blob: 7fce12f07a87d4aa0944cee1155837974647e1ab [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):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090025 """Binary implementation of the Thrift protocol driver."""
Mark Sleecde2b612006-09-03 21:13:07 +000026
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090027 # 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.
Mark Slee9b36ef32007-10-02 04:44:48 +000030
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090031 # VERSION_MASK = 0xffff0000
32 VERSION_MASK = -65536
Mark Slee9b36ef32007-10-02 04:44:48 +000033
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090034 # VERSION_1 = 0x80010000
35 VERSION_1 = -2147418112
Mark Slee9b36ef32007-10-02 04:44:48 +000036
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090037 TYPE_MASK = 0x000000ff
Mark Slee808454e2007-06-20 21:51:57 +000038
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090039 def __init__(self, trans, strictRead=False, strictWrite=True, **kwargs):
40 TProtocolBase.__init__(self, trans)
41 self.strictRead = strictRead
42 self.strictWrite = strictWrite
43 self.string_length_limit = kwargs.get('string_length_limit', None)
44 self.container_length_limit = kwargs.get('container_length_limit', None)
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +090045
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090046 def _check_string_length(self, length):
47 self._check_length(self.string_length_limit, length)
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +090048
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090049 def _check_container_length(self, length):
50 self._check_length(self.container_length_limit, length)
Mark Sleecde2b612006-09-03 21:13:07 +000051
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090052 def writeMessageBegin(self, name, type, seqid):
53 if self.strictWrite:
54 self.writeI32(TBinaryProtocol.VERSION_1 | type)
55 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
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090062 def writeMessageEnd(self):
63 pass
Mark Sleecde2b612006-09-03 21:13:07 +000064
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090065 def writeStructBegin(self, name):
66 pass
Mark Sleecde2b612006-09-03 21:13:07 +000067
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090068 def writeStructEnd(self):
69 pass
Mark Sleecde2b612006-09-03 21:13:07 +000070
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090071 def writeFieldBegin(self, name, type, id):
72 self.writeByte(type)
73 self.writeI16(id)
Mark Sleecde2b612006-09-03 21:13:07 +000074
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090075 def writeFieldEnd(self):
76 pass
Mark Sleecde2b612006-09-03 21:13:07 +000077
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090078 def writeFieldStop(self):
79 self.writeByte(TType.STOP)
Mark Sleecde2b612006-09-03 21:13:07 +000080
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090081 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
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090086 def writeMapEnd(self):
87 pass
Mark Sleecde2b612006-09-03 21:13:07 +000088
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090089 def writeListBegin(self, etype, size):
90 self.writeByte(etype)
91 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000092
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090093 def writeListEnd(self):
94 pass
Mark Sleecde2b612006-09-03 21:13:07 +000095
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090096 def writeSetBegin(self, etype, size):
97 self.writeByte(etype)
98 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000099
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900100 def writeSetEnd(self):
101 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000102
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900103 def writeBool(self, bool):
104 if bool:
105 self.writeByte(1)
106 else:
107 self.writeByte(0)
David Reiss382fc302007-08-25 18:01:30 +0000108
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900109 def writeByte(self, byte):
110 buff = pack("!b", byte)
111 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000112
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900113 def writeI16(self, i16):
114 buff = pack("!h", i16)
115 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000116
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900117 def writeI32(self, i32):
118 buff = pack("!i", i32)
119 self.trans.write(buff)
David Reiss382fc302007-08-25 18:01:30 +0000120
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900121 def writeI64(self, i64):
122 buff = pack("!q", i64)
123 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000124
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900125 def writeDouble(self, dub):
126 buff = pack("!d", dub)
127 self.trans.write(buff)
Mark Sleec98d0502006-09-06 02:42:25 +0000128
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900129 def writeBinary(self, str):
130 self.writeI32(len(str))
131 self.trans.write(str)
Mark Sleecde2b612006-09-03 21:13:07 +0000132
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900133 def readMessageBegin(self):
134 sz = self.readI32()
135 if sz < 0:
136 version = sz & TBinaryProtocol.VERSION_MASK
137 if version != TBinaryProtocol.VERSION_1:
138 raise TProtocolException(
139 type=TProtocolException.BAD_VERSION,
140 message='Bad version in readMessageBegin: %d' % (sz))
141 type = sz & TBinaryProtocol.TYPE_MASK
142 name = self.readString()
143 seqid = self.readI32()
144 else:
145 if self.strictRead:
146 raise TProtocolException(type=TProtocolException.BAD_VERSION,
147 message='No protocol version header')
148 name = self.trans.readAll(sz)
149 type = self.readByte()
150 seqid = self.readI32()
151 return (name, type, seqid)
Mark Sleecde2b612006-09-03 21:13:07 +0000152
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900153 def readMessageEnd(self):
154 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000155
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900156 def readStructBegin(self):
157 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000158
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900159 def readStructEnd(self):
160 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000161
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900162 def readFieldBegin(self):
163 type = self.readByte()
164 if type == TType.STOP:
165 return (None, type, 0)
166 id = self.readI16()
167 return (None, type, id)
Mark Sleecde2b612006-09-03 21:13:07 +0000168
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900169 def readFieldEnd(self):
170 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000171
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900172 def readMapBegin(self):
173 ktype = self.readByte()
174 vtype = self.readByte()
175 size = self.readI32()
176 self._check_container_length(size)
177 return (ktype, vtype, size)
Mark Sleecde2b612006-09-03 21:13:07 +0000178
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900179 def readMapEnd(self):
180 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000181
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900182 def readListBegin(self):
183 etype = self.readByte()
184 size = self.readI32()
185 self._check_container_length(size)
186 return (etype, size)
Mark Sleecde2b612006-09-03 21:13:07 +0000187
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900188 def readListEnd(self):
189 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000190
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900191 def readSetBegin(self):
192 etype = self.readByte()
193 size = self.readI32()
194 self._check_container_length(size)
195 return (etype, size)
Mark Sleecde2b612006-09-03 21:13:07 +0000196
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900197 def readSetEnd(self):
198 pass
Mark Sleecde2b612006-09-03 21:13:07 +0000199
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900200 def readBool(self):
201 byte = self.readByte()
202 if byte == 0:
203 return False
204 return True
Mark Sleecde2b612006-09-03 21:13:07 +0000205
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900206 def readByte(self):
207 buff = self.trans.readAll(1)
208 val, = unpack('!b', buff)
209 return val
Mark Sleecde2b612006-09-03 21:13:07 +0000210
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900211 def readI16(self):
212 buff = self.trans.readAll(2)
213 val, = unpack('!h', buff)
214 return val
Mark Sleecde2b612006-09-03 21:13:07 +0000215
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900216 def readI32(self):
217 buff = self.trans.readAll(4)
218 val, = unpack('!i', buff)
219 return val
Mark Sleecde2b612006-09-03 21:13:07 +0000220
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900221 def readI64(self):
222 buff = self.trans.readAll(8)
223 val, = unpack('!q', buff)
224 return val
Mark Sleecde2b612006-09-03 21:13:07 +0000225
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900226 def readDouble(self):
227 buff = self.trans.readAll(8)
228 val, = unpack('!d', buff)
229 return val
Mark Sleec98d0502006-09-06 02:42:25 +0000230
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900231 def readBinary(self):
232 size = self.readI32()
233 self._check_string_length(size)
234 s = self.trans.readAll(size)
235 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 Sukegawa10308cb2016-02-03 01:57:03 +0900239 def __init__(self, strictRead=False, strictWrite=True, **kwargs):
240 self.strictRead = strictRead
241 self.strictWrite = strictWrite
242 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
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900245 def getProtocol(self, trans):
246 prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite,
247 string_length_limit=self.string_length_limit,
248 container_length_limit=self.container_length_limit)
249 return prot
David Reiss382fc302007-08-25 18:01:30 +0000250
251
252class TBinaryProtocolAccelerated(TBinaryProtocol):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900253 """C-Accelerated version of TBinaryProtocol.
David Reiss382fc302007-08-25 18:01:30 +0000254
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900255 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
260 reason. (TODO(dreiss): Make this happen sanely in more cases.)
David Reiss382fc302007-08-25 18:01:30 +0000261
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900262 In order to take advantage of the C module, just use
263 TBinaryProtocolAccelerated instead of TBinaryProtocol.
David Reiss382fc302007-08-25 18:01:30 +0000264
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900265 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 """
271 pass
David Reiss382fc302007-08-25 18:01:30 +0000272
273
Nobuaki Sukegawab9c859a2015-12-21 01:10:25 +0900274class TBinaryProtocolAcceleratedFactory(object):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +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
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900280
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900281 def getProtocol(self, trans):
282 return TBinaryProtocolAccelerated(
283 trans,
284 string_length_limit=self.string_length_limit,
285 container_length_limit=self.container_length_limit)