2 * @brief functions for reading and writing different width words
4 /* Copyright (C) 2016,2018 Olly Betts
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 #ifndef XAPIAN_INCLUDED_WORDACCESS_H
26 #define XAPIAN_INCLUDED_WORDACCESS_H
29 #include <type_traits>
31 #include "alignment_cast.h"
34 #ifndef WORDS_BIGENDIAN
36 #if HAVE_DECL__BYTESWAP_USHORT || HAVE_DECL__BYTESWAP_ULONG
40 inline int do_bswap(uint16_t value
) {
41 # if HAVE_DECL___BUILTIN_BSWAP16
42 return __builtin_bswap16(value
);
43 # elif HAVE_DECL__BYTESWAP_USHORT
44 return _byteswap_ushort(value
);
46 return (value
<< 8) | (value
>> 8);
50 inline int do_bswap(uint32_t value
) {
51 # if HAVE_DECL___BUILTIN_BSWAP32
52 return __builtin_bswap32(value
);
53 # elif HAVE_DECL__BYTESWAP_USHORT
54 return _byteswap_ulong(value
);
56 return (value
<< 24) |
57 ((value
& 0xff00) << 8) |
58 ((value
>> 8) & 0xff00) |
65 template<typename UINT
>
67 do_aligned_read(const unsigned char * ptr
)
69 UINT value
= *alignment_cast
<const UINT
*>(ptr
);
70 #ifndef WORDS_BIGENDIAN
71 value
= do_bswap(value
);
76 template<typename T
, typename UINT
>
78 do_aligned_write(unsigned char * ptr
, T value
)
80 if (std::is_signed
<T
>::value
) {
81 AssertRel(value
, >=, 0);
83 if (sizeof(T
) > sizeof(UINT
)) {
84 AssertEq(value
, T(UINT(value
)));
87 #ifndef WORDS_BIGENDIAN
90 *alignment_cast
<UINT
*>(ptr
) = v
;
93 template<typename UINT
>
95 do_unaligned_read(const unsigned char * ptr
)
98 memcpy(&value
, ptr
, sizeof(UINT
));
99 #ifndef WORDS_BIGENDIAN
100 value
= do_bswap(value
);
105 template<typename T
, typename UINT
>
107 do_unaligned_write(unsigned char * ptr
, T value
)
109 if (std::is_signed
<T
>::value
) {
110 AssertRel(value
, >=, 0);
112 if (sizeof(T
) > sizeof(UINT
)) {
113 AssertEq(value
, T(UINT(value
)));
115 UINT v
= UINT(value
);
116 #ifndef WORDS_BIGENDIAN
119 memcpy(ptr
, &v
, sizeof(UINT
));
123 aligned_read4(const unsigned char *ptr
)
125 return do_aligned_read
<uint32_t>(ptr
);
129 unaligned_read4(const unsigned char *ptr
)
131 return do_unaligned_read
<uint32_t>(ptr
);
135 aligned_read2(const unsigned char *ptr
)
137 return do_aligned_read
<uint16_t>(ptr
);
141 unaligned_read2(const unsigned char *ptr
)
143 return do_unaligned_read
<uint16_t>(ptr
);
148 aligned_write4(unsigned char *ptr
, T value
)
150 do_aligned_write
<T
, uint32_t>(ptr
, value
);
155 unaligned_write4(unsigned char *ptr
, T value
)
157 do_unaligned_write
<T
, uint32_t>(ptr
, value
);
162 aligned_write2(unsigned char *ptr
, T value
)
164 do_aligned_write
<T
, uint16_t>(ptr
, value
);
169 unaligned_write2(unsigned char *ptr
, T value
)
171 do_unaligned_write
<T
, uint16_t>(ptr
, value
);
174 #endif // XAPIAN_INCLUDED_WORDACCESS_H