aboutsummaryrefslogtreecommitdiff
path: root/src/util.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.h')
-rw-r--r--src/util.h477
1 files changed, 58 insertions, 419 deletions
diff --git a/src/util.h b/src/util.h
index 32bc050369..4cc0faf4d7 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,109 +1,40 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2014 The Bitcoin developers
-// Distributed under the MIT/X11 software license, see the accompanying
+// Copyright (c) 2009-2014 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+/**
+ * Server/client environment: argument handling, config file parsing,
+ * logging, thread wrappers
+ */
#ifndef BITCOIN_UTIL_H
#define BITCOIN_UTIL_H
#if defined(HAVE_CONFIG_H)
-#include "bitcoin-config.h"
+#include "config/bitcoin-config.h"
#endif
#include "compat.h"
-#include "serialize.h"
#include "tinyformat.h"
+#include "utiltime.h"
-#include <cstdio>
#include <exception>
#include <map>
-#include <stdarg.h>
#include <stdint.h>
#include <string>
-#include <utility>
#include <vector>
-#ifndef WIN32
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#endif
-
#include <boost/filesystem/path.hpp>
-#include <boost/thread.hpp>
-
-class CNetAddr;
-class uint256;
-
-static const int64_t COIN = 100000000;
-static const int64_t CENT = 1000000;
-
-#define BEGIN(a) ((char*)&(a))
-#define END(a) ((char*)&((&(a))[1]))
-#define UBEGIN(a) ((unsigned char*)&(a))
-#define UEND(a) ((unsigned char*)&((&(a))[1]))
-#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
-
-/* Format characters for (s)size_t, ptrdiff_t.
- *
- * Define these as empty as the tinyformat-based formatting system is
- * type-safe, no special format characters are needed to specify sizes.
- */
-#define PRIszx "x"
-#define PRIszu "u"
-#define PRIszd "d"
-#define PRIpdx "x"
-#define PRIpdu "u"
-#define PRIpdd "d"
-
-// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
-#define PAIRTYPE(t1, t2) std::pair<t1, t2>
-
-// Align by increasing pointer, must have extra space at end of buffer
-template <size_t nBytes, typename T>
-T* alignup(T* p)
-{
- union
- {
- T* ptr;
- size_t n;
- } u;
- u.ptr = p;
- u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
- return u.ptr;
-}
-
-#ifdef WIN32
-#define MSG_DONTWAIT 0
-
-#ifndef S_IRUSR
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#endif
-#else
-#define MAX_PATH 1024
-#endif
-// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0
-#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
-#define MSG_NOSIGNAL 0
-#endif
+#include <boost/signals2/signal.hpp>
+#include <boost/thread/exceptions.hpp>
-inline void MilliSleep(int64_t n)
+/** Signals for translation. */
+class CTranslationInterface
{
-// Boost's sleep_for was uninterruptable when backed by nanosleep from 1.50
-// until fixed in 1.52. Use the deprecated sleep method for the broken case.
-// See: https://svn.boost.org/trac/boost/ticket/7238
-#if defined(HAVE_WORKING_BOOST_SLEEP_FOR)
- boost::this_thread::sleep_for(boost::chrono::milliseconds(n));
-#elif defined(HAVE_WORKING_BOOST_SLEEP)
- boost::this_thread::sleep(boost::posix_time::milliseconds(n));
-#else
-//should never get here
-#error missing boost sleep implementation
-#endif
-}
-
-
+public:
+ /** Translate a message to the native language of the user. */
+ boost::signals2::signal<std::string (const char* psz)> Translate;
+};
extern std::map<std::string, std::string> mapArgs;
extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
@@ -112,33 +43,43 @@ extern bool fPrintToConsole;
extern bool fPrintToDebugLog;
extern bool fServer;
extern std::string strMiscWarning;
-extern bool fNoListen;
extern bool fLogTimestamps;
+extern bool fLogIPs;
extern volatile bool fReopenDebugLog;
+extern CTranslationInterface translationInterface;
+
+/**
+ * Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
+ * If no translation slot is registered, nothing is returned, and simply return the input.
+ */
+inline std::string _(const char* psz)
+{
+ boost::optional<std::string> rv = translationInterface.Translate(psz);
+ return rv ? (*rv) : psz;
+}
-void RandAddSeed();
-void RandAddSeedPerfmon();
+void SetupEnvironment();
-/* Return true if log accepts specified category */
+/** Return true if log accepts specified category */
bool LogAcceptCategory(const char* category);
-/* Send a string to the log output */
+/** Send a string to the log output */
int LogPrintStr(const std::string &str);
-#define strprintf tfm::format
#define LogPrintf(...) LogPrint(NULL, __VA_ARGS__)
-/* When we switch to C++11, this can be switched to variadic templates instead
+/**
+ * When we switch to C++11, this can be switched to variadic templates instead
* of this macro-based construction (see tinyformat.h).
*/
#define MAKE_ERROR_AND_LOG_FUNC(n) \
- /* Print to debug.log if -debug=category switch is given OR category is NULL. */ \
+ /** Print to debug.log if -debug=category switch is given OR category is NULL. */ \
template<TINYFORMAT_ARGTYPES(n)> \
static inline int LogPrint(const char* category, const char* format, TINYFORMAT_VARARGS(n)) \
{ \
if(!LogAcceptCategory(category)) return 0; \
return LogPrintStr(tfm::format(format, TINYFORMAT_PASSARGS(n))); \
} \
- /* Log error and return false */ \
+ /** Log error and return false */ \
template<TINYFORMAT_ARGTYPES(n)> \
static inline bool error(const char* format, TINYFORMAT_VARARGS(n)) \
{ \
@@ -148,7 +89,8 @@ int LogPrintStr(const std::string &str);
TINYFORMAT_FOREACH_ARGNUM(MAKE_ERROR_AND_LOG_FUNC)
-/* Zero-arg versions of logging and error, these are not covered by
+/**
+ * Zero-arg versions of logging and error, these are not covered by
* TINYFORMAT_FOREACH_ARGNUM
*/
static inline int LogPrint(const char* category, const char* format)
@@ -162,39 +104,20 @@ static inline bool error(const char* format)
return false;
}
-
-void LogException(std::exception* pex, const char* pszThread);
-void PrintExceptionContinue(std::exception* pex, const char* pszThread);
-void ParseString(const std::string& str, char c, std::vector<std::string>& v);
-std::string FormatMoney(int64_t n, bool fPlus=false);
-bool ParseMoney(const std::string& str, int64_t& nRet);
-bool ParseMoney(const char* pszIn, int64_t& nRet);
-std::string SanitizeString(const std::string& str);
-std::vector<unsigned char> ParseHex(const char* psz);
-std::vector<unsigned char> ParseHex(const std::string& str);
-bool IsHex(const std::string& str);
-std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
-std::string DecodeBase64(const std::string& str);
-std::string EncodeBase64(const unsigned char* pch, size_t len);
-std::string EncodeBase64(const std::string& str);
-std::vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid = NULL);
-std::string DecodeBase32(const std::string& str);
-std::string EncodeBase32(const unsigned char* pch, size_t len);
-std::string EncodeBase32(const std::string& str);
+void PrintExceptionContinue(const std::exception *pex, const char* pszThread);
void ParseParameters(int argc, const char*const argv[]);
-bool WildcardMatch(const char* psz, const char* mask);
-bool WildcardMatch(const std::string& str, const std::string& mask);
void FileCommit(FILE *fileout);
-int GetFilesize(FILE* file);
bool TruncateFile(FILE *file, unsigned int length);
int RaiseFileDescriptorLimit(int nMinFD);
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest);
+bool TryCreateDirectory(const boost::filesystem::path& p);
boost::filesystem::path GetDefaultDataDir();
const boost::filesystem::path &GetDataDir(bool fNetSpecific = true);
+void ClearDatadirCache();
boost::filesystem::path GetConfigFile();
-boost::filesystem::path GetPidFile();
#ifndef WIN32
+boost::filesystem::path GetPidFile();
void CreatePidFile(const boost::filesystem::path &path, pid_t pid);
#endif
void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
@@ -203,151 +126,8 @@ boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
#endif
boost::filesystem::path GetTempPath();
void ShrinkDebugFile();
-int GetRandInt(int nMax);
-uint64_t GetRand(uint64_t nMax);
-uint256 GetRandHash();
-int64_t GetTime();
-void SetMockTime(int64_t nMockTimeIn);
-int64_t GetAdjustedTime();
-int64_t GetTimeOffset();
-std::string FormatFullVersion();
-std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
-void AddTimeData(const CNetAddr& ip, int64_t nTime);
void runCommand(std::string strCommand);
-
-
-
-
-
-
-
-
-inline std::string i64tostr(int64_t n)
-{
- return strprintf("%d", n);
-}
-
-inline std::string itostr(int n)
-{
- return strprintf("%d", n);
-}
-
-inline int64_t atoi64(const char* psz)
-{
-#ifdef _MSC_VER
- return _atoi64(psz);
-#else
- return strtoll(psz, NULL, 10);
-#endif
-}
-
-inline int64_t atoi64(const std::string& str)
-{
-#ifdef _MSC_VER
- return _atoi64(str.c_str());
-#else
- return strtoll(str.c_str(), NULL, 10);
-#endif
-}
-
-inline int atoi(const std::string& str)
-{
- return atoi(str.c_str());
-}
-
-inline int roundint(double d)
-{
- return (int)(d > 0 ? d + 0.5 : d - 0.5);
-}
-
-inline int64_t roundint64(double d)
-{
- return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
-}
-
-inline int64_t abs64(int64_t n)
-{
- return (n >= 0 ? n : -n);
-}
-
-template<typename T>
-std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
-{
- std::string rv;
- static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- rv.reserve((itend-itbegin)*3);
- for(T it = itbegin; it < itend; ++it)
- {
- unsigned char val = (unsigned char)(*it);
- if(fSpaces && it != itbegin)
- rv.push_back(' ');
- rv.push_back(hexmap[val>>4]);
- rv.push_back(hexmap[val&15]);
- }
-
- return rv;
-}
-
-template<typename T>
-inline std::string HexStr(const T& vch, bool fSpaces=false)
-{
- return HexStr(vch.begin(), vch.end(), fSpaces);
-}
-
-template<typename T>
-void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
-{
- LogPrintf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
-}
-
-inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
-{
- LogPrintf(pszFormat, HexStr(vch, fSpaces).c_str());
-}
-
-inline int64_t GetPerformanceCounter()
-{
- int64_t nCounter = 0;
-#ifdef WIN32
- QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
-#else
- timeval t;
- gettimeofday(&t, NULL);
- nCounter = (int64_t) t.tv_sec * 1000000 + t.tv_usec;
-#endif
- return nCounter;
-}
-
-inline int64_t GetTimeMillis()
-{
- return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
-}
-
-inline int64_t GetTimeMicros()
-{
- return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
- boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_microseconds();
-}
-
-inline std::string DateTimeStrFormat(const char* pszFormat, int64_t nTime)
-{
- time_t n = nTime;
- struct tm* ptmTime = gmtime(&n);
- char pszTime[200];
- strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
- return pszTime;
-}
-
-template<typename T>
-void skipspaces(T& it)
-{
- while (isspace(*it))
- ++it;
-}
-
inline bool IsSwitchChar(char c)
{
#ifdef WIN32
@@ -403,169 +183,28 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue);
bool SoftSetBoolArg(const std::string& strArg, bool fValue);
/**
- * MWC RNG of George Marsaglia
- * This is intended to be fast. It has a period of 2^59.3, though the
- * least significant 16 bits only have a period of about 2^30.1.
+ * Format a string to be used as group of options in help messages
*
- * @return random value
+ * @param message Group name (e.g. "RPC server options:")
+ * @return the formatted string
*/
-extern uint32_t insecure_rand_Rz;
-extern uint32_t insecure_rand_Rw;
-static inline uint32_t insecure_rand(void)
-{
- insecure_rand_Rz = 36969 * (insecure_rand_Rz & 65535) + (insecure_rand_Rz >> 16);
- insecure_rand_Rw = 18000 * (insecure_rand_Rw & 65535) + (insecure_rand_Rw >> 16);
- return (insecure_rand_Rw << 16) + insecure_rand_Rz;
-}
-
-/**
- * Seed insecure_rand using the random pool.
- * @param Deterministic Use a determinstic seed
- */
-void seed_insecure_rand(bool fDeterministic=false);
+std::string HelpMessageGroup(const std::string& message);
/**
- * Timing-attack-resistant comparison.
- * Takes time proportional to length
- * of first argument.
- */
-template <typename T>
-bool TimingResistantEqual(const T& a, const T& b)
-{
- if (b.size() == 0) return a.size() == 0;
- size_t accumulator = a.size() ^ b.size();
- for (size_t i = 0; i < a.size(); i++)
- accumulator |= a[i] ^ b[i%b.size()];
- return accumulator == 0;
-}
-
-/** Median filter over a stream of values.
- * Returns the median of the last N numbers
+ * Format a string to be used as option description in help messages
+ *
+ * @param option Option message (e.g. "-rpcuser=<user>")
+ * @param message Option description (e.g. "Username for JSON-RPC connections")
+ * @return the formatted string
*/
-template <typename T> class CMedianFilter
-{
-private:
- std::vector<T> vValues;
- std::vector<T> vSorted;
- unsigned int nSize;
-public:
- CMedianFilter(unsigned int size, T initial_value):
- nSize(size)
- {
- vValues.reserve(size);
- vValues.push_back(initial_value);
- vSorted = vValues;
- }
-
- void input(T value)
- {
- if(vValues.size() == nSize)
- {
- vValues.erase(vValues.begin());
- }
- vValues.push_back(value);
-
- vSorted.resize(vValues.size());
- std::copy(vValues.begin(), vValues.end(), vSorted.begin());
- std::sort(vSorted.begin(), vSorted.end());
- }
-
- T median() const
- {
- int size = vSorted.size();
- assert(size>0);
- if(size & 1) // Odd number of elements
- {
- return vSorted[size/2];
- }
- else // Even number of elements
- {
- return (vSorted[size/2-1] + vSorted[size/2]) / 2;
- }
- }
-
- int size() const
- {
- return vValues.size();
- }
-
- std::vector<T> sorted () const
- {
- return vSorted;
- }
-};
-
-#ifdef WIN32
-inline void SetThreadPriority(int nPriority)
-{
- SetThreadPriority(GetCurrentThread(), nPriority);
-}
-#else
-
-// PRIO_MAX is not defined on Solaris
-#ifndef PRIO_MAX
-#define PRIO_MAX 20
-#endif
-#define THREAD_PRIORITY_LOWEST PRIO_MAX
-#define THREAD_PRIORITY_BELOW_NORMAL 2
-#define THREAD_PRIORITY_NORMAL 0
-#define THREAD_PRIORITY_ABOVE_NORMAL (-2)
-
-inline void SetThreadPriority(int nPriority)
-{
- // It's unclear if it's even possible to change thread priorities on Linux,
- // but we really and truly need it for the generation threads.
-#ifdef PRIO_THREAD
- setpriority(PRIO_THREAD, 0, nPriority);
-#else
- setpriority(PRIO_PROCESS, 0, nPriority);
-#endif
-}
-#endif
+std::string HelpMessageOpt(const std::string& option, const std::string& message);
+void SetThreadPriority(int nPriority);
void RenameThread(const char* name);
-inline uint32_t ByteReverse(uint32_t value)
-{
- value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
- return (value<<16) | (value>>16);
-}
-
-// Standard wrapper for do-something-forever thread functions.
-// "Forever" really means until the thread is interrupted.
-// Use it like:
-// new boost::thread(boost::bind(&LoopForever<void (*)()>, "dumpaddr", &DumpAddresses, 900000));
-// or maybe:
-// boost::function<void()> f = boost::bind(&FunctionWithArg, argument);
-// threadGroup.create_thread(boost::bind(&LoopForever<boost::function<void()> >, "nothing", f, milliseconds));
-template <typename Callable> void LoopForever(const char* name, Callable func, int64_t msecs)
-{
- std::string s = strprintf("bitcoin-%s", name);
- RenameThread(s.c_str());
- LogPrintf("%s thread start\n", name);
- try
- {
- while (1)
- {
- MilliSleep(msecs);
- func();
- }
- }
- catch (boost::thread_interrupted)
- {
- LogPrintf("%s thread stop\n", name);
- throw;
- }
- catch (std::exception& e) {
- PrintExceptionContinue(&e, name);
- throw;
- }
- catch (...) {
- PrintExceptionContinue(NULL, name);
- throw;
- }
-}
-// .. and a wrapper that just calls func once
+/**
+ * .. and a wrapper that just calls func once
+ */
template <typename Callable> void TraceThread(const char* name, Callable func)
{
std::string s = strprintf("bitcoin-%s", name);
@@ -576,12 +215,12 @@ template <typename Callable> void TraceThread(const char* name, Callable func)
func();
LogPrintf("%s thread exit\n", name);
}
- catch (boost::thread_interrupted)
+ catch (const boost::thread_interrupted&)
{
LogPrintf("%s thread interrupt\n", name);
throw;
}
- catch (std::exception& e) {
+ catch (const std::exception& e) {
PrintExceptionContinue(&e, name);
throw;
}
@@ -591,4 +230,4 @@ template <typename Callable> void TraceThread(const char* name, Callable func)
}
}
-#endif
+#endif // BITCOIN_UTIL_H