// Copyright (C) 2009 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. // $Id$ #include // For each class, we need a struct, a helper functions (init, destroy, // and static wrappers around the methods we export), a list of methods, // and a type description using namespace isc::dns; // MessageRenderer // 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. typedef struct { PyObject_HEAD OutputBuffer* outputbuffer; MessageRenderer* messagerenderer; } s_MessageRenderer; static int MessageRenderer_init(s_MessageRenderer* self); static void MessageRenderer_destroy(s_MessageRenderer* self); static PyObject* MessageRenderer_getData(s_MessageRenderer* self); static PyObject* MessageRenderer_getLength(s_MessageRenderer* self); static PyObject* MessageRenderer_isTruncated(s_MessageRenderer* self); static PyObject* MessageRenderer_getLengthLimit(s_MessageRenderer* self); static PyMethodDef MessageRenderer_methods[] = { { "get_data", (PyCFunction)MessageRenderer_getData, METH_NOARGS, "Return the data" }, { "get_length", (PyCFunction)MessageRenderer_getLength, METH_NOARGS, "Return the length of the data" }, { "is_truncated", (PyCFunction)MessageRenderer_isTruncated, METH_NOARGS, "Returns True if the data is truncated" }, { "get_length_limit", (PyCFunction)MessageRenderer_getLengthLimit, METH_NOARGS, "Return the length limit of the data" }, { NULL, NULL, 0, NULL } }; static PyTypeObject messagerenderer_type = { PyVarObject_HEAD_INIT(NULL, 0) "libdns_python.MessageRenderer", sizeof(s_MessageRenderer), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)MessageRenderer_destroy, /* tp_dealloc */ NULL, /* tp_print */ NULL, /* tp_getattr */ NULL, /* tp_setattr */ NULL, /* tp_reserved */ NULL, /* tp_repr */ NULL, /* tp_as_number */ NULL, /* tp_as_sequence */ NULL, /* tp_as_mapping */ NULL, /* tp_hash */ NULL, /* tp_call */ NULL, /* tp_str */ NULL, /* tp_getattro */ NULL, /* tp_setattro */ NULL, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "C++ MessageRenderer Object", /* tp_doc */ NULL, /* tp_traverse */ NULL, /* tp_clear */ NULL, /* tp_richcompare */ 0, /* tp_weaklistoffset */ NULL, /* tp_iter */ NULL, /* tp_iternext */ MessageRenderer_methods, /* tp_methods */ NULL, /* tp_members */ NULL, /* tp_getset */ NULL, /* tp_base */ NULL, /* tp_dict */ NULL, /* tp_descr_get */ NULL, /* tp_descr_set */ 0, /* tp_dictoffset */ (initproc)MessageRenderer_init, /* tp_init */ NULL, /* tp_alloc */ PyType_GenericNew, /* tp_new */ NULL, /* tp_free */ NULL, /* tp_is_gc */ NULL, /* tp_bases */ NULL, /* tp_mro */ NULL, /* tp_cache */ NULL, /* tp_subclasses */ NULL, /* tp_weaklist */ // Note: not sure if the following are correct. Added them just to // make the compiler happy. NULL, /* tp_del */ 0 /* tp_version_tag */ }; static int MessageRenderer_init(s_MessageRenderer* self) { self->outputbuffer = new OutputBuffer(4096); self->messagerenderer = new MessageRenderer(*self->outputbuffer); return 0; } static void MessageRenderer_destroy(s_MessageRenderer* self) { delete self->messagerenderer; delete self->outputbuffer; self->messagerenderer = NULL; Py_TYPE(self)->tp_free(self); } static PyObject* MessageRenderer_getData(s_MessageRenderer* self) { return Py_BuildValue("y#", self->messagerenderer->getData(), self->messagerenderer->getLength()); } static PyObject* MessageRenderer_getLength(s_MessageRenderer* self) { return Py_BuildValue("I", self->messagerenderer->getLength()); } static PyObject* MessageRenderer_isTruncated(s_MessageRenderer* self) { if (self->messagerenderer->isTruncated()) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject* MessageRenderer_getLengthLimit(s_MessageRenderer* self) { return Py_BuildValue("I", self->messagerenderer->getLengthLimit()); } // end of MessageRenderer // Module Initialization, all statics are initialized here bool initModulePart_MessageRenderer(PyObject* mod) { // Add the exceptions to the module // Add the enums to the module // Add the constants to the module // Add the classes to the module // We initialize the static description object with PyType_Ready(), // then add it to the module // NameComparisonResult if (PyType_Ready(&messagerenderer_type) < 0) { return false; } Py_INCREF(&messagerenderer_type); PyModule_AddObject(mod, "MessageRenderer", (PyObject*) &messagerenderer_type); return true; }