From ec94c22d99b1158e7ada97f7e7ffc199891c62eb Mon Sep 17 00:00:00 2001 From: Chee Yee Date: Mon, 20 Feb 2023 20:26:17 -0800 Subject: [PATCH] code refactor and add support for iis http server --- CMakeLists.txt | 2 + source/actions.cpp | 3 +- source/common.h | 20 ++++ source/ftpclient.cpp | 17 +-- source/http/baseclient.cpp | 227 +++++++++++++++++++++++++++++++++++++ source/http/baseclient.h | 42 +++++++ source/http/iis.cpp | 167 +++++++++++++++++++++++++++ source/http/iis.h | 17 +++ source/http/npxserve.cpp | 188 +----------------------------- source/http/npxserve.h | 29 +---- source/smbclient.cpp | 17 +-- source/util.h | 19 ++++ source/webdavclient.cpp | 17 +-- 13 files changed, 502 insertions(+), 263 deletions(-) create mode 100644 source/http/baseclient.cpp create mode 100644 source/http/baseclient.h create mode 100644 source/http/iis.cpp create mode 100644 source/http/iis.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a929dc..1f1fa98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,8 @@ add_executable(ezremote_client source/web/urn.cpp source/webdav/client.cpp source/http/httplib.cpp + source/http/baseclient.cpp + source/http/iis.cpp source/http/npxserve.cpp source/actions.cpp source/config.cpp diff --git a/source/actions.cpp b/source/actions.cpp index 63a9a65..e5c8750 100644 --- a/source/actions.cpp +++ b/source/actions.cpp @@ -19,6 +19,7 @@ #include "smbclient.h" #include "webdavclient.h" #include "http/npxserve.h" +#include "http/iis.h" #include "zip_util.h" namespace Actions @@ -1106,7 +1107,7 @@ namespace Actions CONFIG::SaveConfig(); if (strncmp(remote_settings->server, "https://", 8) == 0 || strncmp(remote_settings->server, "http://", 7) == 0) { - remoteclient = new NpxServeClient(); + remoteclient = new IISClient(); } else if (strncmp(remote_settings->server, "davs://", 7) == 0 || strncmp(remote_settings->server, "dav://", 6) == 0) { diff --git a/source/common.h b/source/common.h index 2c4fd36..fd1b8da 100644 --- a/source/common.h +++ b/source/common.h @@ -60,6 +60,26 @@ struct DirEntry { qsort(&list[0], list.size(), sizeof(DirEntry), DirEntryComparator); } + + static void SetDisplaySize(DirEntry *entry) + { + if (entry->file_size < 1024) + { + sprintf(entry->display_size, "%ldB", entry->file_size); + } + else if (entry->file_size < 1024 * 1024) + { + sprintf(entry->display_size, "%.2fKB", entry->file_size * 1.0f / 1024); + } + else if (entry->file_size < 1024 * 1024 * 1024) + { + sprintf(entry->display_size, "%.2fMB", entry->file_size * 1.0f / (1024 * 1024)); + } + else + { + sprintf(entry->display_size, "%.2fGB", entry->file_size * 1.0f / (1024 * 1024 * 1024)); + } + } }; #endif \ No newline at end of file diff --git a/source/ftpclient.cpp b/source/ftpclient.cpp index af016b4..129b571 100644 --- a/source/ftpclient.cpp +++ b/source/ftpclient.cpp @@ -1628,22 +1628,7 @@ std::vector FtpClient::ListDir(const std::string &path) } else { - if (entry.file_size < 1024) - { - sprintf(entry.display_size, "%ldB", entry.file_size); - } - else if (entry.file_size < 1024 * 1024) - { - sprintf(entry.display_size, "%.2fKB", entry.file_size * 1.0f / 1024); - } - else if (entry.file_size < 1024 * 1024 * 1024) - { - sprintf(entry.display_size, "%.2fMB", entry.file_size * 1.0f / (1024 * 1024)); - } - else - { - sprintf(entry.display_size, "%.2fGB", entry.file_size * 1.0f / (1024 * 1024 * 1024)); - } + DirEntry::SetDisplaySize(&entry); } if (strcmp(entry.name, "..") != 0 && strcmp(entry.name, ".") != 0) out.push_back(entry); diff --git a/source/http/baseclient.cpp b/source/http/baseclient.cpp new file mode 100644 index 0000000..07a83f3 --- /dev/null +++ b/source/http/baseclient.cpp @@ -0,0 +1,227 @@ +#include +#include +#include +#include "common.h" +#include "remote_client.h" +#include "http/npxserve.h" +#include "lang.h" +#include "util.h" +#include "windows.h" + +using httplib::Client; +using httplib::Headers; +using httplib::Result; + +BaseClient::BaseClient(){}; + +BaseClient::~BaseClient() +{ + if (client != nullptr) + delete client; +}; + +int BaseClient::Connect(const std::string &url, const std::string &username, const std::string &password) +{ + client = new httplib::Client(url); + if (username.length() > 0) + client->set_basic_auth(username, password); + client->set_keep_alive(true); + client->set_follow_location(true); + client->set_connection_timeout(30); + client->set_read_timeout(30); + client->enable_server_certificate_verification(false); + if (Ping()) + this->connected = true; + return 1; +} + +int BaseClient::Mkdir(const std::string &path) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Rmdir(const std::string &path, bool recursive) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Size(const std::string &path, int64_t *size) +{ + if (auto res = client->Head(path)) + { + std::string content_length = res->get_header_value("Content-Length"); + if (content_length.length() > 0) + *size = atoll(content_length.c_str()); + return 1; + } + else + { + sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); + } + return 0; +} + +int BaseClient::Get(const std::string &outputfile, const std::string &path, uint64_t offset) +{ + std::ofstream file_stream(outputfile, std::ios::binary); + bytes_transfered = 0; + if (auto res = client->Get(path, + [&](const char *data, size_t data_length) + { + file_stream.write(data, data_length); + bytes_transfered += data_length; + return true; + })) + { + file_stream.close(); + return 1; + } + else + { + sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); + } + return 0; +} + +int BaseClient::Put(const std::string &inputfile, const std::string &path, uint64_t offset) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Rename(const std::string &src, const std::string &dst) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Delete(const std::string &path) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Copy(const std::string &from, const std::string &to) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Move(const std::string &from, const std::string &to) +{ + sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); + return 0; +} + +int BaseClient::Head(const std::string &path, void *buffer, uint64_t len) +{ + char range_header[64]; + sprintf(range_header, "bytes=%lu-%lu", 0L, len-1); + Headers headers = {{"Range", range_header}}; + size_t bytes_read = 0; + std::vector body; + if (auto res = client->Get(path, headers, + [&](const char *data, size_t data_length) + { + body.insert(body.end(), data, data+data_length); + bytes_read += data_length; + if (bytes_read > len) + return false; + return true; + })) + { + if (body.size() < len) return 0; + memcpy(buffer, body.data(), len); + return 1; + } + else + { + sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); + } + return 0; +} + +bool BaseClient::FileExists(const std::string &path) +{ + int64_t file_size; + return Size(path, &file_size); +} + +std::vector BaseClient::ListDir(const std::string &path) +{ + std::vector out; + DirEntry entry; + memset(&entry, 0, sizeof(DirEntry)); + if (path[path.length() - 1] == '/' && path.length() > 1) + { + strlcpy(entry.directory, path.c_str(), path.length() - 1); + } + else + { + sprintf(entry.directory, "%s", path.c_str()); + } + sprintf(entry.name, ".."); + sprintf(entry.path, "%s", entry.directory); + sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]); + entry.file_size = 0; + entry.isDir = true; + entry.selectable = false; + out.push_back(entry); + + return out; +} + +std::string BaseClient::GetPath(std::string ppath1, std::string ppath2) +{ + std::string path1 = ppath1; + std::string path2 = ppath2; + path1 = Util::Rtrim(Util::Trim(path1, " "), "/"); + path2 = Util::Rtrim(Util::Trim(path2, " "), "/"); + path1 = path1 + "/" + path2; + return path1; +} + +bool BaseClient::IsConnected() +{ + return this->connected; +} + +bool BaseClient::Ping() +{ + if (auto res = client->Head("/")) + { + return true; + } + else + { + sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); + } + return false; +} + +const char *BaseClient::LastResponse() +{ + return this->response; +} + +int BaseClient::Quit() +{ + if (client != nullptr) + { + delete client; + client = nullptr; + } + return 1; +} + +ClientType BaseClient::clientType() +{ + return CLIENT_TYPE_HTTP_SERVER; +} + +uint32_t BaseClient::SupportedActions() +{ + return REMOTE_ACTION_DOWNLOAD | REMOTE_ACTION_INSTALL; +} diff --git a/source/http/baseclient.h b/source/http/baseclient.h new file mode 100644 index 0000000..585e5fa --- /dev/null +++ b/source/http/baseclient.h @@ -0,0 +1,42 @@ +#ifndef BASESERVER_H +#define BASESERVER_H + +#include +#include +#include "http/httplib.h" +#include "common.h" +#include "remote_client.h" + +class BaseClient : public RemoteClient +{ +public: + BaseClient(); + ~BaseClient(); + int Connect(const std::string &url, const std::string &username, const std::string &password); + int Mkdir(const std::string &path); + int Rmdir(const std::string &path, bool recursive); + int Size(const std::string &path, int64_t *size); + int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0); + int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0); + int Rename(const std::string &src, const std::string &dst); + int Delete(const std::string &path); + int Copy(const std::string &from, const std::string &to); + int Move(const std::string &from, const std::string &to); + int Head(const std::string &path, void *buffer, uint64_t len); + bool FileExists(const std::string &path); + std::vector ListDir(const std::string &path); + std::string GetPath(std::string path1, std::string path2); + bool IsConnected(); + bool Ping(); + const char *LastResponse(); + int Quit(); + ClientType clientType(); + uint32_t SupportedActions(); + +protected: + httplib::Client *client; + char response[512]; + bool connected = false; +}; + +#endif \ No newline at end of file diff --git a/source/http/iis.cpp b/source/http/iis.cpp new file mode 100644 index 0000000..b0e6438 --- /dev/null +++ b/source/http/iis.cpp @@ -0,0 +1,167 @@ +#include +#include +#include +#include "common.h" +#include "remote_client.h" +#include "http/iis.h" +#include "lang.h" +#include "util.h" +#include "windows.h" + +using httplib::Client; +using httplib::Headers; +using httplib::Result; + +std::vector IISClient::ListDir(const std::string &path) +{ + std::vector out; + DirEntry entry; + memset(&entry, 0, sizeof(DirEntry)); + if (path[path.length() - 1] == '/' && path.length() > 1) + { + strlcpy(entry.directory, path.c_str(), path.length() - 1); + } + else + { + sprintf(entry.directory, "%s", path.c_str()); + } + sprintf(entry.name, ".."); + sprintf(entry.path, "%s", entry.directory); + sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]); + entry.file_size = 0; + entry.isDir = true; + entry.selectable = false; + out.push_back(entry); + + if (auto res = client->Get(path)) + { + lxb_status_t status; + lxb_dom_attr_t *attr; + lxb_dom_node_t *node; + lxb_dom_element_t *element; + lxb_html_document_t *document; + lxb_dom_collection_t *collection; + + document = lxb_html_document_create(); + status = lxb_html_document_parse(document, (lxb_char_t *)res->body.c_str(), res->body.length()); + if (status != LXB_STATUS_OK) + { + lxb_html_document_destroy(document); + goto finish; + } + collection = lxb_dom_collection_make(&document->dom_document, 128); + if (collection == NULL) + { + lxb_html_document_destroy(document); + goto finish; + } + status = lxb_dom_elements_by_tag_name(lxb_dom_interface_element(document->body), + collection, (const lxb_char_t *)"pre", 3); + if (status != LXB_STATUS_OK) + { + lxb_dom_collection_destroy(collection, true); + lxb_html_document_destroy(document); + goto finish; + } + + int coll_size = lxb_dom_collection_length(collection); + if (coll_size < 1) + { + lxb_dom_collection_destroy(collection, true); + lxb_html_document_destroy(document); + goto finish; + } + + element = lxb_dom_collection_element(collection, 0); + const lxb_char_t *name; + size_t name_len; + std::string tmp; + node = element->node.first_child; + + DirEntry entry; + memset(&entry, 0, sizeof(DirEntry)); + do + { + if (node->type == LXB_DOM_NODE_TYPE_ELEMENT) + { + name = lxb_dom_element_local_name(lxb_dom_interface_element(node), &name_len); + tmp = std::string((const char *)name, name_len); + if (tmp.compare("a") == 0) + { + name = lxb_dom_node_text_content(node, &name_len); + tmp = std::string((const char *)name, name_len); + if (tmp.compare("[To Parent Directory]") != 0) + { + sprintf(entry.directory, "%s", path.c_str()); + sprintf(entry.name, "%s", tmp.c_str()); + if (path.length() > 0 && path[path.length() - 1] == '/') + { + sprintf(entry.path, "%s%s", path.c_str(), entry.name); + } + else + { + sprintf(entry.path, "%s/%s", path.c_str(), entry.name); + } + out.push_back(entry); + memset(&entry, 0, sizeof(DirEntry)); + } + } + } + else if (node->type == LXB_DOM_NODE_TYPE_TEXT) + { + name = lxb_dom_node_text_content(node, &name_len); + std::vector tokens = Util::Split(std::string((const char *)name, name_len), " "); + if (tokens.size() == 4) + { + if (tokens[3].compare("") == 0) + { + entry.isDir = true; + entry.selectable = true; + entry.file_size = 0; + sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]); + } + else + { + entry.isDir = false; + entry.selectable = true; + entry.file_size = atoll(tokens[3].c_str()); + DirEntry::SetDisplaySize(&entry); + } + + std::vector adate = Util::Split(tokens[0], "/"); + if (adate.size() == 3) + { + entry.modified.month = atoi(adate[0].c_str()); + entry.modified.day = atoi(adate[1].c_str()); + entry.modified.year = atoi(adate[2].c_str()); + } + + std::vector atime = Util::Split(tokens[1], ":"); + if (atime.size() == 2) + { + entry.modified.hours = atoi(atime[0].c_str()); + entry.modified.minutes = atoi(atime[1].c_str()); + } + + if (tokens[3].compare("PM") == 0) + { + if (entry.modified.hours < 12) + entry.modified.hours += 11; + } + } + } + node = node->next; + } while (node != element->node.last_child); + + lxb_dom_collection_destroy(collection, true); + lxb_html_document_destroy(document); + } + else + { + sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); + return out; + } + +finish: + return out; +} \ No newline at end of file diff --git a/source/http/iis.h b/source/http/iis.h new file mode 100644 index 0000000..a39ae12 --- /dev/null +++ b/source/http/iis.h @@ -0,0 +1,17 @@ +#ifndef IIS_H +#define IIS_H + +#include +#include +#include "http/httplib.h" +#include "http/baseclient.h" +#include "common.h" +#include "remote_client.h" + +class IISClient : public BaseClient +{ +public: + std::vector ListDir(const std::string &path); +}; + +#endif \ No newline at end of file diff --git a/source/http/npxserve.cpp b/source/http/npxserve.cpp index dd6ecdc..a652851 100644 --- a/source/http/npxserve.cpp +++ b/source/http/npxserve.cpp @@ -12,139 +12,6 @@ using httplib::Client; using httplib::Headers; using httplib::Result; -NpxServeClient::NpxServeClient(){}; - -NpxServeClient::~NpxServeClient() -{ - if (client != nullptr) - delete client; -}; - -int NpxServeClient::Connect(const std::string &url, const std::string &username, const std::string &password) -{ - client = new httplib::Client(url); - if (username.length() > 0) - client->set_basic_auth(username, password); - client->set_keep_alive(true); - client->set_follow_location(true); - client->set_connection_timeout(30); - client->set_read_timeout(30); - client->enable_server_certificate_verification(false); - if (Ping()) - this->connected = true; - return 1; -} - -int NpxServeClient::Mkdir(const std::string &path) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Rmdir(const std::string &path, bool recursive) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Size(const std::string &path, int64_t *size) -{ - if (auto res = client->Head(path)) - { - std::string content_length = res->get_header_value("Content-Length"); - if (content_length.length() > 0) - *size = atoll(content_length.c_str()); - return 1; - } - else - { - sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); - } - return 0; -} - -int NpxServeClient::Get(const std::string &outputfile, const std::string &path, uint64_t offset) -{ - std::ofstream file_stream(outputfile, std::ios::binary); - bytes_transfered = 0; - if (auto res = client->Get(path, - [&](const char *data, size_t data_length) - { - file_stream.write(data, data_length); - bytes_transfered += data_length; - return true; - })) - { - file_stream.close(); - return 1; - } - else - { - sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); - } - return 0; -} - -int NpxServeClient::Put(const std::string &inputfile, const std::string &path, uint64_t offset) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Rename(const std::string &src, const std::string &dst) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Delete(const std::string &path) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Copy(const std::string &from, const std::string &to) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Move(const std::string &from, const std::string &to) -{ - sprintf(this->response, "%s", lang_strings[STR_UNSUPPORTED_OPERATION_MSG]); - return 0; -} - -int NpxServeClient::Head(const std::string &path, void *buffer, uint64_t len) -{ - char range_header[64]; - sprintf(range_header, "bytes=%lu-%lu", 0L, len-1); - Headers headers = {{"Range", range_header}}; - - std::vector body; - if (auto res = client->Get(path, headers, - [&](const char *data, size_t data_length) - { - body.insert(body.end(), data, data+data_length); - return true; - })) - { - if (body.size() < len) return 0; - memcpy(buffer, body.data(), len); - return 1; - } - else - { - sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); - } - return 0; -} - -bool NpxServeClient::FileExists(const std::string &path) -{ - return 0; -} - std::vector NpxServeClient::ListDir(const std::string &path) { std::vector out; @@ -252,57 +119,4 @@ std::vector NpxServeClient::ListDir(const std::string &path) finish: return out; -} - -std::string NpxServeClient::GetPath(std::string ppath1, std::string ppath2) -{ - std::string path1 = ppath1; - std::string path2 = ppath2; - path1 = Util::Rtrim(Util::Trim(path1, " "), "/"); - path2 = Util::Rtrim(Util::Trim(path2, " "), "/"); - path1 = path1 + "/" + path2; - return path1; -} - -bool NpxServeClient::IsConnected() -{ - return this->connected; -} - -bool NpxServeClient::Ping() -{ - if (auto res = client->Head("/")) - { - return true; - } - else - { - sprintf(this->response, "%s", httplib::to_string(res.error()).c_str()); - } - return false; -} - -const char *NpxServeClient::LastResponse() -{ - return this->response; -} - -int NpxServeClient::Quit() -{ - if (client != nullptr) - { - delete client; - client = nullptr; - } - return 1; -} - -ClientType NpxServeClient::clientType() -{ - return CLIENT_TYPE_HTTP_SERVER; -} - -uint32_t NpxServeClient::SupportedActions() -{ - return REMOTE_ACTION_DOWNLOAD | REMOTE_ACTION_INSTALL; -} +} \ No newline at end of file diff --git a/source/http/npxserve.h b/source/http/npxserve.h index 8ff9403..7a8dc8d 100644 --- a/source/http/npxserve.h +++ b/source/http/npxserve.h @@ -4,39 +4,14 @@ #include #include #include "http/httplib.h" +#include "http/baseclient.h" #include "common.h" #include "remote_client.h" -class NpxServeClient : public RemoteClient +class NpxServeClient : public BaseClient { public: - NpxServeClient(); - ~NpxServeClient(); - int Connect(const std::string &url, const std::string &username, const std::string &password); - int Mkdir(const std::string &path); - int Rmdir(const std::string &path, bool recursive); - int Size(const std::string &path, int64_t *size); - int Get(const std::string &outputfile, const std::string &path, uint64_t offset=0); - int Put(const std::string &inputfile, const std::string &path, uint64_t offset=0); - int Rename(const std::string &src, const std::string &dst); - int Delete(const std::string &path); - int Copy(const std::string &from, const std::string &to); - int Move(const std::string &from, const std::string &to); - int Head(const std::string &path, void *buffer, uint64_t len); - bool FileExists(const std::string &path); std::vector ListDir(const std::string &path); - std::string GetPath(std::string path1, std::string path2); - bool IsConnected(); - bool Ping(); - const char *LastResponse(); - int Quit(); - ClientType clientType(); - uint32_t SupportedActions(); - -private: - httplib::Client *client; - char response[512]; - bool connected = false; }; #endif \ No newline at end of file diff --git a/source/smbclient.cpp b/source/smbclient.cpp index b831420..f8ce036 100644 --- a/source/smbclient.cpp +++ b/source/smbclient.cpp @@ -459,22 +459,7 @@ std::vector SmbClient::ListDir(const std::string &path) sprintf(entry.display_size, "%s", lang_strings[STR_LINK]); break; case SMB2_TYPE_FILE: - if (entry.file_size < 1024) - { - sprintf(entry.display_size, "%ldB", entry.file_size); - } - else if (entry.file_size < 1024 * 1024) - { - sprintf(entry.display_size, "%.2fKB", entry.file_size * 1.0f / 1024); - } - else if (entry.file_size < 1024 * 1024 * 1024) - { - sprintf(entry.display_size, "%.2fMB", entry.file_size * 1.0f / (1024 * 1024)); - } - else - { - sprintf(entry.display_size, "%.2fGB", entry.file_size * 1.0f / (1024 * 1024 * 1024)); - } + DirEntry::SetDisplaySize(&entry); break; case SMB2_TYPE_DIRECTORY: entry.isDir = true; diff --git a/source/util.h b/source/util.h index 9a23207..48160b4 100644 --- a/source/util.h +++ b/source/util.h @@ -46,6 +46,25 @@ namespace Util return s; } + static inline std::vector Split(const std::string &str, const std::string &delimiter) + { + std::string text = std::string(str); + std::vector tokens; + size_t pos = 0; + while ((pos = text.find(delimiter)) != std::string::npos) + { + if (text.substr(0, pos).length() > 0) + tokens.push_back(text.substr(0, pos)); + text.erase(0, pos + delimiter.length()); + } + if (text.length() > 0) + { + tokens.push_back(text); + } + + return tokens; + } + static inline void Notify(const char *fmt, ...) { OrbisNotificationRequest request; diff --git a/source/webdavclient.cpp b/source/webdavclient.cpp index 3ab764c..b1048a8 100644 --- a/source/webdavclient.cpp +++ b/source/webdavclient.cpp @@ -297,22 +297,7 @@ namespace WebDAV if (!entry.isDir) { entry.file_size = std::stoll(WebDAV::get(files[i], "size")); - if (entry.file_size < 1024) - { - sprintf(entry.display_size, "%luB", entry.file_size); - } - else if (entry.file_size < 1024 * 1024) - { - sprintf(entry.display_size, "%.2fKB", entry.file_size * 1.0f / 1024); - } - else if (entry.file_size < 1024 * 1024 * 1024) - { - sprintf(entry.display_size, "%.2fMB", entry.file_size * 1.0f / (1024 * 1024)); - } - else - { - sprintf(entry.display_size, "%.2fGB", entry.file_size * 1.0f / (1024 * 1024 * 1024)); - } + DirEntry::SetDisplaySize(&entry); } else {