diff --git a/common/cpp/include/system_wrappers/io.h b/common/cpp/include/system_wrappers/io.h index 8d581ce3b3db90f70a4334cdbea6d3367b3ab1b3..75699696c268aa1e65addd01c925f3e660c13917 100644 --- a/common/cpp/include/system_wrappers/io.h +++ b/common/cpp/include/system_wrappers/io.h @@ -27,11 +27,9 @@ class IO { public: virtual FileData GetDataFromFile(const std::string& fname, uint64_t fsize, IOErrors* err) const noexcept = 0; - + virtual uint64_t Read(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept = 0; virtual int open(const char* __file, int __oflag) const noexcept = 0; virtual int close(int __fd) const noexcept = 0; - virtual int64_t read(int __fd, void* buf, size_t count) const noexcept = 0; - virtual int64_t write(int __fd, const void* __buf, size_t __n) const noexcept = 0; // this is not standard function - to be implemented differently in windows and linux virtual FileInfos FilesInFolder(const std::string& folder, IOErrors* err) const = 0; diff --git a/common/cpp/include/system_wrappers/system_io.h b/common/cpp/include/system_wrappers/system_io.h index 5ad61883c50f58c59941b9c429a3b24188c59068..7f74fd582c6b52ebfa0c28d2ba6613137766fb83 100644 --- a/common/cpp/include/system_wrappers/system_io.h +++ b/common/cpp/include/system_wrappers/system_io.h @@ -10,14 +10,13 @@ class SystemIO final : public IO { FileData GetDataFromFile(const std::string& fname, uint64_t fsize, IOErrors* err) const noexcept override; int open(const char* __file, int __oflag) const noexcept override; int close(int __fd) const noexcept override; - int64_t read(int __fd, void* buf, size_t count) const noexcept override; - int64_t write(int __fd, const void* __buf, size_t __n) const noexcept override; - FileInfos FilesInFolder(const std::string& folder, IOErrors* err) const override; + uint64_t Read(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept override; + std::vector<FileInfo> FilesInFolder(const std::string& folder, IOErrors* err) const override; private: - void ReadWholeFile(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept; void CollectFileInformationRecursivly(const std::string& path, - FileInfos* files, IOErrors* err) const; - + std::vector<FileInfo>* files, IOErrors* err) const; + int64_t read(int __fd, void* buf, size_t count) const noexcept; + int64_t write(int __fd, const void* __buf, size_t __n) const noexcept; }; } diff --git a/common/cpp/include/unittests/MockIO.h b/common/cpp/include/unittests/MockIO.h index 87de9664887289e931a0fb34c083820cd755154b..036da76928f027c5325a30de46167b6a3f9ab1a8 100644 --- a/common/cpp/include/unittests/MockIO.h +++ b/common/cpp/include/unittests/MockIO.h @@ -14,17 +14,15 @@ class MockIO : public IO { return GetDataFromFile_t(fname, fsize, err); } int open(const char* __file, int __oflag) const noexcept override { - return open_t(__file, __oflag); + return 0; } int close(int __fd) const noexcept override { - return close_t(__fd); + return 0; } - int64_t read(int __fd, void* buf, size_t count) const noexcept override { - return read_t(__fd, buf, count); - } - int64_t write(int __fd, const void* __buf, size_t __n) const noexcept override { - return write_t(__fd, __buf, __n); + uint64_t Read(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept override { + return 0; } + MOCK_CONST_METHOD3(GetDataFromFile_t, FileData(const std::string& fname, uint64_t fsize, IOErrors* err)); MOCK_CONST_METHOD2(FilesInFolder, diff --git a/common/cpp/src/system_io/system_io.cpp b/common/cpp/src/system_io/system_io.cpp index 875a945fc0e4077f34d0472fa0434d579ba1af85..99b20e8bb1b17362d178375c707482b36f472d01 100644 --- a/common/cpp/src/system_io/system_io.cpp +++ b/common/cpp/src/system_io/system_io.cpp @@ -29,7 +29,7 @@ IOErrors IOErrorFromErrno() { return err; } -void SystemIO::ReadWholeFile(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept { +uint64_t SystemIO::Read(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept { uint64_t totalbytes = 0; int64_t readbytes = 0; do { @@ -40,6 +40,7 @@ void SystemIO::ReadWholeFile(int fd, uint8_t* array, uint64_t fsize, IOErrors* e if (totalbytes != fsize) { *err = IOErrors::kReadError; } + return totalbytes; } FileData SystemIO::GetDataFromFile(const std::string& fname, uint64_t fsize, IOErrors* err) const noexcept { @@ -57,7 +58,7 @@ FileData SystemIO::GetDataFromFile(const std::string& fname, uint64_t fsize, IOE return nullptr; } - ReadWholeFile(fd, data_array, fsize, err); + Read(fd, data_array, fsize, err); FileData data{data_array}; if (*err != IOErrors::kNoError) { close(fd); diff --git a/common/cpp/src/system_io/system_io_windows.cpp b/common/cpp/src/system_io/system_io_windows.cpp index acb23e381b305b6376c7153ad1cc73a5322b8133..9e08b483e10b9a79b63f87927b4f75a01ad57142 100644 --- a/common/cpp/src/system_io/system_io_windows.cpp +++ b/common/cpp/src/system_io/system_io_windows.cpp @@ -32,22 +32,47 @@ IOErrors IOErrorFromGetLastError() { return err; } -std::chrono::system_clock::time_point FileTime2TimePoint(const FILETIME& ft, IOErrors* err) { +IOErrors CheckFileTime(const FILETIME& ft) { SYSTEMTIME st = {0}; if (!FileTimeToSystemTime(&ft, &st)) { - *err = IOErrorFromGetLastError(); - return {}; + return IOErrorFromGetLastError(); + } + return IOErrors::kNoError; +} + +constexpr auto kShift = 11644473600ULL; +constexpr auto k100nsInSec = 10000000ULL; + +uint64_t GetLinuxEpochSecFromWindowsEpoch(ULARGE_INTEGER ull) { +// ull.QuadPart is amount of 100ns intervals since Windows Epoch + return (uint64_t) ull.QuadPart / k100nsInSec - kShift; +} + +uint64_t GetLinuxNanosecFromWindowsEpoch(ULARGE_INTEGER ull) { + return (uint64_t)(ull.QuadPart % k100nsInSec) * 100; +} + +std::chrono::system_clock::time_point FileTime2TimePoint(const FILETIME& ft, IOErrors* err) { + + *err = CheckFileTime(ft); + if (*err != IOErrors::kNoError) { + return std::chrono::system_clock::time_point{}; } + // number of seconds ULARGE_INTEGER ull; ull.LowPart = ft.dwLowDateTime; ull.HighPart = ft.dwHighDateTime; - time_t secs = ull.QuadPart / 10000000ULL - 11644473600ULL; - std::chrono::milliseconds ms((ull.QuadPart / 10000ULL) % 1000); + auto sec = GetLinuxEpochSecFromWindowsEpoch(ull); + auto nsec = GetLinuxNanosecFromWindowsEpoch(ull); + + std::chrono::nanoseconds d = std::chrono::nanoseconds {nsec} + + std::chrono::seconds{sec}; + + auto tp = system_clock::time_point + {std::chrono::duration_cast<std::chrono::system_clock::duration>(d)}; - auto tp = std::chrono::system_clock::from_time_t(secs); - tp += ms; *err = IOErrors::kNoError; return tp; } diff --git a/worker/api/cpp/unittests/test_folder_broker.cpp b/worker/api/cpp/unittests/test_folder_broker.cpp index 20589a2dba30bfe3e03fd7c098301dd0b83f9dda..b7131c45efb68c40dfbdada3564203f573ddfc5f 100644 --- a/worker/api/cpp/unittests/test_folder_broker.cpp +++ b/worker/api/cpp/unittests/test_folder_broker.cpp @@ -53,10 +53,8 @@ class FakeIO: public IO { int close(int __fd)const noexcept override { return 0; }; - int64_t read(int __fd, void* buf, size_t count) const noexcept override { - return 0; - }; - int64_t write(int __fd, const void* __buf, size_t __n) const noexcept override { + + uint64_t Read(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const noexcept override { return 0; }; FileInfos FilesInFolder(const std::string& folder, IOErrors* err) const override { @@ -70,7 +68,6 @@ class FakeIO: public IO { file_infos.push_back(fi); fi.base_name = "3"; file_infos.push_back(fi); - return file_infos; } }; @@ -165,7 +162,6 @@ TEST_F(FolderDataBrokerTests, GetNextWithNullPointersReturnsError) { ASSERT_THAT(err, Eq(WorkerErrorCode::kWrongInput)); } - TEST_F(FolderDataBrokerTests, GetNextReturnsFileInfo) { data_broker->Connect(); FileInfo fi;