[ci] Enable IRC notifications from travis
[xapian.git] / xapian-core / common / wordaccess.h
bloba92e06ba8b214ed6bff0ebbd90a228022c91278f
1 /** @file wordaccess.h
2 * @brief functions for reading and writing different width words
3 */
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
22 * IN THE SOFTWARE.
25 #ifndef XAPIAN_INCLUDED_WORDACCESS_H
26 #define XAPIAN_INCLUDED_WORDACCESS_H
28 #include <cstdint>
29 #include <type_traits>
31 #include "alignment_cast.h"
32 #include "omassert.h"
34 #ifndef WORDS_BIGENDIAN
36 #if HAVE_DECL__BYTESWAP_USHORT || HAVE_DECL__BYTESWAP_ULONG
37 # include <stdlib.h>
38 #endif
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);
45 # else
46 return (value << 8) | (value >> 8);
47 # endif
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);
55 # else
56 return (value << 24) |
57 ((value & 0xff00) << 8) |
58 ((value >> 8) & 0xff00) |
59 (value >> 24);
60 # endif
63 #endif
65 template<typename UINT>
66 inline 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);
72 #endif
73 return value;
76 template<typename T, typename UINT>
77 inline void
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)));
86 UINT v = UINT(value);
87 #ifndef WORDS_BIGENDIAN
88 v = do_bswap(v);
89 #endif
90 *alignment_cast<UINT*>(ptr) = v;
93 template<typename UINT>
94 inline UINT
95 do_unaligned_read(const unsigned char * ptr)
97 UINT value;
98 memcpy(&value, ptr, sizeof(UINT));
99 #ifndef WORDS_BIGENDIAN
100 value = do_bswap(value);
101 #endif
102 return value;
105 template<typename T, typename UINT>
106 inline void
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
117 v = do_bswap(v);
118 #endif
119 memcpy(ptr, &v, sizeof(UINT));
122 inline uint32_t
123 aligned_read4(const unsigned char *ptr)
125 return do_aligned_read<uint32_t>(ptr);
128 inline uint32_t
129 unaligned_read4(const unsigned char *ptr)
131 return do_unaligned_read<uint32_t>(ptr);
134 inline uint16_t
135 aligned_read2(const unsigned char *ptr)
137 return do_aligned_read<uint16_t>(ptr);
140 inline uint16_t
141 unaligned_read2(const unsigned char *ptr)
143 return do_unaligned_read<uint16_t>(ptr);
146 template<typename T>
147 inline void
148 aligned_write4(unsigned char *ptr, T value)
150 do_aligned_write<T, uint32_t>(ptr, value);
153 template<typename T>
154 inline void
155 unaligned_write4(unsigned char *ptr, T value)
157 do_unaligned_write<T, uint32_t>(ptr, value);
160 template<typename T>
161 inline void
162 aligned_write2(unsigned char *ptr, T value)
164 do_aligned_write<T, uint16_t>(ptr, value);
167 template<typename T>
168 inline void
169 unaligned_write2(unsigned char *ptr, T value)
171 do_unaligned_write<T, uint16_t>(ptr, value);
174 #endif // XAPIAN_INCLUDED_WORDACCESS_H