#pragma once #include #include #include #include "json.hpp" #include using json = nlohmann::json; #define NS_BEGIN(n) namespace n { #define NS_END1() } #define NS_END2() NS_END1() } #define NS_END3() NS_END2() } #define NS_END4() NS_END3() } #define NS_END5() NS_END4() } #define NS_END(c) NS_END##c() NS_BEGIN(Sia) NS_BEGIN(Api) typedef std::wstring String; #define DEFAULT_CONFIG_FILE_PATH L".\\Config\\SiaDriveConfig.json" #define Property(type, name, get_access, set_access) \ private:\ type _##name;\ get_access:\ const type& Get##name() const { return _##name;}\ set_access:\ const type& Set##name(const type& value) { _##name = value; return _##name; } #define JProperty(type, name, get_access, set_access, json_doc) \ get_access:\ type Get##name() const { return json_doc[#name].get();}\ set_access:\ type Set##name(const type& value) { json_doc[#name] = value; return value; } struct SiaHostConfig { String HostName; std::uint16_t HostPort; String RequiredVersion; }; template inline bool ApiSuccess(const T& t) { return t == T::Success; } typedef ttmath::UInt<256> Hastings; typedef ttmath::Big<1, 30> SiaCurrency; /* BigNumber.config({ EXPONENTIAL_AT: 1e+9 }) BigNumber.config({ DECIMAL_PLACES: 30 }) const hastingsPerSiacoin = new BigNumber('10').toPower(24) const siacoinsToHastings = (siacoins) => new BigNumber(siacoins).times(hastingsPerSiacoin) const hastingsToSiacoins = (hastings) => new BigNumber(hastings).dividedBy(hastingsPerSiacoin) */ inline static SiaCurrency HastingsStringToSiaCurrency(const String& value) { ttmath::Parser parser; parser.Parse(value + L" / (10^24)"); return parser.stack[0].value; } inline static String SiaCurrencyToString(const SiaCurrency& value) { ttmath::Conv conv; conv.base = 10; conv.round = 8; return value.ToWString(conv); } class IHost { public: IHost() {} virtual ~IHost() {} public: virtual Hastings GetStoragePrice() const = 0; virtual Hastings GetDownloadPrice() const = 0; virtual Hastings GetUploadPrice() const = 0; }; template inline static R CalculateAveragePrice(const std::vector& v, std::function PriceGetter) { R result = v.size() ? std::accumulate(std::next(v.begin()), v.end(), PriceGetter(v[0]), [&](const R& a, const T& b) { return a + PriceGetter(b); }).Div(v.size()) : 0; return result; } inline static Hastings CalculateAverageHostPrice(const std::vector& hosts) { return CalculateAveragePrice(hosts, [](const IHost& host)->Hastings { return host.GetStoragePrice(); }); } inline static Hastings CalculateAverageDownloadPrice(const std::vector& hosts) { return CalculateAveragePrice(hosts, [](const IHost& host)->Hastings { return host.GetDownloadPrice(); }); } inline static Hastings CalculateAverageUploadPrice(const std::vector& hosts) { return CalculateAveragePrice(hosts, [](const IHost& host)->Hastings { return host.GetUploadPrice(); }); } template static T& ReplaceStringInPlace(T& subject, const T& search, const T& replace) { size_t pos = 0; while ((pos = subject.find(search, pos)) != std::string::npos) { subject.replace(pos, search.length(), replace); pos += replace.length(); } return subject; } template inline static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, const T& replace) { return ReplaceStringInPlace(subject, T(search), replace); } template inline static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, typename T::value_type* replace) { return ReplaceStringInPlace(subject, T(search), T(replace)); } static BOOL RetryAction(std::function func, std::uint16_t retryCount, const DWORD& retryDelay) { BOOL ret = FALSE; while (retryCount-- && !((ret = func()))) { ::Sleep(retryDelay); } return ret; } #define RetryableAction(exec, count, delayMs) RetryAction([&]()->BOOL{return exec;}, count, delayMs) #define DEFAULT_RETRY_COUNT 10 #define DEFAULT_RETRY_DELAY_MS 1000 static BOOL RetryDeleteFileIfExists(const String& filePath) { BOOL ret = TRUE; if (::PathFileExists(filePath.c_str())) { ret = RetryableAction(::DeleteFile(filePath.c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS); } return ret; } String AFX_EXT_API GenerateSha256(const String& str); NS_END(2)