1 /* $NetBSD: rriterator.c,v 1.4 2014/12/10 04:37:58 christos Exp $ */
4 * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
29 #include <isc/string.h>
33 #include <dns/dbiterator.h>
34 #include <dns/rdata.h>
35 #include <dns/rdataset.h>
36 #include <dns/rdatasetiter.h>
37 #include <dns/result.h>
38 #include <dns/rriterator.h>
41 *** RRiterator methods
45 dns_rriterator_init(dns_rriterator_t
*it
, dns_db_t
*db
, dns_dbversion_t
*ver
,
49 it
->magic
= RRITERATOR_MAGIC
;
55 result
= dns_db_createiterator(it
->db
, 0, &it
->dbit
);
56 if (result
!= ISC_R_SUCCESS
)
58 it
->rdatasetit
= NULL
;
59 dns_rdata_init(&it
->rdata
);
60 dns_rdataset_init(&it
->rdataset
);
61 dns_fixedname_init(&it
->fixedname
);
62 INSIST(! dns_rdataset_isassociated(&it
->rdataset
));
63 it
->result
= ISC_R_SUCCESS
;
68 dns_rriterator_first(dns_rriterator_t
*it
) {
69 REQUIRE(VALID_RRITERATOR(it
));
71 if (dns_rdataset_isassociated(&it
->rdataset
))
72 dns_rdataset_disassociate(&it
->rdataset
);
73 if (it
->rdatasetit
!= NULL
)
74 dns_rdatasetiter_destroy(&it
->rdatasetit
);
76 dns_db_detachnode(it
->db
, &it
->node
);
77 it
->result
= dns_dbiterator_first(it
->dbit
);
80 * The top node may be empty when out of zone glue exists.
81 * Walk the tree to find the first node with data.
83 while (it
->result
== ISC_R_SUCCESS
) {
84 it
->result
= dns_dbiterator_current(it
->dbit
, &it
->node
,
85 dns_fixedname_name(&it
->fixedname
));
86 if (it
->result
!= ISC_R_SUCCESS
)
89 it
->result
= dns_db_allrdatasets(it
->db
, it
->node
, it
->ver
,
90 it
->now
, &it
->rdatasetit
);
91 if (it
->result
!= ISC_R_SUCCESS
)
94 it
->result
= dns_rdatasetiter_first(it
->rdatasetit
);
95 if (it
->result
!= ISC_R_SUCCESS
) {
97 * This node is empty. Try next node.
99 dns_rdatasetiter_destroy(&it
->rdatasetit
);
100 dns_db_detachnode(it
->db
, &it
->node
);
101 it
->result
= dns_dbiterator_next(it
->dbit
);
104 dns_rdatasetiter_current(it
->rdatasetit
, &it
->rdataset
);
105 it
->rdataset
.attributes
|= DNS_RDATASETATTR_LOADORDER
;
106 it
->result
= dns_rdataset_first(&it
->rdataset
);
113 dns_rriterator_nextrrset(dns_rriterator_t
*it
) {
114 REQUIRE(VALID_RRITERATOR(it
));
115 if (dns_rdataset_isassociated(&it
->rdataset
))
116 dns_rdataset_disassociate(&it
->rdataset
);
117 it
->result
= dns_rdatasetiter_next(it
->rdatasetit
);
119 * The while loop body is executed more than once
120 * only when an empty dbnode needs to be skipped.
122 while (it
->result
== ISC_R_NOMORE
) {
123 dns_rdatasetiter_destroy(&it
->rdatasetit
);
124 dns_db_detachnode(it
->db
, &it
->node
);
125 it
->result
= dns_dbiterator_next(it
->dbit
);
126 if (it
->result
== ISC_R_NOMORE
) {
127 /* We are at the end of the entire database. */
130 if (it
->result
!= ISC_R_SUCCESS
)
132 it
->result
= dns_dbiterator_current(it
->dbit
, &it
->node
,
133 dns_fixedname_name(&it
->fixedname
));
134 if (it
->result
!= ISC_R_SUCCESS
)
136 it
->result
= dns_db_allrdatasets(it
->db
, it
->node
, it
->ver
,
137 it
->now
, &it
->rdatasetit
);
138 if (it
->result
!= ISC_R_SUCCESS
)
140 it
->result
= dns_rdatasetiter_first(it
->rdatasetit
);
142 if (it
->result
!= ISC_R_SUCCESS
)
144 dns_rdatasetiter_current(it
->rdatasetit
, &it
->rdataset
);
145 it
->rdataset
.attributes
|= DNS_RDATASETATTR_LOADORDER
;
146 it
->result
= dns_rdataset_first(&it
->rdataset
);
151 dns_rriterator_next(dns_rriterator_t
*it
) {
152 REQUIRE(VALID_RRITERATOR(it
));
153 if (it
->result
!= ISC_R_SUCCESS
)
156 INSIST(it
->dbit
!= NULL
);
157 INSIST(it
->node
!= NULL
);
158 INSIST(it
->rdatasetit
!= NULL
);
160 it
->result
= dns_rdataset_next(&it
->rdataset
);
161 if (it
->result
== ISC_R_NOMORE
)
162 return (dns_rriterator_nextrrset(it
));
167 dns_rriterator_pause(dns_rriterator_t
*it
) {
168 REQUIRE(VALID_RRITERATOR(it
));
169 RUNTIME_CHECK(dns_dbiterator_pause(it
->dbit
) == ISC_R_SUCCESS
);
173 dns_rriterator_destroy(dns_rriterator_t
*it
) {
174 REQUIRE(VALID_RRITERATOR(it
));
175 if (dns_rdataset_isassociated(&it
->rdataset
))
176 dns_rdataset_disassociate(&it
->rdataset
);
177 if (it
->rdatasetit
!= NULL
)
178 dns_rdatasetiter_destroy(&it
->rdatasetit
);
179 if (it
->node
!= NULL
)
180 dns_db_detachnode(it
->db
, &it
->node
);
181 dns_dbiterator_destroy(&it
->dbit
);
185 dns_rriterator_current(dns_rriterator_t
*it
, dns_name_t
**name
,
186 isc_uint32_t
*ttl
, dns_rdataset_t
**rdataset
,
189 REQUIRE(name
!= NULL
&& *name
== NULL
);
190 REQUIRE(VALID_RRITERATOR(it
));
191 REQUIRE(it
->result
== ISC_R_SUCCESS
);
192 REQUIRE(rdataset
== NULL
|| *rdataset
== NULL
);
193 REQUIRE(rdata
== NULL
|| *rdata
== NULL
);
195 *name
= dns_fixedname_name(&it
->fixedname
);
196 *ttl
= it
->rdataset
.ttl
;
198 dns_rdata_reset(&it
->rdata
);
199 dns_rdataset_current(&it
->rdataset
, &it
->rdata
);
201 if (rdataset
!= NULL
)
202 *rdataset
= &it
->rdataset
;