diff --git a/src/sim/SConscript b/src/sim/SConscript index bf46ccb5c3..72797b78f4 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -45,6 +45,7 @@ SimObject('PowerDomain.py', sim_objects=['PowerDomain']) Source('async.cc') Source('backtrace_%s.cc' % env['BACKTRACE_IMPL'], add_tags='gem5 trace') +Source('bufval.cc') Source('core.cc') Source('cur_tick.cc', add_tags='gem5 trace') Source('tags.cc') @@ -93,6 +94,7 @@ env.TagImplies('gem5 drain', ['gem5 events', 'gem5 trace']) env.TagImplies('gem5 events', ['gem5 serialize', 'gem5 trace']) env.TagImplies('gem5 serialize', 'gem5 trace') +GTest('bufval.test', 'bufval.test.cc', 'bufval.cc') GTest('byteswap.test', 'byteswap.test.cc', '../base/types.cc') GTest('globals.test', 'globals.test.cc', 'globals.cc', with_tag('gem5 serialize')) diff --git a/src/sim/bufval.cc b/src/sim/bufval.cc new file mode 100644 index 0000000000..48248d1cd4 --- /dev/null +++ b/src/sim/bufval.cc @@ -0,0 +1,159 @@ +/* + * Copyright 2022 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "sim/bufval.hh" + +#include +#include + +#include "base/intmath.hh" +#include "base/logging.hh" +#include "sim/byteswap.hh" + +namespace gem5 +{ + +std::pair +getUintX(const void *buf, std::size_t bytes, ByteOrder endian) +{ + assert(buf); + switch (bytes) { + case sizeof(std::uint64_t): + return {gtoh(*(const std::uint64_t *)buf, endian), true}; + case sizeof(std::uint32_t): + return {gtoh(*(const std::uint32_t *)buf, endian), true}; + case sizeof(std::uint16_t): + return {gtoh(*(const std::uint16_t *)buf, endian), true}; + case sizeof(std::uint8_t): + return {gtoh(*(const std::uint8_t *)buf, endian), true}; + default: + return {0, false}; + } +} + +bool +setUintX(std::uint64_t val, void *buf, std::size_t bytes, ByteOrder endian) +{ + assert(buf); + + switch (bytes) { + case sizeof(std::uint64_t): + *(std::uint64_t *)buf = htog(val, endian); + return true; + case sizeof(std::uint32_t): + *(std::uint32_t *)buf = htog(val, endian); + return true; + case sizeof(std::uint16_t): + *(std::uint16_t *)buf = htog(val, endian); + return true; + case sizeof(std::uint8_t): + *(std::uint8_t *)buf = htog(val, endian); + return true; + default: + return false; + } +} + +std::pair +printUintX(const void *buf, std::size_t bytes, ByteOrder endian) +{ + auto [val, success] = getUintX(buf, bytes, endian); + if (!success) + return {"", false}; + + std::ostringstream out; + out << "0x"; + out.width(2 * bytes); + out.fill('0'); + out.setf(std::ios::hex, std::ios::basefield); + out << val; + + return {out.str(), true}; +} + +std::string +printByteBuf(const void *buf, std::size_t bytes, ByteOrder endian, + std::size_t chunk_size) +{ + assert(buf); + + std::ostringstream out; + out << "["; + + out.width(2); + out.fill('0'); + out.setf(std::ios::hex, std::ios::basefield); + + // Bytes that fall outside of a complete chunk. Will always be MSBs. + size_t extra = bytes % chunk_size; + + const uint8_t *ptr = (const uint8_t *)buf; + int step = 1; + + if (endian == ByteOrder::big) { + step = -1; + ptr = ptr + bytes - 1; + + // If there's an incomplete chunk, start with that. + if (extra) { + bytes -= extra; + while (extra--) { + out.width(2); + out << (unsigned)*ptr; + ptr += step; + } + if (bytes) + out << " "; + } + } + + // Print all the complete chunks. + while (bytes >= chunk_size) { + for (int i = 0; i < chunk_size; i++) { + out.width(2); + out << (unsigned)*ptr; + ptr += step; + } + bytes -= chunk_size; + if (bytes) + out << " "; + } + + // Print any trailing leftovers. Only happens for little endian. + while (bytes--) { + out.width(2); + out << (unsigned)*ptr; + ptr += step; + } + + out.width(0); + out << "]"; + + return out.str(); +} + +} // namespace gem5 diff --git a/src/sim/bufval.hh b/src/sim/bufval.hh new file mode 100644 index 0000000000..cf8ead4b4f --- /dev/null +++ b/src/sim/bufval.hh @@ -0,0 +1,66 @@ +/* + * Copyright 2022 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SIM_BUFVAL_HH__ +#define __SIM_BUFVAL_HH__ + +#include +#include +#include +#include + +#include "enums/ByteOrder.hh" + +namespace gem5 +{ + +// Extract an integer with a given endianness from a variably sized buffer. +// Returns the value extraced (if any) and a bool indicating success. +std::pair getUintX(const void *buf, std::size_t bytes, + ByteOrder endian); + +// Set a variably sized buffer to an integer value with a given endianness. +// Returns whether the assignment was successful. +bool setUintX(std::uint64_t val, void *buf, std::size_t bytes, + ByteOrder endian); + +// Print an integer with a given endianness into a string from a variably +// sized buffer. Returns the string (if any) and a bool indicating success. +std::pair printUintX(const void *buf, std::size_t bytes, + ByteOrder endian); + +// Print a buffer as "chunk_size" sized groups of bytes. The endianness +// determines if the bytes are output in memory order (little) or inverse of +// memory order (big). The default is in memory order so that this acts like +// a hexdump type utility. The return value is a string holding the printed +// bytes. +std::string printByteBuf(const void *buf, std::size_t bytes, + ByteOrder endian=ByteOrder::little, std::size_t chunk_size=4); + +} // namespace gem5 + +#endif // __SIM_BUFVAL_HH__ diff --git a/src/sim/bufval.test.cc b/src/sim/bufval.test.cc new file mode 100644 index 0000000000..91c074af56 --- /dev/null +++ b/src/sim/bufval.test.cc @@ -0,0 +1,323 @@ +/* + * Copyright 2022 Google Inc + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include + +#include "sim/bufval.hh" + +using namespace gem5; + +using testing::ElementsAre; + +template +bool +pairFail(const std::pair &p) +{ + auto &[first, success] = p; + return !success; +} + +bool +pairFailU64(const std::pair &p) +{ + return pairFail(p); +} +bool +pairFailStr(const std::pair &p) +{ + return pairFail(p); +} + +template +bool +pairVal(const std::pair &p, const First &expected) +{ + auto &[first, success] = p; + return success && (first == expected); +} + +bool +pairValU64(const std::pair &p, std::uint64_t expected) +{ + return pairVal(p, expected); +} + +bool +pairValStr(const std::pair &p, const std::string &expected) +{ + return pairVal(p, expected); +} + +TEST(GetUintX, BadSize) +{ + uint8_t dummy{}; + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 0, ByteOrder::little)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 0, ByteOrder::big)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 3, ByteOrder::little)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 3, ByteOrder::big)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 5, ByteOrder::little)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 5, ByteOrder::big)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 6, ByteOrder::little)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 6, ByteOrder::big)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 7, ByteOrder::little)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 7, ByteOrder::big)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 9, ByteOrder::little)); + EXPECT_PRED1(pairFailU64, getUintX(&dummy, 9, ByteOrder::big)); +} + +TEST(GetUintX, LittleEndian) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 1, ByteOrder::little), + 0x01); + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 2, ByteOrder::little), + 0x0201); + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 4, ByteOrder::little), + 0x04030201); + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 8, ByteOrder::little), + 0x0807060504030201); +} + +TEST(GetUintX, BigEndian) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 1, ByteOrder::big), + 0x01); + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 2, ByteOrder::big), + 0x0102); + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 4, ByteOrder::big), + 0x01020304); + EXPECT_PRED2(pairValU64, getUintX(buf.data(), 8, ByteOrder::big), + 0x0102030405060708); +} + +TEST(SetUintX, BadSize) +{ + uint8_t dummy{}; + EXPECT_FALSE(setUintX(0, &dummy, 0, ByteOrder::little)); + EXPECT_FALSE(setUintX(0, &dummy, 0, ByteOrder::big)); + EXPECT_FALSE(setUintX(0, &dummy, 3, ByteOrder::little)); + EXPECT_FALSE(setUintX(0, &dummy, 3, ByteOrder::big)); + EXPECT_FALSE(setUintX(0, &dummy, 5, ByteOrder::little)); + EXPECT_FALSE(setUintX(0, &dummy, 5, ByteOrder::big)); + EXPECT_FALSE(setUintX(0, &dummy, 6, ByteOrder::little)); + EXPECT_FALSE(setUintX(0, &dummy, 6, ByteOrder::big)); + EXPECT_FALSE(setUintX(0, &dummy, 7, ByteOrder::little)); + EXPECT_FALSE(setUintX(0, &dummy, 7, ByteOrder::big)); + EXPECT_FALSE(setUintX(0, &dummy, 9, ByteOrder::little)); + EXPECT_FALSE(setUintX(0, &dummy, 9, ByteOrder::big)); +} + +TEST(SetUintX, LittleEndian) +{ + const std::array orig_buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + auto buf = orig_buf; + + EXPECT_TRUE(setUintX(0xf1, buf.data(), 1, ByteOrder::little)); + EXPECT_THAT(buf, + ElementsAre(0xf1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9)); + EXPECT_TRUE(setUintX(0xe2e1, buf.data(), 2, ByteOrder::little)); + EXPECT_THAT(buf, + ElementsAre(0xe1, 0xe2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9)); + EXPECT_TRUE(setUintX(0xd4d3d2d1, buf.data(), 4, ByteOrder::little)); + EXPECT_THAT(buf, + ElementsAre(0xd1, 0xd2, 0xd3, 0xd4, 0x5, 0x6, 0x7, 0x8, 0x9)); + EXPECT_TRUE(setUintX(0xc8c7c6c5c4c3c2c1, buf.data(), 8, + ByteOrder::little)); + EXPECT_THAT(buf, + ElementsAre(0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0x9)); +} + +TEST(SetUintX, BigEndian) +{ + const std::array orig_buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + auto buf = orig_buf; + + EXPECT_TRUE(setUintX(0xf1, buf.data(), 1, ByteOrder::big)); + EXPECT_THAT(buf, + ElementsAre(0xf1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9)); + EXPECT_TRUE(setUintX(0xe1e2, buf.data(), 2, ByteOrder::big)); + EXPECT_THAT(buf, + ElementsAre(0xe1, 0xe2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9)); + EXPECT_TRUE(setUintX(0xd1d2d3d4, buf.data(), 4, ByteOrder::big)); + EXPECT_THAT(buf, + ElementsAre(0xd1, 0xd2, 0xd3, 0xd4, 0x5, 0x6, 0x7, 0x8, 0x9)); + EXPECT_TRUE(setUintX(0xc1c2c3c4c5c6c7c8, buf.data(), 8, ByteOrder::big)); + EXPECT_THAT(buf, + ElementsAre(0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0x9)); +} + +TEST(PrintUintX, BadSize) +{ + uint8_t dummy{}; + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 0, ByteOrder::little)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 0, ByteOrder::big)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 3, ByteOrder::little)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 3, ByteOrder::big)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 5, ByteOrder::little)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 5, ByteOrder::big)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 6, ByteOrder::little)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 6, ByteOrder::big)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 7, ByteOrder::little)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 7, ByteOrder::big)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 9, ByteOrder::little)); + EXPECT_PRED1(pairFailStr, printUintX(&dummy, 9, ByteOrder::big)); +} + +TEST(PrintUintX, LittleEndian) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 1, ByteOrder::little), + "0x01"); + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 2, ByteOrder::little), + "0x0201"); + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 4, ByteOrder::little), + "0x04030201"); + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 8, ByteOrder::little), + "0x0807060504030201"); +} + +TEST(PrintUintX, BigEndian) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9}; + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 1, ByteOrder::big), + "0x01"); + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 2, ByteOrder::big), + "0x0102"); + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 4, ByteOrder::big), + "0x01020304"); + EXPECT_PRED2(pairValStr, printUintX(buf.data(), 8, ByteOrder::big), + "0x0102030405060708"); +} + +TEST(PrintByteBuf, LittleEndian) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xa}; + + EXPECT_EQ(printByteBuf(buf.data(), 0, ByteOrder::little, 3), "[]"); + EXPECT_EQ(printByteBuf(buf.data(), 1, ByteOrder::little, 3), "[01]"); + EXPECT_EQ(printByteBuf(buf.data(), 2, ByteOrder::little, 3), "[0102]"); + EXPECT_EQ(printByteBuf(buf.data(), 3, ByteOrder::little, 3), + "[010203]"); + EXPECT_EQ(printByteBuf(buf.data(), 4, ByteOrder::little, 3), + "[010203 04]"); + EXPECT_EQ(printByteBuf(buf.data(), 5, ByteOrder::little, 3), + "[010203 0405]"); + EXPECT_EQ(printByteBuf(buf.data(), 6, ByteOrder::little, 3), + "[010203 040506]"); + EXPECT_EQ(printByteBuf(buf.data(), 7, ByteOrder::little, 3), + "[010203 040506 07]"); + EXPECT_EQ(printByteBuf(buf.data(), 8, ByteOrder::little, 3), + "[010203 040506 0708]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 3), + "[010203 040506 07080a]"); +} + +TEST(PrintByteBuf, BigEndian) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xa}; + + EXPECT_EQ(printByteBuf(buf.data(), 0, ByteOrder::big, 3), "[]"); + EXPECT_EQ(printByteBuf(buf.data(), 1, ByteOrder::big, 3), "[01]"); + EXPECT_EQ(printByteBuf(buf.data(), 2, ByteOrder::big, 3), "[0201]"); + EXPECT_EQ(printByteBuf(buf.data(), 3, ByteOrder::big, 3), "[030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 4, ByteOrder::big, 3), + "[04 030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 5, ByteOrder::big, 3), + "[0504 030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 6, ByteOrder::big, 3), + "[060504 030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 7, ByteOrder::big, 3), + "[07 060504 030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 8, ByteOrder::big, 3), + "[0807 060504 030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 3), + "[0a0807 060504 030201]"); +} + +TEST(PrintByteBuf, ChunkSize) +{ + const std::array buf = + {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0xa}; + + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 1), + "[01 02 03 04 05 06 07 08 0a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 2), + "[0102 0304 0506 0708 0a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 3), + "[010203 040506 07080a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 4), + "[01020304 05060708 0a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 5), + "[0102030405 0607080a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 6), + "[010203040506 07080a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 7), + "[01020304050607 080a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 8), + "[0102030405060708 0a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 9), + "[01020304050607080a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 10), + "[01020304050607080a]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::little, 100), + "[01020304050607080a]"); + + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 1), + "[0a 08 07 06 05 04 03 02 01]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 2), + "[0a 0807 0605 0403 0201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 3), + "[0a0807 060504 030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 4), + "[0a 08070605 04030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 5), + "[0a080706 0504030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 6), + "[0a0807 060504030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 7), + "[0a08 07060504030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 8), + "[0a 0807060504030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 9), + "[0a0807060504030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 10), + "[0a0807060504030201]"); + EXPECT_EQ(printByteBuf(buf.data(), 9, ByteOrder::big, 100), + "[0a0807060504030201]"); +}