LCOV - code coverage report
Current view: top level - dns/python - rrset_python.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 100 132 75.8 %
Date: 2012-05-15 Functions: 19 20 95.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 84 220 38.2 %

           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/python/pycppwrapper_util.h>
      18                 :            : 
      19                 :            : #include <dns/rrset.h>
      20                 :            : #include <dns/name.h>
      21                 :            : #include <dns/messagerenderer.h>
      22                 :            : 
      23                 :            : #include "name_python.h"
      24                 :            : #include "pydnspp_common.h"
      25                 :            : #include "rrset_python.h"
      26                 :            : #include "rrclass_python.h"
      27                 :            : #include "rrtype_python.h"
      28                 :            : #include "rrttl_python.h"
      29                 :            : #include "rdata_python.h"
      30                 :            : #include "messagerenderer_python.h"
      31                 :            : 
      32                 :            : using namespace std;
      33                 :            : using namespace isc::dns;
      34                 :            : using namespace isc::dns::python;
      35                 :            : using namespace isc::util;
      36                 :            : using namespace isc::util::python;
      37                 :            : 
      38                 :            : namespace {
      39                 :            : 
      40                 :            : // The s_* Class simply coverst one instantiation of the object
      41                 :            : 
      42                 :            : // Using a shared_ptr here should not really be necessary (PyObject
      43                 :            : // is already reference-counted), however internally on the cpp side,
      44                 :            : // not doing so might result in problems, since we can't copy construct
      45                 :            : // rdata field, adding them to rrsets results in a problem when the
      46                 :            : // rrset is destroyed later
      47                 :            : class s_RRset : public PyObject {
      48                 :            : public:
      49                 :            :     isc::dns::RRsetPtr cppobj;
      50                 :            : };
      51                 :            : 
      52                 :            : int RRset_init(s_RRset* self, PyObject* args);
      53                 :            : void RRset_destroy(s_RRset* self);
      54                 :            : 
      55                 :            : PyObject* RRset_getRdataCount(PyObject* self, PyObject* args);
      56                 :            : PyObject* RRset_getName(PyObject* self, PyObject* args);
      57                 :            : PyObject* RRset_getClass(PyObject* self, PyObject* args);
      58                 :            : PyObject* RRset_getType(PyObject* self, PyObject* args);
      59                 :            : PyObject* RRset_getTTL(PyObject* self, PyObject* args);
      60                 :            : PyObject* RRset_setName(PyObject* self, PyObject* args);
      61                 :            : PyObject* RRset_setTTL(PyObject* self, PyObject* args);
      62                 :            : PyObject* RRset_toText(PyObject* self, PyObject* args);
      63                 :            : PyObject* RRset_str(PyObject* self);
      64                 :            : PyObject* RRset_toWire(PyObject* self, PyObject* args);
      65                 :            : PyObject* RRset_addRdata(PyObject* self, PyObject* args);
      66                 :            : PyObject* RRset_getRdata(PyObject* po_self, PyObject* args);
      67                 :            : PyObject* RRset_removeRRsig(PyObject* self, PyObject* args);
      68                 :            : 
      69                 :            : // TODO: iterator?
      70                 :            : 
      71                 :            : PyMethodDef RRset_methods[] = {
      72                 :            :     { "get_rdata_count", RRset_getRdataCount, METH_NOARGS,
      73                 :            :       "Returns the number of rdata fields." },
      74                 :            :     { "get_name", RRset_getName, METH_NOARGS,
      75                 :            :       "Returns the name of the RRset, as a Name object." },
      76                 :            :     { "get_class", RRset_getClass, METH_NOARGS,
      77                 :            :       "Returns the class of the RRset as an RRClass object." },
      78                 :            :     { "get_type", RRset_getType, METH_NOARGS,
      79                 :            :       "Returns the type of the RRset as an RRType object." },
      80                 :            :     { "get_ttl", RRset_getTTL, METH_NOARGS,
      81                 :            :       "Returns the TTL of the RRset as an RRTTL object." },
      82                 :            :     { "set_name", RRset_setName, METH_VARARGS,
      83                 :            :       "Sets the name of the RRset.\nTakes a Name object as an argument." },
      84                 :            :     { "set_ttl", RRset_setTTL, METH_VARARGS,
      85                 :            :       "Sets the TTL of the RRset.\nTakes an RRTTL object as an argument." },
      86                 :            :     { "to_text", RRset_toText, METH_NOARGS,
      87                 :            :       "Returns the text representation of the RRset as a string" },
      88                 :            :     { "to_wire", RRset_toWire, METH_VARARGS,
      89                 :            :       "Converts the RRset object to wire format.\n"
      90                 :            :       "The argument can be either a MessageRenderer or an object that "
      91                 :            :       "implements the sequence interface. If the object is mutable "
      92                 :            :       "(for instance a bytearray()), the wire data is added in-place.\n"
      93                 :            :       "If it is not (for instance a bytes() object), a new object is "
      94                 :            :       "returned" },
      95                 :            :     { "add_rdata", RRset_addRdata, METH_VARARGS,
      96                 :            :       "Adds the rdata for one RR to the RRset.\nTakes an Rdata object as an argument" },
      97                 :            :     { "get_rdata", RRset_getRdata, METH_NOARGS,
      98                 :            :       "Returns a List containing all Rdata elements" },
      99                 :            :     { "remove_rrsig", RRset_removeRRsig, METH_NOARGS,
     100                 :            :       "Clears the list of RRsigs for this RRset" },
     101                 :            :     { NULL, NULL, 0, NULL }
     102                 :            : };
     103                 :            : 
     104                 :            : int
     105                 :       1121 : RRset_init(s_RRset* self, PyObject* args) {
     106                 :            :     PyObject* name;
     107                 :            :     PyObject* rrclass;
     108                 :            :     PyObject* rrtype;
     109                 :            :     PyObject* rrttl;
     110                 :            : 
     111         [ +  + ]:       1121 :     if (PyArg_ParseTuple(args, "O!O!O!O!", &name_type, &name,
     112                 :            :                                            &rrclass_type, &rrclass,
     113                 :            :                                            &rrtype_type, &rrtype,
     114                 :            :                                            &rrttl_type, &rrttl
     115                 :       1121 :        )) {
     116                 :       1120 :         self->cppobj = RRsetPtr(new RRset(PyName_ToName(name),
     117                 :       1120 :                                           PyRRClass_ToRRClass(rrclass),
     118                 :       1120 :                                           PyRRType_ToRRType(rrtype),
     119 [ +  - ][ +  - ]:       1120 :                                           PyRRTTL_ToRRTTL(rrttl)));
     120                 :            :         return (0);
     121                 :            :     }
     122                 :            : 
     123         [ +  - ]:          1 :     self->cppobj = RRsetPtr();
     124                 :            :     return (-1);
     125                 :            : }
     126                 :            : 
     127                 :            : void
     128                 :       2049 : RRset_destroy(s_RRset* self) {
     129                 :            :     // Clear the shared_ptr so that its reference count is zero
     130                 :            :     // before we call tp_free() (there is no direct release())
     131                 :       2049 :     self->cppobj.reset();
     132                 :       2049 :     Py_TYPE(self)->tp_free(self);
     133                 :       2049 : }
     134                 :            : 
     135                 :            : PyObject*
     136                 :        786 : RRset_getRdataCount(PyObject* self, PyObject*) {
     137                 :        786 :     return (Py_BuildValue("I", static_cast<const s_RRset*>(self)->cppobj->
     138                 :        786 :                           getRdataCount()));
     139                 :            : }
     140                 :            : 
     141                 :            : PyObject*
     142                 :       1034 : RRset_getName(PyObject* self, PyObject*) {
     143                 :            :     try {
     144                 :       1034 :         return (createNameObject(static_cast<const s_RRset*>(self)->cppobj->
     145 [ +  - ][ +  - ]:       1034 :                                  getName()));
     146                 :          0 :     } catch (const exception& ex) {
     147                 :            :         const string ex_what =
     148                 :            :             "Unexpected failure getting rrset Name: " +
     149 [ #  # ][ #  # ]:          0 :             string(ex.what());
     150         [ #  # ]:          0 :         PyErr_SetString(po_IscException, ex_what.c_str());
     151         [ #  # ]:          0 :     } catch (...) {
     152                 :            :         PyErr_SetString(PyExc_SystemError,
     153         [ #  # ]:          0 :                         "Unexpected failure getting rrset Name");
     154                 :            :     }
     155                 :            :     return (NULL);
     156                 :            : }
     157                 :            : 
     158                 :            : PyObject*
     159                 :       1070 : RRset_getClass(PyObject* self, PyObject*) {
     160                 :            :     try {
     161                 :       1070 :         return (createRRClassObject(static_cast<const s_RRset*>(self)->cppobj->
     162 [ +  - ][ +  - ]:       1070 :                                     getClass()));
     163                 :          0 :     } catch (const exception& ex) {
     164                 :            :         const string ex_what =
     165                 :            :             "Unexpected failure getting question RRClass: " +
     166 [ #  # ][ #  # ]:          0 :             string(ex.what());
     167         [ #  # ]:          0 :         PyErr_SetString(po_IscException, ex_what.c_str());
     168         [ #  # ]:          0 :     } catch (...) {
     169                 :            :         PyErr_SetString(PyExc_SystemError,
     170         [ #  # ]:          0 :                         "Unexpected failure getting question RRClass");
     171                 :            :     }
     172                 :            :     return (NULL);
     173                 :            : }
     174                 :            : 
     175                 :            : PyObject*
     176                 :       1741 : RRset_getType(PyObject* self, PyObject*) {
     177                 :            :     try {
     178                 :       1741 :         return (createRRTypeObject(static_cast<const s_RRset*>(self)->cppobj->
     179 [ +  - ][ +  - ]:       1741 :                                    getType()));
     180                 :          0 :     } catch (const exception& ex) {
     181                 :            :         const string ex_what =
     182                 :            :             "Unexpected failure getting question RRType: " +
     183 [ #  # ][ #  # ]:          0 :             string(ex.what());
     184         [ #  # ]:          0 :         PyErr_SetString(po_IscException, ex_what.c_str());
     185         [ #  # ]:          0 :     } catch (...) {
     186                 :            :         PyErr_SetString(PyExc_SystemError,
     187         [ #  # ]:          0 :                         "Unexpected failure getting question RRType");
     188                 :            :     }
     189                 :            :     return (NULL);
     190                 :            : }
     191                 :            : 
     192                 :            : PyObject*
     193                 :       1021 : RRset_getTTL(PyObject* self, PyObject*) {
     194                 :            :     try {
     195                 :       1021 :         return (createRRTTLObject(static_cast<const s_RRset*>(self)->cppobj->
     196 [ +  - ][ +  - ]:       1021 :                                   getTTL()));
     197                 :          0 :     } catch (const exception& ex) {
     198                 :            :         const string ex_what =
     199                 :            :             "Unexpected failure getting question TTL: " +
     200 [ #  # ][ #  # ]:          0 :             string(ex.what());
     201         [ #  # ]:          0 :         PyErr_SetString(po_IscException, ex_what.c_str());
     202         [ #  # ]:          0 :     } catch (...) {
     203                 :            :         PyErr_SetString(PyExc_SystemError,
     204         [ #  # ]:          0 :                         "Unexpected failure getting question TTL");
     205                 :            :     }
     206                 :            :     return (NULL);
     207                 :            : }
     208                 :            : 
     209                 :            : PyObject*
     210                 :          2 : RRset_setName(PyObject* self, PyObject* args) {
     211                 :            :     PyObject* name;
     212         [ +  + ]:          2 :     if (!PyArg_ParseTuple(args, "O!", &name_type, &name)) {
     213                 :            :         return (NULL);
     214                 :            :     }
     215                 :          1 :     static_cast<s_RRset*>(self)->cppobj->setName(PyName_ToName(name));
     216                 :          2 :     Py_RETURN_NONE;
     217                 :            : }
     218                 :            : 
     219                 :            : PyObject*
     220                 :          3 : RRset_setTTL(PyObject* self, PyObject* args) {
     221                 :            :     PyObject* rrttl;
     222         [ +  + ]:          3 :     if (!PyArg_ParseTuple(args, "O!", &rrttl_type, &rrttl)) {
     223                 :            :         return (NULL);
     224                 :            :     }
     225                 :          2 :     static_cast<s_RRset*>(self)->cppobj->setTTL(PyRRTTL_ToRRTTL(rrttl));
     226                 :          3 :     Py_RETURN_NONE;
     227                 :            : }
     228                 :            : 
     229                 :            : PyObject*
     230                 :         50 : RRset_toText(PyObject* self, PyObject*) {
     231                 :            :     try {
     232                 :         50 :         return (Py_BuildValue("s", static_cast<const s_RRset*>(self)->cppobj->
     233 [ +  + ][ +  - ]:         51 :                               toText().c_str()));
     234         [ -  + ]:          2 :     } catch (const EmptyRRset& ers) {
     235         [ -  + ]:          1 :         PyErr_SetString(po_EmptyRRset, ers.what());
     236                 :            :         return (NULL);
     237                 :            :     }
     238                 :            : }
     239                 :            : 
     240                 :            : PyObject*
     241                 :          9 : RRset_str(PyObject* self) {
     242                 :            :     // Simply call the to_text method we already defined
     243                 :            :     return (PyObject_CallMethod(self,
     244                 :            :                                 const_cast<char*>("to_text"),
     245                 :          9 :                                 const_cast<char*>("")));
     246                 :            : }
     247                 :            : 
     248                 :            : PyObject*
     249                 :         64 : RRset_toWire(PyObject* self_p, PyObject* args) {
     250                 :            :     PyObject* bytes;
     251                 :            :     PyObject* mr;
     252                 :         64 :     const s_RRset* self(static_cast<const s_RRset*>(self_p));
     253                 :            : 
     254                 :            :     try {
     255 [ +  - ][ +  - ]:         64 :         if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
         [ +  - ][ +  + ]
                 [ +  + ]
     256                 :         62 :             PyObject* bytes_o = bytes;
     257                 :            : 
     258                 :         62 :             OutputBuffer buffer(4096);
     259         [ +  + ]:         62 :             self->cppobj->toWire(buffer);
     260         [ +  - ]:         61 :             PyObject* n = PyBytes_FromStringAndSize(static_cast<const char*>(buffer.getData()), buffer.getLength());
     261         [ +  - ]:         61 :             PyObject* result = PySequence_InPlaceConcat(bytes_o, n);
     262                 :            :             // We need to release the object we temporarily created here
     263                 :            :             // to prevent memory leak
     264 [ +  - ][ +  - ]:         61 :             Py_DECREF(n);
     265                 :            :             return (result);
     266 [ +  - ][ +  + ]:          2 :         } else if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &mr)) {
     267 [ +  - ][ +  - ]:          1 :             self->cppobj->toWire(PyMessageRenderer_ToMessageRenderer(mr));
     268                 :            :             // If we return NULL it is seen as an error, so use this for
     269                 :            :             // None returns
     270                 :          1 :             Py_RETURN_NONE;
     271                 :            :         }
     272         [ -  + ]:          2 :     } catch (const EmptyRRset& ers) {
     273         [ -  + ]:          1 :         PyErr_Clear();
     274         [ -  + ]:          1 :         PyErr_SetString(po_EmptyRRset, ers.what());
     275                 :            :         return (NULL);
     276                 :            :     }
     277                 :          1 :     PyErr_Clear();
     278                 :            :     PyErr_SetString(PyExc_TypeError,
     279                 :          1 :                     "toWire argument must be a sequence object or a MessageRenderer");
     280                 :         64 :     return (NULL);
     281                 :            : }
     282                 :            : 
     283                 :            : PyObject*
     284                 :       1357 : RRset_addRdata(PyObject* self, PyObject* args) {
     285                 :            :     PyObject* rdata;
     286         [ +  - ]:       1357 :     if (!PyArg_ParseTuple(args, "O!", &rdata_type, &rdata)) {
     287                 :            :         return (NULL);
     288                 :            :     }
     289                 :            :     try {
     290 [ +  - ][ +  + ]:       1357 :         static_cast<s_RRset*>(self)->cppobj->addRdata(PyRdata_ToRdata(rdata));
     291                 :       1357 :         Py_RETURN_NONE;
     292         [ -  + ]:          2 :     } catch (const std::bad_cast&) {
     293         [ -  + ]:          1 :         PyErr_Clear();
     294                 :            :         PyErr_SetString(PyExc_TypeError,
     295         [ -  + ]:          1 :                         "Rdata type to add must match type of RRset");
     296                 :            :         return (NULL);
     297                 :            :     }
     298                 :            : }
     299                 :            : 
     300                 :            : PyObject*
     301                 :       1227 : RRset_getRdata(PyObject* po_self, PyObject*) {
     302                 :       1227 :     const s_RRset* const self = static_cast<s_RRset*>(po_self);
     303                 :            : 
     304                 :            :     try {
     305 [ +  - ][ +  - ]:       2454 :         PyObjectContainer list_container(PyList_New(0));
                 [ +  - ]
     306                 :            : 
     307 [ +  - ][ +  + ]:       3851 :         for (RdataIteratorPtr it = self->cppobj->getRdataIterator();
     308 [ +  - ][ +  - ]:       2624 :              !it->isLast(); it->next()) {
     309         [ -  + ]:       1397 :             if (PyList_Append(list_container.get(),
     310                 :            :                               PyObjectContainer(
     311                 :            :                                   createRdataObject(
     312         [ +  - ]:       1397 :                                       createRdata(self->cppobj->getType(),
     313         [ +  - ]:       1397 :                                                   self->cppobj->getClass(),
     314 [ +  - ][ +  - ]:       4191 :                                                   it->getCurrent()))).get())
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     315                 :            :                 == -1) {
     316 [ #  # ][ #  # ]:          0 :                 isc_throw(PyCPPWrapperException, "PyList_Append failed, "
                 [ #  # ]
     317                 :            :                           "probably due to short memory");
     318                 :            :             }
     319                 :            :         }
     320                 :            :         return (list_container.release());
     321                 :          0 :     } catch (const exception& ex) {
     322                 :            :         const string ex_what =
     323                 :            :             "Unexpected failure getting rrset Rdata: " +
     324 [ #  # ][ #  # ]:          0 :             string(ex.what());
     325         [ #  # ]:          0 :         PyErr_SetString(po_IscException, ex_what.c_str());
     326         [ #  # ]:          0 :     } catch (...) {
     327                 :            :         PyErr_SetString(PyExc_SystemError,
     328         [ #  # ]:          0 :                         "Unexpected failure getting rrset Rdata");
     329                 :            :     }
     330                 :            :     return (NULL);
     331                 :            : }
     332                 :            : 
     333                 :            : PyObject*
     334                 :          2 : RRset_removeRRsig(PyObject* self, PyObject*) {
     335                 :          2 :     static_cast<s_RRset*>(self)->cppobj->removeRRsig();
     336                 :          2 :     Py_RETURN_NONE;
     337                 :            : }
     338                 :            : 
     339                 :            : } // end of unnamed namespace
     340                 :            : 
     341                 :            : namespace isc {
     342                 :            : namespace dns {
     343                 :            : namespace python {
     344                 :            : 
     345                 :            : //
     346                 :            : // Declaration of the custom exceptions
     347                 :            : // Initialization and addition of these go in the module init at the
     348                 :            : // end
     349                 :            : //
     350                 :            : PyObject* po_EmptyRRset;
     351                 :            : 
     352                 :            : PyTypeObject rrset_type = {
     353                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
     354                 :            :     "pydnspp.RRset",
     355                 :            :     sizeof(s_RRset),                    // tp_basicsize
     356                 :            :     0,                                  // tp_itemsize
     357                 :            :     (destructor)RRset_destroy,          // tp_dealloc
     358                 :            :     NULL,                               // tp_print
     359                 :            :     NULL,                               // tp_getattr
     360                 :            :     NULL,                               // tp_setattr
     361                 :            :     NULL,                               // tp_reserved
     362                 :            :     NULL,                               // tp_repr
     363                 :            :     NULL,                               // tp_as_number
     364                 :            :     NULL,                               // tp_as_sequence
     365                 :            :     NULL,                               // tp_as_mapping
     366                 :            :     NULL,                               // tp_hash
     367                 :            :     NULL,                               // tp_call
     368                 :            :     RRset_str,                          // tp_str
     369                 :            :     NULL,                               // tp_getattro
     370                 :            :     NULL,                               // tp_setattro
     371                 :            :     NULL,                               // tp_as_buffer
     372                 :            :     Py_TPFLAGS_DEFAULT,                 // tp_flags
     373                 :            :     "The AbstractRRset class is an abstract base class that "
     374                 :            :     "models a DNS RRset.\n\n"
     375                 :            :     "An object of (a specific derived class of) AbstractRRset "
     376                 :            :     "models an RRset as described in the DNS standard:\n"
     377                 :            :     "A set of DNS resource records (RRs) of the same type and class. "
     378                 :            :     "The standard requires the TTL of all RRs in an RRset be the same; "
     379                 :            :     "this class follows that requirement.\n\n"
     380                 :            :     "Note about duplicate RDATA: RFC2181 states that it's meaningless that an "
     381                 :            :     "RRset contains two identical RRs and that name servers should suppress "
     382                 :            :     "such duplicates.\n"
     383                 :            :     "This class is not responsible for ensuring this requirement: For example, "
     384                 :            :     "addRdata() method doesn't check if there's already RDATA identical "
     385                 :            :     "to the one being added.\n"
     386                 :            :     "This is because such checks can be expensive, and it's often easy to "
     387                 :            :     "ensure the uniqueness requirement at the %data preparation phase "
     388                 :            :     "(e.g. when loading a zone).",
     389                 :            :     NULL,                               // tp_traverse
     390                 :            :     NULL,                               // tp_clear
     391                 :            :     NULL,                               // tp_richcompare
     392                 :            :     0,                                  // tp_weaklistoffset
     393                 :            :     NULL,                               // tp_iter
     394                 :            :     NULL,                               // tp_iternext
     395                 :            :     RRset_methods,                      // tp_methods
     396                 :            :     NULL,                               // tp_members
     397                 :            :     NULL,                               // tp_getset
     398                 :            :     NULL,                               // tp_base
     399                 :            :     NULL,                               // tp_dict
     400                 :            :     NULL,                               // tp_descr_get
     401                 :            :     NULL,                               // tp_descr_set
     402                 :            :     0,                                  // tp_dictoffset
     403                 :            :     (initproc)RRset_init,               // tp_init
     404                 :            :     NULL,                               // tp_alloc
     405                 :            :     PyType_GenericNew,                  // tp_new
     406                 :            :     NULL,                               // tp_free
     407                 :            :     NULL,                               // tp_is_gc
     408                 :            :     NULL,                               // tp_bases
     409                 :            :     NULL,                               // tp_mro
     410                 :            :     NULL,                               // tp_cache
     411                 :            :     NULL,                               // tp_subclasses
     412                 :            :     NULL,                               // tp_weaklist
     413                 :            :     NULL,                               // tp_del
     414                 :            :     0                                   // tp_version_tag
     415                 :            : };
     416                 :            : 
     417                 :            : PyObject*
     418                 :        929 : createRRsetObject(const AbstractRRset& source) {
     419                 :            : 
     420                 :            :     // RRsets are noncopyable, so as a workaround we recreate a new one
     421                 :            :     // and copy over all content
     422                 :            :     RRsetPtr new_rrset = isc::dns::RRsetPtr(
     423                 :       1858 :         new isc::dns::RRset(source.getName(), source.getClass(),
     424         [ +  - ]:        929 :                             source.getType(), source.getTTL()));
     425                 :            : 
     426         [ +  - ]:        929 :     isc::dns::RdataIteratorPtr rdata_it(source.getRdataIterator());
     427 [ +  - ][ +  - ]:       2049 :     for (rdata_it->first(); !rdata_it->isLast(); rdata_it->next()) {
         [ +  - ][ +  + ]
     428 [ +  - ][ +  - ]:       1120 :         new_rrset->addRdata(rdata_it->getCurrent());
     429                 :            :     }
     430                 :            : 
     431         [ +  - ]:        929 :     isc::dns::RRsetPtr sigs = source.getRRsig();
     432         [ +  + ]:        929 :     if (sigs) {
     433         [ +  - ]:         12 :         new_rrset->addRRsig(sigs);
     434                 :            :     }
     435                 :            :     s_RRset* py_rrset =
     436         [ +  - ]:        929 :         static_cast<s_RRset*>(rrset_type.tp_alloc(&rrset_type, 0));
     437         [ -  + ]:        929 :     if (py_rrset == NULL) {
     438 [ #  # ][ #  # ]:          0 :         isc_throw(PyCPPWrapperException, "Unexpected NULL C++ object, "
                 [ #  # ]
     439                 :            :                   "probably due to short memory");
     440                 :            :     }
     441         [ +  - ]:        929 :     py_rrset->cppobj = new_rrset;
     442                 :        929 :     return (py_rrset);
     443                 :            : }
     444                 :            : 
     445                 :            : bool
     446                 :          0 : PyRRset_Check(PyObject* obj) {
     447         [ #  # ]:          0 :     if (obj == NULL) {
     448 [ #  # ][ #  # ]:          0 :         isc_throw(PyCPPWrapperException, "obj argument NULL in typecheck");
     449                 :            :     }
     450 [ #  # ][ #  # ]:          0 :     return (PyObject_TypeCheck(obj, &rrset_type));
     451                 :            : }
     452                 :            : 
     453                 :            : AbstractRRset&
     454                 :        431 : PyRRset_ToRRset(PyObject* rrset_obj) {
     455                 :        431 :     s_RRset* rrset = static_cast<s_RRset*>(rrset_obj);
     456                 :        431 :     return (*rrset->cppobj);
     457                 :            : }
     458                 :            : 
     459                 :            : RRsetPtr
     460                 :        400 : PyRRset_ToRRsetPtr(PyObject* rrset_obj) {
     461         [ -  + ]:        400 :     if (rrset_obj == NULL) {
     462 [ #  # ][ #  # ]:          0 :         isc_throw(PyCPPWrapperException,
     463                 :            :                   "obj argument NULL in RRset PyObject conversion");
     464                 :            :     }
     465                 :        400 :     s_RRset* rrset = static_cast<s_RRset*>(rrset_obj);
     466                 :        400 :     return (rrset->cppobj);
     467                 :            : }
     468                 :            : 
     469                 :            : 
     470                 :            : } // end python namespace
     471                 :            : } // end dns namespace
     472                 :        123 : } // end isc namespace

Generated by: LCOV version 1.9