LCOV - code coverage report
Current view: top level - dns/python - messagerenderer_python.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 50 56 89.3 %
Date: 2012-05-15 Functions: 12 13 92.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 14 28 50.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #include <Python.h>
      16                 :            : 
      17                 :            : #include <util/buffer.h>
      18                 :            : 
      19                 :            : #include <dns/messagerenderer.h>
      20                 :            : #include <util/python/pycppwrapper_util.h>
      21                 :            : 
      22                 :            : #include "pydnspp_common.h"
      23                 :            : #include "messagerenderer_python.h"
      24                 :            : 
      25                 :            : using namespace isc::dns;
      26                 :            : using namespace isc::dns::python;
      27                 :            : using namespace isc::util;
      28                 :            : using namespace isc::util::python;
      29                 :            : 
      30                 :            : namespace {
      31                 :            : // The s_* Class simply covers one instantiation of the object.
      32                 :            : //
      33                 :            : // since we don't use *Buffer in the python version (but work with
      34                 :            : // the already existing bytearray type where we use these custom buffers
      35                 :            : // in C++, we need to keep track of one here.
      36                 :            : class s_MessageRenderer : public PyObject {
      37                 :            : public:
      38                 :            :     s_MessageRenderer();
      39                 :            :     MessageRenderer* cppobj;
      40                 :            : };
      41                 :            : 
      42                 :            : int MessageRenderer_init(s_MessageRenderer* self);
      43                 :            : void MessageRenderer_destroy(s_MessageRenderer* self);
      44                 :            : 
      45                 :            : PyObject* MessageRenderer_getData(s_MessageRenderer* self);
      46                 :            : PyObject* MessageRenderer_getLength(s_MessageRenderer* self);
      47                 :            : PyObject* MessageRenderer_isTruncated(s_MessageRenderer* self);
      48                 :            : PyObject* MessageRenderer_getLengthLimit(s_MessageRenderer* self);
      49                 :            : PyObject* MessageRenderer_getCompressMode(s_MessageRenderer* self);
      50                 :            : PyObject* MessageRenderer_setTruncated(s_MessageRenderer* self);
      51                 :            : PyObject* MessageRenderer_setLengthLimit(s_MessageRenderer* self, PyObject* args);
      52                 :            : PyObject* MessageRenderer_setCompressMode(s_MessageRenderer* self, PyObject* args);
      53                 :            : PyObject* MessageRenderer_clear(s_MessageRenderer* self);
      54                 :            : 
      55                 :            : PyMethodDef MessageRenderer_methods[] = {
      56                 :            :     { "get_data", reinterpret_cast<PyCFunction>(MessageRenderer_getData), METH_NOARGS,
      57                 :            :       "Returns the data as a bytes() object" },
      58                 :            :     { "get_length", reinterpret_cast<PyCFunction>(MessageRenderer_getLength), METH_NOARGS,
      59                 :            :       "Returns the length of the data" },
      60                 :            :     { "is_truncated", reinterpret_cast<PyCFunction>(MessageRenderer_isTruncated), METH_NOARGS,
      61                 :            :       "Returns True if the data is truncated" },
      62                 :            :     { "get_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_getLengthLimit), METH_NOARGS,
      63                 :            :       "Returns the length limit of the data" },
      64                 :            :     { "get_compress_mode", reinterpret_cast<PyCFunction>(MessageRenderer_getCompressMode), METH_NOARGS,
      65                 :            :       "Returns the current compression mode" },
      66                 :            :     { "set_truncated", reinterpret_cast<PyCFunction>(MessageRenderer_setTruncated), METH_NOARGS,
      67                 :            :       "Sets truncated to true" },
      68                 :            :     { "set_length_limit", reinterpret_cast<PyCFunction>(MessageRenderer_setLengthLimit), METH_VARARGS,
      69                 :            :       "Sets the length limit of the data to the given number" },
      70                 :            :     { "set_compress_mode", reinterpret_cast<PyCFunction>(MessageRenderer_setCompressMode), METH_VARARGS,
      71                 :            :       "Sets the compression mode of the MessageRenderer" },
      72                 :            :     { "clear", reinterpret_cast<PyCFunction>(MessageRenderer_clear),
      73                 :            :       METH_NOARGS,
      74                 :            :       "Clear the internal buffer and other internal resources." },
      75                 :            :     { NULL, NULL, 0, NULL }
      76                 :            : };
      77                 :            : 
      78                 :            : int
      79                 :        459 : MessageRenderer_init(s_MessageRenderer* self) {
      80         [ +  - ]:        459 :     self->cppobj = new MessageRenderer;
      81                 :        459 :     return (0);
      82                 :            : }
      83                 :            : 
      84                 :            : void
      85                 :        459 : MessageRenderer_destroy(s_MessageRenderer* self) {
      86         [ +  - ]:        459 :     delete self->cppobj;
      87                 :        459 :     self->cppobj = NULL;
      88                 :        459 :     Py_TYPE(self)->tp_free(self);
      89                 :        459 : }
      90                 :            : 
      91                 :            : PyObject*
      92                 :        430 : MessageRenderer_getData(s_MessageRenderer* self) {
      93                 :            :     return (Py_BuildValue("y#",
      94                 :            :                           self->cppobj->getData(),
      95                 :        430 :                           self->cppobj->getLength()));
      96                 :            : }
      97                 :            : 
      98                 :            : PyObject*
      99                 :        316 : MessageRenderer_getLength(s_MessageRenderer* self) {
     100                 :        316 :     return (Py_BuildValue("I", self->cppobj->getLength()));
     101                 :            : }
     102                 :            : 
     103                 :            : PyObject*
     104                 :          7 : MessageRenderer_isTruncated(s_MessageRenderer* self) {
     105         [ +  + ]:          7 :     if (self->cppobj->isTruncated()) {
     106                 :          3 :         Py_RETURN_TRUE;
     107                 :            :     } else {
     108                 :          7 :         Py_RETURN_FALSE;
     109                 :            :     }
     110                 :            : }
     111                 :            : 
     112                 :            : PyObject*
     113                 :          6 : MessageRenderer_getLengthLimit(s_MessageRenderer* self) {
     114                 :          6 :     return (Py_BuildValue("I", self->cppobj->getLengthLimit()));
     115                 :            : }
     116                 :            : 
     117                 :            : PyObject*
     118                 :          6 : MessageRenderer_getCompressMode(s_MessageRenderer* self) {
     119                 :          6 :     return (Py_BuildValue("I", self->cppobj->getCompressMode()));
     120                 :            : }
     121                 :            : 
     122                 :            : PyObject*
     123                 :          1 : MessageRenderer_setTruncated(s_MessageRenderer* self) {
     124                 :          1 :     self->cppobj->setTruncated();
     125                 :          1 :     Py_RETURN_NONE;
     126                 :            : }
     127                 :            : 
     128                 :            : PyObject*
     129                 :        159 : MessageRenderer_setLengthLimit(s_MessageRenderer* self,
     130                 :            :                                PyObject* args)
     131                 :            : {
     132                 :            :     long lengthlimit;
     133         [ +  + ]:        159 :     if (!PyArg_ParseTuple(args, "l", &lengthlimit)) {
     134                 :          1 :         PyErr_Clear();
     135                 :            :         PyErr_SetString(PyExc_TypeError,
     136                 :          1 :                         "No valid type in set_length_limit argument");
     137                 :          1 :         return (NULL);
     138                 :            :     }
     139         [ +  + ]:        158 :     if (lengthlimit < 0) {
     140                 :            :         PyErr_SetString(PyExc_ValueError,
     141                 :          1 :                         "MessageRenderer length limit out of range");
     142                 :          1 :         return (NULL);
     143                 :            :     }
     144                 :        157 :     self->cppobj->setLengthLimit(lengthlimit);
     145                 :        159 :     Py_RETURN_NONE;
     146                 :            : }
     147                 :            : 
     148                 :            : PyObject*
     149                 :        140 : MessageRenderer_setCompressMode(s_MessageRenderer* self,
     150                 :            :                                PyObject* args)
     151                 :            : {
     152                 :            :     int mode;
     153         [ +  + ]:        140 :     if (!PyArg_ParseTuple(args, "i", &mode)) {
     154                 :            :         return (NULL);
     155                 :            :     }
     156                 :            : 
     157         [ +  + ]:        139 :     if (mode == MessageRenderer::CASE_INSENSITIVE) {
     158                 :          1 :         self->cppobj->setCompressMode(MessageRenderer::CASE_INSENSITIVE);
     159                 :            :         // If we return NULL it is seen as an error, so use this for
     160                 :            :         // None returns, it also applies to CASE_SENSITIVE.
     161                 :          1 :         Py_RETURN_NONE;
     162         [ +  - ]:        138 :     } else if (mode == MessageRenderer::CASE_SENSITIVE) {
     163                 :        138 :         self->cppobj->setCompressMode(MessageRenderer::CASE_SENSITIVE);
     164                 :        138 :         Py_RETURN_NONE;
     165                 :            :     } else {
     166                 :            :         PyErr_SetString(PyExc_TypeError,
     167                 :            :                         "MessageRenderer compress mode must be MessageRenderer.CASE_INSENSITIVE"
     168                 :          0 :                         "or MessageRenderer.CASE_SENSITIVE");
     169                 :        140 :         return (NULL);
     170                 :            :     }
     171                 :            : }
     172                 :            : 
     173                 :            : PyObject*
     174                 :         30 : MessageRenderer_clear(s_MessageRenderer* self) {
     175                 :         30 :     self->cppobj->clear();
     176                 :         30 :     Py_RETURN_NONE;
     177                 :            : }
     178                 :            : } // end of unnamed namespace
     179                 :            : 
     180                 :            : namespace isc {
     181                 :            : namespace dns {
     182                 :            : namespace python {
     183                 :            : PyTypeObject messagerenderer_type = {
     184                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
     185                 :            :     "pydnspp.MessageRenderer",
     186                 :            :     sizeof(s_MessageRenderer),          // tp_basicsize
     187                 :            :     0,                                  // tp_itemsize
     188                 :            :     (destructor)MessageRenderer_destroy,// tp_dealloc
     189                 :            :     NULL,                               // tp_print
     190                 :            :     NULL,                               // tp_getattr
     191                 :            :     NULL,                               // tp_setattr
     192                 :            :     NULL,                               // tp_reserved
     193                 :            :     NULL,                               // tp_repr
     194                 :            :     NULL,                               // tp_as_number
     195                 :            :     NULL,                               // tp_as_sequence
     196                 :            :     NULL,                               // tp_as_mapping
     197                 :            :     NULL,                               // tp_hash
     198                 :            :     NULL,                               // tp_call
     199                 :            :     NULL,                               // tp_str
     200                 :            :     NULL,                               // tp_getattro
     201                 :            :     NULL,                               // tp_setattro
     202                 :            :     NULL,                               // tp_as_buffer
     203                 :            :     Py_TPFLAGS_DEFAULT,                 // tp_flags
     204                 :            :     "The MessageRenderer class encapsulates implementation details "
     205                 :            :     "of rendering a DNS message into a buffer in wire format. "
     206                 :            :     "In effect, it's simply responsible for name compression at least in the "
     207                 :            :     "current implementation. A MessageRenderer class object manages the "
     208                 :            :     "positions of names rendered in a buffer and uses that information to render "
     209                 :            :     "subsequent names with compression.",
     210                 :            :     NULL,                               // tp_traverse
     211                 :            :     NULL,                               // tp_clear
     212                 :            :     NULL,                               // tp_richcompare
     213                 :            :     0,                                  // tp_weaklistoffset
     214                 :            :     NULL,                               // tp_iter
     215                 :            :     NULL,                               // tp_iternext
     216                 :            :     MessageRenderer_methods,            // tp_methods
     217                 :            :     NULL,                               // tp_members
     218                 :            :     NULL,                               // tp_getset
     219                 :            :     NULL,                               // tp_base
     220                 :            :     NULL,                               // tp_dict
     221                 :            :     NULL,                               // tp_descr_get
     222                 :            :     NULL,                               // tp_descr_set
     223                 :            :     0,                                  // tp_dictoffset
     224                 :            :     (initproc)MessageRenderer_init,     // tp_init
     225                 :            :     NULL,                               // tp_alloc
     226                 :            :     PyType_GenericNew,                  // tp_new
     227                 :            :     NULL,                               // tp_free
     228                 :            :     NULL,                               // tp_is_gc
     229                 :            :     NULL,                               // tp_bases
     230                 :            :     NULL,                               // tp_mro
     231                 :            :     NULL,                               // tp_cache
     232                 :            :     NULL,                               // tp_subclasses
     233                 :            :     NULL,                               // tp_weaklist
     234                 :            :     NULL,                               // tp_del
     235                 :            :     0                                   // tp_version_tag
     236                 :            : };
     237                 :            : 
     238                 :            : // If we need a createMessageRendererObject(), should we copy? can we?
     239                 :            : // copy the existing buffer into a new one, then create a new renderer with
     240                 :            : // that buffer?
     241                 :            : 
     242                 :            : bool
     243                 :          0 : PyMessageRenderer_Check(PyObject* obj) {
     244         [ #  # ]:          0 :     if (obj == NULL) {
     245         [ #  # ]:          0 :         isc_throw(PyCPPWrapperException, "obj argument NULL in typecheck");
     246                 :            :     }
     247 [ #  # ][ #  # ]:          0 :     return (PyObject_TypeCheck(obj, &messagerenderer_type));
     248                 :            : }
     249                 :            : 
     250                 :            : MessageRenderer&
     251                 :        465 : PyMessageRenderer_ToMessageRenderer(PyObject* messagerenderer_obj) {
     252         [ -  + ]:        465 :     if (messagerenderer_obj == NULL) {
     253         [ #  # ]:          0 :         isc_throw(PyCPPWrapperException,
     254                 :            :                   "obj argument NULL in MessageRenderer PyObject conversion");
     255                 :            :     }
     256                 :        465 :     s_MessageRenderer* messagerenderer = static_cast<s_MessageRenderer*>(messagerenderer_obj);
     257                 :        465 :     return (*messagerenderer->cppobj);
     258                 :            : }
     259                 :            : 
     260                 :            : 
     261                 :            : } // namespace python
     262                 :            : } // namespace dns
     263                 :       1176 : } // namespace isc

Generated by: LCOV version 1.9