1
0

Begin move to CMake

This commit is contained in:
Scott E. Graves
2017-03-15 12:22:19 -05:00
parent 2da20611cb
commit 28674d716a
5 changed files with 13758 additions and 0 deletions

19
CMakeLists.txt Normal file
View File

@@ -0,0 +1,19 @@
project(siadrive)
cmake_minimum_required(VERSION 3.3)
#Common Configuration
set(3RD_PARTY_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/3rd-party/ttmath-0.9.3)
set(COMMON_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/siadrive_api)
include_directories(${3RD_PARTY_INCLUDES} ${COMMON_INCLUDES})
add_definitions(-DTTMATH_NOASM)
#SiaDrive API Library
file(GLOB_RECURSE SIADRIVE_API_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/siadrive_api/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/siadrive_api/*.cxx ${CMAKE_CURRENT_SOURCE_DIR}/src/siadrive_api/*.c)
add_library(siadrive.api SHARED ${SIADRIVE_API_SOURCES})
set_target_properties(siadrive.api
PROPERTIES COMPILE_FLAGS -DSIADRIVE_EXPORT_SYMBOLS
)
if (MSVC OR MINGW)
target_link_libraries(siadrive.api Shlwapi.lib)
endif()

12703
include/siadrive_api/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,206 @@
#ifndef _SIACOMMON_H
#define _SIACOMMON_H
#ifdef _WIN32
// Unicode for Win32
#define UNICODE
#define _UNICODE
// _WIN32_WINNT version constants
#define _WIN32_WINNT_NT4 0x0400 // Windows NT 4.0
#define _WIN32_WINNT_WIN2K 0x0500 // Windows 2000
#define _WIN32_WINNT_WINXP 0x0501 // Windows XP
#define _WIN32_WINNT_WS03 0x0502 // Windows Server 2003
#define _WIN32_WINNT_WIN6 0x0600 // Windows Vista
#define _WIN32_WINNT_VISTA 0x0600 // Windows Vista
#define _WIN32_WINNT_WS08 0x0600 // Windows Server 2008
#define _WIN32_WINNT_LONGHORN 0x0600 // Windows Vista
#define _WIN32_WINNT_WIN7 0x0601 // Windows 7
#define _WIN32_WINNT_WIN8 0x0602 // Windows 8
#define _WIN32_WINNT_WINBLUE 0x0603 // Windows 8.1
#define _WIN32_WINNT_WINTHRESHOLD 0x0A00 // Windows 10
#define _WIN32_WINNT_WIN10 0x0A00 // Windows 10
// Windows 8.1 or above supported
#define WINVER _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT _WIN32_WINNT_WINBLUE
#include <Windows.h>
#include <Shlwapi.h>
// Import or export functions and/or classes
#ifdef SIADRIVE_EXPORT_SYMBOLS
#define SIADRIVE_EXPORTABLE __declspec(dllexport)
#else
#define SIADRIVE_EXPORTABLE __declspec(dllimport)
#endif //SIADRIVE_EXPORT_SYMBOLS
#else
#define SIADRIVE_EXPORT_SYMBOLS
#endif
#include <cstdint>
#include <memory>
#include <json.hpp>
#include <ttmath/ttmath.h>
#include <sstring.h>
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)
class StartupException :
public std::exception
{
public:
StartupException(const SString& reason) :
std::exception(SString::ToUtf8(reason).c_str())
{
}
StartupException(const std::string& reason) :
std::exception(reason.c_str())
{
}
};
#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<type>();}\
set_access:\
type Set##name(const type& value) { json_doc[#name] = value; return value; }
typedef struct
{
SString HostName;
std::uint16_t HostPort;
SString RequiredVersion;
} SiaHostConfig;
template<typename T>
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 SString& value)
{
ttmath::Parser<SiaCurrency> parser;
parser.Parse((value + " / (10^24)").str());
return parser.stack[0].value;
}
inline static SString 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<typename T, typename R>
inline static R CalculateAveragePrice(const std::vector<T>& v, std::function<R(const T& t)> 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<IHost>& hosts)
{
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetStoragePrice(); });
}
inline static Hastings CalculateAverageDownloadPrice(const std::vector<IHost>& hosts)
{
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetDownloadPrice(); });
}
inline static Hastings CalculateAverageUploadPrice(const std::vector<IHost>& hosts)
{
return CalculateAveragePrice<IHost, Hastings>(hosts, [](const IHost& host)->Hastings { return host.GetUploadPrice(); });
}
template<typename T>
static T& ReplaceStringInPlace(T& subject, const T& search, const T& replace)
{
size_t pos = 0;
while ((pos = subject.find(search, pos)) != SString::npos)
{
subject.replace(pos, search.length(), replace);
pos += replace.length();
}
return subject;
}
template<typename T>
inline static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, const T& replace)
{
return ReplaceStringInPlace(subject, T(search), replace);
}
template<typename T>
inline static T& ReplaceStringInPlace(T& subject, typename T::value_type* search, typename T::value_type* replace)
{
return ReplaceStringInPlace(subject, T(search), T(replace));
}
BOOL SIADRIVE_EXPORTABLE RetryAction(std::function<BOOL()> func, std::uint16_t retryCount, const DWORD& retryDelay);
BOOL SIADRIVE_EXPORTABLE RetryDeleteFileIfExists(const SString& filePath);
SString SIADRIVE_EXPORTABLE GenerateSha256(const SString& str);
BOOL SIADRIVE_EXPORTABLE RecurDeleteFilesByExtentsion(const SString& folder, const SString& extensionWithDot);
#define RetryableAction(exec, count, delayMs) RetryAction([&]()->BOOL{return exec;}, count, delayMs)
#define DEFAULT_RETRY_COUNT 10
#define DEFAULT_RETRY_DELAY_MS 1000
NS_END(2)
#endif //_SIACOMMON_H

View File

@@ -0,0 +1,704 @@
#ifndef _SSTRING_H
#define _SSTRING_H
#include <algorithm>
#include <vector>
#include <locale>
#include <sstream>
#include <istream>
#include <ostream>
#include <unordered_map>
class SString
{
public:
#ifdef _UNICODE
typedef wchar_t SChar;
#else
typedef char SChar;
#endif
typedef std::basic_string<SChar> String;
typedef std::vector<SString> SStringVector;
typedef std::basic_stringstream<SChar> SStringStream;
typedef std::basic_istringstream<SChar> ISStringStream;
typedef std::vector<SChar> SCharVector;
typedef std::basic_ifstream<SChar> SCharIfStream;
typedef std::basic_ofstream<SChar> SCharOfStream;
typedef std::unordered_map<SString, SString> SStringMap;
typedef String::iterator SIterator;
typedef String::const_iterator SConstIterator;
typedef String::reverse_iterator SReverseIterator;
typedef String::const_reverse_iterator SConstReverseIterator;
private:
template<class Facet>
struct deletable_facet :
Facet
{
template<class ...Args>
deletable_facet(Args &&...args) :
Facet(std::forward<Args>(args)...)
{
}
~deletable_facet()
{
}
};
public:
#ifdef _UNICODE
static std::wstring ActiveString(const std::string& str)
{
return std::move(FromUtf8(str));
}
static inline std::wstring ActiveString(const std::wstring& str)
{
return str;
}
#else
static inline std::string ActiveString(const std::wstring& str)
{
return std::move(ToUtf8(str));
}
static inline std::string ActiveString(const std::string& str)
{
return str;
}
#endif
static inline std::string ToUtf8(const std::wstring &str)
{
std::wstring_convert<deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>, wchar_t> conv;
return conv.to_bytes(str);
}
static inline std::wstring FromUtf8(const std::string &str)
{
std::wstring_convert<deletable_facet<std::codecvt<wchar_t, char, std::mbstate_t>>, wchar_t> conv;
return conv.from_bytes(str);
}
static inline String &LeftTrim(String &s)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
return s;
}
static inline String &RightTrim(String &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
static inline String &Trim(String &s)
{
return LeftTrim(RightTrim(s));
}
static inline std::int32_t ToInt32(const SString &str)
{
return std::stoi(str.str());
}
static inline SString FromInt32(const std::int32_t &value)
{
return std::move(SString(std::to_string(value)));
}
static inline std::uint8_t ToUInt8(const SString &str)
{
return (std::uint8_t) std::stoi(str.str());
}
static inline SString FromUInt8(const std::uint8_t &value)
{
return std::move(SString(std::to_string(value)));
}
static inline float ToFloat(const SString &str)
{
return std::stof(str.str());
}
static inline SString FromFloat(const float &value)
{
return std::move(SString(std::to_string(value)));
}
static inline long ToLong(const SString &str)
{
return std::stol(str.str());
}
static inline SString FromLong(const long &value)
{
return std::move(SString(std::to_string(value)));
}
static inline double ToDouble(const SString &str)
{
return std::stod(str.str());
}
static inline SString FromDouble(const double &value)
{
return std::move(SString(std::to_string(value)));
}
static bool ToBool(const SString& value)
{
SString str = value.ToLowerCopy();
SString::ISStringStream is(str);
bool b;
is >> std::boolalpha >> b;
return b;
}
static inline SString FromBool(const bool& value)
{
return (value ? "True" : "False");
}
static std::vector<const char*> ToCharArray(const std::vector<std::string>& v)
{
std::vector<const char*> ret;
for (const auto& s : v)
{
ret.push_back(&s[0]);
}
return std::move(ret);
}
#ifdef _UNICODE
static std::vector<std::string> ToUtf8Array(const SStringVector& v)
{
std::vector<std::string> ret;
for (const auto& s : v)
{
ret.push_back(ToUtf8(s.str()));
}
return std::move(ret);
}
#else
static std::vector<std::string> ToUtf8Array(const SStringVector& v)
{
std::vector<std::string> ret;
for (const auto& s : v)
{
ret.push_back(s.str());
}
return std::move(ret);
}
#endif
public:
SString()
{
}
SString(const std::string &str) :
#ifdef _UNICODE
_str(std::move(SString::FromUtf8(str)))
#else
_str(str)
#endif
{
}
SString(const char *str) :
#ifdef _UNICODE
_str(std::move(SString::FromUtf8(str)))
#else
_str(str)
#endif
{
}
SString(const std::wstring &str) :
#ifdef _UNICODE
_str(str)
#else
_str(std::move(SString::ToUtf8(str)))
#endif
{
}
SString(const wchar_t *str) :
#ifdef _UNICODE
_str(str)
#else
_str(std::move(SString::ToUtf8(str)))
#endif
{
}
SString(const char &c) :
#ifdef _UNICODE
_str(1, (wchar_t)c)
#else
_str(1, c)
#endif
{
}
SString(const wchar_t &c) :
#ifdef _UNICODE
_str(1, c)
#else
_str(1, (wchar_t) c)
#endif
{
}
SString(const SString &str) :
_str(str.str())
{
}
SString(SString &&str) noexcept :
_str(std::move(str.str()))
{
}
SString(const SCharVector::const_iterator& begin, const SCharVector::const_iterator& end) :
_str(begin, end)
{
}
SString(const SCharVector::const_reverse_iterator& rbegin, const SCharVector::const_reverse_iterator& rend) :
_str(rbegin, rend)
{
}
SString(const SConstIterator& begin, const SConstIterator& end) :
_str(begin, end)
{
}
SString(const SConstReverseIterator& rbegin, const SConstReverseIterator& rend) :
_str(rbegin, rend)
{
}
public:
virtual ~SString()
{
}
private:
String _str;
public:
bool BeginsWith(const SString& str) const
{
return (IndexOf(str) == 0);
}
bool EndsWith(const SString& str) const
{
if (str.Length() > Length()) return false;
return std::equal(str.str().rbegin(), str.str().rend(), _str.rbegin());
}
SString &ToLower()
{
std::transform(_str.begin(), _str.end(), _str.begin(), ::tolower);
return *this;
}
SString ToLowerCopy() const
{
String str = _str;
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return std::move(str);
}
bool IsEmpty() const
{
return _str.empty();
}
bool IsNull() const
{
return _str.c_str() == nullptr;
}
bool IsNullOrEmpty() const
{
return (_str.c_str() == nullptr) || _str.empty();
}
size_t Length() const
{
return _str.size();
}
size_t ByteLength() const
{
return _str.size() * sizeof(SChar);
}
bool Contains(const SString &str) const
{
return (_str.find(str.str()) != _str.npos);
}
size_t IndexOf(const SString &str) const
{
return _str.find(str.str());
}
size_t LastIndexOf(const SString::SChar & c) const
{
return _str.find_last_of(c);
}
size_t LastIndexOf(const SString& str) const
{
return _str.find_last_of(str.str());
}
#ifdef _UNICODE
SString &Replace(const char &character, const char &with)
{
return Replace(SString(character)[0], SString(with)[0]);
}
#else
SString &Replace(const wchar_t &character, const wchar_t &with)
{
return Replace(SString(character)[0], SString(with)[0]);
}
#endif
SString &Replace(const SChar &character, const SChar &with)
{
std::replace(_str.begin(), _str.end(), character, with);
return *this;
}
#ifdef _UNICODE
SString ReplaceCopy(const char &character, const char &with) const
{
SString copy = _str;
return std::move(copy.Replace((SChar) character, (SChar) with));
}
#endif
SString ReplaceCopy(const SChar &character, const SChar &with) const
{
SString copy = _str;
return std::move(copy.Replace(character, with));
}
SString& Replace(const SString& str, const SString& with, size_t startPos = 0)
{
if (!_str.empty() && (startPos < _str.size()))
{
while ((startPos = _str.find(str._str, startPos)) != String::npos)
{
_str.replace(startPos, str._str.length(), with._str);
startPos += with.Length();
}
}
return *this;
}
SString ReplaceCopy(const SString& str, const SString& with, size_t startPos = 0) const
{
return std::move(SString(_str).Replace(str, with, startPos));
}
inline void Resize(const String::size_type& size)
{
_str.resize(size);
}
#ifdef _UNICODE
SStringVector Split(const char &delim, const bool &trim = true) const
{
return Split((wchar_t)delim, trim);
}
#endif
SStringVector Split(const SChar &delim, const bool &trim = true) const
{
SStringVector elems;
SStringStream ss(_str);
String item;
while (std::getline(ss, item, delim))
{
elems.push_back(trim ? Trim(item) : item);
}
return std::move(elems);
}
SString& TrimLeft()
{
LeftTrim(_str);
return *this;
}
SString TrimLeftCopy() const
{
String copy(_str);
return std::move(LeftTrim(copy));
}
SString& TrimRight()
{
RightTrim(_str);
return *this;
}
SString TrimRightCopy() const
{
String copy(_str);
return std::move(RightTrim(copy));
}
SString& Trim()
{
Trim(_str);
return *this;
}
SString TrimCopy() const
{
String copy(_str);
return std::move(Trim(copy));
}
SString SubString(const size_t &start, const size_t &count) const
{
if (count && (start < _str.size()))
{
return _str.substr(start, count);
}
#ifdef _UNICODE
return SString(L"");
#else
return SString("");
#endif
}
SString SubString(const size_t &start) const
{
if (start < _str.size())
{
return _str.substr(start);
}
#ifdef _UNICODE
return SString(L"");
#else
return SString("");
#endif
}
inline SIterator begin() noexcept
{
return _str.begin();
}
inline SIterator end() noexcept
{
return _str.end();
}
inline SConstIterator begin() const noexcept
{
return _str.begin();
}
inline SConstIterator end() const noexcept
{
return _str.end();
}
inline SReverseIterator rbegin() noexcept
{
return _str.rbegin();
}
inline SReverseIterator rend() noexcept
{
return _str.rend();
}
inline SConstReverseIterator rbegin() const noexcept
{
return _str.rbegin();
}
inline SConstReverseIterator rend() const noexcept
{
return _str.rend();
}
inline SConstIterator cbegin() const noexcept
{
return _str.cbegin();
}
inline SConstIterator cend() const noexcept
{
return _str.end();
}
inline SConstReverseIterator crbegin() const noexcept
{
return _str.crbegin();
}
inline SConstReverseIterator crend() const noexcept
{
return _str.crend();
}
public:
const String& str() const { return _str; }
public:
SString&operator=(const SString& str)
{
if (this != &str)
{
_str = str._str;
}
return *this;
}
SString&operator=(SString&& str) noexcept
{
if (this != &str)
{
_str = std::move(str._str);
}
return *this;
}
operator std::string() const
{
#ifdef _UNICODE
return std::move(SString::ToUtf8(_str));
#else
return _str;
#endif
}
operator std::wstring() const
{
#ifdef _UNICODE
return _str;
#else
return std::move(SString::FromUtf8(_str));
#endif
}
SString &operator+=(const SString &s)
{
_str += s.str();
return *this;
}
bool operator==(const SString &s) const
{
return _str == s.str();
}
bool operator!=(const SString &s) const
{
return _str != s.str();
}
bool operator<(const SString &s) const
{
return _str < s.str();
}
bool operator<=(const SString &s) const
{
return _str <= s.str();
}
bool operator>(const SString &s) const
{
return _str > s.str();
}
bool operator>=(const SString &s) const
{
return _str >= s.str();
}
SChar &operator[](const size_t &idx)
{
return _str[idx];
}
const SChar &operator[](const size_t &idx) const
{
return _str[idx];
}
explicit operator const SChar *() const
{
return _str.c_str();
}
};
static SString operator+(const SString &s1, const SString s2)
{
return SString(s1.str() + s2.str());
}
namespace std
{
template<>
struct hash<SString>
{
typedef SString argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const &s) const
{
return std::hash<SString::String>()(s.str());
}
};
}
#endif //_SSTRING_H

View File

@@ -0,0 +1,126 @@
#include <siacommon.h>
#include <ttmath/ttmath.h>
#ifdef _WIN32
#include <Wincrypt.h>
#endif
NS_BEGIN(Sia)
NS_BEGIN(Api)
SString GenerateSha256(const SString& str)
{
#ifdef _WIN32
SString ret;
HCRYPTPROV hCryptProv = 0;
HCRYPTHASH hHash = 0;
BOOL ok = CryptAcquireContext(&hCryptProv, nullptr, nullptr, PROV_RSA_AES, 0);
ok = ok && CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash);
ok = ok && CryptHashData(hHash, reinterpret_cast<const BYTE*>(&str[0]), str.ByteLength(), 0);
if (ok)
{
DWORD dwHashLen;
DWORD dwCount = sizeof(DWORD);
if (CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE *>(&dwHashLen), &dwCount, 0))
{
std::vector<unsigned char> hash(dwHashLen);
if (CryptGetHashParam(hHash, HP_HASHVAL, reinterpret_cast<BYTE *>(&hash[0]), &dwHashLen, 0))
{
std::ostringstream ss;
ss << std::hex << std::uppercase << std::setfill('0');
for (int c : hash)
{
ss << std::setw(2) << c;
}
ret = ss.str();
}
}
}
if (hHash) CryptDestroyHash(hHash);
if (hCryptProv) CryptReleaseContext(hCryptProv, 0);
return ret;
#else
#endif
}
BOOL RecurDeleteFilesByExtentsion(const SString& folder, const SString& extensionWithDot)
{
#ifdef _WIN32
BOOL ret = FALSE;
WIN32_FIND_DATA fd = { 0 };
SString search;
search.Resize(MAX_PATH + 1);
::PathCombine(&search[0], folder.str().c_str(), L"*.*");
HANDLE find = ::FindFirstFile(search.str().c_str(), &fd);
if (find != INVALID_HANDLE_VALUE)
{
ret = TRUE;
do
{
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if ((SString(fd.cFileName) != ".") && (SString(fd.cFileName) != ".."))
{
SString nextFolder;
nextFolder.Resize(MAX_PATH + 1);
::PathCombine(&nextFolder[0], folder.str().c_str(), fd.cFileName);
ret = RecurDeleteFilesByExtentsion(nextFolder, extensionWithDot);
}
}
else
{
SString ext = ::PathFindExtension(fd.cFileName);
if (ext == extensionWithDot)
{
SString filePath;
filePath.Resize(MAX_PATH + 1);
::PathCombine(&filePath[0], folder.str().c_str(), fd.cFileName);
ret = RetryDeleteFileIfExists(filePath.str().c_str());
}
}
} while (ret && (::FindNextFile(find, &fd) != 0));
}
return ret;
#else
#endif
}
BOOL RetryDeleteFileIfExists(const SString& filePath)
{
#ifdef _WIN32
BOOL ret = TRUE;
if (::PathFileExists(filePath.str().c_str()))
{
ret = RetryableAction(::DeleteFile(filePath.str().c_str()), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS);
}
return ret;
#else
#endif
}
BOOL RetryAction(std::function<BOOL()> func, std::uint16_t retryCount, const DWORD& retryDelay)
{
#ifdef _WIN32
BOOL ret = FALSE;
while (retryCount-- && !((ret = func())))
{
::Sleep(retryDelay);
}
return ret;
#else
#endif
}
NS_END(2)