| Mark Slee | 89e2bb8 | 2007-03-01 00:20:36 +0000 | [diff] [blame] | 1 | #!/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 Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 9 | from TProtocol import * | 
 | 10 | from struct import pack, unpack | 
 | 11 |  | 
 | 12 | class TBinaryProtocol(TProtocolBase): | 
 | 13 |  | 
 | 14 |   """Binary implementation of the Thrift protocol driver.""" | 
 | 15 |  | 
| Mark Slee | 9b36ef3 | 2007-10-02 04:44:48 +0000 | [diff] [blame] | 16 |   # 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 Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 27 |  | 
 | 28 |   def __init__(self, trans, strictRead=False, strictWrite=True): | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 29 |     TProtocolBase.__init__(self, trans) | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 30 |     self.strictRead = strictRead | 
 | 31 |     self.strictWrite = strictWrite | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 32 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 33 |   def writeMessageBegin(self, name, type, seqid): | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 34 |     if self.strictWrite: | 
| Mark Slee | 552410c | 2007-06-22 01:03:55 +0000 | [diff] [blame] | 35 |       self.writeI32(TBinaryProtocol.VERSION_1 | type) | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 36 |       self.writeString(name) | 
 | 37 |       self.writeI32(seqid) | 
 | 38 |     else: | 
 | 39 |       self.writeString(name) | 
 | 40 |       self.writeByte(type) | 
 | 41 |       self.writeI32(seqid) | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 42 |  | 
 | 43 |   def writeMessageEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 44 |     pass | 
 | 45 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 46 |   def writeStructBegin(self, name): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 47 |     pass | 
 | 48 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 49 |   def writeStructEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 50 |     pass | 
 | 51 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 52 |   def writeFieldBegin(self, name, type, id): | 
 | 53 |     self.writeByte(type) | 
 | 54 |     self.writeI16(id) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 55 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 56 |   def writeFieldEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 57 |     pass | 
 | 58 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 59 |   def writeFieldStop(self): | 
 | 60 |     self.writeByte(TType.STOP); | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 61 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 62 |   def writeMapBegin(self, ktype, vtype, size): | 
 | 63 |     self.writeByte(ktype) | 
 | 64 |     self.writeByte(vtype) | 
 | 65 |     self.writeI32(size) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 66 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 67 |   def writeMapEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 68 |     pass | 
 | 69 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 70 |   def writeListBegin(self, etype, size): | 
 | 71 |     self.writeByte(etype) | 
 | 72 |     self.writeI32(size) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 73 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 74 |   def writeListEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 75 |     pass | 
 | 76 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 77 |   def writeSetBegin(self, etype, size): | 
 | 78 |     self.writeByte(etype) | 
 | 79 |     self.writeI32(size) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 80 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 81 |   def writeSetEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 82 |     pass | 
 | 83 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 84 |   def writeBool(self, bool): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 85 |     if bool: | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 86 |       self.writeByte(1) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 87 |     else: | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 88 |       self.writeByte(0) | 
| David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 89 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 90 |   def writeByte(self, byte): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 91 |     buff = pack("!b", byte) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 92 |     self.trans.write(buff) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 93 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 94 |   def writeI16(self, i16): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 95 |     buff = pack("!h", i16) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 96 |     self.trans.write(buff) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 97 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 98 |   def writeI32(self, i32): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 99 |     buff = pack("!i", i32) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 100 |     self.trans.write(buff) | 
| David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 101 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 102 |   def writeI64(self, i64): | 
| Mark Slee | c967656 | 2006-09-05 17:34:52 +0000 | [diff] [blame] | 103 |     buff = pack("!q", i64) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 104 |     self.trans.write(buff) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 105 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 106 |   def writeDouble(self, dub): | 
| Mark Slee | c98d050 | 2006-09-06 02:42:25 +0000 | [diff] [blame] | 107 |     buff = pack("!d", dub) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 108 |     self.trans.write(buff) | 
| Mark Slee | c98d050 | 2006-09-06 02:42:25 +0000 | [diff] [blame] | 109 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 110 |   def writeString(self, str): | 
 | 111 |     self.writeI32(len(str)) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 112 |     self.trans.write(str) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 113 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 114 |   def readMessageBegin(self): | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 115 |     sz = self.readI32() | 
 | 116 |     if sz < 0: | 
| Mark Slee | 552410c | 2007-06-22 01:03:55 +0000 | [diff] [blame] | 117 |       version = sz & TBinaryProtocol.VERSION_MASK | 
 | 118 |       if version != TBinaryProtocol.VERSION_1: | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 119 |         raise TProtocolException(TProtocolException.BAD_VERSION, 'Bad version in readMessageBegin: %d' % (sz)) | 
