Make util phexdigit array reusable

class template base_uint had its own private lookup table.
This is saving 256 bytes per instantiation.

The result is not spectacular as bitcoin-qt has only shrinked of
about 1Kb but it is still valid improvement.

Also, I have replaced a for loop with a memset() call.

Made CBigNum::SetHex() use the new HexDigit() function.

Signed-off-by: Olivier Langlois <olivier@olivierlanglois.net>
This commit is contained in:
Olivier Langlois 2013-10-10 12:35:51 -04:00
parent 15b48ab036
commit f171ec0c7d
5 changed files with 34 additions and 14 deletions

View file

@ -347,13 +347,13 @@ public:
psz++; psz++;
// hex string to bignum // hex string to bignum
static const signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
*this = 0; *this = 0;
while (isxdigit(*psz)) int n;
while ((n = HexDigit(*psz)) != -1)
{ {
*this <<= 4; *this <<= 4;
int n = phexdigit[(unsigned char)*psz++];
*this += n; *this += n;
++psz;
} }
if (fNegative) if (fNegative)
*this = 0 - *this; *this = 0 - *this;

View file

@ -175,4 +175,12 @@ BOOST_AUTO_TEST_CASE(bignum_SetCompact)
BOOST_CHECK_EQUAL(num.GetCompact(), 0xff123456U); BOOST_CHECK_EQUAL(num.GetCompact(), 0xff123456U);
} }
BOOST_AUTO_TEST_CASE(bignum_SetHex)
{
std::string hexStr = "deecf97fd890808b9cc0f1b6a3e7a60b400f52710e6ad075b1340755bfa58cc9";
CBigNum num;
num.SetHex(hexStr);
BOOST_CHECK_EQUAL(num.GetHex(), hexStr);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,6 +1,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include "uint256.h" #include "uint256.h"
#include <string>
BOOST_AUTO_TEST_SUITE(uint256_tests) BOOST_AUTO_TEST_SUITE(uint256_tests)
@ -15,4 +16,12 @@ BOOST_AUTO_TEST_CASE(uint256_equality)
BOOST_CHECK(num1+num2 == num3+num2); BOOST_CHECK(num1+num2 == num3+num2);
} }
BOOST_AUTO_TEST_CASE(uint256_hex)
{
std::string hexStr = "d35583ed493a5eee756931353144f558e6a9ab3ad6024a63ced7f10daf7faad9";
uint256 num1;
num1.SetHex(hexStr);
BOOST_CHECK(num1.GetHex() == hexStr);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -14,7 +14,12 @@
typedef long long int64; typedef long long int64;
typedef unsigned long long uint64; typedef unsigned long long uint64;
extern const signed char p_util_hexdigit[256]; // defined in util.cpp
inline signed char HexDigit(char c)
{
return p_util_hexdigit[(unsigned char)c];
}
inline int Testuint256AdHoc(std::vector<std::string> vArg); inline int Testuint256AdHoc(std::vector<std::string> vArg);
@ -305,8 +310,7 @@ public:
void SetHex(const char* psz) void SetHex(const char* psz)
{ {
for (int i = 0; i < WIDTH; i++) memset(pn,0,sizeof(pn));
pn[i] = 0;
// skip leading spaces // skip leading spaces
while (isspace(*psz)) while (isspace(*psz))
@ -317,19 +321,18 @@ public:
psz += 2; psz += 2;
// hex string to uint // hex string to uint
static const unsigned char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
const char* pbegin = psz; const char* pbegin = psz;
while (phexdigit[(unsigned char)*psz] || *psz == '0') while (::HexDigit(*psz) != -1)
psz++; psz++;
psz--; psz--;
unsigned char* p1 = (unsigned char*)pn; unsigned char* p1 = (unsigned char*)pn;
unsigned char* pend = p1 + WIDTH * 4; unsigned char* pend = p1 + WIDTH * 4;
while (psz >= pbegin && p1 < pend) while (psz >= pbegin && p1 < pend)
{ {
*p1 = phexdigit[(unsigned char)*psz--]; *p1 = ::HexDigit(*psz--);
if (psz >= pbegin) if (psz >= pbegin)
{ {
*p1 |= (phexdigit[(unsigned char)*psz--] << 4); *p1 |= ((unsigned char)::HexDigit(*psz--) << 4);
p1++; p1++;
} }
} }

View file

@ -455,7 +455,7 @@ bool ParseMoney(const char* pszIn, int64& nRet)
} }
static const signed char phexdigit[256] = const signed char p_util_hexdigit[256] =
{ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
@ -475,9 +475,9 @@ static const signed char phexdigit[256] =
bool IsHex(const string& str) bool IsHex(const string& str)
{ {
BOOST_FOREACH(unsigned char c, str) BOOST_FOREACH(char c, str)
{ {
if (phexdigit[c] < 0) if (HexDigit(c) < 0)
return false; return false;
} }
return (str.size() > 0) && (str.size()%2 == 0); return (str.size() > 0) && (str.size()%2 == 0);
@ -491,11 +491,11 @@ vector<unsigned char> ParseHex(const char* psz)
{ {
while (isspace(*psz)) while (isspace(*psz))
psz++; psz++;
signed char c = phexdigit[(unsigned char)*psz++]; signed char c = HexDigit(*psz++);
if (c == (signed char)-1) if (c == (signed char)-1)
break; break;
unsigned char n = (c << 4); unsigned char n = (c << 4);
c = phexdigit[(unsigned char)*psz++]; c = HexDigit(*psz++);
if (c == (signed char)-1) if (c == (signed char)-1)
break; break;
n |= c; n |= c;