1 /* 2 * endians.h - Definitions related to handling of byte ordering. 3 * Originated from the Linux-NTFS project. 4 * 5 * Copyright (c) 2000-2005 Anton Altaparmakov 6 * 7 * This program/include file is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as published 9 * by the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program/include file is distributed in the hope that it will be 13 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program (in the main directory of the NTFS-3G 19 * distribution in the file COPYING); if not, write to the Free Software 20 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 #ifndef _NTFS_ENDIANS_H 24 #define _NTFS_ENDIANS_H 25 26 #ifdef HAVE_CONFIG_H 27 #include "config.h" 28 #endif 29 30 /* 31 * Notes: 32 * We define the conversion functions including typecasts since the 33 * defaults don't necessarily perform appropriate typecasts. 34 * Also, using our own functions means that we can change them if it 35 * turns out that we do need to use the unaligned access macros on 36 * architectures requiring aligned memory accesses... 37 */ 38 39 #ifdef HAVE_ENDIAN_H 40 #include <endian.h> 41 #endif 42 #ifdef HAVE_SYS_ENDIAN_H 43 #include <sys/endian.h> 44 #endif 45 #ifdef HAVE_MACHINE_ENDIAN_H 46 #include <machine/endian.h> 47 #endif 48 #ifdef HAVE_SYS_BYTEORDER_H 49 #include <sys/byteorder.h> 50 #endif 51 #ifdef HAVE_SYS_PARAM_H 52 #include <sys/param.h> 53 #endif 54 55 #ifndef __BYTE_ORDER 56 # if defined(_BYTE_ORDER) 57 # define __BYTE_ORDER _BYTE_ORDER 58 # define __LITTLE_ENDIAN _LITTLE_ENDIAN 59 # define __BIG_ENDIAN _BIG_ENDIAN 60 # elif defined(BYTE_ORDER) 61 # define __BYTE_ORDER BYTE_ORDER 62 # define __LITTLE_ENDIAN LITTLE_ENDIAN 63 # define __BIG_ENDIAN BIG_ENDIAN 64 # elif defined(__BYTE_ORDER__) 65 # define __BYTE_ORDER __BYTE_ORDER__ 66 # define __LITTLE_ENDIAN __LITTLE_ENDIAN__ 67 # define __BIG_ENDIAN __BIG_ENDIAN__ 68 # elif (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \ 69 defined(WORDS_LITTLEENDIAN) 70 # define __BYTE_ORDER 1 71 # define __LITTLE_ENDIAN 1 72 # define __BIG_ENDIAN 0 73 # elif (!defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)) || \ 74 defined(WORDS_BIGENDIAN) 75 # define __BYTE_ORDER 0 76 # define __LITTLE_ENDIAN 1 77 # define __BIG_ENDIAN 0 78 # else 79 # error "__BYTE_ORDER is not defined." 80 # endif 81 #endif 82 83 #define __ntfs_bswap_constant_16(x) \ 84 (u16)((((u16)(x) & 0xff00) >> 8) | \ 85 (((u16)(x) & 0x00ff) << 8)) 86 87 #define __ntfs_bswap_constant_32(x) \ 88 (u32)((((u32)(x) & 0xff000000u) >> 24) | \ 89 (((u32)(x) & 0x00ff0000u) >> 8) | \ 90 (((u32)(x) & 0x0000ff00u) << 8) | \ 91 (((u32)(x) & 0x000000ffu) << 24)) 92 93 #define __ntfs_bswap_constant_64(x) \ 94 (u64)((((u64)(x) & 0xff00000000000000ull) >> 56) | \ 95 (((u64)(x) & 0x00ff000000000000ull) >> 40) | \ 96 (((u64)(x) & 0x0000ff0000000000ull) >> 24) | \ 97 (((u64)(x) & 0x000000ff00000000ull) >> 8) | \ 98 (((u64)(x) & 0x00000000ff000000ull) << 8) | \ 99 (((u64)(x) & 0x0000000000ff0000ull) << 24) | \ 100 (((u64)(x) & 0x000000000000ff00ull) << 40) | \ 101 (((u64)(x) & 0x00000000000000ffull) << 56)) 102 103 #ifdef HAVE_BYTESWAP_H 104 # include <byteswap.h> 105 #else 106 # define bswap_16(x) __ntfs_bswap_constant_16(x) 107 # define bswap_32(x) __ntfs_bswap_constant_32(x) 108 # define bswap_64(x) __ntfs_bswap_constant_64(x) 109 #endif 110 111 #if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) 112 113 #define __le16_to_cpu(x) (x) 114 #define __le32_to_cpu(x) (x) 115 #define __le64_to_cpu(x) (x) 116 117 #define __cpu_to_le16(x) (x) 118 #define __cpu_to_le32(x) (x) 119 #define __cpu_to_le64(x) (x) 120 121 #define __constant_le16_to_cpu(x) (x) 122 #define __constant_le32_to_cpu(x) (x) 123 #define __constant_le64_to_cpu(x) (x) 124 125 #define __constant_cpu_to_le16(x) (x) 126 #define __constant_cpu_to_le32(x) (x) 127 #define __constant_cpu_to_le64(x) (x) 128 129 #elif defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) 130 131 #define __le16_to_cpu(x) bswap_16(x) 132 #define __le32_to_cpu(x) bswap_32(x) 133 #define __le64_to_cpu(x) bswap_64(x) 134 135 #define __cpu_to_le16(x) bswap_16(x) 136 #define __cpu_to_le32(x) bswap_32(x) 137 #define __cpu_to_le64(x) bswap_64(x) 138 139 #define __constant_le16_to_cpu(x) __ntfs_bswap_constant_16((u16)(x)) 140 #define __constant_le32_to_cpu(x) __ntfs_bswap_constant_32((u32)(x)) 141 #define __constant_le64_to_cpu(x) __ntfs_bswap_constant_64((u64)(x)) 142 143 #define __constant_cpu_to_le16(x) __ntfs_bswap_constant_16((u16)(x)) 144 #define __constant_cpu_to_le32(x) __ntfs_bswap_constant_32((u32)(x)) 145 #define __constant_cpu_to_le64(x) __ntfs_bswap_constant_64((u64)(x)) 146 147 #else 148 149 #error "You must define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN." 150 151 #endif 152 153 /* Unsigned from LE to CPU conversion. */ 154 155 #define le16_to_cpu(x) (u16)__le16_to_cpu((u16)(x)) 156 #define le32_to_cpu(x) (u32)__le32_to_cpu((u32)(x)) 157 #define le64_to_cpu(x) (u64)__le64_to_cpu((u64)(x)) 158 159 #define le16_to_cpup(x) (u16)__le16_to_cpu(*(const u16*)(x)) 160 #define le32_to_cpup(x) (u32)__le32_to_cpu(*(const u32*)(x)) 161 #define le64_to_cpup(x) (u64)__le64_to_cpu(*(const u64*)(x)) 162 163 /* Signed from LE to CPU conversion. */ 164 165 #define sle16_to_cpu(x) (s16)__le16_to_cpu((s16)(x)) 166 #define sle32_to_cpu(x) (s32)__le32_to_cpu((s32)(x)) 167 #define sle64_to_cpu(x) (s64)__le64_to_cpu((s64)(x)) 168 169 #define sle16_to_cpup(x) (s16)__le16_to_cpu(*(s16*)(x)) 170 #define sle32_to_cpup(x) (s32)__le32_to_cpu(*(s32*)(x)) 171 #define sle64_to_cpup(x) (s64)__le64_to_cpu(*(s64*)(x)) 172 173 /* Unsigned from CPU to LE conversion. */ 174 175 #define cpu_to_le16(x) (u16)__cpu_to_le16((u16)(x)) 176 #define cpu_to_le32(x) (u32)__cpu_to_le32((u32)(x)) 177 #define cpu_to_le64(x) (u64)__cpu_to_le64((u64)(x)) 178 179 #define cpu_to_le16p(x) (u16)__cpu_to_le16(*(u16*)(x)) 180 #define cpu_to_le32p(x) (u32)__cpu_to_le32(*(u32*)(x)) 181 #define cpu_to_le64p(x) (u64)__cpu_to_le64(*(u64*)(x)) 182 183 /* Signed from CPU to LE conversion. */ 184 185 #define cpu_to_sle16(x) (s16)__cpu_to_le16((s16)(x)) 186 #define cpu_to_sle32(x) (s32)__cpu_to_le32((s32)(x)) 187 #define cpu_to_sle64(x) (s64)__cpu_to_le64((s64)(x)) 188 189 #define cpu_to_sle16p(x) (s16)__cpu_to_le16(*(s16*)(x)) 190 #define cpu_to_sle32p(x) (s32)__cpu_to_le32(*(s32*)(x)) 191 #define cpu_to_sle64p(x) (s64)__cpu_to_le64(*(s64*)(x)) 192 193 /* Constant endianness conversion defines. */ 194 195 #define const_le16_to_cpu(x) __constant_le16_to_cpu(x) 196 #define const_le32_to_cpu(x) __constant_le32_to_cpu(x) 197 #define const_le64_to_cpu(x) __constant_le64_to_cpu(x) 198 199 #define const_cpu_to_le16(x) __constant_cpu_to_le16(x) 200 #define const_cpu_to_le32(x) __constant_cpu_to_le32(x) 201 #define const_cpu_to_le64(x) __constant_cpu_to_le64(x) 202 203 #endif /* defined _NTFS_ENDIANS_H */ 204