/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef THRIFT_PY_BINARY_H #define THRIFT_PY_BINARY_H #include #include "ext/protocol.h" #include "ext/endian.h" #include namespace apache { namespace thrift { namespace py { class BinaryProtocol : public ProtocolBase { public: virtual ~BinaryProtocol() {} void writeI8(int8_t val) { writeBuffer(reinterpret_cast(&val), sizeof(int8_t)); } void writeI16(int16_t val) { int16_t net = static_cast(htons(val)); writeBuffer(reinterpret_cast(&net), sizeof(int16_t)); } void writeI32(int32_t val) { int32_t net = static_cast(htonl(val)); writeBuffer(reinterpret_cast(&net), sizeof(int32_t)); } void writeI64(int64_t val) { int64_t net = static_cast(htonll(val)); writeBuffer(reinterpret_cast(&net), sizeof(int64_t)); } void writeDouble(double dub) { // Unfortunately, bitwise_cast doesn't work in C. Bad C! union { double f; int64_t t; } transfer; transfer.f = dub; writeI64(transfer.t); } void writeBool(int v) { writeByte(static_cast(v)); } void writeString(PyObject* value, int32_t len) { writeI32(len); writeBuffer(PyBytes_AS_STRING(value), len); } bool writeListBegin(PyObject* value, const SetListTypeArgs& parsedargs, int32_t len) { writeByte(parsedargs.element_type); writeI32(len); return true; } bool writeMapBegin(PyObject* value, const MapTypeArgs& parsedargs, int32_t len) { writeByte(parsedargs.ktag); writeByte(parsedargs.vtag); writeI32(len); return true; } bool writeStructBegin() { return true; } bool writeStructEnd() { return true; } bool writeField(PyObject* value, const StructItemSpec& parsedspec) { writeByte(static_cast(parsedspec.type)); writeI16(parsedspec.tag); return encodeValue(value, parsedspec.type, parsedspec.typeargs); } void writeFieldStop() { writeByte(static_cast(T_STOP)); } bool readBool(bool& val) { char* buf; if (!readBytes(&buf, 1)) { return false; } val = buf[0] == 1; return true; } bool readI8(int8_t& val) { char* buf; if (!readBytes(&buf, 1)) { return false; } val = buf[0]; return true; } bool readI16(int16_t& val) { char* buf; if (!readBytes(&buf, sizeof(int16_t))) { return false; } memcpy(&val, buf, sizeof(int16_t)); val = ntohs(val); return true; } bool readI32(int32_t& val) { char* buf; if (!readBytes(&buf, sizeof(int32_t))) { return false; } memcpy(&val, buf, sizeof(int32_t)); val = ntohl(val); return true; } bool readI64(int64_t& val) { char* buf; if (!readBytes(&buf, sizeof(int64_t))) { return false; } memcpy(&val, buf, sizeof(int64_t)); val = ntohll(val); return true; } bool readDouble(double& val) { union { int64_t f; double t; } transfer; if (!readI64(transfer.f)) { return false; } val = transfer.t; return true; } int32_t readString(char** buf) { int32_t len = 0; if (!readI32(len) || !checkLengthLimit(len, stringLimit()) || !readBytes(buf, len)) { return -1; } return len; } int32_t readListBegin(TType& etype) { int32_t len; uint8_t b = 0; if (!readByte(b) || !readI32(len) || !checkLengthLimit(len, containerLimit())) { return -1; } etype = static_cast(b); return len; } int32_t readMapBegin(TType& ktype, TType& vtype) { int32_t len; uint8_t k, v; if (!readByte(k) || !readByte(v) || !readI32(len) || !checkLengthLimit(len, containerLimit())) { return -1; } ktype = static_cast(k); vtype = static_cast(v); return len; } bool readStructBegin() { return true; } bool readStructEnd() { return true; } bool readFieldBegin(TType& type, int16_t& tag); #define SKIPBYTES(n) \ do { \ if (!readBytes(&dummy_buf_, (n))) { \ return false; \ } \ return true; \ } while (0) bool skipBool() { SKIPBYTES(1); } bool skipByte() { SKIPBYTES(1); } bool skipI16() { SKIPBYTES(2); } bool skipI32() { SKIPBYTES(4); } bool skipI64() { SKIPBYTES(8); } bool skipDouble() { SKIPBYTES(8); } bool skipString() { int32_t len; if (!readI32(len)) { return false; } SKIPBYTES(len); } #undef SKIPBYTES private: char* dummy_buf_; }; } } } #endif // THRIFT_PY_BINARY_H