LCOV - code coverage report
Current view: top level - dns/python - pydnspp_towire.h (source / functions) Hit Total Coverage
Test: report.info Lines: 9 21 42.9 %
Date: 2012-05-15 Functions: 1 3 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 12 90 13.3 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2011  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                 :            : #ifndef __LIBDNS_PYTHON_TOWIRE_H
      16                 :            : #define __LIBDNS_PYTHON_TOWIRE_H 1
      17                 :            : 
      18                 :            : #include <Python.h>
      19                 :            : 
      20                 :            : #include <stdexcept>
      21                 :            : #include <string>
      22                 :            : 
      23                 :            : #include <dns/messagerenderer.h>
      24                 :            : 
      25                 :            : #include <util/buffer.h>
      26                 :            : #include <util/python/pycppwrapper_util.h>
      27                 :            : 
      28                 :            : #include "messagerenderer_python.h"
      29                 :            : 
      30                 :            : namespace isc {
      31                 :            : namespace dns {
      32                 :            : namespace python {
      33                 :            : 
      34                 :            : // The following two templated structures are a helper to use the same
      35                 :            : // toWire() template implementation for two types of toWire() methods:
      36                 :            : // return an integer or have no return value.
      37                 :            : template <typename CPPCLASS>
      38                 :            : struct ToWireCallVoid {
      39                 :            :     ToWireCallVoid(CPPCLASS& cppobj) : cppobj_(cppobj) {}
      40                 :            :     int operator()(AbstractMessageRenderer& renderer) const {
      41 [ #  # ][ #  # ]:          0 :         cppobj_.toWire(renderer);
      42                 :            :         return (0);
      43                 :            :     }
      44                 :            :     const CPPCLASS& cppobj_;
      45                 :            : };
      46                 :            : 
      47                 :            : template <typename CPPCLASS>
      48                 :            : struct ToWireCallInt {
      49                 :            :     ToWireCallInt(CPPCLASS& cppobj) : cppobj_(cppobj) {}
      50                 :            :     int operator()(AbstractMessageRenderer& renderer) const {
      51         [ #  # ]:          0 :         return (cppobj_.toWire(renderer));
      52                 :            :     }
      53                 :            :     const CPPCLASS& cppobj_;
      54                 :            : };
      55                 :            : 
      56                 :            : // This templated function gives a common implementation of the toWire()
      57                 :            : // wrapper for various libdns++ classes.  PYSTRUCT and CPPCLASS are
      58                 :            : // (C++ binding of) python and (pure) C++ classes (e.g., s_Name and Name),
      59                 :            : // and TOWIRECALLER is either ToWireCallVoid<CPPCLASS> or
      60                 :            : // ToWireCallInt<CPPCLASS>, depending on the toWire() method of the class
      61                 :            : // returns a value or not.
      62                 :            : //
      63                 :            : // See, e.g., tsigrecord_python.cc for how to use it.
      64                 :            : //
      65                 :            : // This should be able to be used without modification for most classes that
      66                 :            : // have toWire().  But if the underlying toWire() has an extra argument, the
      67                 :            : // definition will need to be adjusted accordingly.
      68                 :            : template <typename PYSTRUCT, typename CPPCLASS, typename TOWIRECALLER>
      69                 :            : PyObject*
      70                 :         19 : toWireWrapper(const PYSTRUCT* const self, PyObject* args) {
      71                 :            :     try {
      72                 :            :         // To OutputBuffer version
      73                 :            :         PyObject* bytes; // this won't have own reference, no risk of leak.
      74 [ +  - ][ +  - ]:         19 :         if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
         [ +  - ][ -  + ]
         [ +  - ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      75                 :            :             // render the object into a buffer (this can throw)
      76                 :         19 :             isc::util::OutputBuffer buffer(0);
      77 [ +  - ][ #  # ]:         19 :             self->cppobj->toWire(buffer);
      78                 :            : 
      79                 :            :             // convert the rendered data into PyObject.  This could leak later,
      80                 :            :             // so we need to store it in a container.
      81                 :            :             PyObject* rd_bytes = PyBytes_FromStringAndSize(
      82                 :            :                 static_cast<const char*>(buffer.getData()),
      83 [ +  - ][ #  # ]:         19 :                 buffer.getLength());
      84 [ +  - ][ +  - ]:         38 :             isc::util::python::PyObjectContainer rd_bytes_container(rd_bytes);
         [ #  # ][ #  # ]
      85                 :            : 
      86                 :            :             // concat the latest data to the given existing sequence.  concat
      87                 :            :             // operation could fail, so we use a container to clean it up
      88                 :            :             // safely should that happen.
      89 [ +  - ][ #  # ]:         19 :             PyObject* result = PySequence_InPlaceConcat(bytes, rd_bytes);
      90 [ +  - ][ +  - ]:         19 :             isc::util::python::PyObjectContainer result_container(result);
         [ #  # ][ #  # ]
      91                 :            : 
      92                 :            :             return (result_container.release());
      93                 :            :         }
      94                 :            : 
      95                 :            :         // To MessageRenderer version
      96                 :            :         PyObject* renderer;
      97 [ #  # ][ #  # ]:          0 :         if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &renderer)) {
         [ #  # ][ #  # ]
      98                 :            :             const unsigned int n = TOWIRECALLER(*self->cppobj)(
      99 [ #  # ][ #  # ]:          0 :                 PyMessageRenderer_ToMessageRenderer(renderer));
     100                 :            : 
     101 [ #  # ][ #  # ]:          0 :             return (Py_BuildValue("I", n));
     102                 :            :         }
     103                 :          0 :     } catch (const std::exception& ex) {
     104                 :            :         const std::string ex_what =
     105                 :            :             "Failed to render an libdns++ object wire-format: "
     106 [ #  # ][ #  # ]:          0 :             + std::string(ex.what());
         [ #  # ][ #  # ]
     107   [ #  #  #  # ]:          0 :         PyErr_SetString(po_IscException, ex_what.c_str());
     108                 :            :         return (NULL);
     109 [ #  # ][ #  # ]:          0 :     } catch (...) {
     110   [ #  #  #  # ]:          0 :         PyErr_SetString(po_IscException, "Unexpectedly failed to render an "
     111                 :            :                         "libdns++ object wire-format.");
     112                 :            :         return (NULL);
     113                 :            :     }
     114                 :            : 
     115                 :          0 :     PyErr_Clear();
     116                 :          0 :     PyErr_SetString(PyExc_TypeError,
     117                 :            :                     "Incorrect arguments for a to_wire() method");
     118                 :         19 :     return (NULL);
     119                 :            : }
     120                 :            : } // namespace python
     121                 :            : } // namespace dns
     122                 :            : } // namespace isc
     123                 :            : #endif // __LIBDNS_PYTHON_TOWIRE_H
     124                 :            : 
     125                 :            : // Local Variables:
     126                 :            : // mode: c++
     127                 :            : // End:

Generated by: LCOV version 1.9