| Mark Slee | 9b36ef3 | 2007-10-02 04:44:48 +0000 | [diff] [blame] | 120 |       type = sz & TBinaryProtocol.TYPE_MASK | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 121 |       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 Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 129 |     return (name, type, seqid) | 
 | 130 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 131 |   def readMessageEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 132 |     pass | 
 | 133 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 134 |   def readStructBegin(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 135 |     pass | 
 | 136 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 137 |   def readStructEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 138 |     pass | 
 | 139 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 140 |   def readFieldBegin(self): | 
 | 141 |     type = self.readByte() | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 142 |     if type == TType.STOP: | 
 | 143 |       return (None, type, 0) | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 144 |     id = self.readI16() | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 145 |     return (None, type, id) | 
 | 146 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 147 |   def readFieldEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 148 |     pass | 
 | 149 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 150 |   def readMapBegin(self): | 
 | 151 |     ktype = self.readByte() | 
 | 152 |     vtype = self.readByte() | 
 | 153 |     size = self.readI32() | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 154 |     return (ktype, vtype, size) | 
 | 155 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 156 |   def readMapEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 157 |     pass | 
 | 158 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 159 |   def readListBegin(self): | 
 | 160 |     etype = self.readByte() | 
 | 161 |     size = self.readI32() | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 162 |     return (etype, size) | 
 | 163 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 164 |   def readListEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 165 |     pass | 
 | 166 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 167 |   def readSetBegin(self): | 
 | 168 |     etype = self.readByte() | 
 | 169 |     size = self.readI32() | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 170 |     return (etype, size) | 
 | 171 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 172 |   def readSetEnd(self): | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 173 |     pass | 
 | 174 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 175 |   def readBool(self): | 
 | 176 |     byte = self.readByte() | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 177 |     if byte == 0: | 
 | 178 |       return False | 
 | 179 |     return True | 
 | 180 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 181 |   def readByte(self): | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 182 |     buff = self.trans.readAll(1) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 183 |     val, = unpack('!b', buff) | 
 | 184 |     return val | 
 | 185 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 186 |   def readI16(self): | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 187 |     buff = self.trans.readAll(2) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 188 |     val, = unpack('!h', buff) | 
 | 189 |     return val | 
 | 190 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 191 |   def readI32(self): | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 192 |     buff = self.trans.readAll(4) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 193 |     val, = unpack('!i', buff) | 
 | 194 |     return val | 
 | 195 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 196 |   def readI64(self): | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 197 |     buff = self.trans.readAll(8) | 
| Mark Slee | c967656 | 2006-09-05 17:34:52 +0000 | [diff] [blame] | 198 |     val, = unpack('!q', buff) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 199 |     return val | 
 | 200 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 201 |   def readDouble(self): | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 202 |     buff = self.trans.readAll(8) | 
| Mark Slee | c98d050 | 2006-09-06 02:42:25 +0000 | [diff] [blame] | 203 |     val, = unpack('!d', buff) | 
 | 204 |     return val | 
 | 205 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 206 |   def readString(self): | 
 | 207 |     len = self.readI32() | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 208 |     str = self.trans.readAll(len) | 
| Mark Slee | cde2b61 | 2006-09-03 21:13:07 +0000 | [diff] [blame] | 209 |     return str | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 210 |  | 
| David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 211 |  | 
| Mark Slee | 4ac459f | 2006-10-25 21:39:01 +0000 | [diff] [blame] | 212 | class TBinaryProtocolFactory: | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 213 |   def __init__(self, strictRead=False, strictWrite=True): | 
 | 214 |     self.strictRead = strictRead | 
 | 215 |     self.strictWrite = strictWrite | 
 | 216 |  | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 217 |   def getProtocol(self, trans): | 
| Mark Slee | 808454e | 2007-06-20 21:51:57 +0000 | [diff] [blame] | 218 |     prot = TBinaryProtocol(trans, self.strictRead, self.strictWrite) | 
| Aditya Agarwal | 5c46819 | 2007-02-06 01:14:33 +0000 | [diff] [blame] | 219 |     return prot | 
| David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 220 |  | 
 | 221 |  | 
 | 222 | class 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 Reiss | 5db3e92 | 2007-08-30 23:07:45 +0000 | [diff] [blame] | 231 |   reason.  (TODO(dreiss): Make this happen sanely in more cases.) | 
| David Reiss | 382fc30 | 2007-08-25 18:01:30 +0000 | [diff] [blame] | 232 |  | 
 | 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 |  | 
 | 246 | class TBinaryProtocolAcceleratedFactory: | 
 | 247 |   def getProtocol(self, trans): | 
 | 248 |     return TBinaryProtocolAccelerated(trans) |