blob: d163a6e653c4f154accebb03fba838a9adb43615 [file] [log] [blame]
Mark Slee89e2bb82007-03-01 00:20:36 +00001#!/usr/bin/env python
2#
3# Copyright (c) 2006- Facebook
4# Distributed under the Thrift Software License
5#
6# See accompanying file LICENSE or visit the Thrift site at:
7# http://developers.facebook.com/thrift/
8
Mark Sleecde2b612006-09-03 21:13:07 +00009from TProtocol import *
10from struct import pack, unpack
11
12class TBinaryProtocol(TProtocolBase):
13
14 """Binary implementation of the Thrift protocol driver."""
15
Mark Slee9b36ef32007-10-02 04:44:48 +000016 # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be
17 # positive, converting this into a long. If we hardcode the int value
18 # instead it'll stay in 32 bit-land.
19
20 # VERSION_MASK = 0xffff0000
21 VERSION_MASK = -65536
22
23 # VERSION_1 = 0x80010000
24 VERSION_1 = -2147418112
25
26 TYPE_MASK = 0x000000ff
Mark Slee808454e2007-06-20 21:51:57 +000027
28 def __init__(self, trans, strictRead=False, strictWrite=True):
Aditya Agarwal5c468192007-02-06 01:14:33 +000029 TProtocolBase.__init__(self, trans)
Mark Slee808454e2007-06-20 21:51:57 +000030 self.strictRead = strictRead
31 self.strictWrite = strictWrite
Mark Sleecde2b612006-09-03 21:13:07 +000032
Mark Slee4ac459f2006-10-25 21:39:01 +000033 def writeMessageBegin(self, name, type, seqid):
Mark Slee808454e2007-06-20 21:51:57 +000034 if self.strictWrite:
Mark Slee552410c2007-06-22 01:03:55 +000035 self.writeI32(TBinaryProtocol.VERSION_1 | type)
Mark Slee808454e2007-06-20 21:51:57 +000036 self.writeString(name)
37 self.writeI32(seqid)
38 else:
39 self.writeString(name)
40 self.writeByte(type)
41 self.writeI32(seqid)
Mark Slee4ac459f2006-10-25 21:39:01 +000042
43 def writeMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000044 pass
45
Mark Slee4ac459f2006-10-25 21:39:01 +000046 def writeStructBegin(self, name):
Mark Sleecde2b612006-09-03 21:13:07 +000047 pass
48
Mark Slee4ac459f2006-10-25 21:39:01 +000049 def writeStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000050 pass
51
Mark Slee4ac459f2006-10-25 21:39:01 +000052 def writeFieldBegin(self, name, type, id):
53 self.writeByte(type)
54 self.writeI16(id)
Mark Sleecde2b612006-09-03 21:13:07 +000055
Mark Slee4ac459f2006-10-25 21:39:01 +000056 def writeFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000057 pass
58
Mark Slee4ac459f2006-10-25 21:39:01 +000059 def writeFieldStop(self):
60 self.writeByte(TType.STOP);
Mark Sleecde2b612006-09-03 21:13:07 +000061
Mark Slee4ac459f2006-10-25 21:39:01 +000062 def writeMapBegin(self, ktype, vtype, size):
63 self.writeByte(ktype)
64 self.writeByte(vtype)
65 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000066
Mark Slee4ac459f2006-10-25 21:39:01 +000067 def writeMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000068 pass
69
Mark Slee4ac459f2006-10-25 21:39:01 +000070 def writeListBegin(self, etype, size):
71 self.writeByte(etype)
72 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000073
Mark Slee4ac459f2006-10-25 21:39:01 +000074 def writeListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000075 pass
76
Mark Slee4ac459f2006-10-25 21:39:01 +000077 def writeSetBegin(self, etype, size):
78 self.writeByte(etype)
79 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000080
Mark Slee4ac459f2006-10-25 21:39:01 +000081 def writeSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000082 pass
83
Mark Slee4ac459f2006-10-25 21:39:01 +000084 def writeBool(self, bool):
Mark Sleecde2b612006-09-03 21:13:07 +000085 if bool:
Mark Slee4ac459f2006-10-25 21:39:01 +000086 self.writeByte(1)
Mark Sleecde2b612006-09-03 21:13:07 +000087 else:
Mark Slee4ac459f2006-10-25 21:39:01 +000088 self.writeByte(0)
David Reiss382fc302007-08-25 18:01:30 +000089
Mark Slee4ac459f2006-10-25 21:39:01 +000090 def writeByte(self, byte):
Mark Sleecde2b612006-09-03 21:13:07 +000091 buff = pack("!b", byte)
Aditya Agarwal5c468192007-02-06 01:14:33 +000092 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +000093
Mark Slee4ac459f2006-10-25 21:39:01 +000094 def writeI16(self, i16):
Mark Sleecde2b612006-09-03 21:13:07 +000095 buff = pack("!h", i16)
Aditya Agarwal5c468192007-02-06 01:14:33 +000096 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +000097
Mark Slee4ac459f2006-10-25 21:39:01 +000098 def writeI32(self, i32):
Mark Sleecde2b612006-09-03 21:13:07 +000099 buff = pack("!i", i32)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000100 self.trans.write(buff)
David Reiss382fc302007-08-25 18:01:30 +0000101
Mark Slee4ac459f2006-10-25 21:39:01 +0000102 def writeI64(self, i64):
Mark Sleec9676562006-09-05 17:34:52 +0000103 buff = pack("!q", i64)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000104 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000105
Mark Slee4ac459f2006-10-25 21:39:01 +0000106 def writeDouble(self, dub):
Mark Sleec98d0502006-09-06 02:42:25 +0000107 buff = pack("!d", dub)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000108 self.trans.write(buff)
Mark Sleec98d0502006-09-06 02:42:25 +0000109
Mark Slee4ac459f2006-10-25 21:39:01 +0000110 def writeString(self, str):
111 self.writeI32(len(str))
Aditya Agarwal5c468192007-02-06 01:14:33 +0000112 self.trans.write(str)
Mark Sleecde2b612006-09-03 21:13:07 +0000113
Mark Slee4ac459f2006-10-25 21:39:01 +0000114 def readMessageBegin(self):
Mark Slee808454e2007-06-20 21:51:57 +0000115 sz = self.readI32()
116 if sz < 0:
Mark Slee552410c2007-06-22 01:03:55 +0000117 version = sz & TBinaryProtocol.VERSION_MASK
118 if version != TBinaryProtocol.VERSION_1:
Mark Slee808454e2007-06-20 21:51:57 +0000119 raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad version in readMessageBegin: %d' % (sz))
Mark Slee9b36ef32007-10-02 04:44:48 +0000120 type = sz & TBinaryProtocol.TYPE_MASK
Mark Slee808454e2007-06-20 21:51:57 +0000121 name = self.readString()
122 seqid = self.readI32()
123 else:
124 if self.strictRead:
125 raise TProtocolException(TProtocolException.BAD_VERSION, 'No protocol version header')
126 name = self.trans.readAll(sz)
127 type = self.readByte()
128 seqid = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000129 return (name, type, seqid)
130
Mark Slee4ac459f2006-10-25 21:39:01 +0000131 def readMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000132 pass
133
Mark Slee4ac459f2006-10-25 21:39:01 +0000134 def readStructBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000135 pass
136
Mark Slee4ac459f2006-10-25 21:39:01 +0000137 def readStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000138 pass
139
Mark Slee4ac459f2006-10-25 21:39:01 +0000140 def readFieldBegin(self):
141 type = self.readByte()
Mark Sleecde2b612006-09-03 21:13:07 +0000142 if type == TType.STOP:
143 return (None, type, 0)
Mark Slee4ac459f2006-10-25 21:39:01 +0000144 id = self.readI16()
Mark Sleecde2b612006-09-03 21:13:07 +0000145 return (None, type, id)
146
Mark Slee4ac459f2006-10-25 21:39:01 +0000147 def readFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000148 pass
149
Mark Slee4ac459f2006-10-25 21:39:01 +0000150 def readMapBegin(self):
151 ktype = self.readByte()
152 vtype = self.readByte()
153 size = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000154 return (ktype, vtype, size)
155
Mark Slee4ac459f2006-10-25 21:39:01 +0000156 def readMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000157 pass
158
Mark Slee4ac459f2006-10-25 21:39:01 +0000159 def readListBegin(self):
160 etype = self.readByte()
161 size = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000162 return (etype, size)
163
Mark Slee4ac459f2006-10-25 21:39:01 +0000164 def readListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000165 pass
166
Mark Slee4ac459f2006-10-25 21:39:01 +0000167 def readSetBegin(self):
168 etype = self.readByte()
169 size = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000170 return (etype, size)
171
Mark Slee4ac459f2006-10-25 21:39:01 +0000172 def readSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000173 pass
174
Mark Slee4ac459f2006-10-25 21:39:01 +0000175 def readBool(self):
176 byte = self.readByte()
Mark Sleecde2b612006-09-03 21:13:07 +0000177 if byte == 0:
178 return False
179 return True
180
Mark Slee4ac459f2006-10-25 21:39:01 +0000181 def readByte(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000182 buff = self.trans.readAll(1)
Mark Sleecde2b612006-09-03 21:13:07 +0000183 val, = unpack('!b', buff)
184 return val
185
Mark Slee4ac459f2006-10-25 21:39:01 +0000186 def readI16(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000187 buff = self.trans.readAll(2)
Mark Sleecde2b612006-09-03 21:13:07 +0000188 val, = unpack('!h', buff)
189 return val
190
Mark Slee4ac459f2006-10-25 21:39:01 +0000191 def readI32(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000192 buff = self.trans.readAll(4)
Mark Sleecde2b612006-09-03 21:13:07 +0000193 val, = unpack('!i', buff)
194 return val
195
Mark Slee4ac459f2006-10-25 21:39:01 +0000196 def readI64(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000197 buff = self.trans.readAll(8)
Mark Sleec9676562006-09-05 17:34:52 +0000198 val, = unpack('!q', buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000199 return val
200
Mark Slee4ac459f2006-10-25 21:39:01 +0000201 def readDouble(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000202 buff = self.trans.readAll(8)
Mark Sleec98d0502006-09-06 02:42:25 +0000203 val, = unpack('!d', buff)
204 return val
205
Mark Slee4ac459f2006-10-25 21:39:01 +0000206 def readString(self):
207 len = self.readI32()
Aditya Agarwal5c468192007-02-06 01:14:33 +0000208 str = self.trans.readAll(len)
Mark Sleecde2b612006-09-03 21:13:07 +0000209 return str
Mark Slee4ac459f2006-10-25 21:39:01 +0000210
David Reiss382fc302007-08-25 18:01:30 +0000211
Mark Slee4ac459f2006-10-25 21:39:01 +0000212class TBinaryProtocolFactory:
Mark Slee808454e2007-06-20 21:51:57 +0000213 def __init__(self, strictRead=False, strictWrite=True):
214 self.strictRead = strictRead
215 self.strictWrite = strictWrite
216
Aditya Agarwal5c468192007-02-06 01:14:33 +0000217 def getProtocol(self, trans):
Mark Slee808454e2007-06-20 21:51:57 +0000218 prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000219 return prot
David Reiss382fc302007-08-25 18:01:30 +0000220
221
222class TBinaryProtocolAccelerated(TBinaryProtocol):
223
224 """C-Accelerated version of TBinaryProtocol.
225
226 This class does not override any of TBinaryProtocol's methods,
227 but the generated code recognizes it directly and will call into
228 our C module to do the encoding, bypassing this object entirely.
229 We inherit from TBinaryProtocol so that the normal TBinaryProtocol
230 encoding can happen if the fastbinary module doesn't work for some
David Reiss5db3e922007-08-30 23:07:45 +0000231 reason. (TODO(dreiss): Make this happen sanely in more cases.)
David Reiss382fc302007-08-25 18:01:30 +0000232
233 In order to take advantage of the C module, just use
234 TBinaryProtocolAccelerated instead of TBinaryProtocol.
235
236 NOTE: This code was contributed by an external developer.
237 The internal Thrift team has reviewed and tested it,
238 but we cannot guarantee that it is production-ready.
239 Please feel free to report bugs and/or success stories
240 to the public mailing list.
241 """
242
243 pass
244
245
246class TBinaryProtocolAcceleratedFactory:
247 def getProtocol(self, trans):
248 return TBinaryProtocolAccelerated(trans)