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 |