From dcd5404185e8212d8446a475bd2e0cf5747e5780 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Fri, 30 Apr 2021 15:09:26 +0900 Subject: [PATCH] setArray on big endian --- include/mcl/vint.hpp | 25 +++++++---- test/vint_test.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 8 deletions(-) diff --git a/include/mcl/vint.hpp b/include/mcl/vint.hpp index aed0880..e642cb6 100644 --- a/include/mcl/vint.hpp +++ b/include/mcl/vint.hpp @@ -1176,7 +1176,7 @@ public: } /* set positive value - @note assume little endian system + @note x is treated as a little endian */ template void setArray(bool *pb, const S *x, size_t size) @@ -1190,14 +1190,23 @@ public: size_t unitSize = (sizeof(S) * size + sizeof(Unit) - 1) / sizeof(Unit); buf_.alloc(pb, unitSize); if (!*pb) return; - char *dst = (char *)&buf_[0]; - const char *src = (const char *)x; + size_t pos = 0; size_t i = 0; - for (; i < sizeof(S) * size; i++) { - dst[i] = src[i]; - } - for (; i < sizeof(Unit) * unitSize; i++) { - dst[i] = 0; + while (i < unitSize) { + if (sizeof(Unit) < sizeof(S)) { + S s = x[pos++]; + for (size_t j = 0; j < sizeof(S); j += sizeof(Unit)) { + buf_[i++] = Unit(s); + s >>= sizeof(Unit) * 8; + } + } else { + Unit u = 0; + for (size_t j = 0; j < sizeof(Unit); j += sizeof(S)) { + S s = (pos < size) ? x[pos++] : 0; + u |= Unit(s) << (j * 8); + } + buf_[i++] = u; + } } trim(unitSize); } diff --git a/test/vint_test.cpp b/test/vint_test.cpp index 39c3688..6f34ede 100644 --- a/test/vint_test.cpp +++ b/test/vint_test.cpp @@ -25,6 +25,111 @@ struct V { unsigned int p[16]; }; +CYBOZU_TEST_AUTO(setArray_u8) +{ + struct { + uint8_t x[12]; + size_t size; + const char *s; + } tbl[] = { + { + { 0x12 }, + 1, + "12" + }, + { + { 0x12, 0x34 }, + 2, + "3412" + }, + { + { 0x12, 0x34, 0x56 }, + 3, + "563412", + }, + { + { 0x12, 0x34, 0x56, 0x78 }, + 4, + "78563412", + }, + { + { 0x12, 0x34, 0x56, 0x78, 0x9a }, + 5, + "9a78563412", + }, + { + { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }, + 8, + "8877665544332211", + }, + { + { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99 }, + 9, + "998877665544332211", + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint v; + v.setArray(tbl[i].x, tbl[i].size); + CYBOZU_TEST_EQUAL(v.getStr(16), tbl[i].s); + } +} + +CYBOZU_TEST_AUTO(setArray_u32) +{ + struct { + uint32_t x[4]; + size_t size; + const char *s; + } tbl[] = { + { + { 0x12345678 }, + 1, + "12345678" + }, + { + { 0x12345678, 0x11223344 }, + 2, + "1122334412345678" + }, + { + { 0x12345678, 0x11223344, 0x55667788 }, + 3, + "556677881122334412345678" + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint v; + v.setArray(tbl[i].x, tbl[i].size); + CYBOZU_TEST_EQUAL(v.getStr(16), tbl[i].s); + } +} + +CYBOZU_TEST_AUTO(setArray_u64) +{ + struct { + uint64_t x[2]; + size_t size; + const char *s; + } tbl[] = { + { + { uint64_t(0x1122334455667788ull) }, + 1, + "1122334455667788" + }, + { + { uint64_t(0x1122334455667788ull), uint64_t(0x8877665544332211ull) }, + 2, + "88776655443322111122334455667788" + }, + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + Vint v; + v.setArray(tbl[i].x, tbl[i].size); + CYBOZU_TEST_EQUAL(v.getStr(16), tbl[i].s); + } +} + CYBOZU_TEST_AUTO(addSub) { static const struct {