1
0

initial commit

This commit is contained in:
2025-10-21 07:58:47 -05:00
commit 19adc4e2b0
144 changed files with 107723 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
#ifndef _SIADRIVEAPP_H
#define _SIADRIVEAPP_H
#include <siacommon.h>
#include <include/cef_app.h>
NS_BEGIN(Sia)
namespace Api
{
class CAutoThread;
class CSiaApi;
class CSiaCurl;
class CSiaDriveConfig;
#ifdef _WIN32
namespace Dokan
{
class CSiaDokanDrive;
}
#else
a
#endif
}
class CSiaDriveApp :
public CefApp,
public CefRenderProcessHandler,
public CefBrowserProcessHandler
{
public:
CSiaDriveApp();
virtual ~CSiaDriveApp();
private:
std::shared_ptr<Api::CSiaDriveConfig> _siaDriveConfig;
std::unique_ptr<Api::CAutoThread> _refreshThread;
std::unique_ptr<Api::CSiaApi> _siaApi;
#ifdef _WIN32
std::unique_ptr<Api::Dokan::CSiaDokanDrive> _siaDrive;
#else
a
#endif
bool _appStarted = false;
bool _formingContracts = false;
SString _walletReceiveAddress;
public:
// CefApp methods:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE
{
return this;
}
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() OVERRIDE
{
return this;
}
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE;
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) OVERRIDE;
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) OVERRIDE;
private:
static void ExecuteSetter(CefRefPtr<CefV8Context> context, CefRefPtr<CefV8Value> obj, const SString& method, const SString& value);
static void ExecuteSetter(CefRefPtr<CefV8Context> context, CefRefPtr<CefV8Value> obj, const SString& method, CefRefPtr<CefV8Value> value);
void ShutdownServices(CefRefPtr<CefBrowser> browser);
void SiaApiRefreshCallback(CefRefPtr<CefV8Context> context);
void ReleaseObjects(CefRefPtr<CefBrowser> browser);
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(CSiaDriveApp);
};
NS_END(1)
#endif //_SIADRIVEAPP_H

View File

@@ -0,0 +1,75 @@
#ifndef _SIADRIVEHANDLER_H
#define _SIADRIVEHANDLER_H
#include <siacommon.h>
#include <include/cef_client.h>
#include <include/cef_load_handler.h>
#include <include/cef_life_span_handler.h>
#include <include/cef_display_handler.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class CSiaDriveConfig;
NS_END(1)
class CSiaDriveHandler :
public CefClient,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler
{
public:
explicit CSiaDriveHandler();
~CSiaDriveHandler();
// Provide access to the single global instance of this object.
static CSiaDriveHandler* GetInstance();
// CefClient methods:
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE
{
return this;
}
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE
{
return this;
}
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE
{
return this;
}
// CefDisplayHandler methods:
virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE;
// CefLifeSpanHandler methods:
virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE;
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) OVERRIDE;
void CloseAllBrowsers(bool forceClose);
bool IsClosing() const { return _isClosing; }
private:
void PlatformTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title);
private:
bool _isClosing;
bool _active;
std::shared_ptr<Api::CSiaDriveConfig> _siaDriveConfig;
bool _closeConfirmed;
bool _waitingConfirmation;
bool _allowClose;
typedef std::list<CefRefPtr<CefBrowser> > BrowserList;
BrowserList _browserList;
IMPLEMENT_REFCOUNTING(CSiaDriveHandler);
};
NS_END(1)
#endif //_SIADRIVEHANDLER_H

View File

@@ -0,0 +1,39 @@
#ifndef _AUTOTHREAD_H
#define _AUTOTHREAD_H
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class CSiaDriveConfig;
class CSiaCurl;
class SIADRIVE_EXPORTABLE CAutoThread
{
public:
CAutoThread(CSiaDriveConfig* siaDriveConfig);
CAutoThread(CSiaDriveConfig* siaDriveConfig, std::function<void(CSiaDriveConfig*)> autoThreadCallback);
public:
virtual ~CAutoThread();
private:
bool _stopRequested;
CSiaDriveConfig* _siaDriveConfig;
std::function<void(CSiaDriveConfig*)> _AutoThreadCallback;
std::unique_ptr<std::thread> _thread;
std::mutex _startStopMutex;
std::mutex _stopMutex;
std::condition_variable _stopEvent;
protected:
virtual void AutoThreadCallback(CSiaDriveConfig* siaDriveConfig);
public:
bool IsRunning() const;
void StartAutoThread();
void StopAutoThread();
};
NS_END(2)
#endif //_AUTOTHREAD_H

View File

