summaryrefslogtreecommitdiff
path: root/include/ntfs-3g/endians.h (plain)
blob: 397f1c20b911c7ffd13ae9c39a346f2e7e69e4ab
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