aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2018-05-17 16:53:11 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2018-05-17 16:53:11 +0800
commit8cad0d8e9a1c1437102c58ed761973b36617cbc3 (patch)
tree7b23c7330e95f4db6092007a5e8ce471e958dd80
parentb33f6fdaa09d89386b7fecc142df922d723b6f7d (diff)
downloadtangerine-mcl-8cad0d8e9a1c1437102c58ed761973b36617cbc3.tar.gz
tangerine-mcl-8cad0d8e9a1c1437102c58ed761973b36617cbc3.tar.zst
tangerine-mcl-8cad0d8e9a1c1437102c58ed761973b36617cbc3.zip
add hexToArray
-rw-r--r--src/conversion.hpp36
-rw-r--r--src/fp.cpp20
-rw-r--r--test/conversion_test.cpp4
3 files changed, 50 insertions, 10 deletions
diff --git a/src/conversion.hpp b/src/conversion.hpp
index 9292a72..039af4a 100644
--- a/src/conversion.hpp
+++ b/src/conversion.hpp
@@ -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;
diff --git a/src/fp.cpp b/src/fp.cpp
index bcbb23f..b015226 100644
--- a/src/fp.cpp
+++ b/src/fp.cpp
@@ -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;
}
diff --git a/test/conversion_test.cpp b/test/conversion_test.cpp
index 3f1f959..41b4203 100644
--- a/test/conversion_test.cpp
+++ b/test/conversion_test.cpp
@@ -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);
}