BIND 10 master, updated. 638087de4edc54e2ef26fa7e444b743c433b44cd Merge branch 'trac2908'

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Jun 12 16:27:44 UTC 2013


The branch, master has been updated
       via  638087de4edc54e2ef26fa7e444b743c433b44cd (commit)
       via  926a9b1b81f91338aa03abcbed25b962ca86d209 (commit)
       via  27dcf35fa3b3d65a031df6c434343db2d5ddb8f8 (commit)
       via  827f143ed26198b3726d0921590f8e91fae11b4c (commit)
       via  db63f2e09dfa7e2742d06dc72f7bb4d52c3442a1 (commit)
       via  003aa4bedf13cd9d7b2e73983aa593deb6281435 (commit)
       via  95af51c86a9d480562526421863e47df7260e6a3 (commit)
       via  ca04c553327800d4a5719dfc1b1343927a9ffa13 (commit)
      from  67704c85b785065865a1b3963b73ba2dc70e5998 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 638087de4edc54e2ef26fa7e444b743c433b44cd
Merge: 67704c8 926a9b1
Author: Paul Selkirk <pselkirk at isc.org>
Date:   Wed Jun 12 10:30:44 2013 -0400

    Merge branch 'trac2908'

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/client_list.h                      |    2 -
 src/lib/datasrc/zone_table_accessor.h              |    3 +
 src/lib/python/isc/datasrc/Makefile.am             |    2 +
 .../isc/datasrc/configurableclientlist_python.cc   |   52 +++++++-
 src/lib/python/isc/datasrc/datasrc.cc              |   48 +++++++
 src/lib/python/isc/datasrc/finder_python.cc        |    4 +-
 .../python/isc/datasrc/tests/clientlist_test.py    |   84 +++++++++++-
 ...ader_python.cc => zonetable_accessor_python.cc} |  130 ++++++++-----------
 ...finder_python.h => zonetable_accessor_python.h} |   17 ++-
 ...ader_python.cc => zonetable_iterator_python.cc} |  137 ++++++++++----------
 ...erator_python.h => zonetable_iterator_python.h} |   22 ++--
 11 files changed, 323 insertions(+), 178 deletions(-)
 copy src/lib/python/isc/datasrc/{journal_reader_python.cc => zonetable_accessor_python.cc} (61%)
 copy src/lib/python/isc/datasrc/{finder_python.h => zonetable_accessor_python.h} (76%)
 copy src/lib/python/isc/datasrc/{journal_reader_python.cc => zonetable_iterator_python.cc} (65%)
 copy src/lib/python/isc/datasrc/{iterator_python.h => zonetable_iterator_python.h} (72%)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index 7917f3f..318cf5c 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -121,8 +121,6 @@ private:
     MemorySegmentState state_;
 };
 
-typedef boost::shared_ptr<const ZoneTableAccessor> ConstZoneTableAccessorPtr;
-
 /// \brief The list of data source clients.
 ///
 /// The purpose of this class is to hold several data source clients and search
diff --git a/src/lib/datasrc/zone_table_accessor.h b/src/lib/datasrc/zone_table_accessor.h
index 378c7eb..8e92d51 100644
--- a/src/lib/datasrc/zone_table_accessor.h
+++ b/src/lib/datasrc/zone_table_accessor.h
@@ -202,6 +202,9 @@ public:
     virtual IteratorPtr getIterator() const = 0;
 };
 
+typedef boost::shared_ptr<ZoneTableAccessor> ZoneTableAccessorPtr;
+typedef boost::shared_ptr<const ZoneTableAccessor> ConstZoneTableAccessorPtr;
+
 }
 }
 
diff --git a/src/lib/python/isc/datasrc/Makefile.am b/src/lib/python/isc/datasrc/Makefile.am
index 28c87ac..8a4b3a7 100644
--- a/src/lib/python/isc/datasrc/Makefile.am
+++ b/src/lib/python/isc/datasrc/Makefile.am
@@ -21,6 +21,8 @@ datasrc_la_SOURCES += journal_reader_python.cc journal_reader_python.h
 datasrc_la_SOURCES += configurableclientlist_python.cc
 datasrc_la_SOURCES += configurableclientlist_python.h
 datasrc_la_SOURCES += zone_loader_python.cc zone_loader_python.h