@@ -0,0 +1,148 @@
#ifndef BASE64_H
#define BASE64_H
#include <string>
const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
class Base64 {
public:
static bool Encode(const BYTE *input, size_t input_length, std::vector<BYTE>& data) {
int i = 0, j = 0;
BYTE a3[3];
BYTE a4[4];
size_t encoded_length = EncodedLength(input_length);
data.resize(EncodedLength(input_length));
BYTE* out = &data[0];
BYTE* out_begin = out;
while (input_length--) {
a3[i++] = *input++;
if (i == 3) {
a3_to_a4(a4, a3);
for (i = 0; i < 4; i++) {
*out++ = kBase64Alphabet[a4[i]];
}
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for (j = 0; j < i + 1; j++) {
*out++ = kBase64Alphabet[a4[j]];
}
while ((i++ < 3)) {
*out++ = '=';
}
}
return (out == (out_begin + encoded_length));
}
static bool Decode(BYTE* input, size_t input_length, std::vector<BYTE>& output) {
int i = 0, j = 0;
BYTE a3[3];
BYTE a4[4];
size_t decoded_length = DecodedLength(input, input_length);
output.resize(decoded_length);
BYTE* out = &output[0];
BYTE *out_begin = out;
while (input_length--) {
if (*input == '=') {
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
for (i = 0; i < 3; i++) {
*out++ = a3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
a4[j] = '\0';
}
for (j = 0; j < 4; j++) {
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
for (j = 0; j < i - 1; j++) {
*out++ = a3[j];
}
}
return (out == (out_begin + decoded_length));
}
static int DecodedLength(const BYTE *in, size_t in_length) {
int numEq = 0;
const BYTE *in_end = in + in_length;
while (*--in_end == '=') ++numEq;
return ((6 * in_length) / 8) - numEq;
}
inline static int EncodedLength(size_t length) {
return (length + 2 - ((length + 2) % 3)) / 3 * 4;
}
inline static void StripPadding(std::string *in) {
while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1);
}
private:
static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
static inline unsigned char b64_lookup(unsigned char c) {
if(c >='A' && c <='Z') return c - 'A';
if(c >='a' && c <='z') return c - 71;
if(c >='0' && c <='9') return c + 4;
if(c == '+') return 62;
if(c == '/') return 63;
return 255;
}
};
#endif // BASE64_H

View File

@@ -0,0 +1,24 @@
#ifndef _DEBUGCONSUMER_H
#define _DEBUGCONSUMER_H
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class CEvent;
class SIADRIVE_EXPORTABLE CDebugConsumer
{
public:
CDebugConsumer();
public:
~CDebugConsumer();
private:
void ProcessEvent(const CEvent& eventData);
};
NS_END(2);
#endif //_DEBUGCONSUMER_H

View File

@@ -0,0 +1,85 @@
#ifndef _EVENTSYSTEM_H
#define _EVENTSYSTEM_H
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
enum class EventLevel
{
Error,
Normal,
Debug,
Verbose
};
EventLevel SIADRIVE_EXPORTABLE EventLevelFromString(const SString& eventLevel);
class SIADRIVE_EXPORTABLE CEvent
{
public:
CEvent(const EventLevel& eventLevel = EventLevel::Normal) :
_eventLevel(eventLevel)
{}
virtual ~CEvent() {}
private:
const EventLevel _eventLevel;
public:
const EventLevel& GetEventLevel() const { return _eventLevel; }
virtual SString GetSingleLineMessage() const = 0;
virtual std::shared_ptr<CEvent> Clone() const = 0;
virtual SString GetEventName() const = 0;
virtual json GetEventJson() const = 0;
};
typedef std::shared_ptr<CEvent> CEventPtr;
#define CreateSystemEvent(E) CEventPtr(new E)
#define CreateSystemEventConsumer(E) [=](const CEvent&) -> void { E(e); }
CEventPtr SIADRIVE_EXPORTABLE CreateSystemCriticalEvent(const SString& reason);
// Singleton
class SIADRIVE_EXPORTABLE CEventSystem
{
private:
CEventSystem();
private:
~CEventSystem();
public:
// Singleton setup
CEventSystem(const CEventSystem&) = delete;
CEventSystem(CEventSystem&&) = delete;
CEventSystem& operator=(CEventSystem&&) = delete;
CEventSystem& operator=(const CEventSystem&) = delete;
private:
#ifdef _WIN32
HANDLE _stopEvent;
#endif
std::deque<CEventPtr> _eventQueue;
std::deque<std::function<void(const CEvent&)>> _eventConsumers;
std::deque<std::function<bool(const CEvent&)>> _oneShotEventConsumers;
std::mutex _eventMutex;
std::unique_ptr<std::thread> _processThread;
std::mutex _oneShotMutex;
public:
static CEventSystem EventSystem;
private:
void ProcessEvents();
public:
void AddEventConsumer(std::function<void(const CEvent&)> consumer);
void AddOneShotEventConsumer(std::function<bool(const CEvent&)> consumer);
void NotifyEvent(CEventPtr eventData);
void Start();
void Stop();
};
NS_END(2)
#endif //_EVENTSYSTEM_H

View File

@@ -0,0 +1,63 @@
#ifndef _FILEPATH_H
#define _FILEPATH_H
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class SIADRIVE_EXPORTABLE FilePath
{
public:
FilePath();
FilePath(const FilePath& filePath);
FilePath(const SString& path);
FilePath(const FilePath& filePath1, const FilePath& filePath2);
FilePath(const FilePath& filePath1, const SString& path2);
FilePath(const SString& path1, const FilePath& filePath2);
FilePath(const SString& path1, const SString& path2);
FilePath(FilePath&& filePath);
public:
~FilePath();
public:
static const SString DirSep;
public:
static SString FinalizePath(const SString& path);
static SString GetTempDirectory();
static SString GetAppDataDirectory();
private:
#ifdef _WIN32
const ComInitWrapper cw;
#endif
SString _path;
public:
FilePath& Append(const FilePath& filePath);
FilePath& Append(const SString& path);
bool IsDirectory() const;
bool IsFile() const;
bool IsUNC() const;
bool CreateDirectory() const;
bool RemoveDirectory() const;
bool DeleteFile() const;
bool MoveFile(const FilePath& filePath);
FilePath& RemoveFileName();
FilePath& MakeAbsolute();
FilePath& SkipRoot();
FilePath& StripToFileName();
bool CreateEmptyFile();
FilePath& Resolve();
public:
FilePath& operator=(const FilePath& filePath);
FilePath& operator=(FilePath&& filePath);
SString::SChar& operator[](const size_t& idx);
const SString::SChar& operator[](const size_t& idx) const;
operator SString() const;
};
NS_END(2)
#endif //_FILEPATH_H

13006
include/siadrive_api/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
#ifndef _LOGGINGCONSUMER_H
#define _LOGGINGCONSUMER_H
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class CEvent;
enum class EventLevel;
class SIADRIVE_EXPORTABLE CLoggingConsumer
{
public:
CLoggingConsumer(const EventLevel& eventLevel);
public:
~CLoggingConsumer();
Property(EventLevel, EventLevel, public, public)
private:
void ProcessEvent(const CEvent& eventData);
};
NS_END(2)
#endif //_LOGGINGCONSUMER_H

View File

@@ -0,0 +1,305 @@
#ifndef _SIAAPI_H
#define _SIAAPI_H
#include <siacommon.h>
#include <siacurl.h>
#include <autothread.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class CSiaDriveConfig;
class SIADRIVE_EXPORTABLE CSiaBase
{
public:
explicit CSiaBase(CSiaDriveConfig* siaDriveConfig) :
_siaDriveConfig(siaDriveConfig)
{
}
public:
virtual ~CSiaBase() = 0
{
}
private:
CSiaDriveConfig* _siaDriveConfig;
public:
inline CSiaDriveConfig& GetSiaDriveConfig() const
{
return *_siaDriveConfig;
}
};
class SIADRIVE_EXPORTABLE CSiaApi
{
public:
enum class _SiaApiErrorCode
{
Success,
NotImplemented,
NotConnected,
RequestError,
WalletExists,
WalletLocked,
WalletUnlocked,
WalletNotCreated
};
enum class _SiaSeedLanguage
{
English,
German,
Japanese
};
class _CSiaFileTree;
class SIADRIVE_EXPORTABLE _CSiaFile :
public virtual CSiaBase
{
friend CSiaApi;
friend _CSiaFileTree;
public:
explicit _CSiaFile(CSiaDriveConfig* siaDriveConfig, const json& fileJson);
public:
virtual ~_CSiaFile();
// Properties
Property(SString, SiaPath, public, private)
Property(std::uint64_t, FileSize, public, private)
Property(bool, Available, public, private)
Property(bool, Renewing, public, private)
Property(std::uint32_t, Redundancy, public, private)
Property(std::uint32_t, UploadProgress, public, private)
Property(std::uint32_t, Expiration, public, private)
};
class SIADRIVE_EXPORTABLE _CSiaFileTree :
public virtual CSiaBase
{
friend CSiaApi;
public:
explicit _CSiaFileTree(CSiaDriveConfig* siaDriveConfig);
public:
virtual ~_CSiaFileTree();
private:
std::shared_ptr<std::vector<std::shared_ptr<_CSiaFile>>> _fileList;
std::mutex _updateMutex;
public:
void BuildTree(const json& result);
std::shared_ptr<std::vector<std::shared_ptr<_CSiaFile>>> GetFileList();
std::vector<std::shared_ptr<_CSiaFile>> Query(SString query);
std::shared_ptr<_CSiaFile> GetFile(const SString& siaPath);
std::vector<SString> QueryDirectories(SString query);
bool FileExists(const SString& siaPath);
};
class SIADRIVE_EXPORTABLE _CSiaWallet :
public virtual CSiaBase
{
friend CSiaApi;
private:
explicit _CSiaWallet(CSiaDriveConfig* siaDriveConfig);
public:
virtual ~_CSiaWallet();
// Properties
Property(bool, Created, public, private)
Property(bool, Locked, public, private)
Property(bool, Connected, public, private)
Property(SiaCurrency, ConfirmedBalance, public, private)
Property(SiaCurrency, UnconfirmedBalance, public, private)
Property(SString, ReceiveAddress, public, private)
private:
virtual void Refresh();
public:
CSiaError<_SiaApiErrorCode> Create(const SString& password, const _SiaSeedLanguage& seedLanguage, SString& seed);
CSiaError<_SiaApiErrorCode> Restore(const SString& seed);
CSiaError<_SiaApiErrorCode> Lock();
CSiaError<_SiaApiErrorCode> Unlock(const SString& password);
CSiaError<_SiaApiErrorCode> Send(const SString& address, const SiaCurrency& amount);
};
class SIADRIVE_EXPORTABLE _CSiaRenter :
public virtual CSiaBase
{
friend CSiaApi;
public:
typedef struct
{
SiaCurrency Funds;
std::uint64_t Hosts;
std::uint64_t Period;
std::uint64_t RenewWindowInBlocks;
} _SiaRenterAllowance;
private:
explicit _CSiaRenter(CSiaDriveConfig* siaDriveConfig);
public:
virtual ~_CSiaRenter();
Property(SiaCurrency, Funds, public, private)
Property(std::uint64_t, Hosts, public, private)
Property(SiaCurrency, Unspent, public, private)
Property(std::uint64_t, TotalUsedBytes, public, private)
Property(std::uint32_t, TotalUploadProgress, public, private)
Property(std::uint64_t, Period, public, private)
Property(std::uint64_t, RenewWindow, public, private)
private:
_SiaRenterAllowance _currentAllowance;
std::shared_ptr<_CSiaFileTree> _fileTree;
SiaCurrency _storageterabytemonth;
SiaCurrency _downloadterabyte;
SiaCurrency _uploadterabyte;
private:
void Refresh();
public:
CSiaError<_SiaApiErrorCode> CalculateEstimatedStorage(const SiaCurrency& funds, SiaCurrency& resultInBytes) const;
CSiaError<_SiaApiErrorCode> CalculateEstimatedStorageCost(SiaCurrency& resultInBytes) const;
CSiaError<_SiaApiErrorCode> CalculateEstimatedDownloadCost(SiaCurrency& result) const;
CSiaError<_SiaApiErrorCode> CalculateEstimatedUploadCost(SiaCurrency& result) const;
CSiaError<_SiaApiErrorCode> DownloadFile(const SString& siaPath, const SString& location) const;
CSiaError<_SiaApiErrorCode> FileExists(const SString& siaPath, bool& exists) const;
_SiaRenterAllowance GetAllowance() const;
CSiaError<_SiaApiErrorCode> GetFileTree(std::shared_ptr<_CSiaFileTree>& siaFileTree) const;
CSiaError<_SiaApiErrorCode> RefreshFileTree( );
CSiaError<_SiaApiErrorCode> RenameFile(const SString& siaPath, const SString& newSiaPath);
CSiaError<_SiaApiErrorCode> RenameFolder(const SString& siaPath, const SString& newSiaPath, std::unordered_map<SString, SString>* renamedMap = nullptr);
CSiaError<_SiaApiErrorCode> SetAllowance(const _SiaRenterAllowance& renterAllowance);
};
class SIADRIVE_EXPORTABLE _CSiaConsensus :
public virtual CSiaBase
{
friend CSiaApi;
private:
explicit _CSiaConsensus(CSiaDriveConfig* siaDriveConfig);
public:
virtual ~_CSiaConsensus();
// Properties
Property(std::uint64_t, Height, public, private)
Property(bool, Synced, public, private)
Property(SString, CurrentBlock, public, private)
private:
void Refresh();
};
class SIADRIVE_EXPORTABLE _CSiaHost :
public virtual CSiaBase
{
friend CSiaApi;
private:
explicit _CSiaHost(CSiaDriveConfig* siaDriveConfig, const json& hostJson);
public:
virtual ~_CSiaHost();
//Properties
Property(bool, AcceptingContracts, public, private)
Property(std::uint64_t, MaxDownloadBatchSize, public, private)
Property(std::uint64_t, MaxDuration, public, private)
Property(std::uint64_t, MaxReviseBatchSize, public, private)
Property(SString, NetAddress, public, private)
Property(std::uint64_t, RemainingStorage, public, private)
Property(std::uint64_t, SectorSize, public, private)
Property(std::uint64_t, TotalStorage, public, private)
Property(SString, UnlockHash, public, private)
Property(std::uint64_t, WindowSize, public, private)
Property(std::pair<SString COMMA SString>, PublicKey, public, private)
};
class SIADRIVE_EXPORTABLE _CSiaHostDb :
public virtual CSiaBase
{
friend CSiaApi;
private:
explicit _CSiaHostDb(CSiaDriveConfig* siaDriveConfig);
public:
virtual ~_CSiaHostDb();
private:
std::shared_ptr<std::vector<std::shared_ptr<_CSiaHost>>> _activeHosts;
private:
void Refresh();
public:
std::shared_ptr<std::vector<std::shared_ptr<_CSiaHost>>> GetActiveHosts() const;
};
public:
explicit CSiaApi(CSiaDriveConfig* siaDriveConfig);
public:
~CSiaApi();
private:
CSiaDriveConfig* _siaDriveConfig;
std::shared_ptr<_CSiaWallet> _wallet;
std::shared_ptr<_CSiaRenter> _renter;
std::shared_ptr<_CSiaConsensus> _consensus;
std::shared_ptr<_CSiaHostDb> _hostDb;
std::unique_ptr<CAutoThread> _refreshThread;
private:
void Refresh();
public:
static SString FormatToSiaPath(SString path);
public:
void StartBackgroundRefresh();
void StopBackgroundRefresh();
std::shared_ptr<_CSiaWallet> GetWallet() const;
std::shared_ptr<_CSiaRenter> GetRenter() const;
std::shared_ptr<_CSiaConsensus> GetConsensus() const;
std::shared_ptr<_CSiaHostDb> GetHostDb() const;
SString GetServerVersion() const;
};
typedef CSiaApi::_SiaApiErrorCode SiaApiErrorCode;
typedef CSiaError<SiaApiErrorCode> SiaApiError;
typedef CSiaApi::_SiaSeedLanguage SiaSeedLanguage;
typedef CSiaApi::_CSiaWallet CSiaWallet;
typedef CSiaApi::_CSiaRenter CSiaRenter;
typedef CSiaRenter::_SiaRenterAllowance SiaRenterAllowance;
typedef CSiaApi::_CSiaConsensus CSiaConsensus;
typedef CSiaApi::_CSiaHostDb CSiaHostDb;
typedef CSiaApi::_CSiaHost CSiaHost;
typedef std::shared_ptr<CSiaHostDb> CSiaHostDbPtr;
typedef std::shared_ptr<CSiaWallet> CSiaWalletPtr;
typedef std::shared_ptr<CSiaRenter> CSiaRenterPtr;
typedef std::shared_ptr<CSiaConsensus> CSiaConsensusPtr;
typedef std::shared_ptr<CSiaHost> CSiaHostPtr;
typedef std::vector<CSiaHostPtr> CSiaHostCollection;
typedef std::shared_ptr<CSiaHostCollection> CSiaHostCollectionPtr;
typedef CSiaApi::_CSiaFile CSiaFile;
typedef std::shared_ptr<CSiaFile> CSiaFilePtr;
typedef std::vector<CSiaFilePtr> CSiaFileCollection;
typedef std::shared_ptr<CSiaFileCollection> CSiaFileCollectionPtr;
typedef CSiaApi::_CSiaFileTree CSiaFileTree;
typedef std::shared_ptr<CSiaFileTree> CSiaFileTreePtr;
NS_END(2)
#endif //_SIAAPI_H

View File

@@ -0,0 +1,256 @@
#ifndef _SIACOMMON_H
#define _SIACOMMON_H
#include <cstdint>
#ifdef _WIN32
// Disable DLL-interface warnings
#pragma warning(disable: 4251)
#pragma warning(disable: 4275)
// 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_WIN7
#define _WIN32_WINNT _WIN32_WINNT_WIN7
#define _WINSOCKAPI_
#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>
#include <thread>
#include <mutex>
#include <unordered_map>
#include <deque>
using json = nlohmann::json;
SIADRIVE_EXPORTABLE extern const char* SIADRIVE_VERSION_STRING;
SIADRIVE_EXPORTABLE extern const char* COMPAT_SIAD_VERSION;
#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()
#define COMMA ,
NS_BEGIN(Sia)
NS_BEGIN(Api)
class FilePath;
class CSiaDriveConfig;
class StartupException :
public std::exception
{
public:
StartupException(const SString& reason) :
std::exception(SString::ToUtf8(reason).c_str())
{
}
};
typedef ttmath::UInt<256> Hastings;
typedef ttmath::Big<1, 30> SiaCurrency;
const std::uint8_t SIA_BLOCK_TIME_MINS = 10;
const std::uint32_t MINUTES_PER_MONTH = (730 * 60);
const std::uint32_t SIA_BLOCKS_PER_MONTH = MINUTES_PER_MONTH / SIA_BLOCK_TIME_MINS;
const std::uint32_t SIA_DEFAULT_HOST_COUNT = 24;
const SiaCurrency SIA_DEFAULT_MINIMUM_FUNDS = 4000;
const std::uint32_t SIA_DEFAULT_CONTRACT_LENGTH = SIA_BLOCKS_PER_MONTH * 3;
const std::uint32_t SIA_DEFAULT_RENEW_WINDOW = SIA_DEFAULT_CONTRACT_LENGTH / 3;
#define DEFAULT_CONFIG_FILE_PATH L"~/siadrive/siadriveconfig.json"
#define DEFAULT_RENTER_DB_FILE_PATH L"~/siadrive/renter_upload.db3"
#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; }\
protected:\
bool Check##name() { return json_doc.find(#name) != json_doc.end(); }
#define JPropertyCb(type, name, get_access, set_access, json_doc, cb) \
get_access:\
type Get##name() const { return json_doc[#name].get<type>();}\
set_access:\
type Set##name(const type& value) { json_doc[#name] = value; cb(value); return value; }\
protected:\
bool Check##name() { return json_doc.find(#name) != json_doc.end(); }
template<typename T>
class CSiaError
{
public:
CSiaError()
{
SetCode(T::Success);
}
CSiaError(const T& t)
{
SetCode(t);
}
CSiaError(const T& code, const SString& reason)
{
SetCode(code);
SetReason(reason);
}
public:
Property(T, Code, public, private)
Property(SString, Reason, public, private)
public:
operator bool() { return GetCode() == T::Success; }
operator bool() const { return GetCode() == T::Success; }
CSiaError& operator=(const T& code) { SetCode(code); return *this; }
};
typedef struct
{
SString HostName;
std::uint16_t HostPort;
SString RequiredVersion;
} SiaHostConfig;
template<typename T>
inline bool ApiSuccess(const T& t) {
return static_cast<bool>(t);
}
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);
}
inline static SString SiaCurrencyToHastingsString(const SiaCurrency& value)
{
ttmath::Parser<SiaCurrency> parser;
parser.Parse(value.ToString() + " * (10 ^ 24)");
ttmath::Conv conv;
conv.scient_from = 256;
conv.base = 10;
conv.round = 0;
SString ret = parser.stack[0].value.ToWString(conv);
return ret;
}
inline static Hastings SiaCurrencyToHastings(const SiaCurrency& currency)
{
ttmath::Parser<SiaCurrency> parser;
parser.Parse(currency.ToString() + " * (10 ^ 24)");
ttmath::Conv conv;
conv.scient_from = 256;
conv.base = 10;
conv.round = 0;
return parser.stack[0].value.ToString(conv);
}
__int64 SIADRIVE_EXPORTABLE FileSize(const SString& filePath);
SString SIADRIVE_EXPORTABLE BytesToFriendlyDisplay(const SiaCurrency& bytes);
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);
#ifdef _WIN32
std::vector<SString> SIADRIVE_EXPORTABLE GetAvailableDrives();
std::int32_t SIADRIVE_EXPORTABLE GetRegistry(const SString& name, const std::int32_t& defaultValue, const bool& user = false);
SString SIADRIVE_EXPORTABLE GetRegistry(const SString& name, const SString& defaultValue, const bool& user = false);
void SIADRIVE_EXPORTABLE SetRegistry(const SString& name, const SString& value);
HRESULT SIADRIVE_EXPORTABLE CreateShortcut(const SString& execPath, const SString& description, const SString& shortcutPath, const bool& minimized);
SString SIADRIVE_EXPORTABLE SecureEncryptString(const SString& name, const SString& data);
SString SIADRIVE_EXPORTABLE SecureDecryptString(const SString& name, const SString& data);
bool SIADRIVE_EXPORTABLE CheckSingleInstance(const SString& name);
class SIADRIVE_EXPORTABLE ComInitWrapper
{
public:
ComInitWrapper();
~ComInitWrapper();
private:
const BOOL _uninit;
};
#endif
bool SIADRIVE_EXPORTABLE ExecuteProcess(CSiaDriveConfig* siaDriveConfig, FilePath process, FilePath workingDir, const bool& waitForExit);
#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,60 @@
#ifndef _SIACURL_H
#define _SIACURL_H
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class SIADRIVE_EXPORTABLE CSiaCurl
{
public:
enum class _SiaCurlErrorCode
{
Success,
ServerVersionMismatch,
InvalidRequiredVersion,
NoResponse,
HttpError,
UnknownFailure
};
typedef std::unordered_map<SString, SString> _HttpParameters;
public:
CSiaCurl();
CSiaCurl(const SiaHostConfig& hostConfig);
public:
~CSiaCurl();
private:
Property(SiaHostConfig, HostConfig, public, public)
public:
static SString UrlEncode(const SString& data, const bool& allowSlash = false);
private:
static SString CSiaCurl::GetApiErrorMessage(const SString& result);
private:
std::string ConstructPath(const SString& relativePath) const;
CSiaError<_SiaCurlErrorCode> _Get(const SString& path, const _HttpParameters& parameters, json& response) const;
bool CheckVersion(CSiaError<_SiaCurlErrorCode>& error) const;
CSiaError<_SiaCurlErrorCode> ProcessResponse(const int& res, const int& httpCode, const std::string& result, json& response) const;
public:
SString GetServerVersion() const;
CSiaError<_SiaCurlErrorCode> Get(const SString& path, json& result) const;
CSiaError<_SiaCurlErrorCode> Get(const SString& path, const _HttpParameters& parameters, json& result) const;
CSiaError<_SiaCurlErrorCode> Post(const SString& path, const _HttpParameters& parameters, json& response) const;
};
typedef CSiaCurl::_SiaCurlErrorCode SiaCurlErrorCode;
typedef CSiaError<SiaCurlErrorCode> SiaCurlError;
typedef CSiaCurl::_HttpParameters HttpParameters;
NS_END(2)
#endif //_SIACURL_H

