1/*
2 * Copyright (C) 2004, 2007-2009  Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2002  Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* $Id: txt_16.c,v 1.47 2009/12/04 22:06:37 tbox Exp $ */
19
20/* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */
21
22#ifndef RDATA_GENERIC_TXT_16_C
23#define RDATA_GENERIC_TXT_16_C
24
25#define RRTYPE_TXT_ATTRIBUTES (0)
26
27static inline isc_result_t
28fromtext_txt(ARGS_FROMTEXT) {
29	isc_token_t token;
30	int strings;
31
32	REQUIRE(type == 16);
33
34	UNUSED(type);
35	UNUSED(rdclass);
36	UNUSED(origin);
37	UNUSED(options);
38	UNUSED(callbacks);
39
40	strings = 0;
41	for (;;) {
42		RETERR(isc_lex_getmastertoken(lexer, &token,
43					      isc_tokentype_qstring,
44					      ISC_TRUE));
45		if (token.type != isc_tokentype_qstring &&
46		    token.type != isc_tokentype_string)
47			break;
48		RETTOK(txt_fromtext(&token.value.as_textregion, target));
49		strings++;
50	}
51	/* Let upper layer handle eol/eof. */
52	isc_lex_ungettoken(lexer, &token);
53	return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS);
54}
55
56static inline isc_result_t
57totext_txt(ARGS_TOTEXT) {
58	isc_region_t region;
59
60	UNUSED(tctx);
61
62	REQUIRE(rdata->type == 16);
63
64	dns_rdata_toregion(rdata, &region);
65
66	while (region.length > 0) {
67		RETERR(txt_totext(&region, 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
76fromwire_txt(ARGS_FROMWIRE) {
77	isc_result_t result;
78
79	REQUIRE(type == 16);
80
81	UNUSED(type);
82	UNUSED(dctx);
83	UNUSED(rdclass);
84	UNUSED(options);
85
86	do {
87		result = txt_fromwire(source, target);
88		if (result != ISC_R_SUCCESS)
89			return (result);
90	} while (!buffer_empty(source));
91	return (ISC_R_SUCCESS);
92}
93
94static inline isc_result_t
95towire_txt(ARGS_TOWIRE) {
96	isc_region_t region;
97
98	REQUIRE(rdata->type == 16);
99
100	UNUSED(cctx);
101
102	isc_buffer_availableregion(target, &region);
103	if (region.length < rdata->length)
104		return (ISC_R_NOSPACE);
105
106	memcpy(region.base, rdata->data, rdata->length);
107	isc_buffer_add(target, rdata->length);
108	return (ISC_R_SUCCESS);
109}
110
111static inline int
112compare_txt(ARGS_COMPARE) {
113	isc_region_t r1;
114	isc_region_t r2;
115
116	REQUIRE(rdata1->type == rdata2->type);
117	REQUIRE(rdata1->rdclass == rdata2->rdclass);
118	REQUIRE(rdata1->type == 16);
119
120	dns_rdata_toregion(rdata1, &r1);
121	dns_rdata_toregion(rdata2, &r2);
122	return (isc_region_compare(&r1, &r2));
123}
124
125static inline isc_result_t
126fromstruct_txt(ARGS_FROMSTRUCT) {
127	dns_rdata_txt_t *txt = source;
128	isc_region_t region;
129	isc_uint8_t length;
130
131	REQUIRE(type == 16);
132	REQUIRE(source != NULL);
133	REQUIRE(txt->common.rdtype == type);
134	REQUIRE(txt->common.rdclass == rdclass);
135	REQUIRE(txt->txt != NULL && txt->txt_len != 0);
136
137	UNUSED(type);
138	UNUSED(rdclass);
139
140	region.base = txt->txt;
141	region.length = txt->txt_len;
142	while (region.length > 0) {
143		length = uint8_fromregion(&region);
144		isc_region_consume(&region, 1);
145		if (region.length < length)
146			return (ISC_R_UNEXPECTEDEND);
147		isc_region_consume(&region, length);
148	}
149
150	return (mem_tobuffer(target, txt->txt, txt->txt_len));
151}
152
153static inline isc_result_t
154tostruct_txt(ARGS_TOSTRUCT) {
155	dns_rdata_txt_t *txt = target;
156	isc_region_t r;
157
158	REQUIRE(rdata->type == 16);
159	REQUIRE(target != NULL);
160
161	txt->common.rdclass = rdata->rdclass;
162	txt->common.rdtype = rdata->type;
163	ISC_LINK_INIT(&txt->common, link);
164
165	dns_rdata_toregion(rdata, &r);
166	txt->txt_len = r.length;
167	txt->txt = mem_maybedup(mctx, r.base, r.length);
168	if (txt->txt == NULL)
169		return (ISC_R_NOMEMORY);
170
171	txt->offset = 0;
172	txt->mctx = mctx;
173	return (ISC_R_SUCCESS);
174}
175
176static inline void
177freestruct_txt(ARGS_FREESTRUCT) {
178	dns_rdata_txt_t *txt = source;
179
180	REQUIRE(source != NULL);
181	REQUIRE(txt->common.rdtype == 16);
182
183	if (txt->mctx == NULL)
184		return;
185
186	if (txt->txt != NULL)
187		isc_mem_free(txt->mctx, txt->txt);
188	txt->mctx = NULL;
189}
190
191static inline isc_result_t
192additionaldata_txt(ARGS_ADDLDATA) {
193	REQUIRE(rdata->type == 16);
194
195	UNUSED(rdata);
196	UNUSED(add);
197	UNUSED(arg);
198
199	return (ISC_R_SUCCESS);
200}
201
202static inline isc_result_t
203digest_txt(ARGS_DIGEST) {
204	isc_region_t r;
205
206	REQUIRE(rdata->type == 16);
207
208	dns_rdata_toregion(rdata, &r);
209
210	return ((digest)(arg, &r));
211}
212
213static inline isc_boolean_t
214checkowner_txt(ARGS_CHECKOWNER) {
215
216	REQUIRE(type == 16);
217
218	UNUSED(name);
219	UNUSED(type);
220	UNUSED(rdclass);
221	UNUSED(wildcard);
222
223	return (ISC_TRUE);
224}
225
226static inline isc_boolean_t
227checknames_txt(ARGS_CHECKNAMES) {
228
229	REQUIRE(rdata->type == 16);
230
231	UNUSED(rdata);
232	UNUSED(owner);
233	UNUSED(bad);
234
235	return (ISC_TRUE);
236}
237
238static inline isc_result_t
239casecompare_txt(ARGS_COMPARE) {
240	return (compare_txt(rdata1, rdata2));
241}
242
243#endif	/* RDATA_GENERIC_TXT_16_C */
244