]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
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_TYPES_H | |
21 | #define THRIFT_PY_TYPES_H | |
22 | ||
23 | #include <Python.h> | |
24 | ||
25 | #ifdef _MSC_VER | |
26 | #define __STDC_FORMAT_MACROS | |
27 | #define __STDC_LIMIT_MACROS | |
28 | #endif | |
29 | #include <stdint.h> | |
30 | ||
31 | #if PY_MAJOR_VERSION >= 3 | |
32 | ||
33 | #include <vector> | |
34 | ||
35 | // TODO: better macros | |
36 | #define PyInt_AsLong(v) PyLong_AsLong(v) | |
37 | #define PyInt_FromLong(v) PyLong_FromLong(v) | |
38 | ||
39 | #define PyString_InternFromString(v) PyUnicode_InternFromString(v) | |
40 | ||
41 | #endif | |
42 | ||
43 | #define INTERN_STRING(value) _intern_##value | |
44 | ||
45 | #define INT_CONV_ERROR_OCCURRED(v) (((v) == -1) && PyErr_Occurred()) | |
46 | ||
47 | extern "C" { | |
48 | extern PyObject* INTERN_STRING(TFrozenDict); | |
49 | extern PyObject* INTERN_STRING(cstringio_buf); | |
50 | extern PyObject* INTERN_STRING(cstringio_refill); | |
51 | } | |
52 | ||
53 | namespace apache { | |
54 | namespace thrift { | |
55 | namespace py { | |
56 | ||
57 | extern PyObject* ThriftModule; | |
58 | ||
59 | // Stolen out of TProtocol.h. | |
60 | // It would be a huge pain to have both get this from one place. | |
61 | enum TType { | |
62 | T_INVALID = -1, | |
63 | T_STOP = 0, | |
64 | T_VOID = 1, | |
65 | T_BOOL = 2, | |
66 | T_BYTE = 3, | |
67 | T_I08 = 3, | |
68 | T_I16 = 6, | |
69 | T_I32 = 8, | |
70 | T_U64 = 9, | |
71 | T_I64 = 10, | |
72 | T_DOUBLE = 4, | |
73 | T_STRING = 11, | |
74 | T_UTF7 = 11, | |
75 | T_STRUCT = 12, | |
76 | T_MAP = 13, | |
77 | T_SET = 14, | |
78 | T_LIST = 15, | |
79 | T_UTF8 = 16, | |
80 | T_UTF16 = 17 | |
81 | }; | |
82 | ||
83 | // replace with unique_ptr when we're OK with C++11 | |
84 | class ScopedPyObject { | |
85 | public: | |
86 | ScopedPyObject() : obj_(NULL) {} | |
87 | explicit ScopedPyObject(PyObject* py_object) : obj_(py_object) {} | |
88 | ~ScopedPyObject() { | |
89 | if (obj_) | |
90 | Py_DECREF(obj_); | |
91 | } | |
92 | PyObject* get() throw() { return obj_; } | |
93 | operator bool() { return obj_; } | |
94 | void reset(PyObject* py_object) throw() { | |
95 | if (obj_) | |
96 | Py_DECREF(obj_); | |
97 | obj_ = py_object; | |
98 | } | |
99 | PyObject* release() throw() { | |
100 | PyObject* tmp = obj_; | |
101 | obj_ = NULL; | |
102 | return tmp; | |
103 | } | |
104 | void swap(ScopedPyObject& other) throw() { | |
105 | ScopedPyObject tmp(other.release()); | |
106 | other.reset(release()); | |
107 | reset(tmp.release()); | |
108 | } | |
109 | ||
110 | private: | |
111 | ScopedPyObject(const ScopedPyObject&) {} | |
112 | ScopedPyObject& operator=(const ScopedPyObject&) { return *this; } | |
113 | ||
114 | PyObject* obj_; | |
115 | }; | |
116 | ||
117 | /** | |
118 | * A cache of the two key attributes of a CReadableTransport, | |
119 | * so we don't have to keep calling PyObject_GetAttr. | |
120 | */ | |
121 | struct DecodeBuffer { | |
122 | ScopedPyObject stringiobuf; | |
123 | ScopedPyObject refill_callable; | |
124 | }; | |
125 | ||
126 | #if PY_MAJOR_VERSION < 3 | |
127 | extern char refill_signature[3]; | |
128 | typedef PyObject EncodeBuffer; | |
129 | #else | |
130 | extern const char* refill_signature; | |
131 | struct EncodeBuffer { | |
132 | std::vector<char> buf; | |
133 | size_t pos; | |
134 | }; | |
135 | #endif | |
136 | ||
137 | /** | |
138 | * A cache of the spec_args for a set or list, | |
139 | * so we don't have to keep calling PyTuple_GET_ITEM. | |
140 | */ | |
141 | struct SetListTypeArgs { | |
142 | TType element_type; | |
143 | PyObject* typeargs; | |
144 | bool immutable; | |
145 | }; | |
146 | ||
147 | /** | |
148 | * A cache of the spec_args for a map, | |
149 | * so we don't have to keep calling PyTuple_GET_ITEM. | |
150 | */ | |
151 | struct MapTypeArgs { | |
152 | TType ktag; | |
153 | TType vtag; | |
154 | PyObject* ktypeargs; | |
155 | PyObject* vtypeargs; | |
156 | bool immutable; | |
157 | }; | |
158 | ||
159 | /** | |
160 | * A cache of the spec_args for a struct, | |
161 | * so we don't have to keep calling PyTuple_GET_ITEM. | |
162 | */ | |
163 | struct StructTypeArgs { | |
164 | PyObject* klass; | |
165 | PyObject* spec; | |
166 | bool immutable; | |
167 | }; | |
168 | ||
169 | /** | |
170 | * A cache of the item spec from a struct specification, | |
171 | * so we don't have to keep calling PyTuple_GET_ITEM. | |
172 | */ | |
173 | struct StructItemSpec { | |
174 | int tag; | |
175 | TType type; | |
176 | PyObject* attrname; | |
177 | PyObject* typeargs; | |
178 | PyObject* defval; | |
179 | }; | |
180 | ||
181 | bool parse_set_list_args(SetListTypeArgs* dest, PyObject* typeargs); | |
182 | ||
183 | bool parse_map_args(MapTypeArgs* dest, PyObject* typeargs); | |
184 | ||
185 | bool parse_struct_args(StructTypeArgs* dest, PyObject* typeargs); | |
186 | ||
187 | bool parse_struct_item_spec(StructItemSpec* dest, PyObject* spec_tuple); | |
188 | } | |
189 | } | |
190 | } | |
191 | ||
192 | #endif // THRIFT_PY_TYPES_H |