blob: b61f50eeb3e7fc6a860ad52fef8ffe23b6c6a78f [file] [log] [blame]
Mark Slee89e2bb82007-03-01 00:20:36 +00001# Copyright (c) 2006- Facebook
2# Distributed under the Thrift Software License
3#
4# See accompanying file LICENSE or visit the Thrift site at:
5# http://developers.facebook.com/thrift/
6
Mark Sleecde2b612006-09-03 21:13:07 +00007from TProtocol import *
8from struct import pack, unpack
9
10class TBinaryProtocol(TProtocolBase):
11
12 """Binary implementation of the Thrift protocol driver."""
13
Mark Slee9b36ef32007-10-02 04:44:48 +000014 # NastyHaxx. Python 2.4+ on 32-bit machines forces hex constants to be
15 # positive, converting this into a long. If we hardcode the int value
16 # instead it'll stay in 32 bit-land.
17
18 # VERSION_MASK = 0xffff0000
19 VERSION_MASK = -65536
20
21 # VERSION_1 = 0x80010000
22 VERSION_1 = -2147418112
23
24 TYPE_MASK = 0x000000ff
Mark Slee808454e2007-06-20 21:51:57 +000025
26 def __init__(self, trans, strictRead=False, strictWrite=True):
Aditya Agarwal5c468192007-02-06 01:14:33 +000027 TProtocolBase.__init__(self, trans)
Mark Slee808454e2007-06-20 21:51:57 +000028 self.strictRead = strictRead
29 self.strictWrite = strictWrite
Mark Sleecde2b612006-09-03 21:13:07 +000030
Mark Slee4ac459f2006-10-25 21:39:01 +000031 def writeMessageBegin(self, name, type, seqid):
Mark Slee808454e2007-06-20 21:51:57 +000032 if self.strictWrite:
Mark Slee552410c2007-06-22 01:03:55 +000033 self.writeI32(TBinaryProtocol.VERSION_1 | type)
Mark Slee808454e2007-06-20 21:51:57 +000034 self.writeString(name)
35 self.writeI32(seqid)
36 else:
37 self.writeString(name)
38 self.writeByte(type)
39 self.writeI32(seqid)
Mark Slee4ac459f2006-10-25 21:39:01 +000040
41 def writeMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000042 pass
43
Mark Slee4ac459f2006-10-25 21:39:01 +000044 def writeStructBegin(self, name):
Mark Sleecde2b612006-09-03 21:13:07 +000045 pass
46
Mark Slee4ac459f2006-10-25 21:39:01 +000047 def writeStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000048 pass
49
Mark Slee4ac459f2006-10-25 21:39:01 +000050 def writeFieldBegin(self, name, type, id):
51 self.writeByte(type)
52 self.writeI16(id)
Mark Sleecde2b612006-09-03 21:13:07 +000053
Mark Slee4ac459f2006-10-25 21:39:01 +000054 def writeFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000055 pass
56
Mark Slee4ac459f2006-10-25 21:39:01 +000057 def writeFieldStop(self):
58 self.writeByte(TType.STOP);
Mark Sleecde2b612006-09-03 21:13:07 +000059
Mark Slee4ac459f2006-10-25 21:39:01 +000060 def writeMapBegin(self, ktype, vtype, size):
61 self.writeByte(ktype)
62 self.writeByte(vtype)
63 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000064
Mark Slee4ac459f2006-10-25 21:39:01 +000065 def writeMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000066 pass
67
Mark Slee4ac459f2006-10-25 21:39:01 +000068 def writeListBegin(self, etype, size):
69 self.writeByte(etype)
70 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000071
Mark Slee4ac459f2006-10-25 21:39:01 +000072 def writeListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000073 pass
74
Mark Slee4ac459f2006-10-25 21:39:01 +000075 def writeSetBegin(self, etype, size):
76 self.writeByte(etype)
77 self.writeI32(size)
Mark Sleecde2b612006-09-03 21:13:07 +000078
Mark Slee4ac459f2006-10-25 21:39:01 +000079 def writeSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +000080 pass
81
Mark Slee4ac459f2006-10-25 21:39:01 +000082 def writeBool(self, bool):
Mark Sleecde2b612006-09-03 21:13:07 +000083 if bool:
Mark Slee4ac459f2006-10-25 21:39:01 +000084 self.writeByte(1)
Mark Sleecde2b612006-09-03 21:13:07 +000085 else:
Mark Slee4ac459f2006-10-25 21:39:01 +000086 self.writeByte(0)
David Reiss382fc302007-08-25 18:01:30 +000087
Mark Slee4ac459f2006-10-25 21:39:01 +000088 def writeByte(self, byte):
Mark Sleecde2b612006-09-03 21:13:07 +000089 buff = pack("!b", byte)
Aditya Agarwal5c468192007-02-06 01:14:33 +000090 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +000091
Mark Slee4ac459f2006-10-25 21:39:01 +000092 def writeI16(self, i16):
Mark Sleecde2b612006-09-03 21:13:07 +000093 buff = pack("!h", i16)
Aditya Agarwal5c468192007-02-06 01:14:33 +000094 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +000095
Mark Slee4ac459f2006-10-25 21:39:01 +000096 def writeI32(self, i32):
Mark Sleecde2b612006-09-03 21:13:07 +000097 buff = pack("!i", i32)
Aditya Agarwal5c468192007-02-06 01:14:33 +000098 self.trans.write(buff)
David Reiss382fc302007-08-25 18:01:30 +000099
Mark Slee4ac459f2006-10-25 21:39:01 +0000100 def writeI64(self, i64):
Mark Sleec9676562006-09-05 17:34:52 +0000101 buff = pack("!q", i64)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000102 self.trans.write(buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000103
Mark Slee4ac459f2006-10-25 21:39:01 +0000104 def writeDouble(self, dub):
Mark Sleec98d0502006-09-06 02:42:25 +0000105 buff = pack("!d", dub)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000106 self.trans.write(buff)
Mark Sleec98d0502006-09-06 02:42:25 +0000107
Mark Slee4ac459f2006-10-25 21:39:01 +0000108 def writeString(self, str):
109 self.writeI32(len(str))
Aditya Agarwal5c468192007-02-06 01:14:33 +0000110 self.trans.write(str)
Mark Sleecde2b612006-09-03 21:13:07 +0000111
Mark Slee4ac459f2006-10-25 21:39:01 +0000112 def readMessageBegin(self):
Mark Slee808454e2007-06-20 21:51:57 +0000113 sz = self.readI32()
114 if sz < 0:
Mark Slee552410c2007-06-22 01:03:55 +0000115 version = sz & TBinaryProtocol.VERSION_MASK
116 if version != TBinaryProtocol.VERSION_1:
Mark Slee808454e2007-06-20 21:51:57 +0000117 raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad version in readMessageBegin: %d' % (sz))
Mark Slee9b36ef32007-10-02 04:44:48 +0000118 type = sz & TBinaryProtocol.TYPE_MASK
Mark Slee808454e2007-06-20 21:51:57 +0000119 name = self.readString()
120 seqid = self.readI32()
121 else:
122 if self.strictRead:
123 raise TProtocolException(TProtocolException.BAD_VERSION, 'No protocol version header')
124 name = self.trans.readAll(sz)
125 type = self.readByte()
126 seqid = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000127 return (name, type, seqid)
128
Mark Slee4ac459f2006-10-25 21:39:01 +0000129 def readMessageEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000130 pass
131
Mark Slee4ac459f2006-10-25 21:39:01 +0000132 def readStructBegin(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000133 pass
134
Mark Slee4ac459f2006-10-25 21:39:01 +0000135 def readStructEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000136 pass
137
Mark Slee4ac459f2006-10-25 21:39:01 +0000138 def readFieldBegin(self):
139 type = self.readByte()
Mark Sleecde2b612006-09-03 21:13:07 +0000140 if type == TType.STOP:
141 return (None, type, 0)
Mark Slee4ac459f2006-10-25 21:39:01 +0000142 id = self.readI16()
Mark Sleecde2b612006-09-03 21:13:07 +0000143 return (None, type, id)
144
Mark Slee4ac459f2006-10-25 21:39:01 +0000145 def readFieldEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000146 pass
147
Mark Slee4ac459f2006-10-25 21:39:01 +0000148 def readMapBegin(self):
149 ktype = self.readByte()
150 vtype = self.readByte()
151 size = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000152 return (ktype, vtype, size)
153
Mark Slee4ac459f2006-10-25 21:39:01 +0000154 def readMapEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000155 pass
156
Mark Slee4ac459f2006-10-25 21:39:01 +0000157 def readListBegin(self):
158 etype = self.readByte()
159 size = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000160 return (etype, size)
161
Mark Slee4ac459f2006-10-25 21:39:01 +0000162 def readListEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000163 pass
164
Mark Slee4ac459f2006-10-25 21:39:01 +0000165 def readSetBegin(self):
166 etype = self.readByte()
167 size = self.readI32()
Mark Sleecde2b612006-09-03 21:13:07 +0000168 return (etype, size)
169
Mark Slee4ac459f2006-10-25 21:39:01 +0000170 def readSetEnd(self):
Mark Sleecde2b612006-09-03 21:13:07 +0000171 pass
172
Mark Slee4ac459f2006-10-25 21:39:01 +0000173 def readBool(self):
174 byte = self.readByte()
Mark Sleecde2b612006-09-03 21:13:07 +0000175 if byte == 0:
176 return False
177 return True
178
Mark Slee4ac459f2006-10-25 21:39:01 +0000179 def readByte(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000180 buff = self.trans.readAll(1)
Mark Sleecde2b612006-09-03 21:13:07 +0000181 val, = unpack('!b', buff)
182 return val
183
Mark Slee4ac459f2006-10-25 21:39:01 +0000184 def readI16(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000185 buff = self.trans.readAll(2)
Mark Sleecde2b612006-09-03 21:13:07 +0000186 val, = unpack('!h', buff)
187 return val
188
Mark Slee4ac459f2006-10-25 21:39:01 +0000189 def readI32(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000190 buff = self.trans.readAll(4)
Mark Sleecde2b612006-09-03 21:13:07 +0000191 val, = unpack('!i', buff)
192 return val
193
Mark Slee4ac459f2006-10-25 21:39:01 +0000194 def readI64(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000195 buff = self.trans.readAll(8)
Mark Sleec9676562006-09-05 17:34:52 +0000196 val, = unpack('!q', buff)
Mark Sleecde2b612006-09-03 21:13:07 +0000197 return val
198
Mark Slee4ac459f2006-10-25 21:39:01 +0000199 def readDouble(self):
Aditya Agarwal5c468192007-02-06 01:14:33 +0000200 buff = self.trans.readAll(8)
Mark Sleec98d0502006-09-06 02:42:25 +0000201 val, = unpack('!d', buff)
202 return val
203
Mark Slee4ac459f2006-10-25 21:39:01 +0000204 def readString(self):
205 len = self.readI32()
Aditya Agarwal5c468192007-02-06 01:14:33 +0000206 str = self.trans.readAll(len)
Mark Sleecde2b612006-09-03 21:13:07 +0000207 return str
Mark Slee4ac459f2006-10-25 21:39:01 +0000208
David Reiss382fc302007-08-25 18:01:30 +0000209
Mark Slee4ac459f2006-10-25 21:39:01 +0000210class TBinaryProtocolFactory:
Mark Slee808454e2007-06-20 21:51:57 +0000211 def __init__(self, strictRead=False, strictWrite=True):
212 self.strictRead = strictRead
213 self.strictWrite = strictWrite
214
Aditya Agarwal5c468192007-02-06 01:14:33 +0000215 def getProtocol(self, trans):
Mark Slee808454e2007-06-20 21:51:57 +0000216 prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite)
Aditya Agarwal5c468192007-02-06 01:14:33 +0000217 return prot
David Reiss382fc302007-08-25 18:01:30 +0000218
219
220class TBinaryProtocolAccelerated(TBinaryProtocol):
221
222 """C-Accelerated version of TBinaryProtocol.
223
224 This class does not override any of TBinaryProtocol's methods,
225 but the generated code recognizes it directly and will call into
226 our C module to do the encoding, bypassing this object entirely.
227 We inherit from TBinaryProtocol so that the normal TBinaryProtocol
228 encoding can happen if the fastbinary module doesn't work for some
David Reiss5db3e922007-08-30 23:07:45 +0000229 reason. (TODO(dreiss): Make this happen sanely in more cases.)
David Reiss382fc302007-08-25 18:01:30 +0000230
231 In order to take advantage of the C module, just use
232 TBinaryProtocolAccelerated instead of TBinaryProtocol.
233
234 NOTE: This code was contributed by an external developer.
235 The internal Thrift team has reviewed and tested it,
236 but we cannot guarantee that it is production-ready.
237 Please feel free to report bugs and/or success stories
238 to the public mailing list.
239 """
240
241 pass
242
243
244class TBinaryProtocolAcceleratedFactory:
245 def getProtocol(self, trans):
246 return TBinaryProtocolAccelerated(trans)