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_PROTOCOL_H
21 #define THRIFT_PY_PROTOCOL_H
22 
23 #include "ext/types.h"
24 #include <limits>
25 #include <stdint.h>
26 
27 namespace apache {
28 namespace thrift {
29 namespace py {
30 
31 template <typename Impl>
32 class ProtocolBase {
33 
34 public:
ProtocolBase()35   ProtocolBase()
36     : stringLimit_((std::numeric_limits<int32_t>::max)()),
37       containerLimit_((std::numeric_limits<int32_t>::max)()),
38       output_(nullptr) {}
39   inline virtual ~ProtocolBase();
40 
41   bool prepareDecodeBufferFromTransport(PyObject* trans);
42 
43   PyObject* readStruct(PyObject* output, PyObject* klass, PyObject* spec_seq);
44 
45   bool prepareEncodeBuffer();
46 
47   bool encodeValue(PyObject* value, TType type, PyObject* typeargs);
48 
49   PyObject* getEncodedValue();
50 
stringLimit()51   long stringLimit() const { return stringLimit_; }
setStringLengthLimit(long limit)52   void setStringLengthLimit(long limit) { stringLimit_ = limit; }
53 
containerLimit()54   long containerLimit() const { return containerLimit_; }
setContainerLengthLimit(long limit)55   void setContainerLengthLimit(long limit) { containerLimit_ = limit; }
56 
57 protected:
58   bool readBytes(char** output, int len);
59 
readByte(uint8_t & val)60   bool readByte(uint8_t& val) {
61     char* buf;
62     if (!readBytes(&buf, 1)) {
63       return false;
64     }
65     val = static_cast<uint8_t>(buf[0]);
66     return true;
67   }
68 
69   bool writeBuffer(char* data, size_t len);
70 
writeByte(uint8_t val)71   void writeByte(uint8_t val) { writeBuffer(reinterpret_cast<char*>(&val), 1); }
72 
73   PyObject* decodeValue(TType type, PyObject* typeargs);
74 
75   bool skip(TType type);
76 
77   inline bool checkType(TType got, TType expected);
78   inline bool checkLengthLimit(int32_t len, long limit);
79 
80   inline bool isUtf8(PyObject* typeargs);
81 
82 private:
impl()83   Impl* impl() { return static_cast<Impl*>(this); }
84 
85   long stringLimit_;
86   long containerLimit_;
87   EncodeBuffer* output_;
88   DecodeBuffer input_;
89 };
90 }
91 }
92 }
93 
94 #include "ext/protocol.tcc"
95 
96 #endif // THRIFT_PY_PROTOCOL_H
97