Annotation of gpl/axl/py-axl/py_axl_node.c, revision 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>