rriterator.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009, 2011, 2012, 2015  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 /*! \file */
00020 
00021 /***
00022  *** Imports
00023  ***/
00024 
00025 #include <config.h>
00026 
00027 #include <isc/string.h>
00028 #include <isc/util.h>
00029 
00030 #include <dns/db.h>
00031 #include <dns/dbiterator.h>
00032 #include <dns/rdata.h>
00033 #include <dns/rdataset.h>
00034 #include <dns/rdatasetiter.h>
00035 #include <dns/result.h>
00036 #include <dns/rriterator.h>
00037 
00038 /***
00039  *** RRiterator methods
00040  ***/
00041 
00042 isc_result_t
00043 dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
00044                     isc_stdtime_t now)
00045 {
00046         isc_result_t result;
00047         it->magic = RRITERATOR_MAGIC;
00048         it->db = db;
00049         it->dbit = NULL;
00050         it->ver = ver;
00051         it->now = now;
00052         it->node = NULL;
00053         result = dns_db_createiterator(it->db, 0, &it->dbit);
00054         if (result != ISC_R_SUCCESS)
00055                 return (result);
00056         it->rdatasetit = NULL;
00057         dns_rdata_init(&it->rdata);
00058         dns_rdataset_init(&it->rdataset);
00059         dns_fixedname_init(&it->fixedname);
00060         INSIST(! dns_rdataset_isassociated(&it->rdataset));
00061         it->result = ISC_R_SUCCESS;
00062         return (it->result);
00063 }
00064 
00065 isc_result_t
00066 dns_rriterator_first(dns_rriterator_t *it) {
00067         REQUIRE(VALID_RRITERATOR(it));
00068         /* Reset state */
00069         if (dns_rdataset_isassociated(&it->rdataset))
00070                 dns_rdataset_disassociate(&it->rdataset);
00071         if (it->rdatasetit != NULL)
00072                 dns_rdatasetiter_destroy(&it->rdatasetit);
00073         if (it->node != NULL)
00074                 dns_db_detachnode(it->db, &it->node);
00075         it->result = dns_dbiterator_first(it->dbit);
00076 
00077         /*
00078          * The top node may be empty when out of zone glue exists.
00079          * Walk the tree to find the first node with data.
00080          */
00081         while (it->result == ISC_R_SUCCESS) {
00082                 it->result = dns_dbiterator_current(it->dbit, &it->node,
00083                                            dns_fixedname_name(&it->fixedname));
00084                 if (it->result != ISC_R_SUCCESS)
00085                         return (it->result);
00086 
00087                 it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
00088                                                  it->now, &it->rdatasetit);
00089                 if (it->result != ISC_R_SUCCESS)
00090                         return (it->result);
00091 
00092                 it->result = dns_rdatasetiter_first(it->rdatasetit);
00093                 if (it->result != ISC_R_SUCCESS) {
00094                         /*
00095                          * This node is empty. Try next node.
00096                          */
00097                         dns_rdatasetiter_destroy(&it->rdatasetit);
00098                         dns_db_detachnode(it->db, &it->node);
00099                         it->result = dns_dbiterator_next(it->dbit);
00100                         continue;
00101                 }
00102                 dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
00103                 dns_rdataset_getownercase(&it->rdataset,
00104                                           dns_fixedname_name(&it->fixedname));
00105                 it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
00106                 it->result = dns_rdataset_first(&it->rdataset);
00107                 return (it->result);
00108         }
00109         return (it->result);
00110 }
00111 
00112 isc_result_t
00113 dns_rriterator_nextrrset(dns_rriterator_t *it) {
00114         REQUIRE(VALID_RRITERATOR(it));
00115         if (dns_rdataset_isassociated(&it->rdataset))
00116                 dns_rdataset_disassociate(&it->rdataset);
00117         it->result = dns_rdatasetiter_next(it->rdatasetit);
00118         /*
00119          * The while loop body is executed more than once
00120          * only when an empty dbnode needs to be skipped.
00121          */
00122         while (it->result == ISC_R_NOMORE) {
00123                 dns_rdatasetiter_destroy(&it->rdatasetit);
00124                 dns_db_detachnode(it->db, &it->node);
00125                 it->result = dns_dbiterator_next(it->dbit);
00126                 if (it->result == ISC_R_NOMORE) {
00127                         /* We are at the end of the entire database. */
00128                         return (it->result);
00129                 }
00130                 if (it->result != ISC_R_SUCCESS)
00131                         return (it->result);
00132                 it->result = dns_dbiterator_current(it->dbit, &it->node,
00133                                            dns_fixedname_name(&it->fixedname));
00134                 if (it->result != ISC_R_SUCCESS)
00135                         return (it->result);
00136                 it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
00137                                                  it->now, &it->rdatasetit);
00138                 if (it->result != ISC_R_SUCCESS)
00139                         return (it->result);
00140                 it->result = dns_rdatasetiter_first(it->rdatasetit);
00141         }
00142         if (it->result != ISC_R_SUCCESS)
00143                 return (it->result);
00144         dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
00145         dns_rdataset_getownercase(&it->rdataset,
00146                                   dns_fixedname_name(&it->fixedname));
00147         it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
00148         it->result = dns_rdataset_first(&it->rdataset);
00149         return (it->result);
00150 }
00151 
00152 isc_result_t
00153 dns_rriterator_next(dns_rriterator_t *it) {
00154         REQUIRE(VALID_RRITERATOR(it));
00155         if (it->result != ISC_R_SUCCESS)
00156                 return (it->result);
00157 
00158         INSIST(it->dbit != NULL);
00159         INSIST(it->node != NULL);
00160         INSIST(it->rdatasetit != NULL);
00161 
00162         it->result = dns_rdataset_next(&it->rdataset);
00163         if (it->result == ISC_R_NOMORE)
00164                 return (dns_rriterator_nextrrset(it));
00165         return (it->result);
00166 }
00167 
00168 void
00169 dns_rriterator_pause(dns_rriterator_t *it) {
00170         REQUIRE(VALID_RRITERATOR(it));
00171         RUNTIME_CHECK(dns_dbiterator_pause(it->dbit) == ISC_R_SUCCESS);
00172 }
00173 
00174 void
00175 dns_rriterator_destroy(dns_rriterator_t *it) {
00176         REQUIRE(VALID_RRITERATOR(it));
00177         if (dns_rdataset_isassociated(&it->rdataset))
00178                 dns_rdataset_disassociate(&it->rdataset);
00179         if (it->rdatasetit != NULL)
00180                 dns_rdatasetiter_destroy(&it->rdatasetit);
00181         if (it->node != NULL)
00182                 dns_db_detachnode(it->db, &it->node);
00183         dns_dbiterator_destroy(&it->dbit);
00184 }
00185 
00186 void
00187 dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
00188                        isc_uint32_t *ttl, dns_rdataset_t **rdataset,
00189                        dns_rdata_t **rdata)
00190 {
00191         REQUIRE(name != NULL && *name == NULL);
00192         REQUIRE(VALID_RRITERATOR(it));
00193         REQUIRE(it->result == ISC_R_SUCCESS);
00194         REQUIRE(rdataset == NULL || *rdataset == NULL);
00195         REQUIRE(rdata == NULL || *rdata == NULL);
00196 
00197         *name = dns_fixedname_name(&it->fixedname);
00198         *ttl = it->rdataset.ttl;
00199 
00200         dns_rdata_reset(&it->rdata);
00201         dns_rdataset_current(&it->rdataset, &it->rdata);
00202 
00203         if (rdataset != NULL)
00204                 *rdataset = &it->rdataset;
00205 
00206         if (rdata != NULL)
00207                 *rdata = &it->rdata;
00208 }

Generated on Tue Apr 28 17:41:01 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha