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>