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 #include "ext/types.h"
21 #include "ext/protocol.h"
22 
23 namespace apache {
24 namespace thrift {
25 namespace py {
26 
27 PyObject* ThriftModule = NULL;
28 
29 #if PY_MAJOR_VERSION < 3
30 char refill_signature[] = {'s', '#', 'i'};
31 #else
32 const char* refill_signature = "y#i";
33 #endif
34 
parse_struct_item_spec(StructItemSpec * dest,PyObject * spec_tuple)35 bool parse_struct_item_spec(StructItemSpec* dest, PyObject* spec_tuple) {
36   // i'd like to use ParseArgs here, but it seems to be a bottleneck.
37   if (PyTuple_Size(spec_tuple) != 5) {
38     PyErr_Format(PyExc_TypeError, "expecting 5 arguments for spec tuple but got %d",
39                  static_cast<int>(PyTuple_Size(spec_tuple)));
40     return false;
41   }
42 
43   dest->tag = static_cast<TType>(PyInt_AsLong(PyTuple_GET_ITEM(spec_tuple, 0)));
44   if (INT_CONV_ERROR_OCCURRED(dest->tag)) {
45     return false;
46   }
47 
48   dest->type = static_cast<TType>(PyInt_AsLong(PyTuple_GET_ITEM(spec_tuple, 1)));
49   if (INT_CONV_ERROR_OCCURRED(dest->type)) {
50     return false;
51   }
52 
53   dest->attrname = PyTuple_GET_ITEM(spec_tuple, 2);
54   dest->typeargs = PyTuple_GET_ITEM(spec_tuple, 3);
55   dest->defval = PyTuple_GET_ITEM(spec_tuple, 4);
56   return true;
57 }
58 
parse_set_list_args(SetListTypeArgs * dest,PyObject * typeargs)59 bool parse_set_list_args(SetListTypeArgs* dest, PyObject* typeargs) {
60   if (PyTuple_Size(typeargs) != 3) {
61     PyErr_SetString(PyExc_TypeError, "expecting tuple of size 3 for list/set type args");
62     return false;
63   }
64 
65   dest->element_type = static_cast<TType>(PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 0)));
66   if (INT_CONV_ERROR_OCCURRED(dest->element_type)) {
67     return false;
68   }
69 
70   dest->typeargs = PyTuple_GET_ITEM(typeargs, 1);
71 
72   dest->immutable = Py_True == PyTuple_GET_ITEM(typeargs, 2);
73 
74   return true;
75 }
76 
parse_map_args(MapTypeArgs * dest,PyObject * typeargs)77 bool parse_map_args(MapTypeArgs* dest, PyObject* typeargs) {
78   if (PyTuple_Size(typeargs) != 5) {
79     PyErr_SetString(PyExc_TypeError, "expecting 5 arguments for typeargs to map");
80     return false;
81   }
82 
83   dest->ktag = static_cast<TType>(PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 0)));
84   if (INT_CONV_ERROR_OCCURRED(dest->ktag)) {
85     return false;
86   }
87 
88   dest->vtag = static_cast<TType>(PyInt_AsLong(PyTuple_GET_ITEM(typeargs, 2)));
89   if (INT_CONV_ERROR_OCCURRED(dest->vtag)) {
90     return false;
91   }
92 
93   dest->ktypeargs = PyTuple_GET_ITEM(typeargs, 1);
94   dest->vtypeargs = PyTuple_GET_ITEM(typeargs, 3);
95   dest->immutable = Py_True == PyTuple_GET_ITEM(typeargs, 4);
96 
97   return true;
98 }
99 
parse_struct_args(StructTypeArgs * dest,PyObject * typeargs)100 bool parse_struct_args(StructTypeArgs* dest, PyObject* typeargs) {
101   if (PyList_Size(typeargs) != 2) {
102     PyErr_SetString(PyExc_TypeError, "expecting list of size 2 for struct args");
103     return false;
104   }
105 
106   dest->klass = PyList_GET_ITEM(typeargs, 0);
107   dest->spec = PyList_GET_ITEM(typeargs, 1);
108 
109   return true;
110 }
111 }
112 }
113 }
114