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