View File

@@ -0,0 +1,59 @@
#pragma once
#include <siacommon.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class SIADRIVE_EXPORTABLE CSiaDriveConfig
{
public:
CSiaDriveConfig(const bool& autoSave);
CSiaDriveConfig(const bool& autoSave, const SString& filePath);
explicit CSiaDriveConfig(const json& configDoc);
public:
~CSiaDriveConfig();
Property(SString, FilePath, public, private)
JProperty(std::string, Renter_UploadDbFilePath, public, private, _configDocument)
JProperty(std::string, TempFolder, public, private, _configDocument)
JProperty(std::string, CacheFolder, public, public, _configDocument)
JProperty(std::uint16_t, ApiPort, public, public, _configDocument)
JProperty(std::uint16_t, HostPort, public, public, _configDocument)
JProperty(std::uint16_t, RpcPort, public, public, _configDocument)
JProperty(std::uint8_t, MaxUploadCount, public, public, _configDocument)
JProperty(std::string, HostNameOrIp, public, public, _configDocument)
JProperty(bool, LockWalletOnExit, public, public, _configDocument)
JPropertyCb(bool, AutoStartOnLogon, public, public, _configDocument, OnAutoStartOnLogonChanged)
JProperty(bool, LaunchBundledSiad, public, public, _configDocument)
JProperty(bool, LaunchFileMgrOnMount, public, public, _configDocument)
JProperty(std::string, EventLevel, public, public, _configDocument)
JProperty(bool, ConfirmApplicationExit, public, public, _configDocument)
JProperty(bool, CloseToTray, public, public, _configDocument)
JProperty(bool, StoreUnlockPassword, public, public, _configDocument)
JProperty(bool, AutoMountOnUnlock, public, public, _configDocument)
JProperty(std::string, LastMountLocation, public, public, _configDocument)
private:
const bool _autoSave;
json _configDocument;
private:
bool LoadDefaults();
void Load( );
void OnAutoStartOnLogonChanged(const bool& value);
void Save() const;
public:
SiaHostConfig GetHostConfig() const;
SString ToString() const;
};
NS_END(2)

