blob: db1a7a4073012995a7fac56078e82420e692b4f6 [file] [log] [blame]
Gavin McDonald0b75e1a2010-10-28 02:12:01 +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
20from TProtocol import *
21from struct import pack, unpack
22
23class TBinaryProtocol(TProtocolBase):
24
25 """Binary implementation of the Thrift protocol driver."""
26
27 # 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
38
39 def __init__(self, trans, strictRead=False, strictWrite=True):
40 TProtocolBase.__init__(self, trans)
41 self.strictRead = strictRead
42 self.strictWrite = strictWrite
43
44 def writeMessageBegin(self, name, type, seqid):
45 if self.strictWrite:
46 self.writeI32(TBinaryProtocol.VERSION_1 | type)
47 self.writeString(name)
48 self.writeI32(seqid)
49 else:
50 self.writeString(name)
51 self.writeByte(type)
52 self.writeI32(seqid)
53
54 def writeMessageEnd(self):
55 pass
56
57 def writeStructBegin(self, name):
58 pass
59
60 def writeStructEnd(self):
61 pass
62
63 def writeFieldBegin(self, name, type, id):
64 self.writeByte(type)
65 self.writeI16(id)
66
67 def writeFieldEnd(self):
68 pass
69
70 def writeFieldStop(self):
71 self.writeByte(TType.STOP);
72
73 def writeMapBegin(self, ktype, vtype, size):
74 self.writeByte(ktype)
75 self.writeByte(vtype)
76 self.writeI32(size)
77
78 def writeMapEnd(self):
79 pass
80
81 def writeListBegin(self, etype, size):
82 self.writeByte(etype)
83 self.writeI32(size)
84
85 def writeListEnd(self):
86 pass
87
88 def writeSetBegin(self, etype, size):
89 self.writeByte(etype)
90 self.writeI32(size)
91
92 def writeSetEnd(self):
93 pass
94
95 def writeBool(self, bool):
96 if bool:
97 self.writeByte(1)
98 else:
99 self.writeByte(0)
100
101 def writeByte(self, byte):
102 buff = pack("!b", byte)
103 self.trans.write(buff)
104
105 def writeI16(self, i16):
106 buff = pack("!h", i16)
107 self.trans.write(buff)
108
109 def writeI32(self, i32):
110 buff = pack("!i", i32)
111 self.trans.write(buff)
112
113 def writeI64(self, i64):
114 buff = pack("!q", i64)
115 self.trans.write(buff)
116
117 def writeDouble(self, dub):
118 buff = pack("!d", dub)
119 self.trans.write(buff)
120
121 def writeString(self, str):
122 self.writeI32(len(str))
123 self.trans.write(str)
124
125 def readMessageBegin(self):
126 sz = self.readI32()
127 if sz < 0:
128 version = sz & TBinaryProtocol.VERSION_MASK
129 if version != TBinaryProtocol.VERSION_1:
130 raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad version in readMessageBegin: %d' % (sz))
131 type = sz & TBinaryProtocol.TYPE_MASK
132 name = self.readString()
133 seqid = self.readI32()
134 else:
135 if self.strictRead:
136 raise TProtocolException(TProtocolException.BAD_VERSION, 'No protocol version header')
137 name = self.trans.readAll(sz)
138 type = self.readByte()
139 seqid = self.readI32()
140 return (name, type, seqid)
141
142 def readMessageEnd(self):
143 pass
144
145 def readStructBegin(self):
146 pass
147
148 def readStructEnd(self):
149 pass
150
151 def readFieldBegin(self):
152 type = self.readByte()
153 if type == TType.STOP:
154 return (None, type, 0)
155 id = self.readI16()
156 return (None, type, id)
157
158 def readFieldEnd(self):
159 pass
160
161 def readMapBegin(self):
162 ktype = self.readByte()
163 vtype = self.readByte()
164 size = self.readI32()
165 return (ktype, vtype, size)
166
167 def readMapEnd(self):
168 pass
169
170 def readListBegin(self):
171 etype = self.readByte()
172 size = self.readI32()
173 return (etype, size)
174
175 def readListEnd(self):
176 pass
177
178 def readSetBegin(self):
179 etype = self.readByte()
180 size = self.readI32()
181 return (etype, size)
182
183 def readSetEnd(self):
184 pass
185
186 def readBool(self):
187 byte = self.readByte()
188 if byte == 0:
189 return False
190 return True
191
192 def readByte(self):
193 buff = self.trans.readAll(1)
194 val, = unpack('!b', buff)
195 return val
196
197 def readI16(self):
198 buff = self.trans.readAll(2)
199 val, = unpack('!h', buff)
200 return val
201
202 def readI32(self):
203 buff = self.trans.readAll(4)
204 val, = unpack('!i', buff)
205 return val
206
207 def readI64(self):
208 buff = self.trans.readAll(8)
209 val, = unpack('!q', buff)
210 return val
211
212 def readDouble(self):
213 buff = self.trans.readAll(8)
214 val, = unpack('!d', buff)
215 return val
216
217 def readString(self):
218 len = self.readI32()
219 str = self.trans.readAll(len)
220 return str
221
222
223class TBinaryProtocolFactory:
224 def __init__(self, strictRead=False, strictWrite=True):
225 self.strictRead = strictRead
226 self.strictWrite = strictWrite
227
228 def getProtocol(self, trans):
229 prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite)
230 return prot
231
232
233class TBinaryProtocolAccelerated(TBinaryProtocol):
234
235 """C-Accelerated version of TBinaryProtocol.
236
237 This class does not override any of TBinaryProtocol's methods,
238 but the generated code recognizes it directly and will call into
239 our C module to do the encoding, bypassing this object entirely.
240 We inherit from TBinaryProtocol so that the normal TBinaryProtocol
241 encoding can happen if the fastbinary module doesn't work for some
242 reason. (TODO(dreiss): Make this happen sanely in more cases.)
243
244 In order to take advantage of the C module, just use
245 TBinaryProtocolAccelerated instead of TBinaryProtocol.
246
247 NOTE: This code was contributed by an external developer.
248 The internal Thrift team has reviewed and tested it,
249 but we cannot guarantee that it is production-ready.
250 Please feel free to report bugs and/or success stories
251 to the public mailing list.
252 """
253
254 pass
255
256
257class TBinaryProtocolAcceleratedFactory:
258 def getProtocol(self, trans):
259 return TBinaryProtocolAccelerated(trans)