From 2837892ec0a79bce26864283d45ad51c40a84937 Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Wed, 14 May 2014 17:11:36 -0400 Subject: [PATCH 01/31] Upgrade to new version of city_hash library. This version has performance improvements, plus implements a variant with 32-bit output which will quiet some compiler warnings on win32. --- include/fc/array.hpp | 2 +- include/fc/crypto/city.hpp | 12 +- include/fc/network/ip.hpp | 2 +- include/fc/uint128.hpp | 4 +- src/crypto/city.cpp | 412 ++++++++++++++++++++++++++----------- 5 files changed, 307 insertions(+), 125 deletions(-) diff --git a/include/fc/array.hpp b/include/fc/array.hpp index ce86ee0..2796456 100644 --- a/include/fc/array.hpp +++ b/include/fc/array.hpp @@ -123,7 +123,7 @@ namespace std { size_t operator()( const fc::array& e )const { - return fc::city_hash64( (char*)&e, sizeof(e) ); + return fc::city_hash_size_t( (char*)&e, sizeof(e) ); } }; } diff --git a/include/fc/crypto/city.hpp b/include/fc/crypto/city.hpp index 4c050c8..74b8884 100644 --- a/include/fc/crypto/city.hpp +++ b/include/fc/crypto/city.hpp @@ -52,6 +52,14 @@ namespace fc { // Hash function for a byte array. uint64_t city_hash64(const char *buf, size_t len); +uint32_t city_hash32(const char *buf, size_t len); + +#if SIZE_MAX > UINT32_MAX +inline size_t city_hash_size_t(const char *buf, size_t len) { return city_hash64(buf, len); } +#else +inline size_t city_hash_size_t(const char *buf, size_t len) { return city_hash32(buf, len); } +#endif + // Hash function for a byte array. uint128 city_hash128(const char *s, size_t len); @@ -59,7 +67,7 @@ uint128 city_hash128(const char *s, size_t len); uint64_t city_hash_crc_64(const char *buf, size_t len); // Hash function for a byte array. -uint128 city_hash_crc_128(const char *s, size_t len); -fc::array city_hash_crc_256(const char *s, size_t len); +uint128 city_hash_crc_128(const char *s, size_t len); +array city_hash_crc_256(const char *s, size_t len); } // namespace fc diff --git a/include/fc/network/ip.hpp b/include/fc/network/ip.hpp index 5d59c1b..9760aeb 100644 --- a/include/fc/network/ip.hpp +++ b/include/fc/network/ip.hpp @@ -118,7 +118,7 @@ namespace std { size_t operator()( const fc::ip::endpoint& e )const { - return fc::city_hash64( (char*)&e, sizeof(e) ); + return fc::city_hash_size_t( (char*)&e, sizeof(e) ); } }; } diff --git a/include/fc/uint128.hpp b/include/fc/uint128.hpp index 5375b4d..35c5083 100644 --- a/include/fc/uint128.hpp +++ b/include/fc/uint128.hpp @@ -99,7 +99,7 @@ namespace fc inline void unpack( Stream& s, uint128& u ) { s.read( (char*)&u, sizeof(u) ); } } - uint64_t city_hash64(const char *buf, size_t len); + size_t city_hash_size_t(const char *buf, size_t len); } // namespace fc namespace std @@ -109,7 +109,7 @@ namespace std { size_t operator()( const fc::uint128& s )const { - return fc::city_hash64((char*)&s, sizeof(s)); + return fc::city_hash_size_t((char*)&s, sizeof(s)); } }; } diff --git a/src/crypto/city.cpp b/src/crypto/city.cpp index 0100c6a..d90d79c 100644 --- a/src/crypto/city.cpp +++ b/src/crypto/city.cpp @@ -28,11 +28,12 @@ // compromising on hash quality. //#include "config.h" -//#include "city.h" +//#include #include #include // for memcpy and memset #include + #if defined(__SSE4_2__) && defined(__x86_64__) #include #else @@ -41,6 +42,9 @@ uint64_t _mm_crc32_u64(uint64_t a, uint64_t b ); namespace fc { +using namespace std; + + inline uint64_t Uint128Low64(const uint128& x) { return x.low_bits(); } inline uint64_t Uint128High64(const uint128& x) { return x.high_bits(); } @@ -56,17 +60,6 @@ inline uint64_t Hash128to64(const uint128& x) { b *= kMul; return b; } -// Hash function for a byte array. For convenience, a 64-bit seed is also -// hashed into the result. -uint64_t CityHash64WithSeed(const char *buf, size_t len, uint64_t seed); - -// Hash function for a byte array. For convenience, two seeds are also -// hashed into the result. -uint64_t CityHash64WithSeeds(const char *buf, size_t len, - uint64_t seed0, uint64_t seed1); - - -using namespace std; static uint64_t UNALIGNED_LOAD64(const char *p) { uint64_t result; @@ -80,32 +73,59 @@ static uint32_t UNALIGNED_LOAD32(const char *p) { return result; } -#if !defined(WORDS_BIGENDIAN) - -#define uint32_in_expected_order(x) (x) -#define uint64_in_expected_order(x) (x) - -#else - #ifdef _MSC_VER + #include #define bswap_32(x) _byteswap_ulong(x) #define bswap_64(x) _byteswap_uint64(x) #elif defined(__APPLE__) + // Mac OS X / Darwin features #include #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#else -#include +#elif defined(__sun) || defined(sun) + +#include +#define bswap_32(x) BSWAP_32(x) +#define bswap_64(x) BSWAP_64(x) + +#elif defined(__FreeBSD__) + +#include +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) + +#elif defined(__OpenBSD__) + +#include +#define bswap_32(x) swap32(x) +#define bswap_64(x) swap64(x) + +#elif defined(__NetBSD__) + +#include +#include +#if defined(__BSWAP_RENAME) && !defined(__bswap_32) +#define bswap_32(x) bswap32(x) +#define bswap_64(x) bswap64(x) #endif +#else + +#include + +#endif + +#ifdef WORDS_BIGENDIAN #define uint32_in_expected_order(x) (bswap_32(x)) #define uint64_in_expected_order(x) (bswap_64(x)) - -#endif // WORDS_BIGENDIAN +#else +#define uint32_in_expected_order(x) (x) +#define uint64_in_expected_order(x) (x) +#endif #if !defined(LIKELY) #if HAVE_BUILTIN_EXPECT @@ -127,7 +147,139 @@ static uint32_t Fetch32(const char *p) { static const uint64_t k0 = 0xc3a5c85c97cb3127ULL; static const uint64_t k1 = 0xb492b66fbe98f273ULL; static const uint64_t k2 = 0x9ae16a3b2f90404fULL; -static const uint64_t k3 = 0xc949d7c7509e6557ULL; + +// Magic numbers for 32-bit hashing. Copied from Murmur3. +static const uint32_t c1 = 0xcc9e2d51; +static const uint32_t c2 = 0x1b873593; + +// A 32-bit to 32-bit integer hash copied from Murmur3. +static uint32_t fmix(uint32_t h) +{ + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + return h; +} + +static uint32_t Rotate32(uint32_t val, int shift) { + // Avoid shifting by 32: doing so yields an undefined result. + return shift == 0 ? val : ((val >> shift) | (val << (32 - shift))); +} + +#undef PERMUTE3 +#define PERMUTE3(a, b, c) do { std::swap(a, b); std::swap(a, c); } while (0) + +static uint32_t Mur(uint32_t a, uint32_t h) { + // Helper from Murmur3 for combining two 32-bit values. + a *= c1; + a = Rotate32(a, 17); + a *= c2; + h ^= a; + h = Rotate32(h, 19); + return h * 5 + 0xe6546b64; +} + +static uint32_t Hash32Len13to24(const char *s, size_t len) { + uint32_t a = Fetch32(s - 4 + (len >> 1)); + uint32_t b = Fetch32(s + 4); + uint32_t c = Fetch32(s + len - 8); + uint32_t d = Fetch32(s + (len >> 1)); + uint32_t e = Fetch32(s); + uint32_t f = Fetch32(s + len - 4); + uint32_t h = len; + + return fmix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h))))))); +} + +static uint32_t Hash32Len0to4(const char *s, size_t len) { + uint32_t b = 0; + uint32_t c = 9; + for (size_t i = 0; i < len; i++) { + signed char v = s[i]; + b = b * c1 + v; + c ^= b; + } + return fmix(Mur(b, Mur(len, c))); +} + +static uint32_t Hash32Len5to12(const char *s, size_t len) { + uint32_t a = len, b = len * 5, c = 9, d = b; + a += Fetch32(s); + b += Fetch32(s + len - 4); + c += Fetch32(s + ((len >> 1) & 4)); + return fmix(Mur(c, Mur(b, Mur(a, d)))); +} + +uint32_t city_hash32(const char *s, size_t len) { + if (len <= 24) { + return len <= 12 ? + (len <= 4 ? Hash32Len0to4(s, len) : Hash32Len5to12(s, len)) : + Hash32Len13to24(s, len); + } + + // len > 24 + uint32_t h = len, g = c1 * len, f = g; + uint32_t a0 = Rotate32(Fetch32(s + len - 4) * c1, 17) * c2; + uint32_t a1 = Rotate32(Fetch32(s + len - 8) * c1, 17) * c2; + uint32_t a2 = Rotate32(Fetch32(s + len - 16) * c1, 17) * c2; + uint32_t a3 = Rotate32(Fetch32(s + len - 12) * c1, 17) * c2; + uint32_t a4 = Rotate32(Fetch32(s + len - 20) * c1, 17) * c2; + h ^= a0; + h = Rotate32(h, 19); + h = h * 5 + 0xe6546b64; + h ^= a2; + h = Rotate32(h, 19); + h = h * 5 + 0xe6546b64; + g ^= a1; + g = Rotate32(g, 19); + g = g * 5 + 0xe6546b64; + g ^= a3; + g = Rotate32(g, 19); + g = g * 5 + 0xe6546b64; + f += a4; + f = Rotate32(f, 19); + f = f * 5 + 0xe6546b64; + size_t iters = (len - 1) / 20; + do { + uint32_t a0 = Rotate32(Fetch32(s) * c1, 17) * c2; + uint32_t a1 = Fetch32(s + 4); + uint32_t a2 = Rotate32(Fetch32(s + 8) * c1, 17) * c2; + uint32_t a3 = Rotate32(Fetch32(s + 12) * c1, 17) * c2; + uint32_t a4 = Fetch32(s + 16); + h ^= a0; + h = Rotate32(h, 18); + h = h * 5 + 0xe6546b64; + f += a1; + f = Rotate32(f, 19); + f = f * c1; + g += a2; + g = Rotate32(g, 18); + g = g * 5 + 0xe6546b64; + h ^= a3 + a1; + h = Rotate32(h, 19); + h = h * 5 + 0xe6546b64; + g ^= a4; + g = bswap_32(g) * 5; + h += a4 * 5; + h = bswap_32(h); + f += a0; + PERMUTE3(f, h, g); + s += 20; + } while (--iters != 0); + g = Rotate32(g, 11) * c1; + g = Rotate32(g, 17) * c1; + f = Rotate32(f, 11) * c1; + f = Rotate32(f, 17) * c1; + h = Rotate32(h + g, 19); + h = h * 5 + 0xe6546b64; + h = Rotate32(h, 17) * c1; + h = Rotate32(h + f, 19); + h = h * 5 + 0xe6546b64; + h = Rotate32(h, 17) * c1; + return h; +} // Bitwise right rotate. Normally this will compile to a single // instruction, especially if the shift is a manifest constant. @@ -136,13 +288,6 @@ static uint64_t Rotate(uint64_t val, int shift) { return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); } -// Equivalent to Rotate(), but requires the second arg to be non-zero. -// On x86-64, and probably others, it's possible for this to compile -// to a single instruction if both args are already in registers. -static uint64_t RotateByAtLeast1(uint64_t val, int shift) { - return (val >> shift) | (val << (64 - shift)); -} - static uint64_t ShiftMix(uint64_t val) { return val ^ (val >> 47); } @@ -151,15 +296,29 @@ static uint64_t HashLen16(uint64_t u, uint64_t v) { return Hash128to64(uint128(u, v)); } +static uint64_t HashLen16(uint64_t u, uint64_t v, uint64_t mul) { + // Murmur-inspired hashing. + uint64_t a = (u ^ v) * mul; + a ^= (a >> 47); + uint64_t b = (v ^ a) * mul; + b ^= (b >> 47); + b *= mul; + return b; +} + static uint64_t HashLen0to16(const char *s, size_t len) { - if (len > 8) { - uint64_t a = Fetch64(s); + if (len >= 8) { + uint64_t mul = k2 + len * 2; + uint64_t a = Fetch64(s) + k2; uint64_t b = Fetch64(s + len - 8); - return HashLen16(a, RotateByAtLeast1(b + len, len)) ^ b; + uint64_t c = Rotate(b, 37) * mul + a; + uint64_t d = (Rotate(a, 25) + b) * mul; + return HashLen16(c, d, mul); } if (len >= 4) { + uint64_t mul = k2 + len * 2; uint64_t a = Fetch32(s); - return HashLen16(len + (a << 3), Fetch32(s + len - 4)); + return HashLen16(len + (a << 3), Fetch32(s + len - 4), mul); } if (len > 0) { uint8_t a = s[0]; @@ -167,7 +326,7 @@ static uint64_t HashLen0to16(const char *s, size_t len) { uint8_t c = s[len - 1]; uint32_t y = static_cast(a) + (static_cast(b) << 8); uint32_t z = len + (static_cast(c) << 2); - return ShiftMix(y * k2 ^ z * k3) * k2; + return ShiftMix(y * k2 ^ z * k0) * k2; } return k2; } @@ -175,12 +334,13 @@ static uint64_t HashLen0to16(const char *s, size_t len) { // This probably works well for 16-byte strings as well, but it may be overkill // in that case. static uint64_t HashLen17to32(const char *s, size_t len) { + uint64_t mul = k2 + len * 2; uint64_t a = Fetch64(s) * k1; uint64_t b = Fetch64(s + 8); - uint64_t c = Fetch64(s + len - 8) * k2; - uint64_t d = Fetch64(s + len - 16) * k0; - return HashLen16(Rotate(a - b, 43) + Rotate(c, 30) + d, - a + Rotate(b ^ k3, 20) - c + len); + uint64_t c = Fetch64(s + len - 8) * mul; + uint64_t d = Fetch64(s + len - 16) * k2; + return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d, + a + Rotate(b + k2, 18) + c, mul); } // Return a 16-byte hash for 48 bytes. Quick and dirty. @@ -209,26 +369,24 @@ static pair WeakHashLen32WithSeeds( // Return an 8-byte hash for 33 to 64 bytes. static uint64_t HashLen33to64(const char *s, size_t len) { - uint64_t z = Fetch64(s + 24); - uint64_t a = Fetch64(s) + (len + Fetch64(s + len - 16)) * k0; - uint64_t b = Rotate(a + z, 52); - uint64_t c = Rotate(a, 37); - a += Fetch64(s + 8); - c += Rotate(a, 7); - a += Fetch64(s + 16); - uint64_t vf = a + z; - uint64_t vs = b + Rotate(a, 31) + c; - a = Fetch64(s + 16) + Fetch64(s + len - 32); - z = Fetch64(s + len - 8); - b = Rotate(a + z, 52); - c = Rotate(a, 37); - a += Fetch64(s + len - 24); - c += Rotate(a, 7); - a += Fetch64(s + len - 16); - uint64_t wf = a + z; - uint64_t ws = b + Rotate(a, 31) + c; - uint64_t r = ShiftMix((vf + ws) * k2 + (wf + vs) * k0); - return ShiftMix(r * k0 + vs) * k2; + uint64_t mul = k2 + len * 2; + uint64_t a = Fetch64(s) * k2; + uint64_t b = Fetch64(s + 8); + uint64_t c = Fetch64(s + len - 24); + uint64_t d = Fetch64(s + len - 32); + uint64_t e = Fetch64(s + 16) * k2; + uint64_t f = Fetch64(s + 24) * 9; + uint64_t g = Fetch64(s + len - 8); + uint64_t h = Fetch64(s + len - 16) * mul; + uint64_t u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9; + uint64_t v = ((a + g) ^ d) + f + 1; + uint64_t w = bswap_64((u + v) * mul) + h; + uint64_t x = Rotate(e + f, 42) + c; + uint64_t y = (bswap_64((v + w) * mul) + g) * mul; + uint64_t z = e + f + c; + a = bswap_64((x + z) * mul + y) + b; + b = ShiftMix((z + a) * mul + d + h) * mul; + return b + x; } uint64_t city_hash64(const char *s, size_t len) { @@ -269,15 +427,15 @@ uint64_t city_hash64(const char *s, size_t len) { HashLen16(v.second, w.second) + x); } -uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) { - return CityHash64WithSeeds(s, len, k2, seed); -} - uint64_t CityHash64WithSeeds(const char *s, size_t len, uint64_t seed0, uint64_t seed1) { return HashLen16(city_hash64(s, len) - seed0, seed1); } +uint64_t CityHash64WithSeed(const char *s, size_t len, uint64_t seed) { + return CityHash64WithSeeds(s, len, k2, seed); +} + // A subroutine for CityHash128(). Returns a decent 128-bit hash for strings // of any length representable in signed long. Based on City and Murmur. static uint128 CityMurmur(const char *s, size_t len, uint128 seed) { @@ -349,7 +507,10 @@ uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { len -= 128; } while (LIKELY(len >= 128)); x += Rotate(v.first + z, 49) * k0; - z += Rotate(w.first, 37) * k0; + y = y * k0 + Rotate(w.second, 37); + z = z * k0 + Rotate(w.first, 27); + w.first *= 9; + v.first *= k0; // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. for (size_t tail_done = 0; tail_done < len; ) { tail_done += 32; @@ -359,6 +520,7 @@ uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { z += w.second + Fetch64(s + len - tail_done); w.second += v.first; v = WeakHashLen32WithSeeds(s + len - tail_done, v.first + z, v.second); + v.first *= k0; } // At this point our 56 bytes of state should contain more than // enough information for a strong 128-bit hash. We use two @@ -370,23 +532,14 @@ uint128 CityHash128WithSeed(const char *s, size_t len, uint128 seed) { } uint128 city_hash128(const char *s, size_t len) { - if (len >= 16) { - return CityHash128WithSeed(s + 16, - len - 16, - uint128(Fetch64(s) ^ k3, - Fetch64(s + 8))); - } else if (len >= 8) { - return CityHash128WithSeed(NULL, - 0, - uint128(Fetch64(s) ^ (len * k0), - Fetch64(s + len - 8) ^ k1)); - } else { - return CityHash128WithSeed(s, len, uint128(k0, k1)); - } + return len >= 16 ? + CityHash128WithSeed(s + 16, len - 16, + uint128(Fetch64(s), Fetch64(s + 8) + k0)) : + CityHash128WithSeed(s, len, uint128(k0, k1)); } //#ifdef __SSE4_2__ -//#include "citycrc.h" +//#include //#include // Requires len >= 240. @@ -397,60 +550,79 @@ static void CityHashCrc256Long(const char *s, size_t len, uint64_t c = result[0] = HashLen16(b, len); uint64_t d = result[1] = Fetch64(s + 120) * k0 + len; uint64_t e = Fetch64(s + 184) + seed; - uint64_t f = seed; + uint64_t f = 0; uint64_t g = 0; - uint64_t h = 0; - uint64_t i = 0; - uint64_t j = 0; - uint64_t t = c + d; + uint64_t h = c + d; + uint64_t x = seed; + uint64_t y = 0; + uint64_t z = 0; // 240 bytes of input per iter. size_t iters = len / 240; len -= iters * 240; do { -#define CHUNK(multiplier, z) \ - { \ - uint64_t old_a = a; \ - a = Rotate(b, 41 ^ z) * multiplier + Fetch64(s); \ - b = Rotate(c, 27 ^ z) * multiplier + Fetch64(s + 8); \ - c = Rotate(d, 41 ^ z) * multiplier + Fetch64(s + 16); \ - d = Rotate(e, 33 ^ z) * multiplier + Fetch64(s + 24); \ - e = Rotate(t, 25 ^ z) * multiplier + Fetch64(s + 32); \ - t = old_a; \ - } \ - f = _mm_crc32_u64(f, a); \ - g = _mm_crc32_u64(g, b); \ - h = _mm_crc32_u64(h, c); \ - i = _mm_crc32_u64(i, d); \ - j = _mm_crc32_u64(j, e); \ +#undef CHUNK +#define CHUNK(r) \ + PERMUTE3(x, z, y); \ + b += Fetch64(s); \ + c += Fetch64(s + 8); \ + d += Fetch64(s + 16); \ + e += Fetch64(s + 24); \ + f += Fetch64(s + 32); \ + a += b; \ + h += f; \ + b += c; \ + f += d; \ + g += e; \ + e += z; \ + g += x; \ + z = _mm_crc32_u64(z, b + g); \ + y = _mm_crc32_u64(y, e + h); \ + x = _mm_crc32_u64(x, f + a); \ + e = Rotate(e, r); \ + c += e; \ s += 40 - CHUNK(1, 1); CHUNK(k0, 0); - CHUNK(1, 1); CHUNK(k0, 0); - CHUNK(1, 1); CHUNK(k0, 0); + CHUNK(0); PERMUTE3(a, h, c); + CHUNK(33); PERMUTE3(a, h, f); + CHUNK(0); PERMUTE3(b, h, f); + CHUNK(42); PERMUTE3(b, h, d); + CHUNK(0); PERMUTE3(b, h, e); + CHUNK(33); PERMUTE3(a, h, e); } while (--iters > 0); while (len >= 40) { - CHUNK(k0, 0); + CHUNK(29); + e ^= Rotate(a, 20); + h += Rotate(b, 30); + g ^= Rotate(c, 40); + f += Rotate(d, 34); + PERMUTE3(c, h, g); len -= 40; } if (len > 0) { s = s + len - 40; - CHUNK(k0, 0); + CHUNK(33); + e ^= Rotate(a, 43); + h += Rotate(b, 42); + g ^= Rotate(c, 41); + f += Rotate(d, 40); } - j += i << 32; - a = HashLen16(a, j); - h += g << 32; - b += h; - c = HashLen16(c, f) + i; + result[0] ^= h; + result[1] ^= g; + g += h; + a = HashLen16(a, g + z); + x += y << 32; + b += x; + c = HashLen16(c, z) + h; d = HashLen16(d, e + result[0]); - j += e; - i += HashLen16(h, t); - e = HashLen16(a, d) + j; - f = HashLen16(b, c) + a; - g = HashLen16(j, i) + c; - result[0] = e + f + g + h; - a = ShiftMix((a + g) * k0) * k0 + b; + g += e; + h += HashLen16(x, f); + e = HashLen16(a, d) + g; + z = HashLen16(b, c) + a; + y = HashLen16(g, h) + c; + result[0] = e + z + y + x; + a = ShiftMix((a + y) * k0) * k0 + b; result[1] += a + result[0]; a = ShiftMix(a * k0) * k0 + c; result[2] = a + result[1]; @@ -473,9 +645,10 @@ void CityHashCrc256(const char *s, size_t len, uint64_t *result) { CityHashCrc256Short(s, len, result); } } -fc::array city_hash_crc_256(const char *s, size_t len) + +array city_hash_crc_256(const char *s, size_t len) { - fc::array buf; + array buf; CityHashCrc256( s, len, (uint64_t*)&buf ); return buf; } @@ -502,6 +675,7 @@ uint128 city_hash_crc_128(const char *s, size_t len) { return uint128(result[2], result[3]); } } -} // namespace fc + +} // end namespace fc //#endif From 271fe8b909b5a8d0e66827cc6469c23358082fa0 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 15 May 2014 13:35:49 -0400 Subject: [PATCH 02/31] found major bug in parsing, fixed it --- src/io/json.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index 7fa05e8..6d62b91 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -8,6 +8,7 @@ //#include #include #include +#include namespace fc { @@ -104,11 +105,6 @@ namespace fc { char c = in.peek(); - // if( c != ' ' ) - // FC_THROW_EXCEPTION( parse_error_exception, - // "Expected '\"' but read '${char}'", - // ("char", string(&c, (&c) + 1) ) ); - // in.get(); while( true ) { switch( c = in.peek() ) @@ -118,15 +114,17 @@ namespace fc break; case '\t': case ' ': + case '\0': + case '\n': in.get(); return token.str(); default: + std::cerr< Date: Thu, 15 May 2014 13:52:21 -0400 Subject: [PATCH 03/31] fix bugs parsing json tokens --- src/io/json.cpp | 8 ++++++-- src/io/sstream.cpp | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index 6d62b91..29c75ad 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -119,9 +119,12 @@ namespace fc in.get(); return token.str(); default: - std::cerr< variant token_from_stream( T& in ) { - fc::stringstream ss; + std::stringstream ss; + ss.exceptions( std::ifstream::badbit ); bool parsed_unexpected_character = false; bool received_eof = false; try diff --git a/src/io/sstream.cpp b/src/io/sstream.cpp index 1534f08..28a5aac 100644 --- a/src/io/sstream.cpp +++ b/src/io/sstream.cpp @@ -9,11 +9,13 @@ namespace fc { public: impl( fc::string&s ) :ss( s ) - { } + { ss.exceptions( std::stringstream::badbit | std::stringstream::eofbit ); } + impl( const fc::string&s ) :ss( s ) - { } - impl(){} + { ss.exceptions( std::stringstream::badbit | std::stringstream::eofbit ); } + + impl(){ss.exceptions( std::stringstream::badbit | std::stringstream::eofbit ); } std::stringstream ss; }; From 7078ebf38299ad8cd714a5afdee767ab8ea82958 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 15 May 2014 14:07:19 -0400 Subject: [PATCH 04/31] expanding token chars --- src/io/json.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index 29c75ad..7be1620 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -119,7 +119,7 @@ namespace fc in.get(); return token.str(); default: - if( isalnum( c ) ) + if( isalnum( c ) || c == '_' || c == '-' || c == '.' || c == ':' ) { token << c; in.get(); From b3e30e893b6acb2dfe17c1a3eec52ebb085f303d Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Thu, 15 May 2014 14:14:27 -0400 Subject: [PATCH 05/31] 32/64 bit int stuff --- include/fc/io/varint.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/io/varint.hpp b/include/fc/io/varint.hpp index ad4ac21..3536d4e 100644 --- a/include/fc/io/varint.hpp +++ b/include/fc/io/varint.hpp @@ -33,7 +33,7 @@ struct unsigned_int { * Uses the google protobuf algorithm for seralizing signed numbers */ struct signed_int { - signed_int( int64_t v = 0 ):value(v){} + signed_int( int32_t v = 0 ):value(v){} operator int32_t()const { return value; } template signed_int& operator=( const T& v ) { value = v; return *this; } From 8c370b06e6639a75f5077549465bfbf3b1ea3fd2 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 15 May 2014 17:44:38 -0400 Subject: [PATCH 06/31] update json error handling --- src/io/json.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index 7be1620..e17729e 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -248,6 +248,10 @@ namespace fc ss.put( in.get() ); break; default: + if( isalnum( c ) ) + { + return ss.str() + stringFromToken( in ); + } done = true; break; } @@ -270,12 +274,11 @@ namespace fc { std::stringstream ss; ss.exceptions( std::ifstream::badbit ); - bool parsed_unexpected_character = false; bool received_eof = false; try { char c; - while((c = in.peek()) && !parsed_unexpected_character) + while((c = in.peek()) ) { switch( c ) { @@ -291,8 +294,7 @@ namespace fc ss.put( in.get() ); break; default: - parsed_unexpected_character = true; - break; + return ss.str() + stringFromToken(in); } } } From cde67a202c573b2025459d5b27bf564fe1c82cf0 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Fri, 16 May 2014 22:29:46 -0400 Subject: [PATCH 07/31] Implement assignment by subtraction for time classes --- include/fc/time.hpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/include/fc/time.hpp b/include/fc/time.hpp index 6a6146d..204d586 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -9,7 +9,7 @@ #endif //// _MSC_VER namespace fc { - class microseconds { + class microseconds { public: explicit microseconds( int64_t c = 0) :_count(c){} static microseconds maximum() { return microseconds(0x7fffffffffffffffll); } @@ -23,10 +23,11 @@ namespace fc { friend bool operator<(const microseconds& a, const microseconds& b){ return a._count < b._count; } friend bool operator<=(const microseconds& a, const microseconds& b){ return a._count <= b._count; } microseconds& operator+=(const microseconds& c) { _count += c._count; return *this; } + microseconds& operator-=(const microseconds& c) { _count -= c._count; return *this; } int64_t count()const { return _count; } private: friend class time_point; - int64_t _count; + int64_t _count; }; inline microseconds seconds( int64_t s ) { return microseconds( s * 1000000 ); } inline microseconds milliseconds( int64_t s ) { return microseconds( s * 1000 ); } @@ -34,14 +35,14 @@ namespace fc { inline microseconds hours(int64_t h) { return minutes(60*h); } inline microseconds days(int64_t d) { return hours(24*d); } - class time_point { + class time_point { public: explicit time_point( microseconds e = microseconds() ) :elapsed(e){} static time_point now(); static time_point maximum() { return time_point( microseconds::maximum() ); } static time_point min() { return time_point(); } operator fc::string()const; - + static time_point from_iso_string( const fc::string& s ); const microseconds& time_since_epoch()const { return elapsed; } @@ -53,17 +54,18 @@ namespace fc { bool operator ==( const time_point& t )const { return elapsed._count ==t.elapsed._count; } bool operator !=( const time_point& t )const { return elapsed._count !=t.elapsed._count; } time_point& operator += ( const microseconds& m) { elapsed+=m; return *this; } + time_point& operator -= ( const microseconds& m) { elapsed-=m; return *this; } time_point operator + (const microseconds& m) const { return time_point(elapsed+m); } time_point operator - (const microseconds& m) const { return time_point(elapsed-m); } microseconds operator - (const time_point& m) const { return microseconds(elapsed.count() - m.elapsed.count()); } private: - microseconds elapsed; + microseconds elapsed; }; /** * A lower resolution time_point accurate only to seconds from 1970 */ - class time_point_sec + class time_point_sec { public: time_point_sec() @@ -90,6 +92,7 @@ namespace fc { friend bool operator == ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds == b.utc_seconds; } friend bool operator != ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds != b.utc_seconds; } time_point_sec& operator += ( uint32_t m ) { utc_seconds+=m; return *this; } + time_point_sec& operator -= ( uint32_t m ) { utc_seconds-=m; return *this; } friend time_point operator - ( const time_point_sec& t, const microseconds& m ) { return time_point(t) - m; } friend microseconds operator - ( const time_point_sec& t, const time_point_sec& m ) { return time_point(t) - time_point(m); } From e8326ca66c096714b8bd1361e3305dc3b0b2090d Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Sat, 17 May 2014 03:00:07 -0400 Subject: [PATCH 08/31] Make objectFromStream always throw parse_error_exception when throwing --- src/io/json.cpp | 61 +++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index e17729e..641164b 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -43,9 +43,8 @@ namespace fc FC_THROW_EXCEPTION( parse_error_exception, "Expected '\\'" ); } - template - void skip_white_space( T& in ) + void skip_white_space( T& in ) { while( true ) { @@ -67,18 +66,18 @@ namespace fc fc::string stringFromStream( T& in ) { fc::stringstream token; - try + try { char c = in.peek(); if( c != '"' ) - FC_THROW_EXCEPTION( parse_error_exception, - "Expected '\"' but read '${char}'", + FC_THROW_EXCEPTION( parse_error_exception, + "Expected '\"' but read '${char}'", ("char", string(&c, (&c) + 1) ) ); in.get(); while( true ) { - + switch( c = in.peek() ) { case '\\': @@ -94,14 +93,14 @@ namespace fc } FC_THROW_EXCEPTION( parse_error_exception, "EOF before closing '\"' in string '${token}'", ("token", token.str() ) ); - } FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'", + } FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'", ("token", token.str() ) ); } template fc::string stringFromToken( T& in ) { fc::stringstream token; - try + try { char c = in.peek(); @@ -128,12 +127,12 @@ namespace fc } } return token.str(); - } + } catch( const fc::eof_exception& eof ) { return token.str(); } - FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'", + FC_RETHROW_EXCEPTIONS( warn, "while parsing token '${token}'", ("token", token.str() ) ); } @@ -143,10 +142,10 @@ namespace fc mutable_variant_object obj; try { - char c = in.peek(); + char c = in.peek(); if( c != '{' ) - FC_THROW_EXCEPTION( parse_error_exception, - "Expected '{', but read '${char}'", + FC_THROW_EXCEPTION( parse_error_exception, + "Expected '{', but read '${char}'", ("char",string(&c, &c + 1)) ); in.get(); skip_white_space(in); @@ -176,8 +175,10 @@ namespace fc return obj; } FC_THROW_EXCEPTION( parse_error_exception, "Expected '}' after ${variant}", ("variant", obj ) ); - - + } + catch( const fc::eof_exception& e ) + { + FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF: ${e}", ("e", e.to_detail_string() ) ); } FC_RETHROW_EXCEPTIONS( warn, "Error parsing object" ); } @@ -194,7 +195,7 @@ namespace fc while( in.peek() != ']' ) { - while( in.peek() == ',' ) + while( in.peek() == ',' ) in.get(); ar.push_back( variant_from_stream(in) ); skip_white_space(in); @@ -204,7 +205,7 @@ namespace fc ("variant", ar) ); in.get(); - } FC_RETHROW_EXCEPTIONS( warn, "Attempting to parse array ${array}", + } FC_RETHROW_EXCEPTIONS( warn, "Attempting to parse array ${array}", ("array", ar ) ); return ar; } @@ -228,11 +229,11 @@ namespace fc char c; while((c = in.peek()) && !done) { - + switch( c ) { case '.': - if (dot) + if (dot) FC_THROW_EXCEPTION(parse_error_exception, "Can't parse a number with two decimal places"); dot = true; case '0': @@ -265,7 +266,7 @@ namespace fc FC_THROW_EXCEPTION(parse_error_exception, "Can't parse token \"${token}\" as a JSON numeric constant", ("token", str)); if( dot ) return to_double(str); - if( neg ) + if( neg ) return to_int64(str); return to_uint64(str); } @@ -309,7 +310,7 @@ namespace fc if( str == "null" ) return variant(); if( str == "true" ) return true; if( str == "false" ) return false; - else + else { if (received_eof) FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" ); @@ -372,7 +373,7 @@ namespace fc default: // ilog( "unhandled char '${c}' int ${int}", ("c", fc::string( &c, 1 ) )("int", int(c)) ); return stringFromToken(in); - in.get(); // + in.get(); // ilog( "unhandled char '${c}' int ${int}", ("c", fc::string( &c, 1 ) )("int", int(c)) ); return variant(); } @@ -395,7 +396,7 @@ namespace fc void toUTF8( const wchar_t c, ostream& os ) { - utf8::utf16to8( &c, (&c)+1, ostream_iterator(os) ); + utf8::utf16to8( &c, (&c)+1, ostream_iterator(os) ); } */ @@ -462,7 +463,7 @@ namespace fc { os << '{'; auto itr = o.begin(); - + while( itr != o.end() ) { escape_string( itr->key(), os ); @@ -480,13 +481,13 @@ namespace fc { switch( v.get_type() ) { - case variant::null_type: + case variant::null_type: os << "null"; return; - case variant::int64_type: + case variant::int64_type: os << v.as_int64(); return; - case variant::uint64_type: + case variant::uint64_type: os << v.as_uint64(); return; case variant::double_type: @@ -531,7 +532,7 @@ namespace fc switch( v[i] ) { case '\\': if( !escape ) { - if( quote ) + if( quote ) escape = true; } else { escape = false; } ss<( p, ifstream::binary ); //auto tmp = std::make_shared( p.generic_string().c_str(), std::ios::binary ); - //buffered_istream bi( tmp ); + //buffered_istream bi( tmp ); std::ifstream bi( p.generic_string().c_str(), std::ios::binary ); return variant_from_stream( bi ); } From 06bc873da0b4e64c19b3e3a2cdd1aae7d0c7bb4a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 17 May 2014 19:35:44 +0000 Subject: [PATCH 09/31] improving error reporting in deserialization --- include/fc/array.hpp | 10 ++++++++ include/fc/crypto/elliptic.hpp | 4 ++++ include/fc/crypto/sha256.hpp | 2 ++ include/fc/crypto/sha512.hpp | 3 +++ include/fc/io/raw.hpp | 44 ++++++++++++++++++++-------------- include/fc/time.hpp | 4 ++++ 6 files changed, 49 insertions(+), 18 deletions(-) diff --git a/include/fc/array.hpp b/include/fc/array.hpp index 2796456..6a2053c 100644 --- a/include/fc/array.hpp +++ b/include/fc/array.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace fc { @@ -112,6 +113,14 @@ namespace fc { } + template struct get_typename< fc::array > + { + static const char* name() + { + static std::string _name = std::string("fc::array<")+std::string(fc::get_typename::name())+","+ fc::to_string(N) + ">"; + return _name.c_str(); + } + }; } #include @@ -127,3 +136,4 @@ namespace std } }; } + diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index 2fbec10..03502be 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -153,3 +153,7 @@ namespace fc { } // namespace raw } // namespace fc +#include + +FC_REFLECT_TYPENAME( fc::ecc::private_key ) +FC_REFLECT_TYPENAME( fc::ecc::public_key ) diff --git a/include/fc/crypto/sha256.hpp b/include/fc/crypto/sha256.hpp index 96194e0..ea7b17e 100644 --- a/include/fc/crypto/sha256.hpp +++ b/include/fc/crypto/sha256.hpp @@ -95,3 +95,5 @@ namespace std } }; } +#include +FC_REFLECT_TYPENAME( fc::sha256 ) diff --git a/include/fc/crypto/sha512.hpp b/include/fc/crypto/sha512.hpp index fe24a1b..3fa2352 100644 --- a/include/fc/crypto/sha512.hpp +++ b/include/fc/crypto/sha512.hpp @@ -72,3 +72,6 @@ class sha512 void from_variant( const variant& v, sha512& bi ); } // fc + +#include +FC_REFLECT_TYPENAME( fc::sha512 ) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 6468468..411de23 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -37,11 +37,11 @@ namespace fc { template inline void unpack( Stream& s, fc::time_point_sec& tp ) - { + { try { uint32_t sec; s.read( (char*)&sec, sizeof(sec) ); tp = fc::time_point() + fc::seconds(sec); - } + } FC_RETHROW_EXCEPTIONS( warn, "" ) } template inline void pack( Stream& s, const fc::time_point& tp ) @@ -52,11 +52,11 @@ namespace fc { template inline void unpack( Stream& s, fc::time_point& tp ) - { + { try { uint64_t usec; s.read( (char*)&usec, sizeof(usec) ); tp = fc::time_point() + fc::microseconds(usec); - } + } FC_RETHROW_EXCEPTIONS( warn, "" ) } template inline void pack( Stream& s, const fc::array& v) { @@ -64,9 +64,10 @@ namespace fc { } template - inline void unpack( Stream& s, fc::array& v) { + inline void unpack( Stream& s, fc::array& v) + { try { s.read((char*)&v.data[0],N*sizeof(T)); - } + } FC_RETHROW_EXCEPTIONS( warn, "fc::array", ("type",fc::get_typename::name())("length",N) ) } template inline void pack( Stream& s, const signed_int& v ) { uint32_t val = (v.value<<1) ^ (v.value>>31); @@ -119,10 +120,11 @@ namespace fc { } template - void unpack( Stream& s, fc::optional& v ) { + void unpack( Stream& s, fc::optional& v ) + { try { bool b; unpack( s, b ); if( b ) { v = T(); unpack( s, *v ); } - } + } FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename::name() ) ) } // std::vector template inline void pack( Stream& s, const std::vector& value ) { @@ -177,9 +179,10 @@ namespace fc { :c(_c),s(_s){} template - inline void operator()( const char* name )const { + inline void operator()( const char* name )const + { try { raw::unpack( s, c.*p ); - } + } FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) } private: Class& c; Stream& s; @@ -371,9 +374,10 @@ namespace fc { fc::raw::detail::if_reflected< typename fc::reflector::is_defined >::pack(s,v); } template - inline void unpack( Stream& s, T& v ) { + inline void unpack( Stream& s, T& v ) + { try { fc::raw::detail::if_reflected< typename fc::reflector::is_defined >::unpack(s,v); - } + } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename::name() ) ) } template @@ -390,14 +394,15 @@ namespace fc { } template - inline T unpack( const std::vector& s ) { + inline T unpack( const std::vector& s ) + { try { T tmp; if( s.size() ) { datastream ds( s.data(), size_t(s.size()) ); raw::unpack(ds,tmp); } return tmp; - } + } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename::name() ) ) } template inline void pack( char* d, uint32_t s, const T& v ) { @@ -406,18 +411,21 @@ namespace fc { } template - inline T unpack( const char* d, uint32_t s ) { + inline T unpack( const char* d, uint32_t s ) + { try { T v; datastream ds( d, s ); raw::unpack(ds,v); return v; - } + } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename::name() ) ) } + template - inline void unpack( const char* d, uint32_t s, T& v ) { + inline void unpack( const char* d, uint32_t s, T& v ) + { try { datastream ds( d, s ); raw::unpack(ds,v); return v; - } + } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename::name() ) ) } } } // namespace fc::raw diff --git a/include/fc/time.hpp b/include/fc/time.hpp index 204d586..06d40e3 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -111,6 +111,10 @@ namespace fc { string get_approximate_relative_time_string(const time_point& event_time); } +#include +FC_REFLECT_TYPENAME( fc::time_point ) +FC_REFLECT_TYPENAME( fc::time_point_sec ) + #ifdef _MSC_VER #pragma warning (pop) #endif /// #ifdef _MSC_VER From fd00bddcb4b057161e431a267e72ac1d79be13a6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 17 May 2014 16:38:32 -0400 Subject: [PATCH 10/31] update logging to create parent directory if it does not exist --- include/fc/string.hpp | 3 +++ src/log/file_appender.cpp | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/fc/string.hpp b/include/fc/string.hpp index 4ba03cd..889164a 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -16,6 +16,9 @@ namespace fc fc::string to_string( uint64_t ); fc::string to_string( int64_t ); fc::string to_string( uint16_t ); +#ifdef __APPLE__ + inline fc::string to_string( size_t s) { return to_string(uint64_t(s)); } +#endif typedef fc::optional ostring; class variant_object; diff --git a/src/log/file_appender.cpp b/src/log/file_appender.cpp index 35d27ca..9e2b979 100644 --- a/src/log/file_appender.cpp +++ b/src/log/file_appender.cpp @@ -7,13 +7,14 @@ #include #include #include +#include namespace fc { class file_appender::impl : public fc::retainable { public: - config cfg; - ofstream out; + config cfg; + ofstream out; boost::mutex slock; }; file_appender::config::config( const fc::path& p ) @@ -25,8 +26,10 @@ namespace fc { { try { my->cfg = args.as(); + fc::create_directories( fc::path( my->cfg.filename.string() ).parent_path() ); my->out.open( my->cfg.filename.string().c_str() ); } catch ( ... ) { + std::cerr << "error opening log file: " << my->cfg.filename.string() << "\n"; //elog( "%s", fc::except_str().c_str() ); } } From ce131bae43277a20c6ec31275b16289233fdb7f5 Mon Sep 17 00:00:00 2001 From: HackFisher Date: Sun, 18 May 2014 16:37:06 +0800 Subject: [PATCH 11/31] Fix compile error under windows Error 1 error C2668: 'fc::to_string' : ambiguous call to overloaded function --- include/fc/string.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/fc/string.hpp b/include/fc/string.hpp index 889164a..ff5207b 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -18,6 +18,8 @@ namespace fc fc::string to_string( uint16_t ); #ifdef __APPLE__ inline fc::string to_string( size_t s) { return to_string(uint64_t(s)); } +#elif defined( WIN32 ) + inline fc::string to_string( size_t s ) { return to_string(uint64_t(s)); } #endif typedef fc::optional ostring; From 013b9a867f98e65c585212497502f806ce6e782a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 18 May 2014 21:14:51 -0400 Subject: [PATCH 12/31] reflect typename of variant --- include/fc/variant.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index d9e83b1..7d2690f 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -427,3 +427,6 @@ namespace fc } } // namespace fc + +#include +FC_REFLECT_TYPENAME( fc::variant ) From 6b455ab8508f7f33b432e268c0d99551fd5c9200 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Mon, 19 May 2014 02:52:21 -0400 Subject: [PATCH 13/31] Fix typos --- src/crypto/aes.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/crypto/aes.cpp b/src/crypto/aes.cpp index 3f0933f..954f0b4 100644 --- a/src/crypto/aes.cpp +++ b/src/crypto/aes.cpp @@ -38,7 +38,7 @@ void aes_encoder::init( const fc::sha256& key, const fc::uint128& init_value ) * is 128 bits */ if(1 != EVP_EncryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption init", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption init", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } EVP_CIPHER_CTX_set_padding( my->ctx, 0 ); @@ -52,7 +52,7 @@ uint32_t aes_encoder::encode( const char* plaintxt, uint32_t plaintext_len, char * */ if(1 != EVP_EncryptUpdate(my->ctx, (unsigned char*)ciphertxt, &ciphertext_len, (const unsigned char*)plaintxt, plaintext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption update", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } FC_ASSERT( ciphertext_len == plaintext_len, "", ("ciphertext_len",ciphertext_len)("plaintext_len",plaintext_len) ); @@ -67,7 +67,7 @@ uint32_t aes_encoder::final_encode( char* ciphertxt ) * */ if(1 != EVP_EncryptFinal_ex(my->ctx, (unsigned char*)ciphertxt, &ciphertext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption final", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption final", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } return ciphertext_len; @@ -98,7 +98,7 @@ void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value ) * is 128 bits */ if(1 != EVP_DecryptInit_ex(my->ctx, EVP_aes_256_cbc(), NULL, (unsigned char*)&key, (unsigned char*)&init_value)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption init", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption init", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } EVP_CIPHER_CTX_set_padding( my->ctx, 0 ); @@ -115,7 +115,7 @@ uint32_t aes_decoder::decode( const char* ciphertxt, uint32_t plaintext_len, cha * */ if(1 != EVP_DecryptUpdate(my->ctx, (unsigned char*)plaintext, &ciphertext_len, (const unsigned char*)ciphertxt, plaintext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption update", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } FC_ASSERT( ciphertext_len == plaintext_len, "", ("ciphertext_len",ciphertext_len)("plaintext_len",plaintext_len) ); @@ -131,7 +131,7 @@ uint32_t aes_decoder::final_decode( char* plaintext ) * */ if(1 != EVP_DecryptFinal_ex(my->ctx, (unsigned char*)plaintext, &ciphertext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption final", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption final", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } return ciphertext_len; @@ -172,7 +172,7 @@ int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, * is 128 bits */ if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption init", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption init", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } @@ -181,7 +181,7 @@ int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, * */ if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption update", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } ciphertext_len = len; @@ -191,7 +191,7 @@ int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, * */ if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc encryption final", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc encryption final", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } ciphertext_len += len; @@ -220,7 +220,7 @@ int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *ke * * is 128 bits */ if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt init", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc decrypt init", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } @@ -229,7 +229,7 @@ int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *ke * */ if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt update", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc decrypt update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } @@ -240,7 +240,7 @@ int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *ke * */ if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt final", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc decrypt final", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } plaintext_len += len; @@ -269,7 +269,7 @@ int aes_cfb_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char * * is 128 bits */ if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cfb128(), NULL, key, iv)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt init", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc decrypt init", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } @@ -278,7 +278,7 @@ int aes_cfb_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char * */ if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt update", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc decrypt update", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } @@ -289,7 +289,7 @@ int aes_cfb_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char * */ if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) { - FC_THROW_EXCEPTION( exception, "error durring aes 256 cbc decrypt final", + FC_THROW_EXCEPTION( exception, "error during aes 256 cbc decrypt final", ("s", ERR_error_string( ERR_get_error(), nullptr) ) ); } plaintext_len += len; From c4770f0819d4aa24d3b6d5f9b7ac7b479330bd3f Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Mon, 19 May 2014 14:12:49 -0400 Subject: [PATCH 14/31] Restore correct parsing of json keywords (true/false/null) --- src/io/json.cpp | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index 641164b..208406b 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -276,10 +276,12 @@ namespace fc std::stringstream ss; ss.exceptions( std::ifstream::badbit ); bool received_eof = false; + bool done = false; + try { char c; - while((c = in.peek()) ) + while((c = in.peek()) && !done) { switch( c ) { @@ -295,7 +297,8 @@ namespace fc ss.put( in.get() ); break; default: - return ss.str() + stringFromToken(in); + done = true; + break; } } } @@ -307,22 +310,29 @@ namespace fc // we can get here either by processing a delimiter as in "null," // an EOF like "null", or an invalid token like "nullZ" fc::string str = ss.str(); - if( str == "null" ) return variant(); - if( str == "true" ) return true; - if( str == "false" ) return false; + if( str == "null" ) + return variant(); + if( str == "true" ) + return true; + if( str == "false" ) + return false; else { if (received_eof) - FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" ); + { + if (str.empty()) + FC_THROW_EXCEPTION( parse_error_exception, "Unexpected EOF" ); + else + return str; + } else { - // I'm not sure why we do this, a comment would be helpful. // if we've reached this point, we've either seen a partial // token ("tru") or something our simple parser couldn't // make out ("falfe") - return str; - // FC_THROW_EXCEPTION( parse_error_exception, "Invalid token '${token}'", - // ("token",str) ); + // A strict JSON parser would signal this as an error, but we + // will just treat the malformed token as an un-quoted string. + return str + stringFromToken(in);; } } } From 87c314facb469fd5d70e9240e1bc26038a27fb1e Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 19 May 2014 15:22:19 -0400 Subject: [PATCH 15/31] raw serialization of std::map --- include/fc/io/raw.hpp | 24 ++++++++++++++++++++++++ include/fc/io/raw_fwd.hpp | 2 ++ 2 files changed, 26 insertions(+) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index 411de23..b4ec029 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #define MAX_ARRAY_ALLOC_SIZE (1024*1024*10) @@ -319,6 +320,29 @@ namespace fc { value.insert( std::move(tmp) ); } } + template + inline void pack( Stream& s, const std::map& value ) { + pack( s, unsigned_int(value.size()) ); + auto itr = value.begin(); + auto end = value.end(); + while( itr != end ) { + fc::raw::pack( s, *itr ); + ++itr; + } + } + template + inline void unpack( Stream& s, std::map& value ) + { + unsigned_int size; unpack( s, size ); + value.clear(); + FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE ); + for( uint32_t i = 0; i < size.value; ++i ) + { + std::pair tmp; + fc::raw::unpack( s, tmp ); + value.insert( std::move(tmp) ); + } + } template diff --git a/include/fc/io/raw_fwd.hpp b/include/fc/io/raw_fwd.hpp index cf17bd5..922782e 100644 --- a/include/fc/io/raw_fwd.hpp +++ b/include/fc/io/raw_fwd.hpp @@ -30,6 +30,8 @@ namespace fc { template inline void pack( Stream& s, const std::unordered_map& value ); template inline void unpack( Stream& s, std::unordered_map& value ); + template inline void pack( Stream& s, const std::map& value ); + template inline void unpack( Stream& s, std::map& value ); template inline void pack( Stream& s, const std::pair& value ); template inline void unpack( Stream& s, std::pair& value ); From 8a8ff28221bbc4605fada6ba20b5f066b30c562f Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 19 May 2014 16:59:01 -0400 Subject: [PATCH 16/31] adding '/' to token chars to support paths --- src/io/json.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/json.cpp b/src/io/json.cpp index 208406b..e96cb25 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -118,7 +118,7 @@ namespace fc in.get(); return token.str(); default: - if( isalnum( c ) || c == '_' || c == '-' || c == '.' || c == ':' ) + if( isalnum( c ) || c == '_' || c == '-' || c == '.' || c == ':' || c == '/' ) { token << c; in.get(); From 174096c3ab2e06156df8c47c935b36cddf7ac29e Mon Sep 17 00:00:00 2001 From: HackFisher Date: Tue, 20 May 2014 19:17:19 +0800 Subject: [PATCH 17/31] Fix issue #25 eofbit std exception is replaced by eof_exception, checked in peek(), so no need to throw std exception when encounter EOF. --- src/io/sstream.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/io/sstream.cpp b/src/io/sstream.cpp index 28a5aac..aed1575 100644 --- a/src/io/sstream.cpp +++ b/src/io/sstream.cpp @@ -9,13 +9,13 @@ namespace fc { public: impl( fc::string&s ) :ss( s ) - { ss.exceptions( std::stringstream::badbit | std::stringstream::eofbit ); } + { ss.exceptions( std::stringstream::badbit ); } impl( const fc::string&s ) :ss( s ) - { ss.exceptions( std::stringstream::badbit | std::stringstream::eofbit ); } + { ss.exceptions( std::stringstream::badbit ); } - impl(){ss.exceptions( std::stringstream::badbit | std::stringstream::eofbit ); } + impl(){ss.exceptions( std::stringstream::badbit ); } std::stringstream ss; }; From 17aefe29de21fc77d089389b049d3934793789c5 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 20 May 2014 11:25:31 -0400 Subject: [PATCH 18/31] using explicit bool operator for optional --- include/fc/filesystem.hpp | 2 +- include/fc/io/fstream.hpp | 2 +- include/fc/optional.hpp | 5 ++++- include/fc/variant.hpp | 2 +- src/filesystem.cpp | 2 +- src/log/logger_config.cpp | 4 ++-- src/network/url.cpp | 12 ++++++------ 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/fc/filesystem.hpp b/include/fc/filesystem.hpp index bd091b5..d1a9c31 100644 --- a/include/fc/filesystem.hpp +++ b/include/fc/filesystem.hpp @@ -159,7 +159,7 @@ namespace fc { { public: inline ~temp_file_base() { remove(); } - inline operator bool() const { return _path; } + inline operator bool() const { return _path.valid(); } inline bool operator!() const { return !_path; } const fc::path& path() const; void remove(); diff --git a/include/fc/io/fstream.hpp b/include/fc/io/fstream.hpp index fe05a9a..a11f915 100644 --- a/include/fc/io/fstream.hpp +++ b/include/fc/io/fstream.hpp @@ -29,7 +29,7 @@ namespace fc { enum seekdir { beg, cur, end }; ifstream(); - ifstream( const fc::path& file, int m ); + ifstream( const fc::path& file, int m = binary); ~ifstream(); void open( const fc::path& file, int m ); diff --git a/include/fc/optional.hpp b/include/fc/optional.hpp index 594bf18..a4e774d 100644 --- a/include/fc/optional.hpp +++ b/include/fc/optional.hpp @@ -183,7 +183,10 @@ namespace fc { bool valid()const { return _valid; } bool operator!()const { return !_valid; } - operator bool()const { return _valid; } + + // this operation is not safe and can result in unintential + // casts and comparisons, use valid() or !! + explicit operator bool()const { return _valid; } T& operator*() { assert(_valid); return ref(); } const T& operator*()const { assert(_valid); return ref(); } diff --git a/include/fc/variant.hpp b/include/fc/variant.hpp index 7d2690f..4bed054 100644 --- a/include/fc/variant.hpp +++ b/include/fc/variant.hpp @@ -238,7 +238,7 @@ namespace fc variant( const optional& v ) { memset( this, 0, sizeof(*this) ); - if( v ) *this = variant(*v); + if( v.valid() ) *this = variant(*v); } template diff --git a/src/filesystem.cpp b/src/filesystem.cpp index a95aae7..7b4b8ec 100644 --- a/src/filesystem.cpp +++ b/src/filesystem.cpp @@ -356,7 +356,7 @@ namespace fc { void temp_file_base::remove() { - if (_path) + if (_path.valid()) { try { diff --git a/src/log/logger_config.cpp b/src/log/logger_config.cpp index 22465de..413be71 100644 --- a/src/log/logger_config.cpp +++ b/src/log/logger_config.cpp @@ -36,11 +36,11 @@ namespace fc { auto lgr = logger::get( cfg.loggers[i].name ); // TODO: finish configure logger here... - if( cfg.loggers[i].parent ) { + if( cfg.loggers[i].parent.valid() ) { lgr.set_parent( logger::get( *cfg.loggers[i].parent ) ); } lgr.set_name(cfg.loggers[i].name); - if( cfg.loggers[i].level ) lgr.set_log_level( *cfg.loggers[i].level ); + if( cfg.loggers[i].level.valid() ) lgr.set_log_level( *cfg.loggers[i].level ); for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){ diff --git a/src/network/url.cpp b/src/network/url.cpp index 23a7e79..3456b3c 100644 --- a/src/network/url.cpp +++ b/src/network/url.cpp @@ -59,7 +59,7 @@ namespace fc _path = fc::path( "/" ) / _lpath; #endif fc::getline( ss, _largs ); - if( _args && _args->size() ) + if( _args.valid() && _args->size() ) { // TODO: args = fc::move(_args); } @@ -88,16 +88,16 @@ namespace fc { fc::stringstream ss; ss<_proto<<"://"; - if( my->_user ) { + if( my->_user.valid() ) { ss << *my->_user; - if( my->_pass ) { + if( my->_pass.valid() ) { ss<<":"<<*my->_pass; } ss<<"@"; } - if( my->_host ) ss<<*my->_host; - if( my->_port ) ss<<":"<<*my->_port; - if( my->_path ) ss<_path->generic_string(); + if( my->_host.valid() ) ss<<*my->_host; + if( my->_port.valid() ) ss<<":"<<*my->_port; + if( my->_path.valid() ) ss<_path->generic_string(); // if( my->_args ) ss<<"?"<<*my->_args; return ss.str(); } From b5828dc750321e85cd7245ad86d13299c334f02e Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 20 May 2014 12:31:05 -0400 Subject: [PATCH 19/31] adding extra to_string variants --- include/fc/string.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/fc/string.hpp b/include/fc/string.hpp index ff5207b..b262c90 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -16,6 +16,8 @@ namespace fc fc::string to_string( uint64_t ); fc::string to_string( int64_t ); fc::string to_string( uint16_t ); + inline fc::string to_string( int32_t v ) { return to_string( int64_t(v) ); } + inline fc::string to_string( uint32_t v ){ return to_string( uint64_t(v) ); } #ifdef __APPLE__ inline fc::string to_string( size_t s) { return to_string(uint64_t(s)); } #elif defined( WIN32 ) From 6b9abdf272a0fc456748e582cef4dbac9767894c Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 20 May 2014 13:42:21 -0400 Subject: [PATCH 20/31] adding raw::pack_size() helper --- include/fc/io/raw.hpp | 7 +++++++ include/fc/time.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/include/fc/io/raw.hpp b/include/fc/io/raw.hpp index b4ec029..564af9d 100644 --- a/include/fc/io/raw.hpp +++ b/include/fc/io/raw.hpp @@ -403,6 +403,13 @@ namespace fc { fc::raw::detail::if_reflected< typename fc::reflector::is_defined >::unpack(s,v); } FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename::name() ) ) } + template + inline size_t pack_size( const T& v ) + { + datastream ps; + raw::pack(ps,v ); + return ps.tellp(); + } template inline std::vector pack( const T& v ) { diff --git a/include/fc/time.hpp b/include/fc/time.hpp index 06d40e3..f14c4f0 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -25,6 +25,7 @@ namespace fc { microseconds& operator+=(const microseconds& c) { _count += c._count; return *this; } microseconds& operator-=(const microseconds& c) { _count -= c._count; return *this; } int64_t count()const { return _count; } + int64_t to_seconds()const { return _count/1000000; } private: friend class time_point; int64_t _count; From d2e2311d72417f7de4f12533a53c89378756f10a Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Tue, 20 May 2014 16:40:17 -0400 Subject: [PATCH 21/31] Removed old versions of base-16/58/64 conversion headers from fc/io, they have moved to fc/crypto --- include/fc/io/base16.hpp | 13 ------------- include/fc/io/base58.hpp | 8 -------- include/fc/io/base64.hpp | 10 ---------- 3 files changed, 31 deletions(-) delete mode 100644 include/fc/io/base16.hpp delete mode 100644 include/fc/io/base58.hpp delete mode 100644 include/fc/io/base64.hpp diff --git a/include/fc/io/base16.hpp b/include/fc/io/base16.hpp deleted file mode 100644 index f3ca29e..0000000 --- a/include/fc/io/base16.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include -#include - -namespace fc { - uint8_t from_hex( char c ); - fc::string to_hex( const char* d, uint32_t s ); - - /** - * @return the number of bytes decoded - */ - size_t from_hex( const fc::string& hex_str, char* out_data, size_t out_data_len ); -} diff --git a/include/fc/io/base58.hpp b/include/fc/io/base58.hpp deleted file mode 100644 index 71beb15..0000000 --- a/include/fc/io/base58.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -namespace fc { - fc::string to_base58( const char* d, size_t s ); - fc::vector from_base58( const fc::string& base58_str ); - size_t from_base58( const fc::string& base58_str, char* out_data, size_t out_data_len ); -} diff --git a/include/fc/io/base64.hpp b/include/fc/io/base64.hpp deleted file mode 100644 index 3a69a2e..0000000 --- a/include/fc/io/base64.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _FC_BASE64_HPP -#define _FC_BASE64_HPP -#include - -namespace fc { -std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len); -std::string base64_encode( const std::string& enc ); -std::string base64_decode( const std::string& encoded_string); -} // namespace fc -#endif // _FC_BASE64_HPP From cb6014eecc939eab76cbf0f5601bc00b69e3dfcf Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Tue, 20 May 2014 17:10:38 -0400 Subject: [PATCH 22/31] Remove to_string overload on size_t for win32, it now conflicts with the uint32_t case --- include/fc/string.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/fc/string.hpp b/include/fc/string.hpp index b262c90..b0303ef 100644 --- a/include/fc/string.hpp +++ b/include/fc/string.hpp @@ -20,8 +20,6 @@ namespace fc inline fc::string to_string( uint32_t v ){ return to_string( uint64_t(v) ); } #ifdef __APPLE__ inline fc::string to_string( size_t s) { return to_string(uint64_t(s)); } -#elif defined( WIN32 ) - inline fc::string to_string( size_t s ) { return to_string(uint64_t(s)); } #endif typedef fc::optional ostring; From 5719d28a190358427836f2d492443384b2a902cc Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Tue, 20 May 2014 18:02:20 -0400 Subject: [PATCH 23/31] Move/rename git revision info compiled into FC to be more self-explanatory --- CMakeLists.txt | 8 ++++---- GitSHA3.cpp.in | 7 ------- GitSHA3.h | 9 --------- include/fc/git_revision.hpp | 9 +++++++++ src/git_revision.cpp.in | 11 +++++++++++ 5 files changed, 24 insertions(+), 20 deletions(-) delete mode 100644 GitSHA3.cpp.in delete mode 100644 GitSHA3.h create mode 100644 include/fc/git_revision.hpp create mode 100644 src/git_revision.cpp.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 87ceef0..4f306a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,8 @@ INCLUDE( VersionMacros ) INCLUDE( SetupTargetMacros ) INCLUDE(GetGitRevisionDescription) -get_git_head_revision(GIT_REFSPEC GIT_SHA3) -get_git_unix_timestamp(GIT_UNIX_TIMESTAMP3) +get_git_head_revision(GIT_REFSPEC FC_GIT_REVISION_SHA) +get_git_unix_timestamp(FC_GIT_REVISION_UNIX_TIMESTAMP) SET( DEFAULT_HEADER_INSTALL_DIR include/\${target} ) SET( DEFAULT_LIBRARY_INSTALL_DIR lib/ ) @@ -168,8 +168,8 @@ set( sources ${fc_sources} ) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/GitSHA3.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/GitSHA3.cpp" @ONLY) -list(APPEND sources "${CMAKE_CURRENT_BINARY_DIR}/GitSHA3.cpp" GitSHA3.h) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/git_revision.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp" @ONLY) +list(APPEND sources "${CMAKE_CURRENT_BINARY_DIR}/git_revision.cpp") list(APPEND sources ${fc_headers}) add_subdirectory( vendor/easylzma ) diff --git a/GitSHA3.cpp.in b/GitSHA3.cpp.in deleted file mode 100644 index 045015e..0000000 --- a/GitSHA3.cpp.in +++ /dev/null @@ -1,7 +0,0 @@ -#include -#include "GitSHA3.h" - -#define GIT_SHA3 "@GIT_SHA3@" -const char* const g_GIT_SHA3 = GIT_SHA3; -#define GIT_UNIX_TIMESTAMP3 @GIT_UNIX_TIMESTAMP3@ -const uint32_t g_GIT_UNIX_TIMESTAMP3 = GIT_UNIX_TIMESTAMP3; diff --git a/GitSHA3.h b/GitSHA3.h deleted file mode 100644 index cb8830e..0000000 --- a/GitSHA3.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __GITSHA3_H -#define __GITSHA3_H - -extern const char* const g_GIT_SHA3; -extern const uint32_t g_GIT_UNIX_TIMESTAMP3; - -#define APPLICATION_VERSION "1.0 Beta1" - -#endif ///__GITSHA3_H diff --git a/include/fc/git_revision.hpp b/include/fc/git_revision.hpp new file mode 100644 index 0000000..6232f3c --- /dev/null +++ b/include/fc/git_revision.hpp @@ -0,0 +1,9 @@ +#pragma once +#include + +namespace fc { + +extern const char* const git_revision_sha; +extern const uint32_t git_revision_unix_timestamp; + +} // end namespace fc diff --git a/src/git_revision.cpp.in b/src/git_revision.cpp.in new file mode 100644 index 0000000..40977b7 --- /dev/null +++ b/src/git_revision.cpp.in @@ -0,0 +1,11 @@ +#include + +#define FC_GIT_REVISION_SHA "@FC_GIT_REVISION_SHA@" +#define FC_GIT_REVISION_UNIX_TIMESTAMP @FC_GIT_REVISION_UNIX_TIMESTAMP@ + +namespace fc { + +const char* const git_revision_sha = FC_GIT_REVISION_SHA; +const uint32_t git_revision_unix_timestamp = FC_GIT_REVISION_UNIX_TIMESTAMP; + +} // end namespace fc From 1eac85e9e6888e8ee5a66fb1cc55bda2c3d58372 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Tue, 20 May 2014 19:02:13 -0400 Subject: [PATCH 24/31] Update .gitignore --- .gitignore | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index bbccfeb..f1cf69a 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ *.a *.lib - #CMake->MSVC artifacts *.sln *.vcxproj @@ -41,5 +40,7 @@ libfc.a libfc_debug.a fc_automoc.cpp -*.swp +git_revision.cpp GitSHA3.cpp + +*.swp From ba4839198a083c159c31d14ce62dbe08c4d794fc Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 21 May 2014 03:11:07 -0400 Subject: [PATCH 25/31] Update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f1cf69a..5fc5eea 100644 --- a/.gitignore +++ b/.gitignore @@ -43,4 +43,4 @@ fc_automoc.cpp git_revision.cpp GitSHA3.cpp -*.swp +*.sw* From c9529c8f8781486f4ad691cc3163e4a268b66dce Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Thu, 22 May 2014 03:52:59 -0400 Subject: [PATCH 26/31] Return synonym "uint160_t" for uint160 typename to not break leveldb upgrade routine --- include/fc/crypto/ripemd160.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fc/crypto/ripemd160.hpp b/include/fc/crypto/ripemd160.hpp index e2d13a9..998b01d 100644 --- a/include/fc/crypto/ripemd160.hpp +++ b/include/fc/crypto/ripemd160.hpp @@ -77,7 +77,7 @@ class ripemd160 typedef ripemd160 uint160_t; typedef ripemd160 uint160; - template<> struct get_typename { static const char* name() { return "uint160"; } }; + template<> struct get_typename { static const char* name() { return "uint160_t"; } }; } // namespace fc From 9bafe4d64fc5bd0bb0aba6fc24e747d614689630 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Thu, 22 May 2014 04:52:30 -0400 Subject: [PATCH 27/31] Remove unnecessary compiler flags to get rid of Clang warning messages --- CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f306a1..b7a68cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,13 +186,13 @@ IF(WIN32) # Add /U options to be sure settings specific to dynamic boost link are ineffective target_compile_options(fc PUBLIC /EHsc /UBOOST_ALL_DYN_LINK /UBOOST_LINKING_PYTHON /UBOOST_DEBUG_PYTHON) ELSE() - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall" ) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall") IF(APPLE) - SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -stdlib=libc++ -Wall" ) + SET(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++11 -stdlib=libc++ -Wall") ELSE() - target_compile_options(fc PUBLIC -std=c++11 -Wall -fnon-call-exceptions -Wno-unused-local-typedefs -fmax-errors=3) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-local-typedefs -fmax-errors=3 ") + target_compile_options(fc PUBLIC -std=c++11 -Wall -fnon-call-exceptions) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") ENDIF() ENDIF() From 9874fc907603b742245043614d37ad8169c771ab Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 22 May 2014 14:24:31 -0400 Subject: [PATCH 28/31] adding != operator to fc::microseconds --- include/fc/time.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/fc/time.hpp b/include/fc/time.hpp index f14c4f0..888eefd 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -18,6 +18,7 @@ namespace fc { bool operator==(const microseconds& c)const { return _count == c._count; } + bool operator!=(const microseconds& c)const { return _count != c._count; } friend bool operator>(const microseconds& a, const microseconds& b){ return a._count > b._count; } friend bool operator>=(const microseconds& a, const microseconds& b){ return a._count >= b._count; } friend bool operator<(const microseconds& a, const microseconds& b){ return a._count < b._count; } From ba45a9b09034b4ad477b3aa904ad47c4d8d5a205 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 22 May 2014 14:56:52 -0400 Subject: [PATCH 29/31] improve error reporting on std::exceptions --- include/fc/exception/exception.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fc/exception/exception.hpp b/include/fc/exception/exception.hpp index 5b02e24..9a54db8 100644 --- a/include/fc/exception/exception.hpp +++ b/include/fc/exception/exception.hpp @@ -239,10 +239,10 @@ do { if( !(TEST) ) { FC_THROW_EXCEPTION( assert_exception, #TEST ": " __VA_ARGS catch( fc::exception& er ) { \ FC_RETHROW_EXCEPTION( er, LOG_LEVEL, FORMAT, __VA_ARGS__ ); \ } catch( const std::exception& e ) { \ - throw fc::std_exception( \ - FC_LOG_MESSAGE( LOG_LEVEL, FORMAT,__VA_ARGS__), \ + fc::std_exception fce( \ + FC_LOG_MESSAGE( LOG_LEVEL, "what: ${what} - " FORMAT,__VA_ARGS__("what",e.what())), \ std::current_exception(), \ - e.what() ) ; \ + e.what() ) ; throw fce;\ } catch( ... ) { \ throw fc::unhandled_exception( \ FC_LOG_MESSAGE( LOG_LEVEL, FORMAT,__VA_ARGS__), \ From 7c3767c2082d417cfe439da843d7ff39b7f7e859 Mon Sep 17 00:00:00 2001 From: vogel76 Date: Fri, 23 May 2014 17:37:20 +0200 Subject: [PATCH 30/31] [BW]: [NIP] Changes to support shared libraries build on linux and further installationpackage configuration --- CMakeLists.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f306a1..d754e76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,10 +38,6 @@ LIST(APPEND BOOST_COMPONENTS thread date_time system filesystem program_options IF( WIN32 ) MESSAGE(STATUS "Configuring fc to build on Win32") - #You need to set OPENSSL_ROOT environment variable for your system on WIN32 - message(STATUS "Setting up OpenSSL root and include vars on Win32 platform") - set( OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT} ) - set( RPCRT4 Rpcrt4 ) #boost @@ -77,7 +73,13 @@ ELSE(WIN32) ENDIF(NOT APPLE) ENDIF(WIN32) -find_package( OpenSSL ) +#IF($ENV{OPENSSL_ROOT_DIR}) + set(OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT_DIR} ) + set(OPENSSL_INCLUDE_DIR ${OPENSSL_ROOT_DIR}/include) + message(STATUS "Setting up OpenSSL root and include vars to ${OPENSSL_ROOT_DIR}, ${OPENSSL_INCLUDE_DIR}") +#ENDIF() + +find_package(OpenSSL) set( CMAKE_FIND_LIBRARY_SUFFIXES ${ORIGINAL_LIB_SUFFIXES} ) From c1ff37889bd0022c7884b836ee1fbc22ac97008b Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Fri, 23 May 2014 18:03:27 -0400 Subject: [PATCH 31/31] Add + operator to time_point_sec --- include/fc/time.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/fc/time.hpp b/include/fc/time.hpp index 888eefd..22e577f 100644 --- a/include/fc/time.hpp +++ b/include/fc/time.hpp @@ -95,6 +95,7 @@ namespace fc { friend bool operator != ( const time_point_sec& a, const time_point_sec& b ) { return a.utc_seconds != b.utc_seconds; } time_point_sec& operator += ( uint32_t m ) { utc_seconds+=m; return *this; } time_point_sec& operator -= ( uint32_t m ) { utc_seconds-=m; return *this; } + time_point_sec operator+( uint32_t offset ) { return time_point_sec(utc_seconds + offset); } friend time_point operator - ( const time_point_sec& t, const microseconds& m ) { return time_point(t) - m; } friend microseconds operator - ( const time_point_sec& t, const time_point_sec& m ) { return time_point(t) - time_point(m); }