View File

@@ -0,0 +1,753 @@
#ifndef _SSTRING_H
#define _SSTRING_H
#include <algorithm>
#include <vector>
#include <locale>
#include <sstream>
#include <istream>
#include <ostream>
#include <unordered_map>
class SIADRIVE_EXPORTABLE 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::uint32_t ToUInt32(const SString &str)
{
return std::stoul(str.str());
}
static inline SString FromUInt32(const std::uint32_t &value)
{
return std::move(SString(std::to_string(value)));
}
static inline std::int64_t ToInt64(const SString &str)
{
return std::stoi(str.str());
}
static inline SString FromInt64(const std::int64_t &value)
{
return std::move(SString(std::to_string(value)));
}
static inline SString FromUInt64(const std::uint64_t &value)
{
return std::move(SString(std::to_string(value)));
}
static inline std::uint64_t ToUInt64(const SString &str)
{
return std::stoull(str.str());
}
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& Fit()
{
_str = _str.c_str();
return *this;
}
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);
}
SString &ToUpper()
{
std::transform(_str.begin(), _str.end(), _str.begin(), ::toupper);
return *this;
}
SString ToUpperCopy() const
{
String str = _str;
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
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,156 @@
#ifndef CONCURRENT_THREADPOOL_H
#define CONCURRENT_THREADPOOL_H
#include <siacommon.h>
#include <atomic>
#include <thread>
#include <mutex>
#include <array>
#include <list>
#include <functional>
#include <condition_variable>
NS_BEGIN(Sia)
NS_BEGIN(Api)
/**
* Simple ThreadPool that creates `ThreadCount` threads upon its creation,
* and pulls from a queue to get new jobs. The default is 10 threads.
*
* This class requires a number of c++11 features be present in your compiler.
*/
template <unsigned ThreadCount = 10>
class ThreadPool {
std::array<std::thread, ThreadCount> threads;
std::list<std::function<void(void)>> queue;
std::atomic_int jobs_left;
std::atomic_bool bailout;
std::atomic_bool finished;
std::condition_variable job_available_var;
std::condition_variable wait_var;
std::mutex wait_mutex;
std::mutex queue_mutex;
/**
* Take the next job in the queue and run it.
* Notify the main thread that a job has completed.
*/
void Task() {
while( !bailout ) {
next_job()();
--jobs_left;
wait_var.notify_one();
}
}
/**
* Get the next job; pop the first item in the queue,
* otherwise wait for a signal from the main thread.
*/
std::function<void(void)> next_job() {
std::function<void(void)> res;
std::unique_lock<std::mutex> job_lock( queue_mutex );
// Wait for a job if we don't have any.
job_available_var.wait( job_lock, [this]() ->bool { return queue.size() || bailout; } );
// Get job from the queue
if( !bailout ) {
res = queue.front();
queue.pop_front();
}
else { // If we're bailing out, 'inject' a job into the queue to keep jobs_left accurate.
res = []{};
++jobs_left;
}
return res;
}
public:
ThreadPool()
: jobs_left( 0 )
, bailout( false )
, finished( false )
{
for( unsigned i = 0; i < ThreadCount; ++i )
threads[ i ] = std::move( std::thread( [this,i]{ this->Task(); } ) );
}
/**
* JoinAll on deconstruction
*/
~ThreadPool() {
JoinAll();
}
/**
* Get the number of threads in this pool
*/
inline unsigned Size() const {
return ThreadCount;
}
/**
* Get the number of jobs left in the queue.
*/
inline unsigned JobsRemaining() {
return queue.size();
}
/**
* Add a new job to the pool. If there are no jobs in the queue,
* a thread is woken up to take the job. If all threads are busy,
* the job is added to the end of the queue.
*/
void AddJob( std::function<void(void)> job ) {
std::lock_guard<std::mutex> guard( queue_mutex );
queue.emplace_back( job );
++jobs_left;
job_available_var.notify_one();
}
/**
* Join with all threads. Block until all threads have completed.
* Params: WaitForAll: If true, will wait for the queue to empty
* before joining with threads. If false, will complete
* current jobs, then inform the threads to exit.
* The queue will be empty after this call, and the threads will
* be done. After invoking `ThreadPool::JoinAll`, the pool can no
* longer be used. If you need the pool to exist past completion
* of jobs, look to use `ThreadPool::WaitAll`.
*/
void JoinAll( bool WaitForAll = true ) {
if( !finished ) {
if( WaitForAll ) {
WaitAll();
}
// note that we're done, and wake up any thread that's
// waiting for a new job
bailout = true;
job_available_var.notify_all();
for( auto &x : threads )
if( x.joinable() )
x.join();
finished = true;
}
}
/**
* Wait for the pool to empty before continuing.
* This does not call `std::thread::join`, it only waits until
* all jobs have finshed executing.
*/
void WaitAll() {
if( jobs_left > 0 ) {
std::unique_lock<std::mutex> lk( wait_mutex );
wait_var.wait( lk, [this]{ return this->jobs_left == 0; } );
lk.unlock();
}
}
};
NS_END(2)
#endif //CONCURRENT_THREADPOOL_H

View File

@@ -0,0 +1,88 @@
#ifndef _UPLOADMANAGER_H
#define _UPLOADMANAGER_H
#include <siaapi.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Exception.h>
#include <autothread.h>
#include <deque>
#include <siacurl.h>
#include <eventsystem.h>
#include <filepath.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
class SIADRIVE_EXPORTABLE CUploadManager :
public CAutoThread
{
public:
enum class _UploadStatus : unsigned
{
NotFound,
Queued,
Uploading,
Complete
};
enum class _UploadErrorCode
{
Success,
SourceFileNotFound,
DatabaseError,
RenameFileFailed,
RenameFolderFailed
};
private:
typedef struct
{
std::uint64_t Id;
SString SiaPath;
SString FilePath;
SString TempPath;
_UploadStatus Status;
} UploadData;
public:
CUploadManager(CSiaDriveConfig* siaDriveConfig, const CSiaApi& siaApi);
public:
virtual ~CUploadManager();
private:
CSiaDriveConfig* _siaDriveConfig;
const CSiaApi& _siaApi;
SQLite::Database _uploadDatabase;
std::mutex _uploadMutex;
std::shared_ptr<json> _uploadFileList;
private:
void CleanUploadDatabase(CSiaDriveConfig* siaDriveConfig);
void DeleteFilesRemovedFromSia(CSiaDriveConfig* siaDriveConfig, const bool& isStartup = false);
CSiaDriveConfig& GetSiaDriveConfig() const { return *_siaDriveConfig; }
void HandleFileRemove(const SString& siaPath);
void UpdateDatabaseAfterRename(const SString& siaPath, const SString& newSiaPath);
protected:
virtual void AutoThreadCallback(CSiaDriveConfig* siaDriveConfig) override;
public:
static SString UploadStatusToString(const _UploadStatus& uploadStatus);
public:
CSiaError<_UploadErrorCode> AddOrUpdate(const SString& siaPath, SString filePath, const std::uint64_t& lastModified);
_UploadStatus GetUploadStatus(const SString& siaPath);
CSiaError<_UploadErrorCode> Remove(const SString& siaPath);
CSiaError<_UploadErrorCode> RenameFile(const SString& siaPath, const SString& newSiaPath);
CSiaError<_UploadErrorCode> RenameFolder(const SString& siaPath, const SString& newSiaPath);
std::shared_ptr<json> GetUploadFileList() const;
};
typedef CUploadManager::_UploadStatus UploadStatus;
typedef CUploadManager::_UploadErrorCode UploadErrorCode;
typedef CSiaError<CUploadManager::_UploadErrorCode> UploadError;
NS_END(2)
#endif //_UPLOADMANAGER_H

View File

@@ -0,0 +1,60 @@
#ifndef _SIADOKANDRIVE_H
#define _SIADOKANDRIVE_H
#ifdef _WIN32
#define WIN32_NO_STATUS
// Import or export functions and/or classes
#ifdef SIADRIVE_DOKAN_EXPORT_SYMBOLS
#define SIADRIVE_DOKAN_EXPORTABLE __declspec(dllexport)
#else
#define SIADRIVE_DOKAN_EXPORTABLE __declspec(dllimport)
#endif //SIADRIVE_DOKAN_EXPORT_SYMBOLS
#else
#define SIADRIVE_DOKAN_EXPORTABLE
#endif
#include <siaapi.h>
#include <mutex>
#include <eventsystem.h>
#include <uploadmanager.h>
NS_BEGIN(Sia)
NS_BEGIN(Api)
NS_BEGIN(Dokan)
class SIADRIVE_DOKAN_EXPORTABLE SiaDokanDriveException :
std::exception
{
public:
SiaDokanDriveException(char* message) :
std::exception(message)
{
}
};
class SIADRIVE_DOKAN_EXPORTABLE CSiaDokanDrive
{
public:
// throws SiaDokenDriveException
CSiaDokanDrive(CSiaApi* siaApi, CSiaDriveConfig* siaDriveConfig);
public:
~CSiaDokanDrive();
private:
CSiaApi* _siaApi;
CSiaDriveConfig* _siaDriveConfig;
std::mutex _startStopMutex;
public:
void ClearCache();
std::shared_ptr<json> GetUploadFileList() const;
bool IsMounted() const;
void Mount(const wchar_t& driveLetter, const SString& cacheLocation, const std::uint64_t& maxCacheSizeBytes);
void Unmount(const bool& clearCache = false);
void Shutdown();
};
NS_END(3)
#endif //_SIADOKANDRIVE_H