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