txt_16.c revision 1.1
1/* 2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17/* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */ 18 19#ifndef RDATA_GENERIC_TXT_16_C 20#define RDATA_GENERIC_TXT_16_C 21 22#define RRTYPE_TXT_ATTRIBUTES (0) 23 24static inline isc_result_t 25generic_fromtext_txt(ARGS_FROMTEXT) { 26 isc_token_t token; 27 int strings; 28 29 UNUSED(type); 30 UNUSED(rdclass); 31 UNUSED(origin); 32 UNUSED(options); 33 UNUSED(callbacks); 34 35 strings = 0; 36 if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) { 37 isc_textregion_t r; 38 DE_CONST("#", r.base); 39 r.length = 1; 40 RETERR(txt_fromtext(&r, target)); 41 strings++; 42 } 43 for (;;) { 44 RETERR(isc_lex_getmastertoken(lexer, &token, 45 isc_tokentype_qstring, 46 ISC_TRUE)); 47 if (token.type != isc_tokentype_qstring && 48 token.type != isc_tokentype_string) 49 break; 50 RETTOK(txt_fromtext(&token.value.as_textregion, target)); 51 strings++; 52 } 53 /* Let upper layer handle eol/eof. */ 54 isc_lex_ungettoken(lexer, &token); 55 return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS); 56} 57 58static inline isc_result_t 59generic_totext_txt(ARGS_TOTEXT) { 60 isc_region_t region; 61 62 UNUSED(tctx); 63 64 dns_rdata_toregion(rdata, ®ion); 65 66 while (region.length > 0) { 67 RETERR(txt_totext(®ion, ISC_TRUE, target)); 68 if (region.length > 0) 69 RETERR(str_totext(" ", target)); 70 } 71 72 return (ISC_R_SUCCESS); 73} 74 75static inline isc_result_t 76generic_fromwire_txt(ARGS_FROMWIRE) { 77 isc_result_t result; 78 79 UNUSED(type); 80 UNUSED(dctx); 81 UNUSED(rdclass); 82 UNUSED(options); 83 84 do { 85 result = txt_fromwire(source, target); 86 if (result != ISC_R_SUCCESS) 87 return (result); 88 } while (!buffer_empty(source)); 89 return (ISC_R_SUCCESS); 90} 91 92static inline isc_result_t 93fromtext_txt(ARGS_FROMTEXT) { 94 95 REQUIRE(type == dns_rdatatype_txt); 96 97 return (generic_fromtext_txt(rdclass, type, lexer, origin, options, 98 target, callbacks)); 99} 100 101static inline isc_result_t 102totext_txt(ARGS_TOTEXT) { 103 104 REQUIRE(rdata->type == dns_rdatatype_txt); 105 106 return (generic_totext_txt(rdata, tctx, target)); 107} 108 109static inline isc_result_t 110fromwire_txt(ARGS_FROMWIRE) { 111 112 REQUIRE(type == dns_rdatatype_txt); 113 114 return (generic_fromwire_txt(rdclass, type, source, dctx, options, 115 target)); 116} 117 118static inline isc_result_t 119towire_txt(ARGS_TOWIRE) { 120 121 REQUIRE(rdata->type == dns_rdatatype_txt); 122 123 UNUSED(cctx); 124 125 return (mem_tobuffer(target, rdata->data, rdata->length)); 126} 127 128static inline int 129compare_txt(ARGS_COMPARE) { 130 isc_region_t r1; 131 isc_region_t r2; 132 133 REQUIRE(rdata1->type == rdata2->type); 134 REQUIRE(rdata1->rdclass == rdata2->rdclass); 135 REQUIRE(rdata1->type == dns_rdatatype_txt); 136 137 dns_rdata_toregion(rdata1, &r1); 138 dns_rdata_toregion(rdata2, &r2); 139 return (isc_region_compare(&r1, &r2)); 140} 141 142static inline isc_result_t 143generic_fromstruct_txt(ARGS_FROMSTRUCT) { 144 dns_rdata_txt_t *txt = source; 145 isc_region_t region; 146 uint8_t length; 147 148 REQUIRE(source != NULL); 149 REQUIRE(txt->common.rdtype == type); 150 REQUIRE(txt->common.rdclass == rdclass); 151 REQUIRE(txt->txt != NULL && txt->txt_len != 0); 152 153 UNUSED(type); 154 UNUSED(rdclass); 155 156 region.base = txt->txt; 157 region.length = txt->txt_len; 158 while (region.length > 0) { 159 length = uint8_fromregion(®ion); 160 isc_region_consume(®ion, 1); 161 if (region.length < length) 162 return (ISC_R_UNEXPECTEDEND); 163 isc_region_consume(®ion, length); 164 } 165 166 return (mem_tobuffer(target, txt->txt, txt->txt_len)); 167} 168 169static inline isc_result_t 170generic_tostruct_txt(ARGS_TOSTRUCT) { 171 dns_rdata_txt_t *txt = target; 172 isc_region_t r; 173 174 REQUIRE(target != NULL); 175 REQUIRE(txt->common.rdclass == rdata->rdclass); 176 REQUIRE(txt->common.rdtype == rdata->type); 177 REQUIRE(!ISC_LINK_LINKED(&txt->common, link)); 178 179 dns_rdata_toregion(rdata, &r); 180 txt->txt_len = r.length; 181 txt->txt = mem_maybedup(r.base, r.length); 182 if (txt->txt == NULL) 183 return (ISC_R_NOMEMORY); 184 185 txt->offset = 0; 186 return (ISC_R_SUCCESS); 187} 188 189static inline void 190generic_freestruct_txt(ARGS_FREESTRUCT) { 191 dns_rdata_txt_t *txt = source; 192 193 REQUIRE(source != NULL); 194 195 if (txt->txt != NULL) 196 free(txt->txt); 197} 198 199static inline isc_result_t 200fromstruct_txt(ARGS_FROMSTRUCT) { 201 202 REQUIRE(type == dns_rdatatype_txt); 203 204 return (generic_fromstruct_txt(rdclass, type, source, target)); 205} 206 207static inline isc_result_t 208tostruct_txt(ARGS_TOSTRUCT) { 209 dns_rdata_txt_t *txt = target; 210 211 REQUIRE(rdata->type == dns_rdatatype_txt); 212 REQUIRE(target != NULL); 213 214 txt->common.rdclass = rdata->rdclass; 215 txt->common.rdtype = rdata->type; 216 ISC_LINK_INIT(&txt->common, link); 217 218 return (generic_tostruct_txt(rdata, target)); 219} 220 221static inline void 222freestruct_txt(ARGS_FREESTRUCT) { 223 dns_rdata_txt_t *txt = source; 224 225 REQUIRE(source != NULL); 226 REQUIRE(txt->common.rdtype == dns_rdatatype_txt); 227 228 generic_freestruct_txt(source); 229} 230 231static inline isc_result_t 232additionaldata_txt(ARGS_ADDLDATA) { 233 REQUIRE(rdata->type == dns_rdatatype_txt); 234 235 UNUSED(rdata); 236 UNUSED(add); 237 UNUSED(arg); 238 239 return (ISC_R_SUCCESS); 240} 241 242static inline isc_result_t 243digest_txt(ARGS_DIGEST) { 244 isc_region_t r; 245 246 REQUIRE(rdata->type == dns_rdatatype_txt); 247 248 dns_rdata_toregion(rdata, &r); 249 250 return ((digest)(arg, &r)); 251} 252 253static inline isc_boolean_t 254checkowner_txt(ARGS_CHECKOWNER) { 255 256 REQUIRE(type == dns_rdatatype_txt); 257 258 UNUSED(name); 259 UNUSED(type); 260 UNUSED(rdclass); 261 UNUSED(wildcard); 262 263 return (ISC_TRUE); 264} 265 266static inline isc_boolean_t 267checknames_txt(ARGS_CHECKNAMES) { 268 269 REQUIRE(rdata->type == dns_rdatatype_txt); 270 271 UNUSED(rdata); 272 UNUSED(owner); 273 UNUSED(bad); 274 275 return (ISC_TRUE); 276} 277 278static inline int 279casecompare_txt(ARGS_COMPARE) { 280 return (compare_txt(rdata1, rdata2)); 281} 282 283static isc_result_t 284generic_txt_first(dns_rdata_txt_t *txt) { 285 286 REQUIRE(txt != NULL); 287 REQUIRE(txt->txt != NULL || txt->txt_len == 0); 288 289 if (txt->txt_len == 0) 290 return (ISC_R_NOMORE); 291 292 txt->offset = 0; 293 return (ISC_R_SUCCESS); 294} 295 296static isc_result_t 297generic_txt_next(dns_rdata_txt_t *txt) { 298 isc_region_t r; 299 uint8_t length; 300 301 REQUIRE(txt != NULL); 302 REQUIRE(txt->txt != NULL && txt->txt_len != 0); 303 304 INSIST(txt->offset + 1 <= txt->txt_len); 305 r.base = txt->txt + txt->offset; 306 r.length = txt->txt_len - txt->offset; 307 length = uint8_fromregion(&r); 308 INSIST(txt->offset + 1 + length <= txt->txt_len); 309 txt->offset = txt->offset + 1 + length; 310 if (txt->offset == txt->txt_len) 311 return (ISC_R_NOMORE); 312 return (ISC_R_SUCCESS); 313} 314 315static isc_result_t 316generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { 317 isc_region_t r; 318 319 REQUIRE(txt != NULL); 320 REQUIRE(string != NULL); 321 REQUIRE(txt->txt != NULL); 322 REQUIRE(txt->offset < txt->txt_len); 323 324 INSIST(txt->offset + 1 <= txt->txt_len); 325 r.base = txt->txt + txt->offset; 326 r.length = txt->txt_len - txt->offset; 327 328 string->length = uint8_fromregion(&r); 329 isc_region_consume(&r, 1); 330 string->data = r.base; 331 INSIST(txt->offset + 1 + string->length <= txt->txt_len); 332 333 return (ISC_R_SUCCESS); 334} 335 336isc_result_t 337dns_rdata_txt_first(dns_rdata_txt_t *txt) { 338 339 REQUIRE(txt != NULL); 340 REQUIRE(txt->common.rdtype == dns_rdatatype_txt); 341 342 return (generic_txt_first(txt)); 343} 344 345isc_result_t 346dns_rdata_txt_next(dns_rdata_txt_t *txt) { 347 348 REQUIRE(txt != NULL); 349 REQUIRE(txt->common.rdtype == dns_rdatatype_txt); 350 351 return (generic_txt_next(txt)); 352} 353 354isc_result_t 355dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { 356 357 REQUIRE(txt != NULL); 358 REQUIRE(txt->common.rdtype == dns_rdatatype_txt); 359 360 return (generic_txt_current(txt, string)); 361} 362#endif /* RDATA_GENERIC_TXT_16_C */ 363