Begin move to CMake
This commit is contained in:
19
CMakeLists.txt
Normal file
19
CMakeLists.txt
Normal 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
12703
include/siadrive_api/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
206
include/siadrive_api/siacommon.h
Normal file
206
include/siadrive_api/siacommon.h
Normal 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
|
704
include/siadrive_api/sstring.h
Normal file
704
include/siadrive_api/sstring.h
Normal 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
|
126
src/siadrive_api/siacommon.cpp
Normal file
126
src/siadrive_api/siacommon.cpp
Normal 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)
|
Reference in New Issue
Block a user