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:
parent
15b48ab036
commit
f171ec0c7d
5 changed files with 34 additions and 14 deletions
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
src/util.cpp
10
src/util.cpp
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue