2 #include <openvswitch/json.h>
3 #include "structmember.h"
5 #if PY_MAJOR_VERSION >= 3
11 struct json_parser *_parser;
15 Parser_dealloc(json_ParserObject * p)
17 json_parser_abort(p->_parser);
18 Py_TYPE(p)->tp_free(p);
22 Parser_new(PyTypeObject * type, PyObject * args, PyObject * kwargs)
24 json_ParserObject *self;
25 static char *kwlist[] = { "check_trailer", NULL };
26 PyObject *check_trailer = NULL;
29 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
34 if (check_trailer != NULL) {
35 ct_int = PyObject_IsTrue(check_trailer);
39 ct_int = JSPF_TRAILER;
43 self = (json_ParserObject *) type->tp_alloc(type, 0);
45 self->_parser = json_parser_create(ct_int);
48 return (PyObject *) self;
52 Parser_feed(json_ParserObject * self, PyObject * args)
59 if (self->_parser == NULL) {
63 if (!PyArg_UnpackTuple(args, "input", 1, 1, &input)) {
67 if ((input_str = PyUnicode_AsUTF8AndSize(input, &input_sz)) == NULL) {
69 if (PyString_AsStringAndSize(input, &input_str, &input_sz) < 0) {
74 rd = json_parser_feed(self->_parser, input_str, (size_t) input_sz);
77 return PyLong_FromSize_t(rd);
79 return PyInt_FromSize_t(rd);
84 Parser_is_done(json_ParserObject * self)
86 if (self->_parser == NULL) {
89 return PyBool_FromLong(json_parser_is_done(self->_parser));
93 json_to_python(struct json *json)
103 struct shash_node *node;
104 PyObject *dict = PyDict_New();
107 return PyErr_NoMemory();
109 SHASH_FOR_EACH(node, json->u.object) {
110 PyObject *key = PyUnicode_FromString(node->name);
111 PyObject *val = json_to_python(node->data);
113 if (!(key && val) || PyDict_SetItem(dict, key, val)) {
127 PyObject *arr = PyList_New(json->u.array.n);
130 return PyErr_NoMemory();
132 for (i = 0; i < json->u.array.n; i++) {
133 PyObject *item = json_to_python(json->u.array.elems[i]);
135 if (!item || PyList_SetItem(arr, i, item)) {
143 if (json->u.real != 0) {
144 return PyFloat_FromDouble(json->u.real);
145 } /* fall through to treat 0 as int */
148 return PyLong_FromLong((long) json->u.integer);
150 return PyInt_FromLong((long) json->u.integer);
154 return PyUnicode_FromString(json->u.string);
161 Parser_finish(json_ParserObject * self)
166 if (self->_parser == NULL) {
170 json = json_parser_finish(self->_parser);
171 self->_parser = NULL;
172 obj = json_to_python(json);
176 static PyMethodDef Parser_methods[] = {
177 {"feed", (PyCFunction) Parser_feed, METH_VARARGS,
178 "Feed data to the parser and return the index of the last object."},
179 {"is_done", (PyCFunction) Parser_is_done, METH_NOARGS,
180 "Whether the parser has finished decoding an object."},
181 {"finish", (PyCFunction) Parser_finish, METH_NOARGS,
182 "Finish parsing and return Python object parsed."},
186 static PyTypeObject json_ParserType = {
187 PyVarObject_HEAD_INIT(NULL, 0)
188 "ovs._json.Parser", /* tp_name */
189 sizeof (json_ParserObject), /* tp_basicsize */
191 (destructor) Parser_dealloc, /* tp_dealloc */
197 0, /* tp_as_number */
198 0, /* tp_as_sequence */
199 0, /* tp_as_mapping */
205 0, /* tp_as_buffer */
206 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
207 "Parser objects", /* tp_doc */
210 0, /* tp_richcompare */
211 0, /* tp_weaklistoffset */
214 Parser_methods, /* tp_methods */
219 0, /* tp_descr_get */
220 0, /* tp_descr_set */
221 0, /* tp_dictoffset */
224 Parser_new, /* tp_new */
228 static struct PyModuleDef moduledef = {
229 PyModuleDef_HEAD_INIT,
230 "ovs._json", /* m_name */
231 "OVS JSON Parser module", /* m_doc */
240 #define INITERROR return NULL
242 #define INITERROR return
254 if (PyType_Ready(&json_ParserType) < 0) {
258 m = PyModule_Create(&moduledef);
260 m = Py_InitModule3("ovs._json", NULL, "OVS JSON Parser module");
263 Py_INCREF(&json_ParserType);
264 PyModule_AddObject(m, "Parser", (PyObject *) & json_ParserType);