Commit ade0b1a8 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[trac915] added related new header files for the previous commit.

pydnspp_towire is a separate utility to centralize the code logic for
toWire() bindings.
parent ff207112
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __PYTHON_MESSAGERENDERER_H
#define __PYTHON_MESSAGERENDERER_H 1
#include <Python.h>
namespace isc {
namespace util {
class OutputBuffer;
}
namespace dns {
class MessageRenderer;
namespace python {
// The s_* Class simply covers one instantiation of the object.
//
// since we don't use *Buffer in the python version (but work with
// the already existing bytearray type where we use these custom buffers
// in C++, we need to keep track of one here.
class s_MessageRenderer : public PyObject {
public:
s_MessageRenderer();
isc::util::OutputBuffer* outputbuffer;
MessageRenderer* messagerenderer;
};
extern PyTypeObject messagerenderer_type;
bool initModulePart_MessageRenderer(PyObject* mod);
} // namespace python
} // namespace dns
} // namespace isc
#endif // __PYTHON_MESSAGERENDERER_H
// Local Variables:
// mode: c++
// End:
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __PYTHON_NAME_H
#define __PYTHON_NAME_H 1
#include <Python.h>
#include <util/python/pycppwrapper_util.h>
namespace isc {
namespace dns {
class NameComparisonResult;
class Name;
namespace python {
//
// Declaration of the custom exceptions
// Initialization and addition of these go in the module init at the
// end
//
extern PyObject* po_EmptyLabel;
extern PyObject* po_TooLongName;
extern PyObject* po_TooLongLabel;
extern PyObject* po_BadLabelType;
extern PyObject* po_BadEscape;
extern PyObject* po_IncompleteName;
extern PyObject* po_InvalidBufferPosition;
extern PyObject* po_DNSMessageFORMERR;
//
// Declaration of enums
// Initialization and addition of these go in the module init at the
// end
//
extern PyObject* po_NameRelation;
// The s_* Class simply covers one instantiation of the object.
class s_NameComparisonResult : public PyObject {
public:
s_NameComparisonResult() : cppobj(NULL) {}
NameComparisonResult* cppobj;
};
class s_Name : public PyObject {
public:
s_Name() : cppobj(NULL) {}
Name* cppobj;
size_t position;
};
extern PyTypeObject name_comparison_result_type;
extern PyTypeObject name_type;
bool initModulePart_Name(PyObject* mod);
/// This is A simple shortcut to create a python Name object (in the
/// form of a pointer to PyObject) with minimal exception safety.
/// On success, it returns a valid pointer to PyObject with a reference
/// counter of 1; if something goes wrong it throws an exception (it never
/// returns a NULL pointer).
/// This function is expected to be called with in a try block
/// followed by necessary setup for python exception.
PyObject* createNameObject(const Name& source);
} // namespace python
} // namespace dns
} // namespace isc
#endif // __PYTHON_NAME_H
// Local Variables:
// mode: c++
// End:
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __LIBDNS_PYTHON_TOWIRE_H
#define __LIBDNS_PYTHON_TOWIRE_H 1
#include <Python.h>
#include <stdexcept>
#include <string>
#include <dns/messagerenderer.h>
#include <util/buffer.h>
#include <util/python/pycppwrapper_util.h>
#include "messagerenderer_python.h"
namespace isc {
namespace dns {
namespace python {
// The following two templated structures are a helper to use the same
// toWire() template implementation for two types of toWire() methods:
// return an integer or have no return value.
template <typename CPPCLASS>
struct ToWireCallVoid {
ToWireCallVoid(CPPCLASS& cppobj) : cppobj_(cppobj) {}
int operator()(AbstractMessageRenderer& renderer) const {
cppobj_.toWire(renderer);
return (0);
}
const CPPCLASS& cppobj_;
};
template <typename CPPCLASS>
struct ToWireCallInt {
ToWireCallInt(CPPCLASS& cppobj) : cppobj_(cppobj) {}
int operator()(AbstractMessageRenderer& renderer) const {
return (cppobj_.toWire(renderer));
}
const CPPCLASS& cppobj_;
};
// This templated function gives a common implementation of the toWire()
// wrapper for various libdns++ classes. PYSTRUCT and CPPCLASS are
// (C++ binding of) python and (pure) C++ classes (e.g., s_Name and Name),
// and TOWIRECALLER is either ToWireCallVoid<CPPCLASS> or
// ToWireCallInt<CPPCLASS>, depending on the toWire() method of the class
// returns a value or not.
//
// See, e.g., tsigrecord_python.cc for how to use it.
//
// This should be able to be used without modification for most classes that
// have toWire(). But if the underlying toWire() has an extra argument, the
// definition will need to be adjusted accordingly.
template <typename PYSTRUCT, typename CPPCLASS, typename TOWIRECALLER>
PyObject*
toWireWrapper(const PYSTRUCT* const self, PyObject* args) {
try {
// To OutputBuffer version
PyObject* bytes; // this won't have own reference, no risk of leak.
if (PyArg_ParseTuple(args, "O", &bytes) && PySequence_Check(bytes)) {
// render the object into a buffer (this can throw)
isc::util::OutputBuffer buffer(0);
self->cppobj->toWire(buffer);
// convert the rendered data into PyObject. This could leak later,
// so we need to store it in a container.
PyObject* rd_bytes = PyBytes_FromStringAndSize(
static_cast<const char*>(buffer.getData()),
buffer.getLength());
isc::util::python::PyObjectContainer rd_bytes_container(rd_bytes);
// concat the latest data to the given existing sequence. concat
// operation could fail, so we use a container to clean it up
// safely should that happen.
PyObject* result = PySequence_InPlaceConcat(bytes, rd_bytes);
isc::util::python::PyObjectContainer result_container(result);
return (result_container.release());
}
// To MessageRenderer version
s_MessageRenderer* renderer;
if (PyArg_ParseTuple(args, "O!", &messagerenderer_type, &renderer)) {
const unsigned int n = TOWIRECALLER(*self->cppobj)(
*renderer->messagerenderer);
return (Py_BuildValue("I", n));
}
} catch (const std::exception& ex) {
const std::string ex_what =
"Failed to render an libdns++ object wire-format: "
+ std::string(ex.what());
PyErr_SetString(po_IscException, ex_what.c_str());
return (NULL);
} catch (...) {
PyErr_SetString(po_IscException, "Unexpectedly failed to render an "
"libdns++ object wire-format.");
return (NULL);
}
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"Incorrect arguments for a to_wire() method");
return (NULL);
}
} // namespace python
} // namespace dns
} // namespace isc
#endif // __LIBDNS_PYTHON_TOWIRE_H
// Local Variables:
// mode: c++
// End:
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment