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