Annotation of gpl/axl/py-axl/py_axl_node.c, revision 1.1.1.1
1.1 misho 1: /**
2: * PyAxl: Axl Library python bindings
3: * Copyright (C) 2009 Advanced Software Production Line, S.L.
4: *
5: * This program is free software; you can redistribute it and/or
6: * modify it under the terms of the GNU Lesser General Public License
7: * as published by the Free Software Foundation; either version 2.1
8: * of the License, or (at your option) any later version.
9: *
10: * This program is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13: * Lesser General Public License for more details.
14: *
15: * You should have received a copy of the GNU Lesser General Public
16: * License along with this program; if not, write to the Free
17: * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18: * 02111-1307 USA
19: *
20: * You may find a copy of the license under this software is released
21: * at COPYING file. This is LGPL software: you are welcome to develop
22: * proprietary applications using this library without any royalty or
23: * fee but returning back any change, improvement or addition in the
24: * form of source code, project image, documentation patches, etc.
25: *
26: * For commercial support for XML enabled solutions contact us:
27: *
28: * Postal address:
29: * Advanced Software Production Line, S.L.
30: * C/ Antonio Suarez Nº 10,
31: * Edificio Alius A, Despacho 102
32: * Alcalá de Henares 28802 (Madrid)
33: * Spain
34: *
35: * Email address:
36: * info@aspl.es - http://www.aspl.es/axl
37: */
38: #include <py_axl_node.h>
39:
40: #define LOG_DOMAIN "py-axl-node"
41:
42: struct _PyAxlNode {
43: /* header required to initialize python required bits for
44: every python object */
45: PyObject_HEAD
46:
47: /* pointer to the axl node */
48: axlNode * node;
49: axl_bool finish_on_gc;
50: };
51:
52: static int py_axl_node_init_type (PyAxlNode *self, PyObject *args, PyObject *kwds)
53: {
54: return 0;
55: }
56:
57: /**
58: * @brief Function used to allocate memory required by the object
59: * axl.Node
60: */
61: static PyObject * py_axl_node_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
62: {
63: PyAxlNode * self;
64: const char * name = NULL;
65:
66: /* create the object */
67: self = (PyAxlNode *)type->tp_alloc(type, 0);
68:
69: /* parse and get node name */
70: if (! PyArg_ParseTuple (args, "|s", &name))
71: return NULL;
72:
73: /* create the node if received a defined name */
74: if (name != NULL) {
75: self->node = axl_node_create (name);
76: self->finish_on_gc = axl_true;
77: }
78:
79: return (PyObject *)self;
80: }
81:
82: /**
83: * @brief Function used to finish and dealloc memory used by the
84: * object axl.Node
85: */
86: static void py_axl_node_dealloc (PyAxlNode* self)
87: {
88:
89: /* release node on if it is signaled to be released and it was
90: * not configured to be inside a document, which means the
91: * document will take care of this */
92: if (self->finish_on_gc && axl_node_get_doc (self->node) == NULL)
93: axl_node_free (self->node);
94: self->node = NULL;
95:
96: /* free the node it self */
97: self->ob_type->tp_free ((PyObject*)self);
98:
99: return;
100: }
101:
102: /**
103: * @brief This function implements the generic attribute getting that
104: * allows to perform complex member resolution (not merely direct
105: * member access).
106: */
107: PyObject * py_axl_node_get_attr (PyObject *o, PyObject *attr_name) {
108: const char * attr = NULL;
109: PyObject * result;
110: PyAxlNode * self = (PyAxlNode *) o;
111: PyObject * tuple;
112: int size = 0;
113:
114: /* now implement other attributes */
115: if (! PyArg_Parse (attr_name, "s", &attr))
116: return NULL;
117:
118: __axl_log (LOG_DOMAIN, AXL_LEVEL_DEBUG, "received request to report node attr name %s (self: %p)",
119: attr, o);
120:
121: if (axl_cmp (attr, "name")) {
122: /* name */
123: return Py_BuildValue ("s", axl_node_get_name (self->node));
124: } else if (axl_cmp (attr, "first_child")) {
125: /* first_child */
126: if (axl_node_get_first_child (self->node) == NULL) {
127: Py_INCREF (Py_None);
128: return Py_None;
129: }
130:
131: return Py_BuildValue ("O", py_axl_node_create (axl_node_get_first_child (self->node), axl_false));
132: } else if (axl_cmp (attr, "next")) {
133: /* next */
134: if (axl_node_get_next (self->node) == NULL) {
135: Py_INCREF (Py_None);
136: return Py_None;
137: }
138:
139: return Py_BuildValue ("O", py_axl_node_create (axl_node_get_next (self->node), axl_false));
140: } else if (axl_cmp (attr, "previous")) {
141: /* previous */
142: if (axl_node_get_previous (self->node) == NULL) {
143: Py_INCREF (Py_None);
144: return Py_None;
145: }
146:
147: return Py_BuildValue ("O", py_axl_node_create (axl_node_get_previous (self->node), axl_false));
148: } else if (axl_cmp (attr, "parent")) {
149: /* parent */
150: if (axl_node_get_parent (self->node) == NULL) {
151: Py_INCREF (Py_None);
152: return Py_None;
153: }
154:
155: return Py_BuildValue ("O", py_axl_node_create (axl_node_get_parent (self->node), axl_false));
156:
157: } else if (axl_cmp (attr, "content")) {
158: /* return a tuple with content and size */
159: tuple = PyTuple_New (2);
160:
161: PyTuple_SetItem (tuple, 0, Py_BuildValue ("z", axl_node_get_content (self->node, &size)));
162: PyTuple_SetItem (tuple, 1, Py_BuildValue ("i", size));
163:
164: return tuple;
165: } else if (axl_cmp (attr, "doc")) {
166:
167: /* check if the node has a document configured */
168: if (axl_node_get_doc (self->node) == NULL) {
169: /* return none */
170: Py_INCREF (Py_None);
171: return Py_None;
172: } /* end if */
173:
174: /* ok, return document holding the node */
175: return py_axl_doc_create (axl_node_get_doc (self->node), axl_false);
176: }
177:
178: /* first implement generic attr already defined */
179: result = PyObject_GenericGetAttr (o, attr_name);
180: if (result)
181: return result;
182:
183: return NULL;
184: }
185:
186: /**
187: * @brief Implements attribute set operation.
188: */
189: int py_axl_node_set_attr (PyObject *o, PyObject *attr_name, PyObject *v)
190: {
191: const char * attr = NULL;
192: /* PyAxlNode * self = (PyAxlNode *) o; */
193: /* axl_bool boolean_value = axl_false; */
194:
195: /* now implement other attributes */
196: if (! PyArg_Parse (attr_name, "s", &attr))
197: return -1;
198:
199: /* now implement generic setter */
200: return PyObject_GenericSetAttr (o, attr_name, v);
201: }
202:
203: static PyObject * py_axl_node_next_called (PyObject * _self, PyObject * args)
204: {
205: PyAxlNode * self = (PyAxlNode *) _self;
206: const char * node_name = NULL;
207: axlNode * node = NULL;
208:
209: /* parse and check result */
210: if (! PyArg_ParseTuple (args, "s", &node_name))
211: return NULL;
212:
213: /* get next called */
214: node = axl_node_get_next_called (self->node, node_name);
215: if (node == NULL) {
216: Py_INCREF (Py_None);
217: return Py_None;
218: } /* end if */
219:
220: /* create node result */
221: return py_axl_node_create (node, axl_false);
222: }
223:
224: static PyObject * py_axl_node_previous_called (PyObject * _self, PyObject * args)
225: {
226: PyAxlNode * self = (PyAxlNode *) _self;
227: const char * node_name = NULL;
228: axlNode * node = NULL;
229:
230: /* parse and check result */
231: if (! PyArg_ParseTuple (args, "s", &node_name))
232: return NULL;
233:
234: /* get previous called */
235: node = axl_node_get_previous_called (self->node, node_name);
236: if (node == NULL) {
237: Py_INCREF (Py_None);
238: return Py_None;
239: } /* end if */
240:
241: /* create node result */
242: return py_axl_node_create (node, axl_false);
243: }
244:
245: static PyObject * py_axl_node_child_called (PyObject * _self, PyObject * args)
246: {
247: PyAxlNode * self = (PyAxlNode *) _self;
248: const char * node_name = NULL;
249: axlNode * node = NULL;
250:
251: /* parse and check result */
252: if (! PyArg_ParseTuple (args, "s", &node_name))
253: return NULL;
254:
255: /* get previous called */
256: node = axl_node_get_child_called (self->node, node_name);
257: if (node == NULL) {
258: Py_INCREF (Py_None);
259: return Py_None;
260: } /* end if */
261:
262: /* create node result */
263: return py_axl_node_create (node, axl_false);
264: }
265:
266: static PyObject * py_axl_node_find_called (PyObject * _self, PyObject * args)
267: {
268: PyAxlNode * self = (PyAxlNode *) _self;
269: const char * node_name = NULL;
270: axlNode * node = NULL;
271:
272: /* parse and check result */
273: if (! PyArg_ParseTuple (args, "s", &node_name))
274: return NULL;
275:
276: /* get previous called */
277: node = axl_node_find_called (self->node, node_name);
278: if (node == NULL) {
279: Py_INCREF (Py_None);
280: return Py_None;
281: } /* end if */
282:
283: /* create node result */
284: return py_axl_node_create (node, axl_false);
285: }
286:
287: static PyObject * py_axl_node_nth_child (PyObject * _self, PyObject * args)
288: {
289: PyAxlNode * self = (PyAxlNode *) _self;
290: int position = -1;
291: axlNode * node = NULL;
292:
293: /* parse and check result */
294: if (! PyArg_ParseTuple (args, "i", &position))
295: return NULL;
296:
297: /* get previous called */
298: node = axl_node_get_child_nth (self->node, position);
299: if (node == NULL) {
300: Py_INCREF (Py_None);
301: return Py_None;
302: } /* end if */
303:
304: /* create node result */
305: return py_axl_node_create (node, axl_false);
306: }
307:
308: static PyObject * py_axl_node_has_attr (PyObject * _self, PyObject * args)
309: {
310: PyAxlNode * self = (PyAxlNode *) _self;
311: char * attr_name = NULL;
312: char * attr_value = NULL;
313:
314: /* parse and check result */
315: if (! PyArg_ParseTuple (args, "s|s", &attr_name, &attr_value))
316: return NULL;
317:
318: if (attr_value == NULL)
319: return Py_BuildValue ("i", HAS_ATTR (self->node, attr_name));
320: return Py_BuildValue ("i", HAS_ATTR_VALUE (self->node, attr_name, attr_value));
321: }
322:
323: static PyObject * py_axl_node_attr_value (PyObject * _self, PyObject * args)
324: {
325: PyAxlNode * self = (PyAxlNode *) _self;
326: char * attr_name = NULL;
327: char * attr_value = NULL;
328:
329: /* parse and check result */
330: if (! PyArg_ParseTuple (args, "s|s", &attr_name, &attr_value))
331: return NULL;
332:
333: /* check set operation */
334: if (PyTuple_Size (args) == 2) {
335: /* remove previous attribute if exists */
336: axl_node_remove_attribute (self->node, attr_name);
337:
338: /* found set operation */
339: axl_node_set_attribute (self->node, attr_name, attr_value);
340: Py_INCREF (Py_None);
341: return Py_None;
342: } /* end if */
343:
344: return Py_BuildValue ("z", ATTR_VALUE (self->node, attr_name));
345: }
346:
347: static PyObject * py_axl_node_set_child (PyObject * _self, PyObject * args)
348: {
349: PyAxlNode * self = (PyAxlNode *) _self;
350: PyObject * child = Py_None;
351:
352: /* parse and check result */
353: if (! PyArg_ParseTuple (args, "O", &child))
354: return NULL;
355:
356: /* check object received */
357: if (! py_axl_node_check (child)) {
358: /* set exception */
359: PyErr_SetString (PyExc_TypeError, "Expected to receive an axl.Node object but received something different");
360: return NULL;
361: }
362:
363: /* set the node as child */
364: axl_node_set_child (self->node, py_axl_node_get (child));
365:
366: /* return ok */
367: Py_INCREF (Py_None);
368: return Py_None;
369: }
370:
371: static PyObject * py_axl_node_attr_cursor_new (PyObject * _self, PyObject * args)
372: {
373: PyAxlNode * self = (PyAxlNode *) _self;
374:
375: /* create node cursor attr */
376: return py_axl_attr_cursor_create (axl_node_attr_cursor_new (self->node), axl_true);
377: }
378:
379:
380: static PyMethodDef py_axl_node_methods[] = {
381: /* next_called */
382: {"next_called", (PyCFunction) py_axl_node_next_called, METH_VARARGS,
383: "Gest the xml node found at the same level, but with the name provided."},
384: /* previous_called */
385: {"previous_called", (PyCFunction) py_axl_node_previous_called, METH_VARARGS,
386: "Gest the xml node found at the same level, but with the name provided."},
387: /* child_called */
388: {"child_called", (PyCFunction) py_axl_node_child_called, METH_VARARGS,
389: "Gets the xml child node called as provided. The child is looked up only on direct childs."},
390: /* find_called */
391: {"find_called", (PyCFunction) py_axl_node_find_called, METH_VARARGS,
392: "Gets the xml child node called as provided. The child is looked up in all childs found starting the parent node."},
393: /* nth_child */
394: {"nth_child", (PyCFunction) py_axl_node_nth_child, METH_VARARGS,
395: "Allows to get a reference to the child node located at the same level at the nth position"},
396: /* has_attr */
397: {"has_attr", (PyCFunction) py_axl_node_has_attr, METH_VARARGS,
398: "Allows to check if the provided node has the given attribute."},
399: /* attr */
400: {"attr", (PyCFunction) py_axl_node_attr_value, METH_VARARGS,
401: "Allows to get/set the given attribute on the provided node."},
402: /* set_child */
403: {"set_child", (PyCFunction) py_axl_node_set_child, METH_VARARGS,
404: "Allows to configure the provided node as the instance's child."},
405: /* attr_cursor_new */
406: {"attr_cursor_new", (PyCFunction) py_axl_node_attr_cursor_new, METH_NOARGS,
407: "Allows to create a new attribute cursor object used to iterate over all attributes of a node."},
408: {NULL}
409: };
410:
411: static PyTypeObject PyAxlNodeType = {
412: PyObject_HEAD_INIT(NULL)
413: 0, /* ob_size*/
414: "axl.Node", /* tp_name*/
415: sizeof(PyAxlNode), /* tp_basicsize*/
416: 0, /* tp_itemsize*/
417: (destructor)py_axl_node_dealloc, /* tp_dealloc*/
418: 0, /* tp_print*/
419: 0, /* tp_getattr*/
420: 0, /* tp_setattr*/
421: 0, /* tp_compare*/
422: 0, /* tp_repr*/
423: 0, /* tp_as_number*/
424: 0, /* tp_as_sequence*/
425: 0, /* tp_as_mapping*/
426: 0, /* tp_hash */
427: 0, /* tp_call*/
428: 0, /* tp_str*/
429: py_axl_node_get_attr, /* tp_getattro*/
430: py_axl_node_set_attr, /* tp_setattro*/
431: 0, /* tp_as_buffer*/
432: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags*/
433: "Node object; wrapper of axlNode API type", /* tp_doc */
434: 0, /* tp_traverse */
435: 0, /* tp_clear */
436: 0, /* tp_richcompare */
437: 0, /* tp_weaklistoffset */
438: 0, /* tp_iter */
439: 0, /* tp_iternext */
440: py_axl_node_methods, /* tp_methods */
441: 0, /* py_axl_node_members, */ /* tp_members */
442: 0, /* tp_getset */
443: 0, /* tp_base */
444: 0, /* tp_dict */
445: 0, /* tp_descr_get */
446: 0, /* tp_descr_set */
447: 0, /* tp_dictoffset */
448: (initproc)py_axl_node_init_type, /* tp_init */
449: 0, /* tp_alloc */
450: py_axl_node_new, /* tp_new */
451:
452: };
453:
454:
455: /**
456: * @brief Allows to check if the PyObject received represents a
457: * PyAxlNode reference.
458: */
459: axl_bool py_axl_node_check (PyObject * obj)
460: {
461: /* check null references */
462: if (obj == NULL)
463: return axl_false;
464:
465: /* return check result */
466: return PyObject_TypeCheck (obj, &PyAxlNodeType);
467: }
468:
469: /**
470: * @brief Allows to create a new PyAxlNode instance using the copy
471: * provided.
472: *
473: * @param node The xml node that will represents the python instance.
474: *
475: * @param finish_on_gc Signal to finish or not the internal copy once
476: * the variable gets garbage collected.
477: */
478: PyObject * py_axl_node_create (axlNode * node,
479: axl_bool finish_on_gc)
480: {
481: /* return a new instance */
482: PyAxlNode * obj = (PyAxlNode *) PyObject_CallObject ((PyObject *) &PyAxlNodeType, NULL);
483:
484: /* check ref created */
485: if (obj == NULL) {
486: __axl_log (LOG_DOMAIN, AXL_LEVEL_CRITICAL, "Failed to create PyAxlNode object, returning NULL");
487: return NULL;
488: } /* end if */
489:
490: /* set node if defined */
491: if (node)
492: obj->node = node;
493: obj->finish_on_gc = finish_on_gc;
494:
495: return __PY_OBJECT (obj);
496: }
497:
498: /**
499: * @internal Allows to get the internal reference used by the provided
500: * PyAxlNode.
501: */
502: axlNode * py_axl_node_get (PyObject * obj)
503: {
504: /* check object received */
505: if (! py_axl_node_check (obj))
506: return NULL;
507:
508: /* return the node */
509: return ((PyAxlNode *)obj)->node;
510: }
511:
512: void init_axl_node (PyObject * module)
513: {
514: /* register type */
515: if (PyType_Ready(&PyAxlNodeType) < 0)
516: return;
517:
518: Py_INCREF (&PyAxlNodeType);
519: PyModule_AddObject(module, "Node", (PyObject *)&PyAxlNodeType);
520:
521: }
522:
523:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>