add hexToArray

dev
MITSUNARI Shigeo 7 years ago
parent b33f6fdaa0
commit 8cad0d8e9a
  1. 36
      src/conversion.hpp
  2. 20
      src/fp.cpp
  3. 4
      test/conversion_test.cpp

@ -111,6 +111,32 @@ void fromStr16(T *x, size_t xn, const char *str, size_t strLen)
for (size_t i = requireSize; i < xn; i++) x[i] = 0;
}
/*
convert hex string to x[0..xn)
hex string = [0-9a-fA-F]+
*/
template<class UT>
inline size_t hexToArray(UT *x, size_t maxN, const char *buf, size_t bufSize)
{
if (bufSize == 0) return 0;
const size_t unitLen = sizeof(UT) * 2;
const size_t q = bufSize / unitLen;
const size_t r = bufSize % unitLen;
const size_t requireSize = q + (r ? 1 : 0);
if (maxN < requireSize) return 0;
for (size_t i = 0; i < q; i++) {
bool b;
x[i] = cybozu::hextoi(&b, &buf[r + (q - 1 - i) * unitLen], unitLen);
if (!b) return 0;
}
if (r) {
bool b;
x[q] = cybozu::hextoi(&b, buf, r);
if (!b) return 0;
}
return requireSize;
}
namespace local {
/*
@ -225,14 +251,14 @@ inline size_t arrayToDec(char *buf, size_t bufSize, const UT *x, size_t xn)
return written num if success else 0
*/
template<class UT>
inline size_t convertDecToArray(UT *_x, size_t xSize, const char *buf, size_t bufSize)
inline size_t decToArray(UT *_x, size_t maxN, const char *buf, size_t bufSize)
{
assert(sizeof(UT) == 4 || sizeof(UT) == 8);
const size_t width = 9;
const uint32_t i1e9 = 1000000000U;
if (xSize == 0) return 0;
if (maxN == 0) return 0;
if (sizeof(UT) == 8) {
xSize *= 2;
maxN *= 2;
}
uint32_t *x = reinterpret_cast<uint32_t*>(_x);
size_t xn = 1;
@ -245,12 +271,12 @@ inline size_t convertDecToArray(UT *_x, size_t xSize, const char *buf, size_t bu
if (!b) return 0;
uint32_t H = local::mulU32(x, x, xn, i1e9);
if (H > 0) {
if (xn == xSize) return 0;
if (xn == maxN) return 0;
x[xn++] = H;
}
H = local::addU32(x, xn, v);
if (H > 0) {
if (xn == xSize) return 0;
if (xn == maxN) return 0;
x[xn++] = H;
}
buf += n;

@ -647,14 +647,28 @@ bool strToArray(bool *pIsMinus, Unit *x, size_t xN, const char *buf, size_t bufS
ioMode &= 0xff;
size_t readSize;
if (!parsePrefix(&readSize, pIsMinus, &ioMode, buf, bufSize)) return false;
#if 0
#else
#if 1
if (ioMode == 10) {
size_t n = mcl::fp::decToArray(x, xN, buf + readSize, bufSize - readSize);
if (n == 0) return false;
for (size_t i = n; i < xN; i++) {
x[i] = 0;
}
return true;
} else if (ioMode == 16) {
size_t n = mcl::fp::hexToArray(x, xN, buf + readSize, bufSize - readSize);
if (n == 0) return false;
for (size_t i = n; i < xN; i++) {
x[i] = 0;
}
return true;
}
#endif
mpz_class mx;
if (!gmp::setStr(mx, std::string(buf + readSize, bufSize - readSize), ioMode)) {
return false;
}
gmp::getArray(x, xN, mx);
#endif
return true;
}

@ -33,7 +33,7 @@ CYBOZU_TEST_AUTO(arrayToDec)
CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n);
const size_t maxN = 32;
uint32_t xx[maxN] = {};
size_t xn = mcl::fp::convertDecToArray(xx, maxN, str, strLen);
size_t xn = mcl::fp::decToArray(xx, maxN, str, strLen);
CYBOZU_TEST_EQUAL(xn, tbl[i].xn);
CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn);
}
@ -50,7 +50,7 @@ CYBOZU_TEST_AUTO(arrayToDec)
CYBOZU_TEST_EQUAL_ARRAY(buf + bufSize - n, str, n);
const size_t maxN = 32;
uint64_t xx[maxN] = {};
size_t xxn = mcl::fp::convertDecToArray(xx, maxN, str, strLen);
size_t xxn = mcl::fp::decToArray(xx, maxN, str, strLen);
CYBOZU_TEST_EQUAL(xxn, xn);
CYBOZU_TEST_EQUAL_ARRAY(xx, x, xn);
}

Loading…
Cancel
Save