]> icculus.org git repositories - icculus/xz.git/blob - src/common/integer.h
Sort of garbage collection commit. :-| Many things are still
[icculus/xz.git] / src / common / integer.h
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       integer.h
4 /// \brief      Reading and writing integers from and to buffers
5 //
6 //  This code has been put into the public domain.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 //
12 ///////////////////////////////////////////////////////////////////////////////
13
14 #ifndef LZMA_INTEGER_H
15 #define LZMA_INTEGER_H
16
17 // I'm aware of AC_CHECK_ALIGNED_ACCESS_REQUIRED from Autoconf archive, but
18 // it's not useful here. We don't care if unaligned access is supported,
19 // we care if it is fast. Some systems can emulate unaligned access in
20 // software, which is horribly slow; we want to use byte-by-byte access on
21 // such systems but the Autoconf test would detect such a system as
22 // supporting unaligned access.
23 //
24 // NOTE: HAVE_FAST_UNALIGNED_ACCESS indicates only support for 16-bit and
25 // 32-bit integer loads and stores. 64-bit integers may or may not work.
26 // That's why 64-bit functions are commented out.
27 #ifdef HAVE_FAST_UNALIGNED_ACCESS
28
29 // On big endian, we need byte swapping.
30 //
31 // TODO: Big endian PowerPC supports byte swapping load and store instructions
32 // that also allow unaligned access. Inline assembler could be OK for that.
33 #ifdef WORDS_BIGENDIAN
34 #       include "bswap.h"
35 #       define integer_le_16(n) bswap_16(n)
36 #       define integer_le_32(n) bswap_32(n)
37 #       define integer_le_64(n) bswap_64(n)
38 #else
39 #       define integer_le_16(n) (n)
40 #       define integer_le_32(n) (n)
41 #       define integer_le_64(n) (n)
42 #endif
43
44
45 static inline uint16_t
46 integer_read_16(const uint8_t buf[static 2])
47 {
48         uint16_t ret = *(const uint16_t *)(buf);
49         return integer_le_16(ret);
50 }
51
52
53 static inline uint32_t
54 integer_read_32(const uint8_t buf[static 4])
55 {
56         uint32_t ret = *(const uint32_t *)(buf);
57         return integer_le_32(ret);
58 }
59
60
61 /*
62 static inline uint64_t
63 integer_read_64(const uint8_t buf[static 8])
64 {
65         uint64_t ret = *(const uint64_t *)(buf);
66         return integer_le_64(ret);
67 }
68 */
69
70
71 static inline void
72 integer_write_16(uint8_t buf[static 2], uint16_t num)
73 {
74         *(uint16_t *)(buf) = integer_le_16(num);
75 }
76
77
78 static inline void
79 integer_write_32(uint8_t buf[static 4], uint32_t num)
80 {
81         *(uint32_t *)(buf) = integer_le_32(num);
82 }
83
84
85 /*
86 static inline void
87 integer_write_64(uint8_t buf[static 8], uint64_t num)
88 {
89         *(uint64_t *)(buf) = integer_le_64(num);
90 }
91 */
92
93
94 #else
95
96 static inline uint16_t
97 integer_read_16(const uint8_t buf[static 2])
98 {
99         uint16_t ret = buf[0] | (buf[1] << 8);
100         return ret;
101 }
102
103
104 static inline uint32_t
105 integer_read_32(const uint8_t buf[static 4])
106 {
107         uint32_t ret = buf[0];
108         ret |= (uint32_t)(buf[1]) << 8;
109         ret |= (uint32_t)(buf[2]) << 16;
110         ret |= (uint32_t)(buf[3]) << 24;
111         return ret;
112 }
113
114
115 /*
116 static inline uint64_t
117 integer_read_64(const uint8_t buf[static 8])
118 {
119         uint64_t ret = buf[0];
120         ret |= (uint64_t)(buf[1]) << 8;
121         ret |= (uint64_t)(buf[2]) << 16;
122         ret |= (uint64_t)(buf[3]) << 24;
123         ret |= (uint64_t)(buf[4]) << 32;
124         ret |= (uint64_t)(buf[5]) << 40;
125         ret |= (uint64_t)(buf[6]) << 48;
126         ret |= (uint64_t)(buf[7]) << 56;
127         return ret;
128 }
129 */
130
131
132 static inline void
133 integer_write_16(uint8_t buf[static 2], uint16_t num)
134 {
135         buf[0] = (uint8_t)(num);
136         buf[1] = (uint8_t)(num >> 8);
137 }
138
139
140 static inline void
141 integer_write_32(uint8_t buf[static 4], uint32_t num)
142 {
143         buf[0] = (uint8_t)(num);
144         buf[1] = (uint8_t)(num >> 8);
145         buf[2] = (uint8_t)(num >> 16);
146         buf[3] = (uint8_t)(num >> 24);
147 }
148
149
150 /*
151 static inline void
152 integer_write_64(uint8_t buf[static 8], uint64_t num)
153 {
154         buf[0] = (uint8_t)(num);
155         buf[1] = (uint8_t)(num >> 8);
156         buf[2] = (uint8_t)(num >> 16);
157         buf[3] = (uint8_t)(num >> 24);
158         buf[4] = (uint8_t)(num >> 32);
159         buf[5] = (uint8_t)(num >> 40);
160         buf[6] = (uint8_t)(num >> 48);
161         buf[7] = (uint8_t)(num >> 56);
162 }
163 */
164
165 #endif
166
167 #endif