First commit
[novacoin.git] / util.h
1 // Copyright (c) 2009 Satoshi Nakamoto\r
2 // Distributed under the MIT/X11 software license, see the accompanying\r
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.\r
4 \r
5 \r
6 #if defined(_MSC_VER) || defined(__BORLANDC__)\r
7 typedef __int64  int64;\r
8 typedef unsigned __int64  uint64;\r
9 #else\r
10 typedef long long  int64;\r
11 typedef unsigned long long  uint64;\r
12 #endif\r
13 #if defined(_MSC_VER) && _MSC_VER < 1300\r
14 #define for  if (false) ; else for\r
15 #endif\r
16 \r
17 #ifndef _MSC_VER\r
18 #define __forceinline  inline\r
19 #endif\r
20 \r
21 #define foreach             BOOST_FOREACH\r
22 #define loop                for (;;)\r
23 #define BEGIN(a)            ((char*)&(a))\r
24 #define END(a)              ((char*)&((&(a))[1]))\r
25 #define UBEGIN(a)           ((unsigned char*)&(a))\r
26 #define UEND(a)             ((unsigned char*)&((&(a))[1]))\r
27 #define ARRAYLEN(array)     (sizeof(array)/sizeof((array)[0]))\r
28 \r
29 #ifdef _WINDOWS\r
30 #define printf              OutputDebugStringF\r
31 #endif\r
32 \r
33 #ifdef snprintf\r
34 #undef snprintf\r
35 #endif\r
36 #define snprintf my_snprintf\r
37 \r
38 #ifndef PRId64\r
39 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)\r
40 #define PRId64  "I64d"\r
41 #define PRIu64  "I64u"\r
42 #define PRIx64  "I64x"\r
43 #else\r
44 #define PRId64  "lld"\r
45 #define PRIu64  "llu"\r
46 #define PRIx64  "llx"\r
47 #endif\r
48 #endif\r
49 \r
50 // This is needed because the foreach macro can't get over the comma in pair<t1, t2>\r
51 #define PAIRTYPE(t1, t2)    pair<t1, t2>\r
52 \r
53 // Used to bypass the rule against non-const reference to temporary\r
54 // where it makes sense with wrappers such as CFlatData or CTxDB\r
55 template<typename T>\r
56 inline T& REF(const T& val)\r
57 {\r
58     return (T&)val;\r
59 }\r
60 \r
61 \r
62 \r
63 \r
64 \r
65 \r
66 \r
67 \r
68 \r
69 extern bool fDebug;\r
70 \r
71 void RandAddSeed(bool fPerfmon=false);\r
72 int my_snprintf(char* buffer, size_t limit, const char* format, ...);\r
73 string strprintf(const char* format, ...);\r
74 bool error(const char* format, ...);\r
75 void PrintException(std::exception* pex, const char* pszThread);\r
76 void ParseString(const string& str, char c, vector<string>& v);\r
77 string FormatMoney(int64 n, bool fPlus=false);\r
78 bool ParseMoney(const char* pszIn, int64& nRet);\r
79 bool FileExists(const char* psz);\r
80 int GetFilesize(FILE* file);\r
81 uint64 GetRand(uint64 nMax);\r
82 int64 GetTime();\r
83 int64 GetAdjustedTime();\r
84 void AddTimeData(unsigned int ip, int64 nTime);\r
85 \r
86 \r
87 \r
88 \r
89 \r
90 \r
91 \r
92 \r
93 \r
94 \r
95 \r
96 \r
97 // Wrapper to automatically initialize critical section\r
98 // Could use wxCriticalSection for portability, but it doesn't support TryEnterCriticalSection\r
99 class CCriticalSection\r
100 {\r
101 protected:\r
102     CRITICAL_SECTION cs;\r
103 public:\r
104     char* pszFile;\r
105     int nLine;\r
106     explicit CCriticalSection() { InitializeCriticalSection(&cs); }\r
107     ~CCriticalSection() { DeleteCriticalSection(&cs); }\r
108     void Enter() { EnterCriticalSection(&cs); }\r
109     void Leave() { LeaveCriticalSection(&cs); }\r
110     bool TryEnter() { return TryEnterCriticalSection(&cs); }\r
111     CRITICAL_SECTION* operator&() { return &cs; }\r
112 };\r
113 \r
114 // Automatically leave critical section when leaving block, needed for exception safety\r
115 class CCriticalBlock\r
116 {\r
117 protected:\r
118     CRITICAL_SECTION* pcs;\r
119 public:\r
120     CCriticalBlock(CRITICAL_SECTION& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }\r
121     CCriticalBlock(CCriticalSection& csIn) { pcs = &csIn; EnterCriticalSection(pcs); }\r
122     ~CCriticalBlock() { LeaveCriticalSection(pcs); }\r
123 };\r
124 \r
125 // WARNING: This will catch continue and break!\r
126 // break is caught with an assertion, but there's no way to detect continue.\r
127 // I'd rather be careful than suffer the other more error prone syntax.\r
128 // The compiler will optimise away all this loop junk.\r
129 #define CRITICAL_BLOCK(cs)     \\r
130     for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \\r
131     for (CCriticalBlock criticalblock(cs); fcriticalblockonce && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)\r
132 \r
133 class CTryCriticalBlock\r
134 {\r
135 protected:\r
136     CRITICAL_SECTION* pcs;\r
137 public:\r
138     CTryCriticalBlock(CRITICAL_SECTION& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }\r
139     CTryCriticalBlock(CCriticalSection& csIn) { pcs = (TryEnterCriticalSection(&csIn) ? &csIn : NULL); }\r
140     ~CTryCriticalBlock() { if (pcs) LeaveCriticalSection(pcs); }\r
141     bool Entered() { return pcs != NULL; }\r
142 };\r
143 \r
144 #define TRY_CRITICAL_BLOCK(cs)     \\r
145     for (bool fcriticalblockonce=true; fcriticalblockonce; assert(("break caught by TRY_CRITICAL_BLOCK!", !fcriticalblockonce)), fcriticalblockonce=false)  \\r
146     for (CTryCriticalBlock criticalblock(cs); fcriticalblockonce && (fcriticalblockonce = criticalblock.Entered()) && (cs.pszFile=__FILE__, cs.nLine=__LINE__, true); fcriticalblockonce=false, cs.pszFile=NULL, cs.nLine=0)\r
147 \r
148 \r
149 \r
150 \r
151 \r
152 \r
153 \r
154 \r
155 \r
156 \r
157 \r
158 \r
159 inline string i64tostr(int64 n)\r
160 {\r
161     return strprintf("%"PRId64, n);\r
162 }\r
163 \r
164 inline string itostr(int n)\r
165 {\r
166     return strprintf("%d", n);\r
167 }\r
168 \r
169 inline int64 atoi64(const char* psz)\r
170 {\r
171 #ifdef _MSC_VER\r
172     return _atoi64(psz);\r
173 #else\r
174     return strtoll(psz, NULL, 10);\r
175 #endif\r
176 }\r
177 \r
178 inline int64 atoi64(const string& str)\r
179 {\r
180 #ifdef _MSC_VER\r
181     return _atoi64(str.c_str());\r
182 #else\r
183     return strtoll(str.c_str(), NULL, 10);\r
184 #endif\r
185 }\r
186 \r
187 inline int atoi(const string& str)\r
188 {\r
189     return atoi(str.c_str());\r
190 }\r
191 \r
192 inline int roundint(double d)\r
193 {\r
194     return (int)(d > 0 ? d + 0.5 : d - 0.5);\r
195 }\r
196 \r
197 template<typename T>\r
198 string HexStr(const T itbegin, const T itend, bool fSpaces=true)\r
199 {\r
200     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];\r
201     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);\r
202     string str;\r
203     for (const unsigned char* p = pbegin; p != pend; p++)\r
204         str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);\r
205     return str;\r
206 }\r
207 \r
208 template<typename T>\r
209 string HexNumStr(const T itbegin, const T itend, bool f0x=true)\r
210 {\r
211     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];\r
212     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);\r
213     string str = (f0x ? "0x" : "");\r
214     for (const unsigned char* p = pend-1; p >= pbegin; p--)\r
215         str += strprintf("%02X", *p);\r
216     return str;\r
217 }\r
218 \r
219 template<typename T>\r
220 void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)\r
221 {\r
222     printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());\r
223 }\r
224 \r
225 \r
226 \r
227 \r
228 \r
229 \r
230 \r
231 \r
232 inline int OutputDebugStringF(const char* pszFormat, ...)\r
233 {\r
234 #ifdef __WXDEBUG__\r
235     // log file\r
236     FILE* fileout = fopen("debug.log", "a");\r
237     if (fileout)\r
238     {\r
239         va_list arg_ptr;\r
240         va_start(arg_ptr, pszFormat);\r
241         vfprintf(fileout, pszFormat, arg_ptr);\r
242         va_end(arg_ptr);\r
243         fclose(fileout);\r
244     }\r
245 \r
246     // accumulate a line at a time\r
247     static CCriticalSection cs_OutputDebugStringF;\r
248     CRITICAL_BLOCK(cs_OutputDebugStringF)\r
249     {\r
250         static char pszBuffer[50000];\r
251         static char* pend;\r
252         if (pend == NULL)\r
253             pend = pszBuffer;\r
254         va_list arg_ptr;\r
255         va_start(arg_ptr, pszFormat);\r
256         int limit = END(pszBuffer) - pend - 2;\r
257         int ret = _vsnprintf(pend, limit, pszFormat, arg_ptr);\r
258         va_end(arg_ptr);\r
259         if (ret < 0 || ret >= limit)\r
260         {\r
261             pend = END(pszBuffer) - 2;\r
262             *pend++ = '\n';\r
263         }\r
264         else\r
265             pend += ret;\r
266         *pend = '\0';\r
267         char* p1 = pszBuffer;\r
268         char* p2;\r
269         while (p2 = strchr(p1, '\n'))\r
270         {\r
271             p2++;\r
272             char c = *p2;\r
273             *p2 = '\0';\r
274             OutputDebugString(p1);\r
275             *p2 = c;\r
276             p1 = p2;\r
277         }\r
278         if (p1 != pszBuffer)\r
279             memmove(pszBuffer, p1, pend - p1 + 1);\r
280         pend -= (p1 - pszBuffer);\r
281         return ret;\r
282     }\r
283 #endif\r
284 \r
285     if (!wxTheApp)\r
286     {\r
287         // print to console\r
288         va_list arg_ptr;\r
289         va_start(arg_ptr, pszFormat);\r
290         vprintf(pszFormat, arg_ptr);\r
291         va_end(arg_ptr);\r
292     }\r
293     return 0;\r
294 }\r
295 \r
296 \r
297 \r
298 \r
299 \r
300 \r
301 \r
302 \r
303 \r
304 inline void heapchk()\r
305 {\r
306     if (_heapchk() != _HEAPOK)\r
307         DebugBreak();\r
308 }\r
309 \r
310 // Randomize the stack to help protect against buffer overrun exploits\r
311 #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn)                         \\r
312     {                                                               \\r
313         static char nLoops;                                         \\r
314         if (nLoops <= 0)                                            \\r
315             nLoops = GetRand(50) + 1;                               \\r
316         if (nLoops-- > 1)                                           \\r
317         {                                                           \\r
318             ThreadFn;                                               \\r
319             return;                                                 \\r
320         }                                                           \\r
321     }\r
322 \r
323 #define CATCH_PRINT_EXCEPTION(pszFn)     \\r
324     catch (std::exception& e) {          \\r
325         PrintException(&e, (pszFn));     \\r
326     } catch (...) {                      \\r
327         PrintException(NULL, (pszFn));   \\r
328     }\r
329 \r
330 \r
331 \r
332 \r
333 \r
334 \r
335 \r
336 \r
337 \r
338 template<typename T1>\r
339 inline uint256 Hash(const T1 pbegin, const T1 pend)\r
340 {\r
341     uint256 hash1;\r
342     SHA256((unsigned char*)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);\r
343     uint256 hash2;\r
344     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
345     return hash2;\r
346 }\r
347 \r
348 template<typename T1, typename T2>\r
349 inline uint256 Hash(const T1 p1begin, const T1 p1end,\r
350                     const T2 p2begin, const T2 p2end)\r
351 {\r
352     uint256 hash1;\r
353     SHA256_CTX ctx;\r
354     SHA256_Init(&ctx);\r
355     SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));\r
356     SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));\r
357     SHA256_Final((unsigned char*)&hash1, &ctx);\r
358     uint256 hash2;\r
359     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
360     return hash2;\r
361 }\r
362 \r
363 template<typename T1, typename T2, typename T3>\r
364 inline uint256 Hash(const T1 p1begin, const T1 p1end,\r
365                     const T2 p2begin, const T2 p2end,\r
366                     const T3 p3begin, const T3 p3end)\r
367 {\r
368     uint256 hash1;\r
369     SHA256_CTX ctx;\r
370     SHA256_Init(&ctx);\r
371     SHA256_Update(&ctx, (unsigned char*)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0]));\r
372     SHA256_Update(&ctx, (unsigned char*)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0]));\r
373     SHA256_Update(&ctx, (unsigned char*)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0]));\r
374     SHA256_Final((unsigned char*)&hash1, &ctx);\r
375     uint256 hash2;\r
376     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
377     return hash2;\r
378 }\r
379 \r
380 template<typename T>\r
381 uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)\r
382 {\r
383     // Most of the time is spent allocating and deallocating CDataStream's\r
384     // buffer.  If this ever needs to be optimized further, make a CStaticStream\r
385     // class with its buffer on the stack.\r
386     CDataStream ss(nType, nVersion);\r
387     ss.reserve(10000);\r
388     ss << obj;\r
389     return Hash(ss.begin(), ss.end());\r
390 }\r
391 \r
392 inline uint160 Hash160(const vector<unsigned char>& vch)\r
393 {\r
394     uint256 hash1;\r
395     SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);\r
396     uint160 hash2;\r
397     RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);\r
398     return hash2;\r
399 }\r