RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
EndiannessTest.cpp
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2017 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#include "EndiannessTest.h"
22#include "io/Endianness.h"
23#include <cstdint>
24#include <cstring>
25#include <iomanip>
26#include <iostream>
27#include <gtest/gtest.h>
28
30using rawspeed::getBE;
34using rawspeed::getLE;
39using std::setfill;
40using std::setw;
41
42namespace rawspeed_test {
43
44namespace {
45
46TEST(EndiannessTest, getHostEndiannessTests) {
47#if defined(__BYTE_ORDER__)
49#endif
50}
51
52/*
53#!/bin/bash
54d=16 # squared, how many samples
55# B=2 # sizeof, bytes
56b=x # print format
57p="0x" # print prefix
58function proc {
59 echo "$1" | od -A n --endian="$2" -t $3$B -N $B -w$B | tr -d ''
60}
61function pp {
62 v=$(proc "$1" "$2" "$b")
63 echo $p$v
64}
65for i in $(seq $d)
66do
67 for j in $(seq $d);
68 do
69 v=$(dd if=/dev/urandom bs=$B conv=sparse count=1 status=none)
70 x=$(pp "$v" little);
71 y=$(pp "$v" big);
72 echo "{$x, $y},";
73 done;
74done;
75*/
76
77#define setupHex setfill('0') << setw(2 * sizeof(T)) << std::hex
78
79template <typename T>
80[[maybe_unused]]
81::std::ostream& operator<<(::std::ostream& os, const intPair<T>& p) {
82 ::testing::Message msg;
83 msg << "(0x" << setupHex << p.first << ", 0x" << setupHex << p.second << ")";
84
85 return os << msg;
86}
87
88// no polymorphic lambda till c++14
89struct HexEquals final {
90 template <typename T>
91 ::testing::AssertionResult operator()(const char* darg1, const char* darg2,
92 const T& arg1, const T& arg2) {
93 if (memcmp(&arg1, &arg2, sizeof(T)) == 0)
94 return ::testing::AssertionSuccess();
95
96 ::testing::Message msg;
97 msg << " Expected: " << darg1 << std::endl;
98 msg << " Which is: " << setupHex << arg1 << std::endl;
99 msg << "To be equal to: " << darg2 << std::endl;
100 msg << " Which is: " << setupHex << arg2;
101
102 return ::testing::AssertionFailure() << msg;
103 }
104};
105
106#undef setupHex
107
108template <class T1, class T2>
109class AbstractGetByteSwappedTest : public ::testing::TestWithParam<T1> {
110protected:
112 virtual void SetUp() {
113 auto p = this->GetParam();
114 auto v = std::get<0>(p);
115
116 // swap them around? the test is symmetrical
117 if (std::get<1>(p)) {
118 memcpy(&in, &(v.first), sizeof(T2));
119 memcpy(&expected, &(v.second), sizeof(T2));
120 } else {
121 memcpy(&in, &(v.second), sizeof(T2));
122 memcpy(&expected, &(v.first), sizeof(T2));
123 }
124 }
125 T2 getByteSwappedT(const void* data, bool bswap) {
126 return getByteSwapped<T2>(data, bswap);
127 }
128 T2 getBEt(const void* data) { return getBE<T2>(data); }
129 T2 getLEt(const void* data) { return getLE<T2>(data); }
130
131 T2 in; // input
132 T2 expected; // expected output
133};
134
135/*
136B=2 # sizeof, bytes
137*/
139 : public AbstractGetByteSwappedTest<ushort16TType, uint16_t> {};
141 ::testing::Combine(::testing::ValuesIn(ushort16Values),
142 ::testing::Bool()));
144 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
145}
147 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
148}
149TEST_P(ushort16Test, typedSwap) {
150 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
151}
154 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
155 } else if (getHostEndianness() == Endianness::big) {
156 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
157 }
158}
161 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
162 } else if (getHostEndianness() == Endianness::big) {
163 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
164 }
165}
166
169 ASSERT_PRED_FORMAT2(HexEquals{}, getU16BE(&in), expected);
170 } else if (getHostEndianness() == Endianness::big) {
171 ASSERT_PRED_FORMAT2(HexEquals{}, getU16LE(&in), expected);
172 }
173}
174TEST_P(ushort16Test, getU16NOP) {
176 ASSERT_PRED_FORMAT2(HexEquals{}, getU16LE(&in), in);
177 } else if (getHostEndianness() == Endianness::big) {
178 ASSERT_PRED_FORMAT2(HexEquals{}, getU16BE(&in), in);
179 }
180}
181
182class short16Test : public AbstractGetByteSwappedTest<ushort16TType, int16_t> {
183};
185 ::testing::Combine(::testing::ValuesIn(ushort16Values),
186 ::testing::Bool()));
188 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
189}
191 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
192}
193TEST_P(short16Test, typedSwap) {
194 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
195}
198 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
199 } else if (getHostEndianness() == Endianness::big) {
200 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
201 }
202}
205 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
206 } else if (getHostEndianness() == Endianness::big) {
207 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
208 }
209}
210
211/*
212B=4 # sizeof, bytes
213*/
214class uint32Test : public AbstractGetByteSwappedTest<uint32TType, uint32_t> {};
216 ::testing::Combine(::testing::ValuesIn(uint32Values),
217 ::testing::Bool()));
219 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
220}
222 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
223}
224TEST_P(uint32Test, typedSwap) {
225 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
226}
229 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
230 } else if (getHostEndianness() == Endianness::big) {
231 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
232 }
233}
236 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
237 } else if (getHostEndianness() == Endianness::big) {
238 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
239 }
240}
241
244 ASSERT_PRED_FORMAT2(HexEquals{}, getU32BE(&in), expected);
245 } else if (getHostEndianness() == Endianness::big) {
246 ASSERT_PRED_FORMAT2(HexEquals{}, getU32LE(&in), expected);
247 }
248}
249TEST_P(uint32Test, getU32NOP) {
251 ASSERT_PRED_FORMAT2(HexEquals{}, getU32LE(&in), in);
252 } else if (getHostEndianness() == Endianness::big) {
253 ASSERT_PRED_FORMAT2(HexEquals{}, getU32BE(&in), in);
254 }
255}
256
257class int32Test : public AbstractGetByteSwappedTest<uint32TType, int32_t> {};
259 ::testing::Combine(::testing::ValuesIn(uint32Values),
260 ::testing::Bool()));
262 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
263}
265 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
266}
267TEST_P(int32Test, typedSwap) {
268 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
269}
272 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
273 } else if (getHostEndianness() == Endianness::big) {
274 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
275 }
276}
279 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
280 } else if (getHostEndianness() == Endianness::big) {
281 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
282 }
283}
284
285/*
286B=8 # sizeof, bytes
287*/
288class uint64Test : public AbstractGetByteSwappedTest<uint64TType, uint64_t> {};
290 ::testing::Combine(::testing::ValuesIn(uint64Values),
291 ::testing::Bool()));
293 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
294}
296 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
297}
298TEST_P(uint64Test, typedSwap) {
299 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
300}
303 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
304 } else if (getHostEndianness() == Endianness::big) {
305 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
306 }
307}
310 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
311 } else if (getHostEndianness() == Endianness::big) {
312 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
313 }
314}
315
316class floatTest : public AbstractGetByteSwappedTest<uint32TType, float> {};
318 ::testing::Combine(::testing::ValuesIn(uint32Values),
319 ::testing::Bool()));
321 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
322}
324 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
325}
326TEST_P(floatTest, typedSwap) {
327 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
328}
331 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
332 } else if (getHostEndianness() == Endianness::big) {
333 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
334 }
335}
338 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
339 } else if (getHostEndianness() == Endianness::big) {
340 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
341 }
342}
343
344class doubleTest : public AbstractGetByteSwappedTest<uint64TType, double> {};
346 ::testing::Combine(::testing::ValuesIn(uint64Values),
347 ::testing::Bool()));
349 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwapped(in), expected);
350}
352 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, false), in);
353}
354TEST_P(doubleTest, typedSwap) {
355 ASSERT_PRED_FORMAT2(HexEquals{}, getByteSwappedT(&in, true), expected);
356}
359 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), expected);
360 } else if (getHostEndianness() == Endianness::big) {
361 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), expected);
362 }
363}
366 ASSERT_PRED_FORMAT2(HexEquals{}, getLEt(&in), in);
367 } else if (getHostEndianness() == Endianness::big) {
368 ASSERT_PRED_FORMAT2(HexEquals{}, getBEt(&in), in);
369 }
370}
371
372} // namespace
373
374} // namespace rawspeed_test
Endianness getHostEndiannessRuntime()
Definition Endianness.h:37
int8_t getByteSwapped(int8_t v)
Definition Endianness.h:75
uint16_t getU16LE(const void *data)
Definition Endianness.h:125
Endianness getHostEndianness()
Definition Endianness.h:51
#define setupHex
uint32_t getU32BE(const void *data)
Definition Endianness.h:126
T getLE(const void *data)
Definition Endianness.h:120
T getBE(const void *data)
Definition Endianness.h:116
INSTANTIATE_TEST_SUITE_P(MD5Test, MD5Test, ::testing::ValuesIn(testCases))
TEST_P(MD5Test, CheckTestCaseSet)
Definition MD5Test.cpp:388
TEST(EndiannessTest, getHostEndiannessTests)
::std::ostream & operator<<(::std::ostream &os, const intPair< T > &p)
Endianness getHostEndiannessRuntime()
Definition Endianness.h:37
int8_t getByteSwapped(int8_t v)
Definition Endianness.h:75
uint16_t getU16LE(const void *data)
Definition Endianness.h:125
uint16_t getU16BE(const void *data)
Definition Endianness.h:124
Endianness getHostEndianness()
Definition Endianness.h:51
uint32_t getU32LE(const void *data)
Definition Endianness.h:127
uint32_t getU32BE(const void *data)
Definition Endianness.h:126
T getLE(const void *data)
Definition Endianness.h:120
T getBE(const void *data)
Definition Endianness.h:116
uint16_t getU16BE(const void *data)
Definition Endianness.h:124
uint32_t getU32LE(const void *data)
Definition Endianness.h:127
::testing::AssertionResult operator()(const char *darg1, const char *darg2, const T &arg1, const T &arg2)