+datasrc_la_SOURCES += zonetable_accessor_python.cc zonetable_accessor_python.h
+datasrc_la_SOURCES += zonetable_iterator_python.cc zonetable_iterator_python.h
 
 datasrc_la_CPPFLAGS = $(AM_CPPFLAGS) $(PYTHON_INCLUDES)
 datasrc_la_CXXFLAGS = $(AM_CXXFLAGS) $(PYTHON_CXXFLAGS)
diff --git a/src/lib/python/isc/datasrc/configurableclientlist_python.cc b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
index 875d7e0..cb1f6f4 100644
--- a/src/lib/python/isc/datasrc/configurableclientlist_python.cc
+++ b/src/lib/python/isc/datasrc/configurableclientlist_python.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  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
@@ -35,6 +35,7 @@
 #include "datasrc.h"
 #include "finder_python.h"
 #include "client_python.h"
+#include "zonetable_accessor_python.h"
 
 using namespace std;
 using namespace isc::util::python;
@@ -206,6 +207,37 @@ ConfigurableClientList_find(PyObject* po_self, PyObject* args) {
     }
 }
 
+PyObject*
+ConfigurableClientList_getZoneTableAccessor(PyObject* po_self, PyObject* args) {
+    s_ConfigurableClientList* self =
+        static_cast<s_ConfigurableClientList*>(po_self);
+    try {
+        const char* datasrc_name;
+        int use_cache;
+        if (PyArg_ParseTuple(args, "zi", &datasrc_name, &use_cache)) {
+            // python 'None' will be read as NULL, which we convert to an
+            // empty string, meaning "any data source"
+            const std::string name(datasrc_name ? datasrc_name : "");
+            const ConstZoneTableAccessorPtr
+                z(self->cppobj->getZoneTableAccessor(name, use_cache));
+            if (z == NULL) {
+                Py_RETURN_NONE;
+            } else {
+                return (createZoneTableAccessorObject(z, po_self));
+            }
+        } else {
+            return (NULL);
+        }
+    } catch (const std::exception& exc) {
+        PyErr_SetString(getDataSourceException("Error"), exc.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(getDataSourceException("Error"),
+                        "Unknown C++ exception");
+        return (NULL);
+    }
+}
+
 // This list contains the actual set of functions we have in
 // python. Each entry has
 // 1. Python method name
@@ -261,6 +293,16 @@ you don't need it, but if you do need it, it is better to set it to True\
 instead of getting it from the datasrc_client later.\n\
 \n\
 If no answer is found, the datasrc_client and zone_finder are None." },
+    { "get_zone_table_accessor", ConfigurableClientList_getZoneTableAccessor,
+      METH_VARARGS,
+"get_zone_table_accessor(datasrc_name, use_cache) -> \
+isc.datasrc.ZoneTableAccessor\n\
+\n\
+Create a ZoneTableAccessor object for the specified data source.\n\
+\n\
+Parameters:\n\
+  datasrc_name      If not empty, the name of the data source\
+  use_cache         If true, create a zone table for in-memory cache." },
     { NULL, NULL, 0, NULL }
 };
 
