diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h index acca54bf78..f74bee626c 100644 --- a/lib/dns/include/dns/rdataslab.h +++ b/lib/dns/include/dns/rdataslab.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.h,v 1.22 2002/02/20 03:34:38 marka Exp $ */ +/* $Id: rdataslab.h,v 1.23 2002/02/20 22:57:13 bwelling Exp $ */ #ifndef DNS_RDATASLAB_H #define DNS_RDATASLAB_H 1 @@ -83,6 +83,22 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, * */ +void +dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, + dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, + dns_rdatatype_t covers, dns_ttl_t ttl, + dns_rdataset_t *rdataset); +/* + * Construct an rdataset from a slab. + * + * Requires: + * 'slab' points to a slab. + * 'rdataset' is disassociated. + * + * Ensures: + * 'rdataset' is associated and points to a valid rdataest. + */ + unsigned int dns_rdataslab_size(unsigned char *slab, unsigned int reservelen); /* diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index 13f0a86f3e..7ffb722046 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.c,v 1.29 2001/01/09 21:51:25 bwelling Exp $ */ +/* $Id: rdataslab.c,v 1.30 2002/02/20 22:57:12 bwelling Exp $ */ #include @@ -152,6 +152,119 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, return (result); } +static void +rdataset_disassociate(dns_rdataset_t *rdataset) { + UNUSED(rdataset); +} + +static isc_result_t +rdataset_first(dns_rdataset_t *rdataset) { + unsigned char *raw = rdataset->private3; + unsigned int count; + + count = raw[0] * 256 + raw[1]; + if (count == 0) { + rdataset->private5 = NULL; + return (ISC_R_NOMORE); + } + raw += 2; + /* + * The private4 field is the number of rdata beyond the cursor + * position, so we decrement the total count by one before storing + * it. + */ + count--; + rdataset->private4 = (void *)count; + rdataset->private5 = raw; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +rdataset_next(dns_rdataset_t *rdataset) { + unsigned int count; + unsigned int length; + unsigned char *raw; + + count = (unsigned int)rdataset->private4; + if (count == 0) + return (ISC_R_NOMORE); + count--; + rdataset->private4 = (void *)count; + raw = rdataset->private5; + length = raw[0] * 256 + raw[1]; + raw += length + 2; + rdataset->private5 = raw; + + return (ISC_R_SUCCESS); +} + +static void +rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) { + unsigned char *raw = rdataset->private5; + isc_region_t r; + + REQUIRE(raw != NULL); + + r.length = raw[0] * 256 + raw[1]; + raw += 2; + r.base = raw; + dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); +} + +static void +rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) { + *target = *source; + + /* + * Reset iterator state. + */ + target->private4 = NULL; + target->private5 = NULL; +} + +static unsigned int +rdataset_count(dns_rdataset_t *rdataset) { + unsigned char *raw = rdataset->private3; + unsigned int count; + + count = raw[0] * 256 + raw[1]; + + return (count); +} + +static dns_rdatasetmethods_t rdataset_methods = { + rdataset_disassociate, + rdataset_first, + rdataset_next, + rdataset_current, + rdataset_clone, + rdataset_count +}; + +void +dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen, + dns_rdataclass_t rdclass, dns_rdatatype_t rdtype, + dns_rdatatype_t covers, dns_ttl_t ttl, + dns_rdataset_t *rdataset) +{ + rdataset->methods = &rdataset_methods; + rdataset->rdclass = rdclass; + rdataset->type = rdtype; + rdataset->covers = covers; + rdataset->ttl = ttl; + rdataset->trust = 0; + rdataset->private1 = NULL; + rdataset->private2 = NULL; + rdataset->private3 = slab + reservelen; + + /* + * Reset iterator state. + */ + rdataset->private4 = NULL; + rdataset->private5 = NULL; +} + unsigned int dns_rdataslab_size(unsigned char *slab, unsigned int reservelen) { unsigned int count, length;