1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1996,2008 Oracle. All rights reserved. 5 */ 6/* 7 * Copyright (c) 1990, 1993, 1994 8 * The Regents of the University of California. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $Id: db_swap.h,v 12.13 2008/05/05 20:26:04 mbrey Exp $ 35 */ 36 37#ifndef _DB_SWAP_H_ 38#define _DB_SWAP_H_ 39 40#if defined(__cplusplus) 41extern "C" { 42#endif 43 44/* 45 * Little endian <==> big endian 64-bit swap macros. 46 * M_64_SWAP swap a memory location 47 * P_64_COPY copy potentially unaligned 4 byte quantities 48 * P_64_SWAP swap a referenced memory location 49 */ 50#undef M_64_SWAP 51#define M_64_SWAP(a) { \ 52 u_int64_t _tmp; \ 53 _tmp = (u_int64_t)a; \ 54 ((u_int8_t *)&a)[0] = ((u_int8_t *)&_tmp)[7]; \ 55 ((u_int8_t *)&a)[1] = ((u_int8_t *)&_tmp)[6]; \ 56 ((u_int8_t *)&a)[2] = ((u_int8_t *)&_tmp)[5]; \ 57 ((u_int8_t *)&a)[3] = ((u_int8_t *)&_tmp)[4]; \ 58 ((u_int8_t *)&a)[4] = ((u_int8_t *)&_tmp)[3]; \ 59 ((u_int8_t *)&a)[5] = ((u_int8_t *)&_tmp)[2]; \ 60 ((u_int8_t *)&a)[6] = ((u_int8_t *)&_tmp)[1]; \ 61 ((u_int8_t *)&a)[7] = ((u_int8_t *)&_tmp)[0]; \ 62} 63#undef P_64_COPY 64#define P_64_COPY(a, b) { \ 65 ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ 66 ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ 67 ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \ 68 ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \ 69 ((u_int8_t *)b)[4] = ((u_int8_t *)a)[4]; \ 70 ((u_int8_t *)b)[5] = ((u_int8_t *)a)[5]; \ 71 ((u_int8_t *)b)[6] = ((u_int8_t *)a)[6]; \ 72 ((u_int8_t *)b)[7] = ((u_int8_t *)a)[7]; \ 73} 74#undef P_64_SWAP 75#define P_64_SWAP(a) { \ 76 u_int64_t _tmp; \ 77 P_64_COPY(a, &_tmp); \ 78 ((u_int8_t *)a)[0] = ((u_int8_t *)&_tmp)[7]; \ 79 ((u_int8_t *)a)[1] = ((u_int8_t *)&_tmp)[6]; \ 80 ((u_int8_t *)a)[2] = ((u_int8_t *)&_tmp)[5]; \ 81 ((u_int8_t *)a)[3] = ((u_int8_t *)&_tmp)[4]; \ 82 ((u_int8_t *)a)[4] = ((u_int8_t *)&_tmp)[3]; \ 83 ((u_int8_t *)a)[5] = ((u_int8_t *)&_tmp)[2]; \ 84 ((u_int8_t *)a)[6] = ((u_int8_t *)&_tmp)[1]; \ 85 ((u_int8_t *)a)[7] = ((u_int8_t *)&_tmp)[0]; \ 86} 87 88/* 89 * Little endian <==> big endian 32-bit swap macros. 90 * P_32_COPY copy potentially unaligned 4 byte quantities 91 * P_32_COPYSWAP copy and swap potentially unaligned 4 byte quantities 92 * P_32_SWAP swap a referenced memory location 93 * M_32_SWAP swap a memory location 94 */ 95#undef P_32_COPY 96#define P_32_COPY(a, b) do { \ 97 ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ 98 ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ 99 ((u_int8_t *)b)[2] = ((u_int8_t *)a)[2]; \ 100 ((u_int8_t *)b)[3] = ((u_int8_t *)a)[3]; \ 101} while (0) 102#undef P_32_COPYSWAP 103#define P_32_COPYSWAP(a, b) do { \ 104 ((u_int8_t *)b)[0] = ((u_int8_t *)a)[3]; \ 105 ((u_int8_t *)b)[1] = ((u_int8_t *)a)[2]; \ 106 ((u_int8_t *)b)[2] = ((u_int8_t *)a)[1]; \ 107 ((u_int8_t *)b)[3] = ((u_int8_t *)a)[0]; \ 108} while (0) 109#undef P_32_SWAP 110#define P_32_SWAP(a) do { \ 111 u_int32_t _tmp; \ 112 P_32_COPY(a, &_tmp); \ 113 P_32_COPYSWAP(&_tmp, a); \ 114} while (0) 115#undef M_32_SWAP 116#define M_32_SWAP(a) P_32_SWAP(&a) 117 118/* 119 * Little endian <==> big endian 16-bit swap macros. 120 * P_16_COPY copy potentially unaligned 2 byte quantities 121 * P_16_COPYSWAP copy and swap potentially unaligned 2 byte quantities 122 * P_16_SWAP swap a referenced memory location 123 * M_16_SWAP swap a memory location 124 */ 125#undef P_16_COPY 126#define P_16_COPY(a, b) do { \ 127 ((u_int8_t *)b)[0] = ((u_int8_t *)a)[0]; \ 128 ((u_int8_t *)b)[1] = ((u_int8_t *)a)[1]; \ 129} while (0) 130#undef P_16_COPYSWAP 131#define P_16_COPYSWAP(a, b) do { \ 132 ((u_int8_t *)b)[0] = ((u_int8_t *)a)[1]; \ 133 ((u_int8_t *)b)[1] = ((u_int8_t *)a)[0]; \ 134} while (0) 135#undef P_16_SWAP 136#define P_16_SWAP(a) do { \ 137 u_int16_t _tmp; \ 138 P_16_COPY(a, &_tmp); \ 139 P_16_COPYSWAP(&_tmp, a); \ 140} while (0) 141#undef M_16_SWAP 142#define M_16_SWAP(a) P_16_SWAP(&a) 143 144#undef SWAP32 145#define SWAP32(p) { \ 146 P_32_SWAP(p); \ 147 (p) += sizeof(u_int32_t); \ 148} 149#undef SWAP16 150#define SWAP16(p) { \ 151 P_16_SWAP(p); \ 152 (p) += sizeof(u_int16_t); \ 153} 154 155/* 156 * Berkeley DB has local versions of htonl() and ntohl() that operate on 157 * pointers to the right size memory locations; the portability magic for 158 * finding the real system functions isn't worth the effort. 159 */ 160#undef DB_HTONL_SWAP 161#define DB_HTONL_SWAP(env, p) do { \ 162 if (F_ISSET((env), ENV_LITTLEENDIAN)) \ 163 P_32_SWAP(p); \ 164} while (0) 165#undef DB_NTOHL_SWAP 166#define DB_NTOHL_SWAP(env, p) do { \ 167 if (F_ISSET((env), ENV_LITTLEENDIAN)) \ 168 P_32_SWAP(p); \ 169} while (0) 170 171#undef DB_NTOHL_COPYIN 172#define DB_NTOHL_COPYIN(env, i, p) do { \ 173 u_int8_t *tmp; \ 174 tmp = (u_int8_t *)&(i); \ 175 if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ 176 tmp[3] = *p++; \ 177 tmp[2] = *p++; \ 178 tmp[1] = *p++; \ 179 tmp[0] = *p++; \ 180 } else { \ 181 memcpy(&i, p, sizeof(u_int32_t)); \ 182 p = (u_int8_t *)p + sizeof(u_int32_t); \ 183 } \ 184} while (0) 185 186#undef DB_NTOHS_COPYIN 187#define DB_NTOHS_COPYIN(env, i, p) do { \ 188 u_int8_t *tmp; \ 189 tmp = (u_int8_t *)&(i); \ 190 if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ 191 tmp[1] = *p++; \ 192 tmp[0] = *p++; \ 193 } else { \ 194 memcpy(&i, p, sizeof(u_int16_t)); \ 195 p = (u_int8_t *)p + sizeof(u_int16_t); \ 196 } \ 197} while (0) 198 199#undef DB_HTONL_COPYOUT 200#define DB_HTONL_COPYOUT(env, p, i) do { \ 201 u_int8_t *tmp; \ 202 tmp = (u_int8_t *)p; \ 203 if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ 204 *tmp++ = ((u_int8_t *)&(i))[3]; \ 205 *tmp++ = ((u_int8_t *)&(i))[2]; \ 206 *tmp++ = ((u_int8_t *)&(i))[1]; \ 207 *tmp++ = ((u_int8_t *)&(i))[0]; \ 208 } else \ 209 memcpy(p, &i, sizeof(u_int32_t)); \ 210 p = (u_int8_t *)p + sizeof(u_int32_t); \ 211} while (0) 212 213#undef DB_HTONS_COPYOUT 214#define DB_HTONS_COPYOUT(env, p, i) do { \ 215 u_int8_t *tmp; \ 216 tmp = (u_int8_t *)p; \ 217 if (F_ISSET(env, ENV_LITTLEENDIAN)) { \ 218 *tmp++ = ((u_int8_t *)&(i))[1]; \ 219 *tmp++ = ((u_int8_t *)&(i))[0]; \ 220 } else \ 221 memcpy(p, &i, sizeof(u_int16_t)); \ 222 p = (u_int8_t *)p + sizeof(u_int16_t); \ 223} while (0) 224 225/* 226 * Helper macros for swapped logs. We write logs in little endian format to 227 * minimize disruption on x86 when upgrading from native byte order to 228 * platform-independent logs. 229 */ 230#define LOG_SWAPPED(env) !F_ISSET(env, ENV_LITTLEENDIAN) 231 232#define LOGCOPY_32(env, x, p) do { \ 233 if (LOG_SWAPPED(env)) \ 234 P_32_COPYSWAP((p), (x)); \ 235 else \ 236 memcpy((x), (p), sizeof (u_int32_t)); \ 237} while (0) 238 239#define LOGCOPY_16(env, x, p) do { \ 240 if (LOG_SWAPPED(env)) \ 241 P_16_COPYSWAP((p), (x)); \ 242 else \ 243 memcpy((x), (p), sizeof (u_int16_t)); \ 244} while (0) 245 246#define LOGCOPY_TOLSN(env, lsnp, p) do { \ 247 LOGCOPY_32((env), &(lsnp)->file, (p)); \ 248 LOGCOPY_32((env), &(lsnp)->offset, \ 249 (u_int8_t *)(p) + sizeof (u_int32_t)); \ 250} while (0) 251 252#define LOGCOPY_FROMLSN(env, p, lsnp) do { \ 253 LOGCOPY_32((env), (p), &(lsnp)->file); \ 254 LOGCOPY_32((env), \ 255 (u_int8_t *)(p) + sizeof (u_int32_t), &(lsnp)->offset); \ 256} while (0) 257 258#if defined(__cplusplus) 259} 260#endif 261 262#endif /* !_DB_SWAP_H_ */ 263