aboutsummaryrefslogtreecommitdiff
path: root/src/util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.cpp')
-rw-r--r--src/util.cpp551
1 files changed, 4 insertions, 547 deletions
diff --git a/src/util.cpp b/src/util.cpp
index 80d27d5826..5a4e187f9e 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -11,13 +11,13 @@
#include "chainparamsbase.h"
#include "random.h"
+#include "serialize.h"
#include "sync.h"
-#include "uint256.h"
+#include "utilstrencodings.h"
+#include "utiltime.h"
#include <stdarg.h>
-#include <boost/date_time/posix_time/posix_time.hpp>
-
#ifndef WIN32
// for posix_fallocate
#ifdef __linux__
@@ -75,6 +75,7 @@
#include <boost/foreach.hpp>
#include <boost/program_options/detail/config_file.hpp>
#include <boost/program_options/parsers.hpp>
+#include <boost/thread.hpp>
#include <openssl/crypto.h>
#include <openssl/rand.h>
@@ -243,148 +244,6 @@ int LogPrintStr(const std::string &str)
return ret;
}
-string FormatMoney(int64_t n, bool fPlus)
-{
- // Note: not using straight sprintf here because we do NOT want
- // localized number formatting.
- int64_t n_abs = (n > 0 ? n : -n);
- int64_t quotient = n_abs/COIN;
- int64_t remainder = n_abs%COIN;
- string str = strprintf("%d.%08d", quotient, remainder);
-
- // Right-trim excess zeros before the decimal point:
- int nTrim = 0;
- for (int i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
- ++nTrim;
- if (nTrim)
- str.erase(str.size()-nTrim, nTrim);
-
- if (n < 0)
- str.insert((unsigned int)0, 1, '-');
- else if (fPlus && n > 0)
- str.insert((unsigned int)0, 1, '+');
- return str;
-}
-
-
-bool ParseMoney(const string& str, int64_t& nRet)
-{
- return ParseMoney(str.c_str(), nRet);
-}
-
-bool ParseMoney(const char* pszIn, int64_t& nRet)
-{
- string strWhole;
- int64_t nUnits = 0;
- const char* p = pszIn;
- while (isspace(*p))
- p++;
- for (; *p; p++)
- {
- if (*p == '.')
- {
- p++;
- int64_t nMult = CENT*10;
- while (isdigit(*p) && (nMult > 0))
- {
- nUnits += nMult * (*p++ - '0');
- nMult /= 10;
- }
- break;
- }
- if (isspace(*p))
- break;
- if (!isdigit(*p))
- return false;
- strWhole.insert(strWhole.end(), *p);
- }
- for (; *p; p++)
- if (!isspace(*p))
- return false;
- if (strWhole.size() > 10) // guard against 63 bit overflow
- return false;
- if (nUnits < 0 || nUnits > COIN)
- return false;
- int64_t nWhole = atoi64(strWhole);
- int64_t nValue = nWhole*COIN + nUnits;
-
- nRet = nValue;
- return true;
-}
-
-// safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
-// even possibly remotely dangerous like & or >
-static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@");
-string SanitizeString(const string& str)
-{
- string strResult;
- for (std::string::size_type i = 0; i < str.size(); i++)
- {
- if (safeChars.find(str[i]) != std::string::npos)
- strResult.push_back(str[i]);
- }
- return strResult;
-}
-
-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,
- 0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
- -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-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,-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, };
-
-signed char HexDigit(char c)
-{
- return p_util_hexdigit[(unsigned char)c];
-}
-
-bool IsHex(const string& str)
-{
- BOOST_FOREACH(char c, str)
- {
- if (HexDigit(c) < 0)
- return false;
- }
- return (str.size() > 0) && (str.size()%2 == 0);
-}
-
-vector<unsigned char> ParseHex(const char* psz)
-{
- // convert hex dump to vector
- vector<unsigned char> vch;
- while (true)
- {
- while (isspace(*psz))
- psz++;
- signed char c = HexDigit(*psz++);
- if (c == (signed char)-1)
- break;
- unsigned char n = (c << 4);
- c = HexDigit(*psz++);
- if (c == (signed char)-1)
- break;
- n |= c;
- vch.push_back(n);
- }
- return vch;
-}
-
-vector<unsigned char> ParseHex(const string& str)
-{
- return ParseHex(str.c_str());
-}
-
static void InterpretNegativeSetting(string name, map<string, string>& mapSettingsRet)
{
// interpret -nofoo as -foo=0 (and -nofoo=0 as -foo=1) as long as -foo not set
@@ -482,334 +341,6 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue)
return SoftSetArg(strArg, std::string("0"));
}
-
-string EncodeBase64(const unsigned char* pch, size_t len)
-{
- static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- string strRet="";
- strRet.reserve((len+2)/3*4);
-
- int mode=0, left=0;
- const unsigned char *pchEnd = pch+len;
-
- while (pch<pchEnd)
- {
- int enc = *(pch++);
- switch (mode)
- {
- case 0: // we have no bits
- strRet += pbase64[enc >> 2];
- left = (enc & 3) << 4;
- mode = 1;
- break;
-
- case 1: // we have two bits
- strRet += pbase64[left | (enc >> 4)];
- left = (enc & 15) << 2;
- mode = 2;
- break;
-
- case 2: // we have four bits
- strRet += pbase64[left | (enc >> 6)];
- strRet += pbase64[enc & 63];
- mode = 0;
- break;
- }
- }
-
- if (mode)
- {
- strRet += pbase64[left];
- strRet += '=';
- if (mode == 1)
- strRet += '=';
- }
-
- return strRet;
-}
-
-string EncodeBase64(const string& str)
-{
- return EncodeBase64((const unsigned char*)str.c_str(), str.size());
-}
-
-vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
-{
- static const int decode64_table[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, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
- -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
- 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51, -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, -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
- };
-
- if (pfInvalid)
- *pfInvalid = false;
-
- vector<unsigned char> vchRet;
- vchRet.reserve(strlen(p)*3/4);
-
- int mode = 0;
- int left = 0;
-
- while (1)
- {
- int dec = decode64_table[(unsigned char)*p];
- if (dec == -1) break;
- p++;
- switch (mode)
- {
- case 0: // we have no bits and get 6
- left = dec;
- mode = 1;
- break;
-
- case 1: // we have 6 bits and keep 4
- vchRet.push_back((left<<2) | (dec>>4));
- left = dec & 15;
- mode = 2;
- break;
-
- case 2: // we have 4 bits and get 6, we keep 2
- vchRet.push_back((left<<4) | (dec>>2));
- left = dec & 3;
- mode = 3;
- break;
-
- case 3: // we have 2 bits and get 6
- vchRet.push_back((left<<6) | dec);
- mode = 0;
- break;
- }
- }
-
- if (pfInvalid)
- switch (mode)
- {
- case 0: // 4n base64 characters processed: ok
- break;
-
- case 1: // 4n+1 base64 character processed: impossible
- *pfInvalid = true;
- break;
-
- case 2: // 4n+2 base64 characters processed: require '=='
- if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
- *pfInvalid = true;
- break;
-
- case 3: // 4n+3 base64 characters processed: require '='
- if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
- *pfInvalid = true;
- break;
- }
-
- return vchRet;
-}
-
-string DecodeBase64(const string& str)
-{
- vector<unsigned char> vchRet = DecodeBase64(str.c_str());
- return string((const char*)&vchRet[0], vchRet.size());
-}
-
-string EncodeBase32(const unsigned char* pch, size_t len)
-{
- static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
-
- string strRet="";
- strRet.reserve((len+4)/5*8);
-
- int mode=0, left=0;
- const unsigned char *pchEnd = pch+len;
-
- while (pch<pchEnd)
- {
- int enc = *(pch++);
- switch (mode)
- {
- case 0: // we have no bits
- strRet += pbase32[enc >> 3];
- left = (enc & 7) << 2;
- mode = 1;
- break;
-
- case 1: // we have three bits
- strRet += pbase32[left | (enc >> 6)];
- strRet += pbase32[(enc >> 1) & 31];
- left = (enc & 1) << 4;
- mode = 2;
- break;
-
- case 2: // we have one bit
- strRet += pbase32[left | (enc >> 4)];
- left = (enc & 15) << 1;
- mode = 3;
- break;
-
- case 3: // we have four bits
- strRet += pbase32[left | (enc >> 7)];
- strRet += pbase32[(enc >> 2) & 31];
- left = (enc & 3) << 3;
- mode = 4;
- break;
-
- case 4: // we have two bits
- strRet += pbase32[left | (enc >> 5)];
- strRet += pbase32[enc & 31];
- mode = 0;
- }
- }
-
- static const int nPadding[5] = {0, 6, 4, 3, 1};
- if (mode)
- {
- strRet += pbase32[left];
- for (int n=0; n<nPadding[mode]; n++)
- strRet += '=';
- }
-
- return strRet;
-}
-
-string EncodeBase32(const string& str)
-{
- return EncodeBase32((const unsigned char*)str.c_str(), str.size());
-}
-
-vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
-{
- static const int decode32_table[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, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2,
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, -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, -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
- };
-
- if (pfInvalid)
- *pfInvalid = false;
-
- vector<unsigned char> vchRet;
- vchRet.reserve((strlen(p))*5/8);
-
- int mode = 0;
- int left = 0;
-
- while (1)
- {
- int dec = decode32_table[(unsigned char)*p];
- if (dec == -1) break;
- p++;
- switch (mode)
- {
- case 0: // we have no bits and get 5
- left = dec;
- mode = 1;
- break;
-
- case 1: // we have 5 bits and keep 2
- vchRet.push_back((left<<3) | (dec>>2));
- left = dec & 3;
- mode = 2;
- break;
-
- case 2: // we have 2 bits and keep 7
- left = left << 5 | dec;
- mode = 3;
- break;
-
- case 3: // we have 7 bits and keep 4
- vchRet.push_back((left<<1) | (dec>>4));
- left = dec & 15;
- mode = 4;
- break;
-
- case 4: // we have 4 bits, and keep 1
- vchRet.push_back((left<<4) | (dec>>1));
- left = dec & 1;
- mode = 5;
- break;
-
- case 5: // we have 1 bit, and keep 6
- left = left << 5 | dec;
- mode = 6;
- break;
-
- case 6: // we have 6 bits, and keep 3
- vchRet.push_back((left<<2) | (dec>>3));
- left = dec & 7;
- mode = 7;
- break;
-
- case 7: // we have 3 bits, and keep 0
- vchRet.push_back((left<<5) | dec);
- mode = 0;
- break;
- }
- }
-
- if (pfInvalid)
- switch (mode)
- {
- case 0: // 8n base32 characters processed: ok
- break;
-
- case 1: // 8n+1 base32 characters processed: impossible
- case 3: // +3
- case 6: // +6
- *pfInvalid = true;
- break;
-
- case 2: // 8n+2 base32 characters processed: require '======'
- if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
- *pfInvalid = true;
- break;
-
- case 4: // 8n+4 base32 characters processed: require '===='
- if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
- *pfInvalid = true;
- break;
-
- case 5: // 8n+5 base32 characters processed: require '==='
- if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
- *pfInvalid = true;
- break;
-
- case 7: // 8n+7 base32 characters processed: require '='
- if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
- *pfInvalid = true;
- break;
- }
-
- return vchRet;
-}
-
-string DecodeBase32(const string& str)
-{
- vector<unsigned char> vchRet = DecodeBase32(str.c_str());
- return string((const char*)&vchRet[0], vchRet.size());
-}
-
static std::string FormatException(std::exception* pex, const char* pszThread)
{
#ifdef WIN32
@@ -1101,21 +632,6 @@ void ShrinkDebugFile()
fclose(file);
}
-static int64_t nMockTime = 0; // For unit testing
-
-int64_t GetTime()
-{
- if (nMockTime) return nMockTime;
-
- return time(NULL);
-}
-
-void SetMockTime(int64_t nMockTimeIn)
-{
- nMockTime = nMockTimeIn;
-}
-
-
#ifdef WIN32
boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate)
{
@@ -1186,20 +702,6 @@ void RenameThread(const char* name)
#endif
}
-bool ParseInt32(const std::string& str, int32_t *out)
-{
- char *endp = NULL;
- errno = 0; // strtol will not set errno if valid
- long int n = strtol(str.c_str(), &endp, 10);
- if(out) *out = (int)n;
- // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
- // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
- // platforms the size of these types may be different.
- return endp && *endp == 0 && !errno &&
- n >= std::numeric_limits<int32_t>::min() &&
- n <= std::numeric_limits<int32_t>::max();
-}
-
void SetupEnvironment()
{
#ifndef WIN32
@@ -1217,51 +719,6 @@ void SetupEnvironment()
#endif
}
-std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
-{
- // std::locale takes ownership of the pointer
- std::locale loc(std::locale::classic(), new boost::posix_time::time_facet(pszFormat));
- std::stringstream ss;
- ss.imbue(loc);
- ss << boost::posix_time::from_time_t(nTime);
- return ss.str();
-}
-
-std::string FormatParagraph(const std::string in, size_t width, size_t indent)
-{
- std::stringstream out;
- size_t col = 0;
- size_t ptr = 0;
- while(ptr < in.size())
- {
- // Find beginning of next word
- ptr = in.find_first_not_of(' ', ptr);
- if (ptr == std::string::npos)
- break;
- // Find end of next word
- size_t endword = in.find_first_of(' ', ptr);
- if (endword == std::string::npos)
- endword = in.size();
- // Add newline and indentation if this wraps over the allowed width
- if (col > 0)
- {
- if ((col + endword - ptr) > width)
- {
- out << '\n';
- for(size_t i=0; i<indent; ++i)
- out << ' ';
- col = 0;
- } else
- out << ' ';
- }
- // Append word
- out << in.substr(ptr, endword - ptr);
- col += endword - ptr;
- ptr = endword;
- }
- return out.str();
-}
-
void SetThreadPriority(int nPriority)
{
#ifdef WIN32