@@ -286,9 +328,9 @@ namespace python {
 PyTypeObject configurableclientlist_type = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "datasrc.ConfigurableClientList",
-    sizeof(s_ConfigurableClientList),                 // tp_basicsize
+    sizeof(s_ConfigurableClientList),   // tp_basicsize
     0,                                  // tp_itemsize
-    ConfigurableClientList_destroy,                 // tp_dealloc
+    ConfigurableClientList_destroy,     // tp_dealloc
     NULL,                               // tp_print
     NULL,                               // tp_getattr
     NULL,                               // tp_setattr
@@ -311,7 +353,7 @@ PyTypeObject configurableclientlist_type = {
     0,                                  // tp_weaklistoffset
     NULL,                               // tp_iter
     NULL,                               // tp_iternext
-    ConfigurableClientList_methods,                   // tp_methods
+    ConfigurableClientList_methods,     // tp_methods
     NULL,                               // tp_members
     NULL,                               // tp_getset
     NULL,                               // tp_base
@@ -319,7 +361,7 @@ PyTypeObject configurableclientlist_type = {
     NULL,                               // tp_descr_get
     NULL,                               // tp_descr_set
     0,                                  // tp_dictoffset
-    ConfigurableClientList_init,                    // tp_init
+    ConfigurableClientList_init,        // tp_init
     NULL,                               // tp_alloc
     PyType_GenericNew,                  // tp_new
     NULL,                               // tp_free
diff --git a/src/lib/python/isc/datasrc/datasrc.cc b/src/lib/python/isc/datasrc/datasrc.cc
index f2cbae3..117e409 100644
--- a/src/lib/python/isc/datasrc/datasrc.cc
+++ b/src/lib/python/isc/datasrc/datasrc.cc
@@ -33,6 +33,8 @@
 #include "journal_reader_python.h"
 #include "configurableclientlist_python.h"
 #include "zone_loader_python.h"
+#include "zonetable_accessor_python.h"
+#include "zonetable_iterator_python.h"
 
 #include <util/python/pycppwrapper_util.h>
 #include <dns/python/pydnspp_common.h>
@@ -255,6 +257,42 @@ initModulePart_ZoneJournalReader(PyObject* mod) {
     return (true);
 }
 
+bool
+initModulePart_ZoneTableAccessor(PyObject* mod) {
+    // We initialize the static description object with PyType_Ready(),
+    // then add it to the module. This is not just a check! (leaving
+    // this out results in segmentation faults)
+    if (PyType_Ready(&zonetableaccessor_type) < 0) {
+        return (false);
+    }
+    void* p = &zonetableaccessor_type;
+    if (PyModule_AddObject(mod, "ZoneTableAccessor",
+                           static_cast<PyObject*>(p)) < 0) {
+        return (false);
+    }
+    Py_INCREF(&zonetableaccessor_type);
+
+    return (true);
+}
+
+bool
+initModulePart_ZoneTableIterator(PyObject* mod) {
+    // We initialize the static description object with PyType_Ready(),
+    // then add it to the module. This is not just a check! (leaving
+    // this out results in segmentation faults)
+    if (PyType_Ready(&zonetableiterator_type) < 0) {
+        return (false);
+    }
+    void* p = &zonetableiterator_type;
+    if (PyModule_AddObject(mod, "ZoneTableIterator",
+                           static_cast<PyObject*>(p)) < 0) {
+        return (false);
+    }
+    Py_INCREF(&zonetableiterator_type);
+
+    return (true);
+}
+
 PyObject* po_DataSourceError;
 PyObject* po_MasterFileError;
 PyObject* po_NotImplemented;
@@ -340,5 +378,15 @@ PyInit_datasrc(void) {
         return (NULL);
     }
 
+    if (!initModulePart_ZoneTableAccessor(mod)) {
+        Py_DECREF(mod);
+        return (NULL);
+    }
+
+    if (!initModulePart_ZoneTableIterator(mod)) {
+        Py_DECREF(mod);
+        return (NULL);
+    }
+
     return (mod);
 }
diff --git a/src/lib/python/isc/datasrc/finder_python.cc b/src/lib/python/isc/datasrc/finder_python.cc
index ef1bcc1..5a8e84f 100644
--- a/src/lib/python/isc/datasrc/finder_python.cc
+++ b/src/lib/python/isc/datasrc/finder_python.cc
@@ -64,7 +64,7 @@ getFindResultFlags(const ZoneFinder::Context& context) {
 
 namespace isc_datasrc_internal {
 // This is the shared code for the find() call in the finder and the updater
-// Is is intentionally not available through any header, nor at our standard
+// It is intentionally not available through any header, nor at our standard
 // namespace, as it is not supposed to be called anywhere but from finder and
 // updater
 PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args) {
@@ -184,7 +184,7 @@ public:
     ZoneFinderPtr cppobj;
     // This is a reference to a base object; if the object of this class
     // depends on another object to be in scope during its lifetime,
-    // we use INCREF the base object upon creation, and DECREF it at
+    // we INCREF the base object upon creation, and DECREF it at
     // the end of the destructor
     // This is an optional argument to createXXX(). If NULL, it is ignored.
     PyObject* base_obj;
diff --git a/src/lib/python/isc/datasrc/tests/clientlist_test.py b/src/lib/python/isc/datasrc/tests/clientlist_test.py
index bdac69c..2609b6b 100644
--- a/src/lib/python/isc/datasrc/tests/clientlist_test.py
+++ b/src/lib/python/isc/datasrc/tests/clientlist_test.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2012  Internet Systems Consortium.
+# Copyright (C) 2012-2013  Internet Systems Consortium.
 #
 # Permission to use, copy, modify, and distribute this software for any
 # purpose with or without fee is hereby granted, provided that the above
@@ -57,7 +57,7 @@ class ClientListTest(unittest.TestCase):
     def test_configure(self):
         """
         Test we can configure the client list. This tests if the valid
-        ones are acceptend and invalid rejected. We check the changes
+        ones are accepted and invalid rejected. We check the changes
         have effect.
         """
         self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
@@ -151,6 +151,86 @@ class ClientListTest(unittest.TestCase):
         self.assertRaises(TypeError, self.clist.find, "example.org")
         self.assertRaises(TypeError, self.clist.find)
 
+    def test_get_zone_table_accessor(self):
+        """
+        Test that we can get the zone table accessor and, thereby,
+        the zone table iterator.
+        """
+        self.clist = isc.datasrc.ConfigurableClientList(isc.dns.RRClass.IN)
+
+        # null configuration
+        self.clist.configure("[]", True)
+        self.assertIsNone(self.clist.get_zone_table_accessor(None, True))
+
+        # empty configuration
+        self.clist.configure('''[{
+            "type": "MasterFiles",
+            "params": {},
+            "cache-enable": true
+        }]''', True)
+        # bogus datasrc
+        self.assertIsNone(self.clist.get_zone_table_accessor("bogus", True))
+        # first datasrc - empty zone table
+        table = self.clist.get_zone_table_accessor(None, True)
+        self.assertIsNotNone(table)
+        iterator = iter(table)
+        self.assertIsNotNone(iterator)
+        self.assertEqual(0, len(list(iterator)))
+
+        # normal configuration
+        self.clist.configure('''[{
+            "type": "MasterFiles",
+            "params": {
+                "example.org": "''' + TESTDATA_PATH + '''example.org.zone"
+            },
+            "cache-enable": true
+        }]''', True)
+        # !use_cache => NotImplemented
+        self.assertRaises(isc.datasrc.Error,
+                          self.clist.get_zone_table_accessor, None, False)
+        # bogus datasrc
+        self.assertIsNone(self.clist.get_zone_table_accessor("bogus", True))
+
+        # first datasrc
+        table = self.clist.get_zone_table_accessor(None, True)
+        self.assertIsNotNone(table)
+        zonelist = list(table)
+        self.assertEqual(1, len(zonelist))
+        self.assertEqual(zonelist[0][1], isc.dns.Name("example.org"))
+
+        # named datasrc
+        table = self.clist.get_zone_table_accessor("MasterFiles", True)
+        self.assertEqual(zonelist, list(table))
+
+        # longer zone list for non-trivial iteration
+        self.clist.configure('''[{
+            "type": "MasterFiles",
+            "params": {
+                "example.org": "''' + TESTDATA_PATH + '''example.org.zone",
+                "example.com": "''' + TESTDATA_PATH + '''example.com.zone",
+                "example.net": "''' + TESTDATA_PATH + '''example.net.zone",
+                "example.biz": "''' + TESTDATA_PATH + '''example.biz.zone",
+                "example.edu": "''' + TESTDATA_PATH + '''example.edu.zone"
+            },
+            "cache-enable": true
+        }]''', True)
+        zonelist = list(self.clist.get_zone_table_accessor(None, True))
+        self.assertEqual(5, len(zonelist))
+        self.assertTrue((0, isc.dns.Name("example.net.")) in zonelist)
+
+        # ensure the iterator returns exactly and only the zones we expect
+        zonelist = [
+            isc.dns.Name("example.org"),
+            isc.dns.Name("example.com"),
+            isc.dns.Name("example.net"),
+            isc.dns.Name("example.biz"),
+            isc.dns.Name("example.edu")]
+        table = self.clist.get_zone_table_accessor("MasterFiles", True)
+        for index, zone in table:
+            self.assertTrue(zone in zonelist)
+            zonelist.remove(zone)
+        self.assertEqual(0, len(zonelist))
+
 if __name__ == "__main__":
     isc.log.init("bind10")
     isc.log.resetUnitTestRootLogger()
diff --git a/src/lib/python/isc/datasrc/zonetable_accessor_python.cc b/src/lib/python/isc/datasrc/zonetable_accessor_python.cc
new file mode 100644
index 0000000..353f7b5
--- /dev/null
+++ b/src/lib/python/isc/datasrc/zonetable_accessor_python.cc
@@ -0,0 +1,178 @@
+// Copyright (C) 2013  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.
+
+// Enable this if you use s# variants with PyArg_ParseTuple(), see
+// http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
+//#define PY_SSIZE_T_CLEAN
+
+// Python.h needs to be placed at the head of the program file, see:
+// http://docs.python.org/py3k/extending/extending.html#a-simple-example
+#include <Python.h>
+
+#include <datasrc/zone_table_accessor.h>
+
+#include "datasrc.h"
+#include "zonetable_accessor_python.h"
+#include "zonetable_iterator_python.h"
+
+using namespace std;
+using namespace isc::datasrc;
+using namespace isc::datasrc::python;
+
+namespace {
+// The s_* Class simply covers one instantiation of the object
+class s_ZoneTableAccessor : public PyObject {
+public:
+    s_ZoneTableAccessor() : cppobj(ConstZoneTableAccessorPtr()) {};
+    ConstZoneTableAccessorPtr cppobj;
+    // This is a reference to a base object; if the object of this class
+    // depends on another object to be in scope during its lifetime,
+    // we use INCREF the base object upon creation, and DECREF it at
+    // the end of the destructor
+    // This is an optional argument to createXXX(). If NULL, it is ignored.
+    PyObject* base_obj;
+};
+
+int
+ZoneTableAccessor_init(PyObject*, PyObject*, PyObject*) {
+    // can't be called directly
+    PyErr_SetString(PyExc_TypeError,
+                    "ZoneTableAccessor cannot be constructed directly");
+
+    return (-1);
+}
+
+void
+ZoneTableAccessor_destroy(PyObject* po_self) {
+    s_ZoneTableAccessor* const self =
+        static_cast<s_ZoneTableAccessor*>(po_self);
+    // cppobj is a shared ptr, but to make sure things are not destroyed in
+    // the wrong order, we reset it here.
+    self->cppobj.reset();
+    if (self->base_obj != NULL) {
+        Py_DECREF(self->base_obj);
+    }
+    Py_TYPE(self)->tp_free(self);
+}
+
+PyObject*
+ZoneTableAccessor_iter(PyObject* po_self) {
+    s_ZoneTableAccessor* const self =
+        static_cast<s_ZoneTableAccessor*>(po_self);
+    try {
+        return (createZoneTableIteratorObject(self->cppobj->getIterator(),
+                                              po_self));
+    } catch (const std::exception& exc) {
+        PyErr_SetString(getDataSourceException("Error"), exc.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(getDataSourceException("Error"),
+                        "Unexpected exception");
+        return (NULL);
+    }
+}
+
+// This list contains the actual set of functions we have in
+// python. Each entry has
+// 1. Python method name
+// 2. Our static function here
+// 3. Argument type
+// 4. Documentation
+PyMethodDef ZoneTableAccessor_methods[] = {
+    { NULL, NULL, 0, NULL }
+};
+
+const char* const ZoneTableAccessor_doc = "\
+An accessor to a zone table for a data source.\n\
+\n\
+This class object is intended to be used by applications that load zones\
+into memory, so that the application can get a list of zones to be loaded.";
+
+} // end anonymous namespace
+
+namespace isc {
+namespace datasrc {
+namespace python {
+// This defines the complete type for reflection in python and
+// parsing of PyObject* to s_ZoneTableAccessor
+// Most of the functions are not actually implemented and NULL here.
+PyTypeObject zonetableaccessor_type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "datasrc.ZoneTableAccessor",
+    sizeof(s_ZoneTableAccessor),        // tp_basicsize
+    0,                                  // tp_itemsize
+    ZoneTableAccessor_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
+    ZoneTableAccessor_doc,              // tp_doc
+    NULL,                               // tp_traverse
+    NULL,                               // tp_clear
+    NULL,                               // tp_richcompare
+    0,                                  // tp_weaklistoffset
+    ZoneTableAccessor_iter,             // tp_iter
+    NULL,                               // tp_iternext
+    ZoneTableAccessor_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
+    ZoneTableAccessor_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
+    NULL,                               // tp_del
+    0                                   // tp_version_tag
+};
+
+PyObject*
+createZoneTableAccessorObject(isc::datasrc::ConstZoneTableAccessorPtr source,
+                              PyObject* base_obj)
+{
+    s_ZoneTableAccessor* py_zt = static_cast<s_ZoneTableAccessor*>(
+        zonetableaccessor_type.tp_alloc(&zonetableaccessor_type, 0));
+    if (py_zt != NULL) {
+        py_zt->cppobj = source;
+        py_zt->base_obj = base_obj;
+        if (base_obj != NULL) {
+            Py_INCREF(base_obj);
+        }
+    }
+    return (py_zt);
+}
+
+} // namespace python
+} // namespace datasrc
+} // namespace isc
diff --git a/src/lib/python/isc/datasrc/zonetable_accessor_python.h b/src/lib/python/isc/datasrc/zonetable_accessor_python.h
new file mode 100644
index 0000000..6ebcd92
--- /dev/null
+++ b/src/lib/python/isc/datasrc/zonetable_accessor_python.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2013  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_ZONETABLE_ACCESSOR_H
+#define PYTHON_ZONETABLE_ACCESSOR_H 1
+
+#include <Python.h>
+
+namespace isc {
+namespace datasrc {
+namespace python {
+
+extern PyTypeObject zonetableaccessor_type;
+
+/// \brief Create a ZoneTableAccessor python object
+///
+/// \param source The zone iterator pointer to wrap
+/// \param base_obj An optional PyObject that this ZoneFinder depends on
+///                 Its refcount is increased, and will be decreased when
+///                 this zone iterator is destroyed, making sure that the
+///                 base object is never destroyed before this zonefinder.
+PyObject* createZoneTableAccessorObject(
+    isc::datasrc::ConstZoneTableAccessorPtr source, PyObject* base_obj);
+
+} // namespace python
+} // namespace datasrc
+} // namespace isc
+#endif // PYTHON_ZONETABLE_ACCESSOR_H
+
+// Local Variables:
+// mode: c++
+// End:
diff --git a/src/lib/python/isc/datasrc/zonetable_iterator_python.cc b/src/lib/python/isc/datasrc/zonetable_iterator_python.cc
new file mode 100644
index 0000000..9ac7cd9
--- /dev/null
+++ b/src/lib/python/isc/datasrc/zonetable_iterator_python.cc
@@ -0,0 +1,197 @@
+// Copyright (C) 2013  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.
+
+// Enable this if you use s# variants with PyArg_ParseTuple(), see
+// http://docs.python.org/py3k/c-api/arg.html#strings-and-buffers
+//#define PY_SSIZE_T_CLEAN
+
+// Python.h needs to be placed at the head of the program file, see:
+// http://docs.python.org/py3k/extending/extending.html#a-simple-example
+#include <Python.h>
+
+#include <datasrc/zone_table_accessor.h>
+#include <dns/python/name_python.h>
+
+#include "datasrc.h"
+#include "zonetable_iterator_python.h"
+
+using namespace std;
+using namespace isc::datasrc;
+using namespace isc::datasrc::python;
+
+namespace {
+// The s_* Class simply covers one instantiation of the object
+class s_ZoneTableIterator : public PyObject {
+public:
+    s_ZoneTableIterator() :
+        cppobj(ZoneTableAccessor::IteratorPtr()), base_obj(NULL)
+    {};
+
+    ZoneTableAccessor::IteratorPtr cppobj;
+    // This is a reference to a base object; if the object of this class
+    // depends on another object to be in scope during its lifetime,
+    // we use INCREF the base object upon creation, and DECREF it at
+    // the end of the destructor
+    // This is an optional argument to createXXX(). If NULL, it is ignored.
+    PyObject* base_obj;
+};
+
+// General creation and destruction
+int
+ZoneTableIterator_init(s_ZoneTableIterator* self, PyObject* args) {
+    // can't be called directly
+    PyErr_SetString(PyExc_TypeError,
+                    "ZoneTableIterator cannot be constructed directly");
+
+    return (-1);
+}
+
+void
+ZoneTableIterator_destroy(s_ZoneTableIterator* const self) {
+    // cppobj is a shared ptr, but to make sure things are not destroyed in
+    // the wrong order, we reset it here.
+    self->cppobj.reset();
+    if (self->base_obj != NULL) {
+        Py_DECREF(self->base_obj);
+    }
+    Py_TYPE(self)->tp_free(self);
+}
+
+//
+// We declare the functions here, the definitions are below
+// the type definition of the object, since both can use the other
+//
+PyObject*
+ZoneTableIterator_iter(PyObject *self) {
+    Py_INCREF(self);
+    return (self);
+}
+
+PyObject*
+ZoneTableIterator_next(PyObject* po_self) {
+    s_ZoneTableIterator* self = static_cast<s_ZoneTableIterator*>(po_self);
+    if (!self->cppobj || self->cppobj->isLast()) {
+        return (NULL);
+    }
+    try {
+        const isc::datasrc::ZoneSpec& zs = self->cppobj->getCurrent();
+        PyObject* result =
+            Py_BuildValue("iO", zs.index,
+                          isc::dns::python::createNameObject(zs.origin));
+        self->cppobj->next();
+        return (result);
+    } catch (const std::exception& exc) {
+        // isc::InvalidOperation is thrown when we call getCurrent()
+        // when we are already done iterating ('iterating past end')
+        // We could also simply return None again
+        PyErr_SetString(getDataSourceException("Error"), exc.what());
+        return (NULL);
+    } catch (...) {
+        PyErr_SetString(getDataSourceException("Error"),
+                        "Unexpected exception");
+        return (NULL);
+    }
+}
+
+PyMethodDef ZoneTableIterator_methods[] = {
+    { NULL, NULL, 0, NULL }
+};
+
+const char* const ZoneTableIterator_doc = "\
+Read-only iterator to a zone table.\n\
+\n\
+You can get an instance of the ZoneTableIterator from the\
+ZoneTableAccessor.get_iterator() method.\n\
+\n\
+There's no way to start iterating from the beginning again or return.\n\
+\n\
+The ZoneTableIterator is a Python iterator, and can be iterated over\
+directly.\n\
+";
+
+} // end of unnamed namespace
+
+namespace isc {
+namespace datasrc {
+namespace python {
+PyTypeObject zonetableiterator_type = {
+    PyVarObject_HEAD_INIT(NULL, 0)
+    "datasrc.ZoneTableIterator",
+    sizeof(s_ZoneTableIterator),        // tp_basicsize
+    0,                                  // tp_itemsize
+    reinterpret_cast<destructor>(ZoneTableIterator_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
+    ZoneTableIterator_doc,              // tp_doc
+    NULL,                               // tp_traverse
+    NULL,                               // tp_clear
+    NULL,                               // tp_richcompare
+    0,                                  // tp_weaklistoffset
+    ZoneTableIterator_iter,             // tp_iter
+    ZoneTableIterator_next,             // tp_iternext
+    ZoneTableIterator_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
+    reinterpret_cast<initproc>(ZoneTableIterator_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
+    NULL,                               // tp_del
+    0                                   // tp_version_tag
+};
+
+PyObject*
+createZoneTableIteratorObject(ZoneTableAccessor::IteratorPtr source,
+                              PyObject* base_obj)
+{
+    s_ZoneTableIterator* py_zi = static_cast<s_ZoneTableIterator*>(
+        zonetableiterator_type.tp_alloc(&zonetableiterator_type, 0));
+    if (py_zi != NULL) {
+        py_zi->cppobj = source;
+        py_zi->base_obj = base_obj;
+        if (base_obj != NULL) {
+            Py_INCREF(base_obj);
+        }
+    }
+    return (py_zi);
+}
+
+} // namespace python
+} // namespace datasrc
+} // namespace isc
+
diff --git a/src/lib/python/isc/datasrc/zonetable_iterator_python.h b/src/lib/python/isc/datasrc/zonetable_iterator_python.h
new file mode 100644
index 0000000..887861e
--- /dev/null
+++ b/src/lib/python/isc/datasrc/zonetable_iterator_python.h
@@ -0,0 +1,44 @@
+// Copyright (C) 2013  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_ZONETABLE_ITERATOR_H
+#define PYTHON_ZONETABLE_ITERATOR_H 1
+
+#include <Python.h>
+
+namespace isc {
+namespace datasrc {
+namespace python {
+
+extern PyTypeObject zonetableiterator_type;
+
+/// \brief Create a ZoneTableIterator python object
+///
+/// \param source The zone table iterator pointer to wrap
+/// \param base_obj An optional PyObject that this ZoneIterator depends on
+///                 Its refcount is increased, and will be decreased when
+///                 this zone iterator is destroyed, making sure that the
+///                 base object is never destroyed before this zone iterator.
+PyObject* createZoneTableIteratorObject(
+    isc::datasrc::ZoneTableAccessor::IteratorPtr source,
+    PyObject* base_obj = NULL);
+
+} // namespace python
+} // namespace datasrc
+} // namespace isc
+#endif // PYTHON_ZONETABLE_ITERATOR_H
+
+// Local Variables:
+// mode: c++
+// End:



More information about the bind10-changes mailing list