1 /*	$NetBSD: util.h,v 1.6 2014/12/10 04:38:01 christos Exp $	*/
2 
3 /*
4  * Portions Copyright (C) 2004-2007, 2014  Internet Systems Consortium, Inc. ("ISC")
5  * Portions Copyright (C) 2001  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL
12  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
13  * OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
14  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  *
19  * Portions Copyright (C) 2001  Nominum, Inc.
20  *
21  * Permission to use, copy, modify, and/or distribute this software for any
22  * purpose with or without fee is hereby granted, provided that the above
23  * copyright notice and this permission notice appear in all copies.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NOMINUM DISCLAIMS ALL
26  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
27  * OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY
28  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
29  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
30  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
31  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32  */
33 
34 /* Id: util.h,v 1.11 2007/08/28 07:20:43 tbox Exp  */
35 
36 #ifndef ISCCC_UTIL_H
37 #define ISCCC_UTIL_H 1
38 
39 #include <isc/util.h>
40 
41 /*! \file isccc/util.h
42  * \brief
43  * Macros for dealing with unaligned numbers.
44  *
45  * \note no side effects are allowed when invoking these macros!
46  */
47 
48 #define GET8(v, w) \
49 	do { \
50 		v = *w; \
51 		w++; \
52 	} while (/*CONSTCOND*/0)
53 
54 #define GET16(v, w) \
55 	do { \
56 		v = (unsigned int)w[0] << 8; \
57 		v |= (unsigned int)w[1]; \
58 		w += 2; \
59 	} while (/*CONSTCOND*/0)
60 
61 #define GET24(v, w) \
62 	do { \
63 		v = (unsigned int)w[0] << 16; \
64 		v |= (unsigned int)w[1] << 8; \
65 		v |= (unsigned int)w[2]; \
66 		w += 3; \
67 	} while (/*CONSTCOND*/0)
68 
69 #define GET32(v, w) \
70 	do { \
71 		v = (unsigned int)w[0] << 24; \
72 		v |= (unsigned int)w[1] << 16; \
73 		v |= (unsigned int)w[2] << 8; \
74 		v |= (unsigned int)w[3]; \
75 		w += 4; \
76 	} while (/*CONSTCOND*/0)
77 
78 #define GET64(v, w) \
79 	do { \
80 		v = (isc_uint64_t)w[0] << 56; \
81 		v |= (isc_uint64_t)w[1] << 48; \
82 		v |= (isc_uint64_t)w[2] << 40; \
83 		v |= (isc_uint64_t)w[3] << 32; \
84 		v |= (isc_uint64_t)w[4] << 24; \
85 		v |= (isc_uint64_t)w[5] << 16; \
86 		v |= (isc_uint64_t)w[6] << 8; \
87 		v |= (isc_uint64_t)w[7]; \
88 		w += 8; \
89 	} while (/*CONSTCOND*/0)
90 
91 #define GETC16(v, w, d) \
92 	do { \
93 		GET8(v, w); \
94 		if (v == 0) \
95 			d = ISCCC_TRUE; \
96 		else { \
97 			d = ISCCC_FALSE; \
98 			if (v == 255) \
99 				GET16(v, w); \
100 		} \
101 	} while (/*CONSTCOND*/0)
102 
103 #define GETC32(v, w) \
104 	do { \
105 		GET24(v, w); \
106 		if (v == 0xffffffu) \
107 			GET32(v, w); \
108 	} while (/*CONSTCOND*/0)
109 
110 #define GET_OFFSET(v, w)		GET32(v, w)
111 
112 #define GET_MEM(v, c, w) \
113 	do { \
114 		memmove(v, w, c); \
115 		w += c; \
116 	} while (/*CONSTCOND*/0)
117 
118 #define GET_TYPE(v, w) \
119 	do { \
120 		GET8(v, w); \
121 		if (v > 127) { \
122 			if (v < 255) \
123 				v = ((v & 0x7f) << 16) | ISCCC_RDATATYPE_SIG; \
124 			else \
125 				GET32(v, w); \
126 		} \
127 	} while (/*CONSTCOND*/0)
128 
129 #define PUT8(v, w) \
130 	do { \
131 		*w = (v & 0x000000ffU); \
132 		w++; \
133 	} while (/*CONSTCOND*/0)
134 
135 #define PUT16(v, w) \
136 	do { \
137 		w[0] = (v & 0x0000ff00U) >> 8; \
138 		w[1] = (v & 0x000000ffU); \
139 		w += 2; \
140 	} while (/*CONSTCOND*/0)
141 
142 #define PUT24(v, w) \
143 	do { \
144 		w[0] = (v & 0x00ff0000U) >> 16; \
145 		w[1] = (v & 0x0000ff00U) >> 8; \
146 		w[2] = (v & 0x000000ffU); \
147 		w += 3; \
148 	} while (/*CONSTCOND*/0)
149 
150 #define PUT32(v, w) \
151 	do { \
152 		w[0] = (v & 0xff000000U) >> 24; \
153 		w[1] = (v & 0x00ff0000U) >> 16; \
154 		w[2] = (v & 0x0000ff00U) >> 8; \
155 		w[3] = (v & 0x000000ffU); \
156 		w += 4; \
157 	} while (/*CONSTCOND*/0)
158 
159 #define PUT64(v, w) \
160 	do { \
161 		w[0] = (v & 0xff00000000000000ULL) >> 56; \
162 		w[1] = (v & 0x00ff000000000000ULL) >> 48; \
163 		w[2] = (v & 0x0000ff0000000000ULL) >> 40; \
164 		w[3] = (v & 0x000000ff00000000ULL) >> 32; \
165 		w[4] = (v & 0x00000000ff000000ULL) >> 24; \
166 		w[5] = (v & 0x0000000000ff0000ULL) >> 16; \
167 		w[6] = (v & 0x000000000000ff00ULL) >> 8; \
168 		w[7] = (v & 0x00000000000000ffULL); \
169 		w += 8; \
170 	} while (/*CONSTCOND*/0)
171 
172 #define PUTC16(v, w) \
173 	do { \
174 		if (v > 0 && v < 255) \
175 			PUT8(v, w); \
176 		else { \
177 			PUT8(255, w); \
178 			PUT16(v, w); \
179 		} \
180 	} while (/*CONSTCOND*/0)
181 
182 #define PUTC32(v, w) \
183 	do { \
184 		if (v < 0xffffffU) \
185 			PUT24(v, w); \
186 		else { \
187 			PUT24(0xffffffU, w); \
188 			PUT32(v, w); \
189 		} \
190 	} while (/*CONSTCOND*/0)
191 
192 #define PUT_OFFSET(v, w)		PUT32(v, w)
193 
194 #include <string.h>
195 
196 #define PUT_MEM(s, c, w) \
197 	do { \
198 		memmove(w, s, c); \
199 		w += c; \
200 	} while (/*CONSTCOND*/0)
201 
202 /*
203  * Regions.
204  */
205 #define REGION_SIZE(r)		((unsigned int)((r).rend - (r).rstart))
206 #define REGION_EMPTY(r)		((r).rstart == (r).rend)
207 #define REGION_FROMSTRING(r, s) do { \
208 	(r).rstart = (unsigned char *)s; \
209 	(r).rend = (r).rstart + strlen(s); \
210 } while (/*CONSTCOND*/0)
211 
212 /*%
213  * Use this to remove the const qualifier of a variable to assign it to
214  * a non-const variable or pass it as a non-const function argument ...
215  * but only when you are sure it won't then be changed!
216  * This is necessary to sometimes shut up some compilers
217  * (as with gcc -Wcast-qual) when there is just no other good way to avoid the
218  * situation.
219  */
220 #define DE_CONST(konst, var) \
221 	do { \
222 		union { const void *k; void *v; } _u; \
223 		_u.k = konst; \
224 		var = _u.v; \
225 	} while (/*CONSTCOND*/0)
226 
227 #endif /* ISCCC_UTIL_H */
228