/src/htslib/htslib/hts_endian.h
Line | Count | Source (jump to first uncovered line) |
1 | | /// @file hts_endian.h |
2 | | /// Byte swapping and unaligned access functions. |
3 | | /* |
4 | | Copyright (C) 2017 Genome Research Ltd. |
5 | | |
6 | | Author: Rob Davies <rmd@sanger.ac.uk> |
7 | | |
8 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
9 | | of this software and associated documentation files (the "Software"), to deal |
10 | | in the Software without restriction, including without limitation the rights |
11 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
12 | | copies of the Software, and to permit persons to whom the Software is |
13 | | furnished to do so, subject to the following conditions: |
14 | | |
15 | | The above copyright notice and this permission notice shall be included in |
16 | | all copies or substantial portions of the Software. |
17 | | |
18 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
19 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
20 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
21 | | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
22 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
23 | | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
24 | | DEALINGS IN THE SOFTWARE. */ |
25 | | |
26 | | #ifndef HTS_ENDIAN_H |
27 | | #define HTS_ENDIAN_H |
28 | | |
29 | | #include <stdint.h> |
30 | | |
31 | | /* |
32 | | * Compile-time endianness tests. |
33 | | * |
34 | | * Note that these tests may fail. They should only be used to enable |
35 | | * faster versions of endian-neutral implementations. The endian-neutral |
36 | | * version should always be available as a fall-back. |
37 | | * |
38 | | * See https://sourceforge.net/p/predef/wiki/Endianness/ |
39 | | */ |
40 | | |
41 | | /* Save typing as both endian and unaligned tests want to know about x86 */ |
42 | | #if (defined(__i386__) || defined(__i386) || defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(__i686__) || defined(__i686)) && !defined(HTS_x86) |
43 | | # define HTS_x86 /* x86 and x86_64 platform */ |
44 | | #endif |
45 | | |
46 | | /** @def HTS_LITTLE_ENDIAN |
47 | | * @brief Defined if platform is known to be little-endian |
48 | | */ |
49 | | |
50 | | #ifndef HTS_LITTLE_ENDIAN |
51 | | # if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ |
52 | | || defined(__LITTLE_ENDIAN__) \ |
53 | | || defined(HTS_x86) \ |
54 | | || defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) \ |
55 | | || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) |
56 | | # define HTS_LITTLE_ENDIAN |
57 | | # endif |
58 | | #endif |
59 | | |
60 | | /** @def HTS_BIG_ENDIAN |
61 | | * @brief Defined if platform is known to be big-endian |
62 | | */ |
63 | | |
64 | | #ifndef HTS_BIG_ENDIAN |
65 | | # if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \ |
66 | | || defined(__BIG_ENDIAN__) \ |
67 | | || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AAARCHEB__) \ |
68 | | || defined(_MIPSEB) || defined(__MIPSEB) || defined(__MIPSEB__) |
69 | | # define HTS_BIG_ENDIAN |
70 | | # endif |
71 | | #endif |
72 | | |
73 | | /** @def HTS_ENDIAN_NEUTRAL |
74 | | * @brief Define this to disable any endian-specific optimizations |
75 | | */ |
76 | | |
77 | | #if defined(HTS_ENDIAN_NEUTRAL) || (defined(HTS_LITTLE_ENDIAN) && defined(HTS_BIG_ENDIAN)) |
78 | | /* Disable all endian-specific code. */ |
79 | | # undef HTS_LITTLE_ENDIAN |
80 | | # undef HTS_BIG_ENDIAN |
81 | | #endif |
82 | | |
83 | | /** @def HTS_ALLOW_UNALIGNED |
84 | | * @brief Control use of unaligned memory access. |
85 | | * |
86 | | * Defining HTS_ALLOW_UNALIGNED=1 converts shift-and-or to simple casts on |
87 | | * little-endian platforms that can tolerate unaligned access (notably Intel |
88 | | * x86). |
89 | | * |
90 | | * Defining HTS_ALLOW_UNALIGNED=0 forces shift-and-or. |
91 | | */ |
92 | | |
93 | | // Consider using AX_CHECK_ALIGNED_ACCESS_REQUIRED in autoconf. |
94 | | #ifndef HTS_ALLOW_UNALIGNED |
95 | | # if defined(HTS_x86) |
96 | | # define HTS_ALLOW_UNALIGNED 1 |
97 | | # else |
98 | | # define HTS_ALLOW_UNALIGNED 0 |
99 | | # endif |
100 | | #endif |
101 | | |
102 | | #if HTS_ALLOW_UNALIGNED != 0 |
103 | | # if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) || defined(__clang__) |
104 | | // This prevents problems with gcc's vectoriser generating the wrong |
105 | | // instructions for unaligned data. |
106 | | typedef uint16_t uint16_u __attribute__ ((__aligned__ (1))); |
107 | | typedef uint32_t uint32_u __attribute__ ((__aligned__ (1))); |
108 | | typedef uint64_t uint64_u __attribute__ ((__aligned__ (1))); |
109 | | #else |
110 | | typedef uint16_t uint16_u; |
111 | | typedef uint32_t uint32_u; |
112 | | typedef uint64_t uint64_u; |
113 | | # endif |
114 | | #endif |
115 | | |
116 | | /// Get a uint8_t value from an unsigned byte array |
117 | | /** @param buf Pointer to source byte, may be unaligned |
118 | | * @return An 8-bit unsigned integer |
119 | | */ |
120 | 0 | static inline uint8_t le_to_u8(const uint8_t *buf) { |
121 | 0 | return *buf; |
122 | 0 | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_u8 Unexecuted instantiation: header.c:le_to_u8 Unexecuted instantiation: hts.c:le_to_u8 Unexecuted instantiation: sam.c:le_to_u8 Unexecuted instantiation: sam_mods.c:le_to_u8 Unexecuted instantiation: simd.c:le_to_u8 Unexecuted instantiation: textutils.c:le_to_u8 Unexecuted instantiation: vcf.c:le_to_u8 Unexecuted instantiation: cram_decode.c:le_to_u8 Unexecuted instantiation: cram_encode.c:le_to_u8 Unexecuted instantiation: cram_index.c:le_to_u8 Unexecuted instantiation: cram_io.c:le_to_u8 Unexecuted instantiation: cram_stats.c:le_to_u8 Unexecuted instantiation: mFILE.c:le_to_u8 Unexecuted instantiation: open_trace_file.c:le_to_u8 Unexecuted instantiation: bgzf.c:le_to_u8 Unexecuted instantiation: md5.c:le_to_u8 Unexecuted instantiation: tbx.c:le_to_u8 Unexecuted instantiation: cram_codecs.c:le_to_u8 |
123 | | |
124 | | /// Get a uint16_t value from an unsigned byte array |
125 | | /** @param buf Pointer to source byte, may be unaligned |
126 | | * @return A 16 bit unsigned integer |
127 | | * The input is read in little-endian byte order. |
128 | | */ |
129 | 40.8M | static inline uint16_t le_to_u16(const uint8_t *buf) { |
130 | 40.8M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 |
131 | 40.8M | return *((uint16_u *) buf); |
132 | | #else |
133 | | return (uint16_t) buf[0] | ((uint16_t) buf[1] << 8); |
134 | | #endif |
135 | 40.8M | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_u16 Unexecuted instantiation: header.c:le_to_u16 Unexecuted instantiation: hts.c:le_to_u16 Line | Count | Source | 129 | 303k | static inline uint16_t le_to_u16(const uint8_t *buf) { | 130 | 303k | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 131 | 303k | return *((uint16_u *) buf); | 132 | | #else | 133 | | return (uint16_t) buf[0] | ((uint16_t) buf[1] << 8); | 134 | | #endif | 135 | 303k | } |
Unexecuted instantiation: sam_mods.c:le_to_u16 Unexecuted instantiation: simd.c:le_to_u16 Unexecuted instantiation: textutils.c:le_to_u16 Line | Count | Source | 129 | 40.5M | static inline uint16_t le_to_u16(const uint8_t *buf) { | 130 | 40.5M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 131 | 40.5M | return *((uint16_u *) buf); | 132 | | #else | 133 | | return (uint16_t) buf[0] | ((uint16_t) buf[1] << 8); | 134 | | #endif | 135 | 40.5M | } |
Unexecuted instantiation: cram_decode.c:le_to_u16 Unexecuted instantiation: cram_encode.c:le_to_u16 Unexecuted instantiation: cram_index.c:le_to_u16 Unexecuted instantiation: cram_io.c:le_to_u16 Unexecuted instantiation: cram_stats.c:le_to_u16 Unexecuted instantiation: mFILE.c:le_to_u16 Unexecuted instantiation: open_trace_file.c:le_to_u16 Unexecuted instantiation: bgzf.c:le_to_u16 Unexecuted instantiation: md5.c:le_to_u16 Unexecuted instantiation: tbx.c:le_to_u16 Unexecuted instantiation: cram_codecs.c:le_to_u16 |
136 | | |
137 | | /// Get a uint32_t value from an unsigned byte array |
138 | | /** @param buf Pointer to source byte array, may be unaligned |
139 | | * @return A 32 bit unsigned integer |
140 | | * The input is read in little-endian byte order. |
141 | | */ |
142 | 103M | static inline uint32_t le_to_u32(const uint8_t *buf) { |
143 | 103M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 |
144 | 103M | return *((uint32_u *) buf); |
145 | | #else |
146 | | return ((uint32_t) buf[0] | |
147 | | ((uint32_t) buf[1] << 8) | |
148 | | ((uint32_t) buf[2] << 16) | |
149 | | ((uint32_t) buf[3] << 24)); |
150 | | #endif |
151 | 103M | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_u32 Unexecuted instantiation: header.c:le_to_u32 Unexecuted instantiation: hts.c:le_to_u32 Line | Count | Source | 142 | 3.02M | static inline uint32_t le_to_u32(const uint8_t *buf) { | 143 | 3.02M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 144 | 3.02M | return *((uint32_u *) buf); | 145 | | #else | 146 | | return ((uint32_t) buf[0] | | 147 | | ((uint32_t) buf[1] << 8) | | 148 | | ((uint32_t) buf[2] << 16) | | 149 | | ((uint32_t) buf[3] << 24)); | 150 | | #endif | 151 | 3.02M | } |
Unexecuted instantiation: sam_mods.c:le_to_u32 Unexecuted instantiation: simd.c:le_to_u32 Unexecuted instantiation: textutils.c:le_to_u32 Line | Count | Source | 142 | 100M | static inline uint32_t le_to_u32(const uint8_t *buf) { | 143 | 100M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 144 | 100M | return *((uint32_u *) buf); | 145 | | #else | 146 | | return ((uint32_t) buf[0] | | 147 | | ((uint32_t) buf[1] << 8) | | 148 | | ((uint32_t) buf[2] << 16) | | 149 | | ((uint32_t) buf[3] << 24)); | 150 | | #endif | 151 | 100M | } |
Unexecuted instantiation: cram_decode.c:le_to_u32 Unexecuted instantiation: cram_encode.c:le_to_u32 Unexecuted instantiation: cram_index.c:le_to_u32 Unexecuted instantiation: cram_io.c:le_to_u32 Unexecuted instantiation: cram_stats.c:le_to_u32 Unexecuted instantiation: mFILE.c:le_to_u32 Unexecuted instantiation: open_trace_file.c:le_to_u32 Line | Count | Source | 142 | 12 | static inline uint32_t le_to_u32(const uint8_t *buf) { | 143 | 12 | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 144 | 12 | return *((uint32_u *) buf); | 145 | | #else | 146 | | return ((uint32_t) buf[0] | | 147 | | ((uint32_t) buf[1] << 8) | | 148 | | ((uint32_t) buf[2] << 16) | | 149 | | ((uint32_t) buf[3] << 24)); | 150 | | #endif | 151 | 12 | } |
Unexecuted instantiation: md5.c:le_to_u32 Unexecuted instantiation: tbx.c:le_to_u32 Unexecuted instantiation: cram_codecs.c:le_to_u32 |
152 | | |
153 | | /// Get a uint64_t value from an unsigned byte array |
154 | | /** @param buf Pointer to source byte array, may be unaligned |
155 | | * @return A 64 bit unsigned integer |
156 | | * The input is read in little-endian byte order. |
157 | | */ |
158 | 17.4k | static inline uint64_t le_to_u64(const uint8_t *buf) { |
159 | 17.4k | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 |
160 | 17.4k | return *((uint64_u *) buf); |
161 | | #else |
162 | | return ((uint64_t) buf[0] | |
163 | | ((uint64_t) buf[1] << 8) | |
164 | | ((uint64_t) buf[2] << 16) | |
165 | | ((uint64_t) buf[3] << 24) | |
166 | | ((uint64_t) buf[4] << 32) | |
167 | | ((uint64_t) buf[5] << 40) | |
168 | | ((uint64_t) buf[6] << 48) | |
169 | | ((uint64_t) buf[7] << 56)); |
170 | | #endif |
171 | 17.4k | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_u64 Unexecuted instantiation: header.c:le_to_u64 Unexecuted instantiation: hts.c:le_to_u64 Line | Count | Source | 158 | 17.4k | static inline uint64_t le_to_u64(const uint8_t *buf) { | 159 | 17.4k | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 160 | 17.4k | return *((uint64_u *) buf); | 161 | | #else | 162 | | return ((uint64_t) buf[0] | | 163 | | ((uint64_t) buf[1] << 8) | | 164 | | ((uint64_t) buf[2] << 16) | | 165 | | ((uint64_t) buf[3] << 24) | | 166 | | ((uint64_t) buf[4] << 32) | | 167 | | ((uint64_t) buf[5] << 40) | | 168 | | ((uint64_t) buf[6] << 48) | | 169 | | ((uint64_t) buf[7] << 56)); | 170 | | #endif | 171 | 17.4k | } |
Unexecuted instantiation: sam_mods.c:le_to_u64 Unexecuted instantiation: simd.c:le_to_u64 Unexecuted instantiation: textutils.c:le_to_u64 Unexecuted instantiation: vcf.c:le_to_u64 Unexecuted instantiation: cram_decode.c:le_to_u64 Unexecuted instantiation: cram_encode.c:le_to_u64 Unexecuted instantiation: cram_index.c:le_to_u64 Unexecuted instantiation: cram_io.c:le_to_u64 Unexecuted instantiation: cram_stats.c:le_to_u64 Unexecuted instantiation: mFILE.c:le_to_u64 Unexecuted instantiation: open_trace_file.c:le_to_u64 Unexecuted instantiation: bgzf.c:le_to_u64 Unexecuted instantiation: md5.c:le_to_u64 Unexecuted instantiation: tbx.c:le_to_u64 Unexecuted instantiation: cram_codecs.c:le_to_u64 |
172 | | |
173 | | /// Store a uint16_t value in little-endian byte order |
174 | | /** @param val The value to store |
175 | | * @param buf Where to store it (may be unaligned) |
176 | | */ |
177 | 92.8M | static inline void u16_to_le(uint16_t val, uint8_t *buf) { |
178 | 92.8M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 |
179 | 92.8M | *((uint16_u *) buf) = val; |
180 | | #else |
181 | | buf[0] = val & 0xff; |
182 | | buf[1] = (val >> 8) & 0xff; |
183 | | #endif |
184 | 92.8M | } Unexecuted instantiation: hts_open_fuzzer.c:u16_to_le Unexecuted instantiation: header.c:u16_to_le Unexecuted instantiation: hts.c:u16_to_le Line | Count | Source | 177 | 12.0M | static inline void u16_to_le(uint16_t val, uint8_t *buf) { | 178 | 12.0M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 179 | 12.0M | *((uint16_u *) buf) = val; | 180 | | #else | 181 | | buf[0] = val & 0xff; | 182 | | buf[1] = (val >> 8) & 0xff; | 183 | | #endif | 184 | 12.0M | } |
Unexecuted instantiation: sam_mods.c:u16_to_le Unexecuted instantiation: simd.c:u16_to_le Unexecuted instantiation: textutils.c:u16_to_le Line | Count | Source | 177 | 80.7M | static inline void u16_to_le(uint16_t val, uint8_t *buf) { | 178 | 80.7M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 179 | 80.7M | *((uint16_u *) buf) = val; | 180 | | #else | 181 | | buf[0] = val & 0xff; | 182 | | buf[1] = (val >> 8) & 0xff; | 183 | | #endif | 184 | 80.7M | } |
Unexecuted instantiation: cram_decode.c:u16_to_le Unexecuted instantiation: cram_encode.c:u16_to_le Unexecuted instantiation: cram_index.c:u16_to_le Unexecuted instantiation: cram_io.c:u16_to_le Unexecuted instantiation: cram_stats.c:u16_to_le Unexecuted instantiation: mFILE.c:u16_to_le Unexecuted instantiation: open_trace_file.c:u16_to_le Unexecuted instantiation: bgzf.c:u16_to_le Unexecuted instantiation: md5.c:u16_to_le Unexecuted instantiation: tbx.c:u16_to_le Unexecuted instantiation: cram_codecs.c:u16_to_le |
185 | | |
186 | | /// Store a uint32_t value in little-endian byte order |
187 | | /** @param val The value to store |
188 | | * @param buf Where to store it (may be unaligned) |
189 | | */ |
190 | 223M | static inline void u32_to_le(uint32_t val, uint8_t *buf) { |
191 | 223M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 |
192 | 223M | *((uint32_u *) buf) = val; |
193 | | #else |
194 | | buf[0] = val & 0xff; |
195 | | buf[1] = (val >> 8) & 0xff; |
196 | | buf[2] = (val >> 16) & 0xff; |
197 | | buf[3] = (val >> 24) & 0xff; |
198 | | #endif |
199 | 223M | } Unexecuted instantiation: hts_open_fuzzer.c:u32_to_le Unexecuted instantiation: header.c:u32_to_le Unexecuted instantiation: hts.c:u32_to_le Line | Count | Source | 190 | 19.5M | static inline void u32_to_le(uint32_t val, uint8_t *buf) { | 191 | 19.5M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 192 | 19.5M | *((uint32_u *) buf) = val; | 193 | | #else | 194 | | buf[0] = val & 0xff; | 195 | | buf[1] = (val >> 8) & 0xff; | 196 | | buf[2] = (val >> 16) & 0xff; | 197 | | buf[3] = (val >> 24) & 0xff; | 198 | | #endif | 199 | 19.5M | } |
Unexecuted instantiation: sam_mods.c:u32_to_le Unexecuted instantiation: simd.c:u32_to_le Unexecuted instantiation: textutils.c:u32_to_le Line | Count | Source | 190 | 203M | static inline void u32_to_le(uint32_t val, uint8_t *buf) { | 191 | 203M | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 192 | 203M | *((uint32_u *) buf) = val; | 193 | | #else | 194 | | buf[0] = val & 0xff; | 195 | | buf[1] = (val >> 8) & 0xff; | 196 | | buf[2] = (val >> 16) & 0xff; | 197 | | buf[3] = (val >> 24) & 0xff; | 198 | | #endif | 199 | 203M | } |
Unexecuted instantiation: cram_decode.c:u32_to_le Unexecuted instantiation: cram_encode.c:u32_to_le Unexecuted instantiation: cram_index.c:u32_to_le Unexecuted instantiation: cram_io.c:u32_to_le Unexecuted instantiation: cram_stats.c:u32_to_le Unexecuted instantiation: mFILE.c:u32_to_le Unexecuted instantiation: open_trace_file.c:u32_to_le Unexecuted instantiation: bgzf.c:u32_to_le Unexecuted instantiation: md5.c:u32_to_le Unexecuted instantiation: tbx.c:u32_to_le Unexecuted instantiation: cram_codecs.c:u32_to_le |
200 | | |
201 | | /// Store a uint64_t value in little-endian byte order |
202 | | /** @param val The value to store |
203 | | * @param buf Where to store it (may be unaligned) |
204 | | */ |
205 | 52.2k | static inline void u64_to_le(uint64_t val, uint8_t *buf) { |
206 | 52.2k | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 |
207 | 52.2k | *((uint64_u *) buf) = val; |
208 | | #else |
209 | | buf[0] = val & 0xff; |
210 | | buf[1] = (val >> 8) & 0xff; |
211 | | buf[2] = (val >> 16) & 0xff; |
212 | | buf[3] = (val >> 24) & 0xff; |
213 | | buf[4] = (val >> 32) & 0xff; |
214 | | buf[5] = (val >> 40) & 0xff; |
215 | | buf[6] = (val >> 48) & 0xff; |
216 | | buf[7] = (val >> 56) & 0xff; |
217 | | #endif |
218 | 52.2k | } Unexecuted instantiation: hts_open_fuzzer.c:u64_to_le Unexecuted instantiation: header.c:u64_to_le Unexecuted instantiation: hts.c:u64_to_le Line | Count | Source | 205 | 52.2k | static inline void u64_to_le(uint64_t val, uint8_t *buf) { | 206 | 52.2k | #if defined(HTS_LITTLE_ENDIAN) && HTS_ALLOW_UNALIGNED != 0 | 207 | 52.2k | *((uint64_u *) buf) = val; | 208 | | #else | 209 | | buf[0] = val & 0xff; | 210 | | buf[1] = (val >> 8) & 0xff; | 211 | | buf[2] = (val >> 16) & 0xff; | 212 | | buf[3] = (val >> 24) & 0xff; | 213 | | buf[4] = (val >> 32) & 0xff; | 214 | | buf[5] = (val >> 40) & 0xff; | 215 | | buf[6] = (val >> 48) & 0xff; | 216 | | buf[7] = (val >> 56) & 0xff; | 217 | | #endif | 218 | 52.2k | } |
Unexecuted instantiation: sam_mods.c:u64_to_le Unexecuted instantiation: simd.c:u64_to_le Unexecuted instantiation: textutils.c:u64_to_le Unexecuted instantiation: vcf.c:u64_to_le Unexecuted instantiation: cram_decode.c:u64_to_le Unexecuted instantiation: cram_encode.c:u64_to_le Unexecuted instantiation: cram_index.c:u64_to_le Unexecuted instantiation: cram_io.c:u64_to_le Unexecuted instantiation: cram_stats.c:u64_to_le Unexecuted instantiation: mFILE.c:u64_to_le Unexecuted instantiation: open_trace_file.c:u64_to_le Unexecuted instantiation: bgzf.c:u64_to_le Unexecuted instantiation: md5.c:u64_to_le Unexecuted instantiation: tbx.c:u64_to_le Unexecuted instantiation: cram_codecs.c:u64_to_le |
219 | | |
220 | | /* Signed values. Grab the data as unsigned, then convert to signed without |
221 | | * triggering undefined behaviour. On any sensible platform, the conversion |
222 | | * should optimise away to nothing. |
223 | | */ |
224 | | |
225 | | /// Get an int8_t value from an unsigned byte array |
226 | | /** @param buf Pointer to source byte array, may be unaligned |
227 | | * @return A 8 bit signed integer |
228 | | * The input data is interpreted as 2's complement representation. |
229 | | */ |
230 | 6.24M | static inline int8_t le_to_i8(const uint8_t *buf) { |
231 | 6.24M | return *buf < 0x80 ? (int8_t) *buf : -((int8_t) (0xff - *buf)) - 1; |
232 | 6.24M | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_i8 Unexecuted instantiation: header.c:le_to_i8 Unexecuted instantiation: hts.c:le_to_i8 Unexecuted instantiation: sam.c:le_to_i8 Unexecuted instantiation: sam_mods.c:le_to_i8 Unexecuted instantiation: simd.c:le_to_i8 Unexecuted instantiation: textutils.c:le_to_i8 Line | Count | Source | 230 | 6.24M | static inline int8_t le_to_i8(const uint8_t *buf) { | 231 | 6.24M | return *buf < 0x80 ? (int8_t) *buf : -((int8_t) (0xff - *buf)) - 1; | 232 | 6.24M | } |
Unexecuted instantiation: cram_decode.c:le_to_i8 Unexecuted instantiation: cram_encode.c:le_to_i8 Unexecuted instantiation: cram_index.c:le_to_i8 Unexecuted instantiation: cram_io.c:le_to_i8 Unexecuted instantiation: cram_stats.c:le_to_i8 Unexecuted instantiation: mFILE.c:le_to_i8 Unexecuted instantiation: open_trace_file.c:le_to_i8 Unexecuted instantiation: bgzf.c:le_to_i8 Unexecuted instantiation: md5.c:le_to_i8 Unexecuted instantiation: tbx.c:le_to_i8 Unexecuted instantiation: cram_codecs.c:le_to_i8 |
233 | | |
234 | | /// Get an int16_t value from an unsigned byte array |
235 | | /** @param buf Pointer to source byte array, may be unaligned |
236 | | * @return A 16 bit signed integer |
237 | | * The input data is interpreted as 2's complement representation in |
238 | | * little-endian byte order. |
239 | | */ |
240 | 40.7M | static inline int16_t le_to_i16(const uint8_t *buf) { |
241 | 40.7M | uint16_t v = le_to_u16(buf); |
242 | 40.7M | return v < 0x8000 ? (int16_t) v : -((int16_t) (0xffff - v)) - 1; |
243 | 40.7M | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_i16 Unexecuted instantiation: header.c:le_to_i16 Unexecuted instantiation: hts.c:le_to_i16 Line | Count | Source | 240 | 173k | static inline int16_t le_to_i16(const uint8_t *buf) { | 241 | 173k | uint16_t v = le_to_u16(buf); | 242 | 173k | return v < 0x8000 ? (int16_t) v : -((int16_t) (0xffff - v)) - 1; | 243 | 173k | } |
Unexecuted instantiation: sam_mods.c:le_to_i16 Unexecuted instantiation: simd.c:le_to_i16 Unexecuted instantiation: textutils.c:le_to_i16 Line | Count | Source | 240 | 40.5M | static inline int16_t le_to_i16(const uint8_t *buf) { | 241 | 40.5M | uint16_t v = le_to_u16(buf); | 242 | 40.5M | return v < 0x8000 ? (int16_t) v : -((int16_t) (0xffff - v)) - 1; | 243 | 40.5M | } |
Unexecuted instantiation: cram_decode.c:le_to_i16 Unexecuted instantiation: cram_encode.c:le_to_i16 Unexecuted instantiation: cram_index.c:le_to_i16 Unexecuted instantiation: cram_io.c:le_to_i16 Unexecuted instantiation: cram_stats.c:le_to_i16 Unexecuted instantiation: mFILE.c:le_to_i16 Unexecuted instantiation: open_trace_file.c:le_to_i16 Unexecuted instantiation: bgzf.c:le_to_i16 Unexecuted instantiation: md5.c:le_to_i16 Unexecuted instantiation: tbx.c:le_to_i16 Unexecuted instantiation: cram_codecs.c:le_to_i16 |
244 | | |
245 | | /// Get an int32_t value from an unsigned byte array |
246 | | /** @param buf Pointer to source byte array, may be unaligned |
247 | | * @return A 32 bit signed integer |
248 | | * The input data is interpreted as 2's complement representation in |
249 | | * little-endian byte order. |
250 | | */ |
251 | 53.2M | static inline int32_t le_to_i32(const uint8_t *buf) { |
252 | 53.2M | uint32_t v = le_to_u32(buf); |
253 | 53.2M | return v < 0x80000000U ? (int32_t) v : -((int32_t) (0xffffffffU - v)) - 1; |
254 | 53.2M | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_i32 Unexecuted instantiation: header.c:le_to_i32 Unexecuted instantiation: hts.c:le_to_i32 Line | Count | Source | 251 | 1.50M | static inline int32_t le_to_i32(const uint8_t *buf) { | 252 | 1.50M | uint32_t v = le_to_u32(buf); | 253 | 1.50M | return v < 0x80000000U ? (int32_t) v : -((int32_t) (0xffffffffU - v)) - 1; | 254 | 1.50M | } |
Unexecuted instantiation: sam_mods.c:le_to_i32 Unexecuted instantiation: simd.c:le_to_i32 Unexecuted instantiation: textutils.c:le_to_i32 Line | Count | Source | 251 | 51.6M | static inline int32_t le_to_i32(const uint8_t *buf) { | 252 | 51.6M | uint32_t v = le_to_u32(buf); | 253 | 51.6M | return v < 0x80000000U ? (int32_t) v : -((int32_t) (0xffffffffU - v)) - 1; | 254 | 51.6M | } |
Unexecuted instantiation: cram_decode.c:le_to_i32 Unexecuted instantiation: cram_encode.c:le_to_i32 Unexecuted instantiation: cram_index.c:le_to_i32 Unexecuted instantiation: cram_io.c:le_to_i32 Unexecuted instantiation: cram_stats.c:le_to_i32 Unexecuted instantiation: mFILE.c:le_to_i32 Unexecuted instantiation: open_trace_file.c:le_to_i32 Unexecuted instantiation: bgzf.c:le_to_i32 Unexecuted instantiation: md5.c:le_to_i32 Unexecuted instantiation: tbx.c:le_to_i32 Unexecuted instantiation: cram_codecs.c:le_to_i32 |
255 | | |
256 | | /// Get an int64_t value from an unsigned byte array |
257 | | /** @param buf Pointer to source byte array, may be unaligned |
258 | | * @return A 64 bit signed integer |
259 | | * The input data is interpreted as 2's complement representation in |
260 | | * little-endian byte order. |
261 | | */ |
262 | 0 | static inline int64_t le_to_i64(const uint8_t *buf) { |
263 | 0 | uint64_t v = le_to_u64(buf); |
264 | 0 | return (v < 0x8000000000000000ULL |
265 | 0 | ? (int64_t) v : -((int64_t) (0xffffffffffffffffULL - v)) - 1); |
266 | 0 | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_i64 Unexecuted instantiation: header.c:le_to_i64 Unexecuted instantiation: hts.c:le_to_i64 Unexecuted instantiation: sam.c:le_to_i64 Unexecuted instantiation: sam_mods.c:le_to_i64 Unexecuted instantiation: simd.c:le_to_i64 Unexecuted instantiation: textutils.c:le_to_i64 Unexecuted instantiation: vcf.c:le_to_i64 Unexecuted instantiation: cram_decode.c:le_to_i64 Unexecuted instantiation: cram_encode.c:le_to_i64 Unexecuted instantiation: cram_index.c:le_to_i64 Unexecuted instantiation: cram_io.c:le_to_i64 Unexecuted instantiation: cram_stats.c:le_to_i64 Unexecuted instantiation: mFILE.c:le_to_i64 Unexecuted instantiation: open_trace_file.c:le_to_i64 Unexecuted instantiation: bgzf.c:le_to_i64 Unexecuted instantiation: md5.c:le_to_i64 Unexecuted instantiation: tbx.c:le_to_i64 Unexecuted instantiation: cram_codecs.c:le_to_i64 |
267 | | |
268 | | // Converting the other way is easier as signed -> unsigned is well defined. |
269 | | |
270 | | /// Store a uint16_t value in little-endian byte order |
271 | | /** @param val The value to store |
272 | | * @param buf Where to store it (may be unaligned) |
273 | | */ |
274 | 81.4M | static inline void i16_to_le(int16_t val, uint8_t *buf) { |
275 | 81.4M | u16_to_le(val, buf); |
276 | 81.4M | } Unexecuted instantiation: hts_open_fuzzer.c:i16_to_le Unexecuted instantiation: header.c:i16_to_le Unexecuted instantiation: hts.c:i16_to_le Line | Count | Source | 274 | 697k | static inline void i16_to_le(int16_t val, uint8_t *buf) { | 275 | 697k | u16_to_le(val, buf); | 276 | 697k | } |
Unexecuted instantiation: sam_mods.c:i16_to_le Unexecuted instantiation: simd.c:i16_to_le Unexecuted instantiation: textutils.c:i16_to_le Line | Count | Source | 274 | 80.7M | static inline void i16_to_le(int16_t val, uint8_t *buf) { | 275 | 80.7M | u16_to_le(val, buf); | 276 | 80.7M | } |
Unexecuted instantiation: cram_decode.c:i16_to_le Unexecuted instantiation: cram_encode.c:i16_to_le Unexecuted instantiation: cram_index.c:i16_to_le Unexecuted instantiation: cram_io.c:i16_to_le Unexecuted instantiation: cram_stats.c:i16_to_le Unexecuted instantiation: mFILE.c:i16_to_le Unexecuted instantiation: open_trace_file.c:i16_to_le Unexecuted instantiation: bgzf.c:i16_to_le Unexecuted instantiation: md5.c:i16_to_le Unexecuted instantiation: tbx.c:i16_to_le Unexecuted instantiation: cram_codecs.c:i16_to_le |
277 | | |
278 | | /// Store a uint32_t value in little-endian byte order |
279 | | /** @param val The value to store |
280 | | * @param buf Where to store it (may be unaligned) |
281 | | */ |
282 | 116M | static inline void i32_to_le(int32_t val, uint8_t *buf) { |
283 | 116M | u32_to_le(val, buf); |
284 | 116M | } Unexecuted instantiation: hts_open_fuzzer.c:i32_to_le Unexecuted instantiation: header.c:i32_to_le Unexecuted instantiation: hts.c:i32_to_le Line | Count | Source | 282 | 12.8M | static inline void i32_to_le(int32_t val, uint8_t *buf) { | 283 | 12.8M | u32_to_le(val, buf); | 284 | 12.8M | } |
Unexecuted instantiation: sam_mods.c:i32_to_le Unexecuted instantiation: simd.c:i32_to_le Unexecuted instantiation: textutils.c:i32_to_le Line | Count | Source | 282 | 103M | static inline void i32_to_le(int32_t val, uint8_t *buf) { | 283 | 103M | u32_to_le(val, buf); | 284 | 103M | } |
Unexecuted instantiation: cram_decode.c:i32_to_le Unexecuted instantiation: cram_encode.c:i32_to_le Unexecuted instantiation: cram_index.c:i32_to_le Unexecuted instantiation: cram_io.c:i32_to_le Unexecuted instantiation: cram_stats.c:i32_to_le Unexecuted instantiation: mFILE.c:i32_to_le Unexecuted instantiation: open_trace_file.c:i32_to_le Unexecuted instantiation: bgzf.c:i32_to_le Unexecuted instantiation: md5.c:i32_to_le Unexecuted instantiation: tbx.c:i32_to_le Unexecuted instantiation: cram_codecs.c:i32_to_le |
285 | | |
286 | | /// Store a uint64_t value in little-endian byte order |
287 | | /** @param val The value to store |
288 | | * @param buf Where to store it (may be unaligned) |
289 | | */ |
290 | 0 | static inline void i64_to_le(int64_t val, uint8_t *buf) { |
291 | 0 | u64_to_le(val, buf); |
292 | 0 | } Unexecuted instantiation: hts_open_fuzzer.c:i64_to_le Unexecuted instantiation: header.c:i64_to_le Unexecuted instantiation: hts.c:i64_to_le Unexecuted instantiation: sam.c:i64_to_le Unexecuted instantiation: sam_mods.c:i64_to_le Unexecuted instantiation: simd.c:i64_to_le Unexecuted instantiation: textutils.c:i64_to_le Unexecuted instantiation: vcf.c:i64_to_le Unexecuted instantiation: cram_decode.c:i64_to_le Unexecuted instantiation: cram_encode.c:i64_to_le Unexecuted instantiation: cram_index.c:i64_to_le Unexecuted instantiation: cram_io.c:i64_to_le Unexecuted instantiation: cram_stats.c:i64_to_le Unexecuted instantiation: mFILE.c:i64_to_le Unexecuted instantiation: open_trace_file.c:i64_to_le Unexecuted instantiation: bgzf.c:i64_to_le Unexecuted instantiation: md5.c:i64_to_le Unexecuted instantiation: tbx.c:i64_to_le Unexecuted instantiation: cram_codecs.c:i64_to_le |
293 | | |
294 | | /* Floating point. Assumptions: |
295 | | * Platform uses IEEE 754 format |
296 | | * sizeof(float) == sizeof(uint32_t) |
297 | | * sizeof(double) == sizeof(uint64_t) |
298 | | * Endian-ness is the same for both floating point and integer |
299 | | * Type-punning via a union is allowed |
300 | | */ |
301 | | |
302 | | /// Get a float value from an unsigned byte array |
303 | | /** @param buf Pointer to source byte array, may be unaligned |
304 | | * @return A 32 bit floating point value |
305 | | * The input is interpreted as an IEEE 754 format float in little-endian |
306 | | * byte order. |
307 | | */ |
308 | 759k | static inline float le_to_float(const uint8_t *buf) { |
309 | 759k | union { |
310 | 759k | uint32_t u; |
311 | 759k | float f; |
312 | 759k | } convert; |
313 | | |
314 | 759k | convert.u = le_to_u32(buf); |
315 | 759k | return convert.f; |
316 | 759k | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_float Unexecuted instantiation: header.c:le_to_float Unexecuted instantiation: hts.c:le_to_float Line | Count | Source | 308 | 15.6k | static inline float le_to_float(const uint8_t *buf) { | 309 | 15.6k | union { | 310 | 15.6k | uint32_t u; | 311 | 15.6k | float f; | 312 | 15.6k | } convert; | 313 | | | 314 | 15.6k | convert.u = le_to_u32(buf); | 315 | 15.6k | return convert.f; | 316 | 15.6k | } |
Unexecuted instantiation: sam_mods.c:le_to_float Unexecuted instantiation: simd.c:le_to_float Unexecuted instantiation: textutils.c:le_to_float Line | Count | Source | 308 | 743k | static inline float le_to_float(const uint8_t *buf) { | 309 | 743k | union { | 310 | 743k | uint32_t u; | 311 | 743k | float f; | 312 | 743k | } convert; | 313 | | | 314 | 743k | convert.u = le_to_u32(buf); | 315 | 743k | return convert.f; | 316 | 743k | } |
Unexecuted instantiation: cram_decode.c:le_to_float Unexecuted instantiation: cram_encode.c:le_to_float Unexecuted instantiation: cram_index.c:le_to_float Unexecuted instantiation: cram_io.c:le_to_float Unexecuted instantiation: cram_stats.c:le_to_float Unexecuted instantiation: mFILE.c:le_to_float Unexecuted instantiation: open_trace_file.c:le_to_float Unexecuted instantiation: bgzf.c:le_to_float Unexecuted instantiation: md5.c:le_to_float Unexecuted instantiation: tbx.c:le_to_float Unexecuted instantiation: cram_codecs.c:le_to_float |
317 | | |
318 | | /// Get a double value from an unsigned byte array |
319 | | /** @param buf Pointer to source byte array, may be unaligned |
320 | | * @return A 64 bit floating point value |
321 | | * The input is interpreted as an IEEE 754 format double in little-endian |
322 | | * byte order. |
323 | | */ |
324 | 17.4k | static inline double le_to_double(const uint8_t *buf) { |
325 | 17.4k | union { |
326 | 17.4k | uint64_t u; |
327 | 17.4k | double f; |
328 | 17.4k | } convert; |
329 | | |
330 | 17.4k | convert.u = le_to_u64(buf); |
331 | 17.4k | return convert.f; |
332 | 17.4k | } Unexecuted instantiation: hts_open_fuzzer.c:le_to_double Unexecuted instantiation: header.c:le_to_double Unexecuted instantiation: hts.c:le_to_double Line | Count | Source | 324 | 17.4k | static inline double le_to_double(const uint8_t *buf) { | 325 | 17.4k | union { | 326 | 17.4k | uint64_t u; | 327 | 17.4k | double f; | 328 | 17.4k | } convert; | 329 | | | 330 | 17.4k | convert.u = le_to_u64(buf); | 331 | 17.4k | return convert.f; | 332 | 17.4k | } |
Unexecuted instantiation: sam_mods.c:le_to_double Unexecuted instantiation: simd.c:le_to_double Unexecuted instantiation: textutils.c:le_to_double Unexecuted instantiation: vcf.c:le_to_double Unexecuted instantiation: cram_decode.c:le_to_double Unexecuted instantiation: cram_encode.c:le_to_double Unexecuted instantiation: cram_index.c:le_to_double Unexecuted instantiation: cram_io.c:le_to_double Unexecuted instantiation: cram_stats.c:le_to_double Unexecuted instantiation: mFILE.c:le_to_double Unexecuted instantiation: open_trace_file.c:le_to_double Unexecuted instantiation: bgzf.c:le_to_double Unexecuted instantiation: md5.c:le_to_double Unexecuted instantiation: tbx.c:le_to_double Unexecuted instantiation: cram_codecs.c:le_to_double |
333 | | |
334 | | /// Store a float value in little-endian byte order |
335 | | /** @param val The value to store |
336 | | * @param buf Where to store it (may be unaligned) |
337 | | */ |
338 | 99.9M | static inline void float_to_le(float val, uint8_t *buf) { |
339 | 99.9M | union { |
340 | 99.9M | uint32_t u; |
341 | 99.9M | float f; |
342 | 99.9M | } convert; |
343 | | |
344 | 99.9M | convert.f = val; |
345 | 99.9M | u32_to_le(convert.u, buf); |
346 | 99.9M | } Unexecuted instantiation: hts_open_fuzzer.c:float_to_le Unexecuted instantiation: header.c:float_to_le Unexecuted instantiation: hts.c:float_to_le Line | Count | Source | 338 | 48.9k | static inline void float_to_le(float val, uint8_t *buf) { | 339 | 48.9k | union { | 340 | 48.9k | uint32_t u; | 341 | 48.9k | float f; | 342 | 48.9k | } convert; | 343 | | | 344 | 48.9k | convert.f = val; | 345 | 48.9k | u32_to_le(convert.u, buf); | 346 | 48.9k | } |
Unexecuted instantiation: sam_mods.c:float_to_le Unexecuted instantiation: simd.c:float_to_le Unexecuted instantiation: textutils.c:float_to_le Line | Count | Source | 338 | 99.9M | static inline void float_to_le(float val, uint8_t *buf) { | 339 | 99.9M | union { | 340 | 99.9M | uint32_t u; | 341 | 99.9M | float f; | 342 | 99.9M | } convert; | 343 | | | 344 | 99.9M | convert.f = val; | 345 | 99.9M | u32_to_le(convert.u, buf); | 346 | 99.9M | } |
Unexecuted instantiation: cram_decode.c:float_to_le Unexecuted instantiation: cram_encode.c:float_to_le Unexecuted instantiation: cram_index.c:float_to_le Unexecuted instantiation: cram_io.c:float_to_le Unexecuted instantiation: cram_stats.c:float_to_le Unexecuted instantiation: mFILE.c:float_to_le Unexecuted instantiation: open_trace_file.c:float_to_le Unexecuted instantiation: bgzf.c:float_to_le Unexecuted instantiation: md5.c:float_to_le Unexecuted instantiation: tbx.c:float_to_le Unexecuted instantiation: cram_codecs.c:float_to_le |
347 | | |
348 | | /// Store a double value in little-endian byte order |
349 | | /** @param val The value to store |
350 | | * @param buf Where to store it (may be unaligned) |
351 | | */ |
352 | 52.2k | static inline void double_to_le(double val, uint8_t *buf) { |
353 | 52.2k | union { |
354 | 52.2k | uint64_t u; |
355 | 52.2k | double f; |
356 | 52.2k | } convert; |
357 | | |
358 | 52.2k | convert.f = val; |
359 | 52.2k | u64_to_le(convert.u, buf); |
360 | 52.2k | } Unexecuted instantiation: hts_open_fuzzer.c:double_to_le Unexecuted instantiation: header.c:double_to_le Unexecuted instantiation: hts.c:double_to_le Line | Count | Source | 352 | 52.2k | static inline void double_to_le(double val, uint8_t *buf) { | 353 | 52.2k | union { | 354 | 52.2k | uint64_t u; | 355 | 52.2k | double f; | 356 | 52.2k | } convert; | 357 | | | 358 | 52.2k | convert.f = val; | 359 | 52.2k | u64_to_le(convert.u, buf); | 360 | 52.2k | } |
Unexecuted instantiation: sam_mods.c:double_to_le Unexecuted instantiation: simd.c:double_to_le Unexecuted instantiation: textutils.c:double_to_le Unexecuted instantiation: vcf.c:double_to_le Unexecuted instantiation: cram_decode.c:double_to_le Unexecuted instantiation: cram_encode.c:double_to_le Unexecuted instantiation: cram_index.c:double_to_le Unexecuted instantiation: cram_io.c:double_to_le Unexecuted instantiation: cram_stats.c:double_to_le Unexecuted instantiation: mFILE.c:double_to_le Unexecuted instantiation: open_trace_file.c:double_to_le Unexecuted instantiation: bgzf.c:double_to_le Unexecuted instantiation: md5.c:double_to_le Unexecuted instantiation: tbx.c:double_to_le Unexecuted instantiation: cram_codecs.c:double_to_le |
361 | | |
362 | | #endif /* HTS_ENDIAN_H */ |