Remove useless inline
[novacoin.git] / src / util.cpp
index b1a7f79..aac1678 100644 (file)
@@ -7,26 +7,16 @@
 #include "sync.h"
 #include "version.h"
 #include "ui_interface.h"
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/case_conv.hpp> // for to_lower()
-
-// Work around clang compilation problem in Boost 1.46:
-// /usr/include/boost/program_options/detail/config_file.hpp:163:17: error: call to function 'to_internal' that is neither visible in the template definition nor found by argument-dependent lookup
-// See also: http://stackoverflow.com/questions/10020179/compilation-fail-in-boost-librairies-program-options
-//           http://clang.debian.net/status.php?version=3.0&key=CANNOT_FIND_FUNCTION
-namespace boost {
-    namespace program_options {
-        string to_internal(const string&);
-    }
-}
+
+#include <random>
 
 #include <boost/program_options/detail/config_file.hpp>
 #include <boost/program_options/parsers.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
-
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/thread.hpp>
+
 #include <openssl/crypto.h>
 #include <openssl/rand.h>
 
@@ -46,14 +36,13 @@ namespace boost {
 #include <io.h> /* for _commit */
 #include "shlobj.h"
 #elif defined(__linux__)
-# include <sys/prctl.h>
+#include <sys/prctl.h>
 #endif
 
 #if !defined(WIN32) && !defined(ANDROID)
 #include <execinfo.h>
 #endif
 
-
 using namespace std;
 namespace bt = boost::posix_time;
 
@@ -196,10 +185,15 @@ int GetRandInt(int nMax)
 uint256 GetRandHash()
 {
     uint256 hash;
-    RAND_bytes((unsigned char*)&hash, sizeof(hash));
+    RAND_bytes(hash.begin(), hash.size());
     return hash;
 }
 
+void FillRand(uint8_t *buffer, size_t nCount)
+{
+    RAND_bytes(buffer, nCount);
+}
+
 static FILE* fileout = NULL;
 
 inline int OutputDebugStringF(const char* pszFormat, ...)
@@ -371,13 +365,14 @@ void ParseString(const string& str, char c, vector<string>& v)
 
 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("%" PRId64 ".%06" PRId64, quotient, remainder);
+    ostringstream ss;
 
+    if (n < 0)
+        ss << '-';
+    else if (fPlus && n > 0)
+        ss << '+';
+    ss << abs(n/COIN) << '.' << setfill('0') << setw(6) << abs(n%COIN);
+    string str = ss.str();
     // Right-trim excess zeros before the decimal point:
     size_t nTrim = 0;
     for (size_t i = str.size()-1; (str[i] == '0' && isdigit(str[i-2])); --i)
@@ -385,10 +380,6 @@ string FormatMoney(int64_t n, bool fPlus)
     if (nTrim)
         str.erase(str.size()-nTrim, nTrim);
 
-    if (n < 0)
-        str.insert(0u, 1, '-');
-    else if (fPlus && n > 0)
-        str.insert(0u, 1, '+');
     return str;
 }
 
@@ -430,31 +421,32 @@ bool ParseMoney(const char* pszIn, int64_t& nRet)
         return false;
     if (nUnits < 0 || nUnits > COIN)
         return false;
-    int64_t nWhole = atoi64(strWhole);
+    int64_t nWhole = strtoll(strWhole);
     int64_t nValue = nWhole*COIN + nUnits;
 
     nRet = nValue;
     return true;
 }
 
-
-static const signed char phexdigit[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, };
+static const int8_t phexdigit[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,
+};
 
 bool IsHex(const string& str)
 {
@@ -474,12 +466,12 @@ vector<unsigned char> ParseHex(const char* psz)
     {
         while (isspace(*psz))
             psz++;
-        signed char c = phexdigit[(unsigned char)*psz++];
+        auto c = phexdigit[(unsigned char)*psz++];
         if (c == (signed char)-1)
             break;
-        unsigned char n = (c << 4);
-        c = phexdigit[(unsigned char)*psz++];
-        if (c == (signed char)-1)
+        auto n = (c << 4);
+        c = phexdigit[(uint8_t)*psz++];
+        if (c == (int8_t)-1)
             break;
         n |= c;
         vch.push_back(n);
@@ -487,11 +479,6 @@ vector<unsigned char> ParseHex(const char* psz)
     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
@@ -522,7 +509,7 @@ void ParseParameters(int argc, const char* const argv[])
             str = str.substr(0, is_index);
         }
 #ifdef WIN32
-        boost::to_lower(str);
+        transform(str.begin(), str.end(), str.begin(), ::tolower);
         if (str.compare(0,1, "/") == 0)
             str = "-" + str.substr(1);
 #endif
@@ -562,7 +549,7 @@ string GetArg(const string& strArg, const string& strDefault)
 int64_t GetArg(const string& strArg, int64_t nDefault)
 {
     if (mapArgs.count(strArg))
-        return atoi64(mapArgs[strArg]);
+        return strtoll(mapArgs[strArg]);
     return nDefault;
 }
 
@@ -1129,20 +1116,19 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific)
     return path;
 }
 
