1 /* 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 20 #ifndef THRIFT_PY_BINARY_H 21 #define THRIFT_PY_BINARY_H 22 23 #include <Python.h> 24 #include "ext/protocol.h" 25 #include "ext/endian.h" 26 #include <stdint.h> 27 28 namespace apache { 29 namespace thrift { 30 namespace py { 31 32 class BinaryProtocol : public ProtocolBase<BinaryProtocol> { 33 public: ~BinaryProtocol()34 virtual ~BinaryProtocol() {} 35 writeI8(int8_t val)36 void writeI8(int8_t val) { writeBuffer(reinterpret_cast<char*>(&val), sizeof(int8_t)); } 37 writeI16(int16_t val)38 void writeI16(int16_t val) { 39 int16_t net = static_cast<int16_t>(htons(val)); 40 writeBuffer(reinterpret_cast<char*>(&net), sizeof(int16_t)); 41 } 42 writeI32(int32_t val)43 void writeI32(int32_t val) { 44 int32_t net = static_cast<int32_t>(htonl(val)); 45 writeBuffer(reinterpret_cast<char*>(&net), sizeof(int32_t)); 46 } 47 writeI64(int64_t val)48 void writeI64(int64_t val) { 49 int64_t net = static_cast<int64_t>(htonll(val)); 50 writeBuffer(reinterpret_cast<char*>(&net), sizeof(int64_t)); 51 } 52 writeDouble(double dub)53 void writeDouble(double dub) { 54 // Unfortunately, bitwise_cast doesn't work in C. Bad C! 55 union { 56 double f; 57 int64_t t; 58 } transfer; 59 transfer.f = dub; 60 writeI64(transfer.t); 61 } 62 writeBool(int v)63 void writeBool(int v) { writeByte(static_cast<uint8_t>(v)); } 64 writeString(PyObject * value,int32_t len)65 void writeString(PyObject* value, int32_t len) { 66 writeI32(len); 67 writeBuffer(PyBytes_AS_STRING(value), len); 68 } 69 writeListBegin(PyObject * value,const SetListTypeArgs & parsedargs,int32_t len)70 bool writeListBegin(PyObject* value, const SetListTypeArgs& parsedargs, int32_t len) { 71 writeByte(parsedargs.element_type); 72 writeI32(len); 73 return true; 74 } 75 writeMapBegin(PyObject * value,const MapTypeArgs & parsedargs,int32_t len)76 bool writeMapBegin(PyObject* value, const MapTypeArgs& parsedargs, int32_t len) { 77 writeByte(parsedargs.ktag); 78 writeByte(parsedargs.vtag); 79 writeI32(len); 80 return true; 81 } 82 writeStructBegin()83 bool writeStructBegin() { return true; } writeStructEnd()84 bool writeStructEnd() { return true; } writeField(PyObject * value,const StructItemSpec & parsedspec)85 bool writeField(PyObject* value, const StructItemSpec& parsedspec) { 86 writeByte(static_cast<uint8_t>(parsedspec.type)); 87 writeI16(parsedspec.tag); 88 return encodeValue(value, parsedspec.type, parsedspec.typeargs); 89 } 90 writeFieldStop()91 void writeFieldStop() { writeByte(static_cast<uint8_t>(T_STOP)); } 92 readBool(bool & val)93 bool readBool(bool& val) { 94 char* buf; 95 if (!readBytes(&buf, 1)) { 96 return false; 97 } 98 val = buf[0] == 1; 99 return true; 100 } 101 readI8(int8_t & val)102 bool readI8(int8_t& val) { 103 char* buf; 104 if (!readBytes(&buf, 1)) { 105 return false; 106 } 107 val = buf[0]; 108 return true; 109 } 110 readI16(int16_t & val)111 bool readI16(int16_t& val) { 112 char* buf; 113 if (!readBytes(&buf, sizeof(int16_t))) { 114 return false; 115 } 116 memcpy(&val, buf, sizeof(int16_t)); 117 val = ntohs(val); 118 return true; 119 } 120 readI32(int32_t & val)121 bool readI32(int32_t& val) { 122 char* buf; 123 if (!readBytes(&buf, sizeof(int32_t))) { 124 return false; 125 } 126 memcpy(&val, buf, sizeof(int32_t)); 127 val = ntohl(val); 128 return true; 129 } 130 readI64(int64_t & val)131 bool readI64(int64_t& val) { 132 char* buf; 133 if (!readBytes(&buf, sizeof(int64_t))) { 134 return false; 135 } 136 memcpy(&val, buf, sizeof(int64_t)); 137 val = ntohll(val); 138 return true; 139 } 140 readDouble(double & val)141 bool readDouble(double& val) { 142 union { 143 int64_t f; 144 double t; 145 } transfer; 146 147 if (!readI64(transfer.f)) { 148 return false; 149 } 150 val = transfer.t; 151 return true; 152 } 153 readString(char ** buf)154 int32_t readString(char** buf) { 155 int32_t len = 0; 156 if (!readI32(len) || !checkLengthLimit(len, stringLimit()) || !readBytes(buf, len)) { 157 return -1; 158 } 159 return len; 160 } 161 readListBegin(TType & etype)162 int32_t readListBegin(TType& etype) { 163 int32_t len; 164 uint8_t b = 0; 165 if (!readByte(b) || !readI32(len) || !checkLengthLimit(len, containerLimit())) { 166 return -1; 167 } 168 etype = static_cast<TType>(b); 169 return len; 170 } 171 readMapBegin(TType & ktype,TType & vtype)172 int32_t readMapBegin(TType& ktype, TType& vtype) { 173 int32_t len; 174 uint8_t k, v; 175 if (!readByte(k) || !readByte(v) || !readI32(len) || !checkLengthLimit(len, containerLimit())) { 176 return -1; 177 } 178 ktype = static_cast<TType>(k); 179 vtype = static_cast<TType>(v); 180 return len; 181 } 182 readStructBegin()183 bool readStructBegin() { return true; } readStructEnd()184 bool readStructEnd() { return true; } 185 186 bool readFieldBegin(TType& type, int16_t& tag); 187 188 #define SKIPBYTES(n) \ 189 do { \ 190 if (!readBytes(&dummy_buf_, (n))) { \ 191 return false; \ 192 } \ 193 return true; \ 194 } while (0) 195 skipBool()196 bool skipBool() { SKIPBYTES(1); } skipByte()197 bool skipByte() { SKIPBYTES(1); } skipI16()198 bool skipI16() { SKIPBYTES(2); } skipI32()199 bool skipI32() { SKIPBYTES(4); } skipI64()200 bool skipI64() { SKIPBYTES(8); } skipDouble()201 bool skipDouble() { SKIPBYTES(8); } skipString()202 bool skipString() { 203 int32_t len; 204 if (!readI32(len)) { 205 return false; 206 } 207 SKIPBYTES(len); 208 } 209 #undef SKIPBYTES 210 211 private: 212 char* dummy_buf_; 213 }; 214 } 215 } 216 } 217 #endif // THRIFT_PY_BINARY_H 218