-string randomStrGen(int length) {
-    static string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+string randomStrGen(size_t length) {
+    std::mt19937 mtrand;
+    mtrand.seed(static_cast<unsigned int>(time(NULL)));
+    static const string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
     string result;
     result.resize(length);
-    for (int32_t i = 0; i < length; i++)
-        result[i] = charset[rand() % charset.length()];
-
+    for (size_t i = 0; i < length; ++i)
+        result[i] = charset[mtrand() % charset.length()];
     return result;
 }
 
 void createConf()
 {
-    srand(static_cast<unsigned int>(time(NULL)));
-
     ofstream pConf;
 #if BOOST_FILESYSTEM_VERSION >= 3
     pConf.open(GetConfigFile().generic_string().c_str());
@@ -1256,8 +1242,9 @@ void ShrinkDebugFile()
         // Restart the file with some of the end
         try {
             vector<char>* vBuf = new vector <char>(200000, 0);
-            fseek(file, -((long)(vBuf->size())), SEEK_END);
-            size_t nBytes = fread(&vBuf->operator[](0), 1, vBuf->size(), file);
+            size_t nBytes = 1; //write one byte if fseek failed
+            if (fseek(file, -((long)(vBuf->size())), SEEK_END) == 0)
+                nBytes = fread(&vBuf->operator[](0), 1, vBuf->size(), file);
             fclose(file);
             file = fopen(pathLog.string().c_str(), "w");
             if (file)
@@ -1295,17 +1282,17 @@ int64_t GetTime()
 extern int64_t nNtpOffset;
 
 // Median of time samples given by other nodes.
-static int64_t nNodesOffset = INT64_MAX;
+static int64_t nNodesOffset = numeric_limits<int64_t>::max();
 
 // Select time offset:
 int64_t GetTimeOffset()
 {
     // If NTP and system clock are in agreement within 40 minutes, then use NTP.
-    if (abs64(nNtpOffset) < 40 * 60)
+    if (abs(nNtpOffset) < 40 * 60)
         return nNtpOffset;
 
     // If not, then choose between median peer time and system clock.
-    if (abs64(nNodesOffset) < 70 * 60)
+    if (abs(nNodesOffset) < 70 * 60)
         return nNodesOffset;
 
     return 0;
@@ -1335,16 +1322,16 @@ void AddTimeData(const CNetAddr& ip, int64_t nTime)
     printf("Added time data, samples %d, offset %+" PRId64 " (%+" PRId64 " minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
     if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
     {
-        int64_t nMedian = vTimeOffsets.median();
-        vector<int64_t> vSorted = vTimeOffsets.sorted();
+        auto nMedian = vTimeOffsets.median();
+        auto vSorted = vTimeOffsets.sorted();
         // Only let other nodes change our time by so much
-        if (abs64(nMedian) < 70 * 60)
+        if (abs(nMedian) < 70 * 60)
         {
             nNodesOffset = nMedian;
         }
         else
         {
-            nNodesOffset = INT64_MAX;
+            nNodesOffset = numeric_limits<int64_t>::max();
 
             static bool fDone;
             if (!fDone)
@@ -1352,14 +1339,14 @@ void AddTimeData(const CNetAddr& ip, int64_t nTime)
                 bool fMatch = false;
 
                 // If nobody has a time different than ours but within 5 minutes of ours, give a warning
-                for(int64_t nOffset :  vSorted)
-                    if (nOffset != 0 && abs64(nOffset) < 5 * 60)
+                for(auto nOffset :  vSorted)
+                    if (nOffset != 0 && abs(nOffset) < 5 * 60)
                         fMatch = true;
 
                 if (!fMatch)
                 {
                     fDone = true;
-                    string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong NovaCoin will not work properly.");
+                    string strMessage("Warning: Please check that your computer's date and time are correct! If your clock is wrong NovaCoin will not work properly.");
                     strMiscWarning = strMessage;
                     printf("*** %s\n", strMessage.c_str());
                     uiInterface.ThreadSafeMessageBox(strMessage+" ", string("NovaCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
@@ -1371,7 +1358,7 @@ void AddTimeData(const CNetAddr& ip, int64_t nTime)
                 printf("%+" PRId64 "  ", n);
             printf("|  ");
         }
-        if (nNodesOffset != INT64_MAX)
+        if (nNodesOffset != numeric_limits<int64_t>::max())
             printf("nNodesOffset = %+" PRId64 "  (%+" PRId64 " minutes)\n", nNodesOffset, nNodesOffset/60);
     }
 }
@@ -1396,7 +1383,16 @@ string FormatSubVersion(const string& name, int nClientVersion, const vector<str
     ss << "/";
     ss << name << ":" << FormatVersion(nClientVersion);
     if (!comments.empty())
-        ss << "(" << boost::algorithm::join(comments, "; ") << ")";
+    {
+        ss << "(";
+        for (const auto& st : comments)
+        {
+            ss << st;
+            if (st == comments.back()) break;
+            ss << "; ";
+        }
+        ss << ")";
+    }
     ss << "/";
     return ss.str();
 }