diff --git a/README.md b/README.md index e07f859b..32265e25 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ and [old][Old Architecture] [RN][React Native] architectures. thumbnails. - [copyAssetsVideoIOS()] — Copies a video from the assets-library to the specified destination. - - [copyFile()] — Copies a file to a new destination. + - [copyFile()] — Copies a file (or a folder with files - except on Android/Windows) to a new destination. - [copyFileAssets()] — (Android only) Copies Android app's asset(s) to the specified destination. - [copyFileRes()] — (Android only) Copies specified resource to @@ -96,7 +96,7 @@ and [old][Old Architecture] [RN][React Native] architectures. - [getFSInfo()] — Gets info on the free and total storage space on the device, and its external storage. - [mkdir()] — Creates folder(s) at the given path. - - [moveFile()] — Moves a file (or a folder with files) to a new location. + - [moveFile()] — Moves a file (or a folder with files - except on Windows) to a new location. - [pathForGroup()] — (iOS only) Returns the absolute path to the directory shared for all applications with the same security group identifier. @@ -626,7 +626,7 @@ Copies a file to a new destination. Throws if called on a directory. already exists. On iOS an error will be thrown if the file already exists. — **beware**, this has not been verified yet. -**BEWARE:** On Android [copyFile()] throws if called on a folder; on other +**BEWARE:** On Android and Windows [copyFile()] throws if called on a folder; on other platforms it does not throw, but it has not been verified yet, if it actually copies a folder with all its content there. @@ -1174,9 +1174,7 @@ in this library fork. ```ts function write(filepath: string, contents: string, position?: number, encoding?: EncodingT): Promise; ``` -**VERIFIED:** Android, iOS, macOS, Windows \ -**BEWARE:** On Windows it seems to work differently from other platforms, -throwing if attempting to write to a non-existing file. +**VERIFIED:** Android, iOS, macOS, Windows Writes content to a file at the given random access position. diff --git a/windows/ReactNativeFs/ReactNativeModule.cpp b/windows/ReactNativeFs/ReactNativeModule.cpp index 30b9ae04..995a878e 100644 --- a/windows/ReactNativeFs/ReactNativeModule.cpp +++ b/windows/ReactNativeFs/ReactNativeModule.cpp @@ -164,7 +164,7 @@ ReactNativeFsSpec_Constants ReactNativeModule::GetConstants() noexcept return res; } -winrt::fire_and_forget ReactNativeModule::mkdir(std::string directory, JSValueObject options, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::mkdir(std::wstring directory, JSValueObject options, ReactPromise promise) noexcept try { size_t pathLength{ directory.length() }; @@ -213,14 +213,14 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::moveFile(std::string filepath, std::string destpath, JSValueObject options, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::moveFile(std::wstring srcPath, std::wstring destPath, JSValueObject options, ReactPromise promise) noexcept try { winrt::hstring srcDirectoryPath, srcFileName; - splitPath(filepath, srcDirectoryPath, srcFileName); + splitPath(srcPath, srcDirectoryPath, srcFileName); winrt::hstring destDirectoryPath, destFileName; - splitPath(destpath, destDirectoryPath, destFileName); + splitPath(destPath, destDirectoryPath, destFileName); StorageFolder srcFolder{ co_await StorageFolder::GetFolderFromPathAsync(srcDirectoryPath) }; StorageFolder destFolder{ co_await StorageFolder::GetFolderFromPathAsync(destDirectoryPath) }; @@ -237,14 +237,14 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::copyFile(std::string filepath, std::string destpath, JSValueObject options, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::copyFile(std::wstring srcPath, std::wstring destPath, JSValueObject options, ReactPromise promise) noexcept try { winrt::hstring srcDirectoryPath, srcFileName; - splitPath(filepath, srcDirectoryPath, srcFileName); + splitPath(srcPath, srcDirectoryPath, srcFileName); winrt::hstring destDirectoryPath, destFileName; - splitPath(destpath, destDirectoryPath, destFileName); + splitPath(destPath, destDirectoryPath, destFileName); StorageFolder srcFolder{ co_await StorageFolder::GetFolderFromPathAsync(srcDirectoryPath) }; StorageFolder destFolder{ co_await StorageFolder::GetFolderFromPathAsync(destDirectoryPath) }; @@ -262,8 +262,8 @@ catch (const hresult_error& ex) winrt::fire_and_forget ReactNativeModule::copyFolder( - std::string srcFolderPath, - std::string destFolderPath, + std::wstring srcFolderPath, + std::wstring destFolderPath, ReactPromise promise) noexcept try { @@ -346,17 +346,17 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::unlink(std::string filepath, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::unlink(std::wstring filePath, ReactPromise promise) noexcept try { - size_t pathLength{ filepath.length() }; + size_t pathLength{ filePath.length() }; if (pathLength <= 0) { promise.Reject("Invalid path."); } else { - bool hasTrailingSlash{ filepath[pathLength - 1] == '\\' || filepath[pathLength - 1] == '/' }; - std::filesystem::path path(hasTrailingSlash ? filepath.substr(0, pathLength - 1) : filepath); + bool hasTrailingSlash{ filePath[pathLength - 1] == '\\' || filePath[pathLength - 1] == '/' }; + std::filesystem::path path(hasTrailingSlash ? filePath.substr(0, pathLength - 1) : filePath); path.make_preferred(); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(path.parent_path().wstring()) }; @@ -371,7 +371,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else { @@ -381,20 +381,20 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::exists(std::string filepath, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::exists(std::wstring filePath, ReactPromise promise) noexcept try { - size_t fileLength{ filepath.length() }; + size_t fileLength{ filePath.length() }; if (fileLength <= 0) { promise.Resolve(false); } else { - bool hasTrailingSlash{ filepath[fileLength - 1] == '\\' || filepath[fileLength - 1] == '/' }; - std::filesystem::path path(hasTrailingSlash ? filepath.substr(0, fileLength - 1) : filepath); + bool hasTrailingSlash{ filePath[fileLength - 1] == '\\' || filePath[fileLength - 1] == '/' }; + std::filesystem::path path(hasTrailingSlash ? filePath.substr(0, fileLength - 1) : filePath); winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; if (fileName.size() > 0) { co_await folder.GetItemAsync(fileName); @@ -425,11 +425,11 @@ void ReactNativeModule::stopUpload(int32_t jobID) noexcept } -winrt::fire_and_forget ReactNativeModule::readFile(std::string filepath, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::readFile(std::wstring filePath, ReactPromise promise) noexcept try { winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; StorageFile file{ co_await folder.GetFileAsync(fileName) }; @@ -443,7 +443,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else if (result == HRESULT_FROM_WIN32(E_ACCESSDENIED)) // UnauthorizedAccessException { @@ -457,17 +457,17 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::stat(std::string filepath, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::stat(std::wstring filePath, ReactPromise promise) noexcept try { - size_t pathLength{ filepath.length() }; + size_t pathLength{ filePath.length() }; if (pathLength <= 0) { promise.Reject("Invalid path."); } else { - bool hasTrailingSlash{ filepath[pathLength - 1] == '\\' || filepath[pathLength - 1] == '/' }; - std::filesystem::path path(hasTrailingSlash ? filepath.substr(0, pathLength - 1) : filepath); + bool hasTrailingSlash{ filePath[pathLength - 1] == '\\' || filePath[pathLength - 1] == '/' }; + std::filesystem::path path(hasTrailingSlash ? filePath.substr(0, pathLength - 1) : filePath); path.make_preferred(); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(path.parent_path().wstring()) }; @@ -478,17 +478,17 @@ try fileInfo["ctime"] = winrt::clock::to_time_t(item.DateCreated()); fileInfo["mtime"] = winrt::clock::to_time_t(properties.DateModified()); fileInfo["size"] = std::to_string(properties.Size()); - fileInfo["type"] = item.IsOfType(StorageItemTypes::Folder) ? 1 : 0; + fileInfo["type"] = item.IsOfType(StorageItemTypes::Folder) ? "1" : "0"; promise.Resolve(fileInfo); } } catch (...) { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } -winrt::fire_and_forget ReactNativeModule::readDir(std::string directory, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::readDir(std::wstring directory, ReactPromise promise) noexcept try { std::filesystem::path path(directory); @@ -508,7 +508,7 @@ try itemInfo["name"] = to_string(item.Name()); itemInfo["path"] = to_string(item.Path()); itemInfo["size"] = properties.Size(); - itemInfo["type"] = item.IsOfType(StorageItemTypes::Folder) ? 1 : 0; + itemInfo["type"] = item.IsOfType(StorageItemTypes::Folder) ? "1" : "0"; resultsArray.push_back(std::move(itemInfo)); } @@ -522,11 +522,11 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::read(std::string filepath, uint32_t length, uint64_t position, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::read(std::wstring filePath, uint32_t length, uint64_t position, ReactPromise promise) noexcept try { winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; StorageFile file{ co_await folder.GetFileAsync(fileName) }; @@ -546,7 +546,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else if (result == HRESULT_FROM_WIN32(E_ACCESSDENIED)) // UnauthorizedAccessException { @@ -560,7 +560,7 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::hash(std::string filepath, std::string algorithm, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::hash(std::wstring filePath, std::string algorithm, ReactPromise promise) noexcept try { // Note: SHA224 is not part of winrt @@ -571,7 +571,7 @@ try } winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; StorageFile file{ co_await folder.GetFileAsync(fileName) }; @@ -596,7 +596,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else if (result == HRESULT_FROM_WIN32(E_ACCESSDENIED)) // UnauthorizedAccessException { @@ -610,14 +610,14 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::writeFile(std::string filepath, std::string base64Content, JSValueObject options, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::writeFile(std::wstring filePath, std::wstring base64Content, JSValueObject options, ReactPromise promise) noexcept try { - winrt::hstring base64ContentStr{ winrt::to_hstring(base64Content) }; + winrt::hstring base64ContentStr{ base64Content }; Streams::IBuffer buffer{ Cryptography::CryptographicBuffer::DecodeFromBase64String(base64ContentStr) }; winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; StorageFile file{ co_await folder.CreateFileAsync(fileName, CreationCollisionOption::ReplaceExisting) }; @@ -632,7 +632,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else { @@ -642,20 +642,20 @@ catch (const hresult_error& ex) } -winrt::fire_and_forget ReactNativeModule::appendFile(std::string filepath, std::string base64Content, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::appendFile(std::wstring filePath, std::wstring base64Content, ReactPromise promise) noexcept try { - size_t fileLength = filepath.length(); - bool hasTrailingSlash{ filepath[fileLength - 1] == '\\' || filepath[fileLength - 1] == '/' }; - std::filesystem::path path(hasTrailingSlash ? filepath.substr(0, fileLength - 1) : filepath); + size_t fileLength = filePath.length(); + bool hasTrailingSlash{ filePath[fileLength - 1] == '\\' || filePath[fileLength - 1] == '/' }; + std::filesystem::path path(hasTrailingSlash ? filePath.substr(0, fileLength - 1) : filePath); winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; StorageFile file{ co_await folder.CreateFileAsync(fileName, CreationCollisionOption::OpenIfExists) }; - winrt::hstring base64ContentStr{ winrt::to_hstring(base64Content) }; + winrt::hstring base64ContentStr{ base64Content }; Streams::IBuffer buffer{ Cryptography::CryptographicBuffer::DecodeFromBase64String(base64ContentStr) }; Streams::IRandomAccessStream stream{ co_await file.OpenAsync(FileAccessMode::ReadWrite) }; @@ -669,7 +669,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else { @@ -677,16 +677,16 @@ catch (const hresult_error& ex) promise.Reject(winrt::to_string(ex.message()).c_str()); } } -winrt::fire_and_forget ReactNativeModule::write(std::string filepath, std::string base64Content, int position, ReactPromise promise) noexcept +winrt::fire_and_forget ReactNativeModule::write(std::wstring filePath, std::wstring base64Content, int position, ReactPromise promise) noexcept try { winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(filePath, directoryPath, fileName); StorageFolder folder{ co_await StorageFolder::GetFolderFromPathAsync(directoryPath) }; - StorageFile file{ co_await folder.GetFileAsync(fileName) }; + StorageFile file{ co_await folder.CreateFileAsync(fileName, CreationCollisionOption::OpenIfExists) }; - winrt::hstring base64ContentStr{ winrt::to_hstring(base64Content) }; + winrt::hstring base64ContentStr{ base64Content }; Streams::IBuffer buffer{ Cryptography::CryptographicBuffer::DecodeFromBase64String(base64ContentStr) }; Streams::IRandomAccessStream stream{ co_await file.OpenAsync(FileAccessMode::ReadWrite) }; @@ -706,7 +706,7 @@ catch (const hresult_error& ex) hresult result{ ex.code() }; if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) // FileNotFoundException { - promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + filepath }); + promise.Reject(ReactError{ "ENOENT", "ENOENT: no such file or directory, open " + winrt::to_string(filePath) }); } else { @@ -723,18 +723,18 @@ winrt::fire_and_forget ReactNativeModule::downloadFile(JSValueObject options, Re try { //Filepath - std::filesystem::path path(options["toFile"].AsString()); + std::wstring filePath = winrt::to_hstring(options["toFile"].AsString()).c_str(); + std::filesystem::path path(filePath); path.make_preferred(); if (path.filename().empty()) { promise.Reject("Failed to determine filename in path"); co_return; } - auto filePath{ winrt::to_hstring(path.c_str()) }; //URL std::string fromURLString{ options["fromUrl"].AsString() }; - std::wstring URLForURI(fromURLString.begin(), fromURLString.end()); + auto URLForURI = winrt::to_hstring(fromURLString); Uri uri{ URLForURI }; //Headers @@ -795,10 +795,13 @@ winrt::fire_and_forget ReactNativeModule::uploadFiles(JSValueObject options, Rea for (const auto& fileInfo : files) { auto const& fileObj{ fileInfo.AsObject() }; - auto filepath{ fileObj["filepath"].AsString() }; + auto filePath{ fileObj["filepath"].AsString() }; + + // Convert std::string to std::wstring + std::wstring wFilePath = winrt::to_hstring(filePath).c_str(); winrt::hstring directoryPath, fileName; - splitPath(filepath, directoryPath, fileName); + splitPath(wFilePath, directoryPath, fileName); try { @@ -829,11 +832,11 @@ winrt::fire_and_forget ReactNativeModule::uploadFiles(JSValueObject options, Rea } -void ReactNativeModule::touch(std::string filepath, int64_t mtime, int64_t ctime, bool modifyCreationTime, ReactPromise promise) noexcept +void ReactNativeModule::touch(std::wstring filePath, int64_t mtime, int64_t ctime, bool modifyCreationTime, ReactPromise promise) noexcept try { - std::filesystem::path path(filepath); + std::filesystem::path path(filePath); path.make_preferred(); auto s_path{ path.c_str() }; PCWSTR actual_path{ s_path }; @@ -896,9 +899,9 @@ catch (const hresult_error& ex) } -void ReactNativeModule::splitPath(const std::string& fullPath, winrt::hstring& directoryPath, winrt::hstring& fileName) noexcept +void ReactNativeModule::splitPath(const std::wstring& filePath, winrt::hstring& directoryPath, winrt::hstring& fileName) noexcept { - std::filesystem::path path(fullPath); + std::filesystem::path path(filePath); path.make_preferred(); directoryPath = path.has_parent_path() ? winrt::to_hstring(path.parent_path().c_str()) : L""; @@ -1067,12 +1070,15 @@ IAsyncAction ReactNativeModule::ProcessUploadRequestAsync(ReactPromise promise) noexcept; + winrt::fire_and_forget mkdir(std::wstring directory, JSValueObject options, ReactPromise promise) noexcept; REACT_METHOD(moveFile); // Implemented winrt::fire_and_forget moveFile( - std::string filepath, - std::string destPath, + std::wstring srcPath, + std::wstring destPath, JSValueObject options, ReactPromise promise) noexcept; REACT_METHOD(copyFile); // Implemented winrt::fire_and_forget copyFile( - std::string filepath, - std::string destPath, + std::wstring srcPath, + std::wstring destPath, JSValueObject options, ReactPromise promise) noexcept; REACT_METHOD(copyFolder); // Implemented winrt::fire_and_forget copyFolder( - std::string src, - std::string dest, + std::wstring srcFolderPath, + std::wstring destFolderPath, ReactPromise promise) noexcept; REACT_METHOD(getFSInfo); // Implemented, no unit tests but cannot be tested winrt::fire_and_forget getFSInfo(ReactPromise promise) noexcept; REACT_METHOD(unlink); // Implemented - winrt::fire_and_forget unlink(std::string filePath, ReactPromise promise) noexcept; + winrt::fire_and_forget unlink(std::wstring filePath, ReactPromise promise) noexcept; REACT_METHOD(exists); // Implemented - winrt::fire_and_forget exists(std::string fullpath, ReactPromise promise) noexcept; + winrt::fire_and_forget exists(std::wstring filePath, ReactPromise promise) noexcept; REACT_METHOD(stopDownload); // DOWNLOADER void stopDownload(int jobID) noexcept; @@ -105,43 +105,43 @@ struct ReactNativeModule void stopUpload(int jobID) noexcept; REACT_METHOD(readDir); // Implemented - winrt::fire_and_forget readDir(std::string directory, ReactPromise promise) noexcept; + winrt::fire_and_forget readDir(std::wstring directory, ReactPromise promise) noexcept; REACT_METHOD(stat); // Implemented, unit tests incomplete - winrt::fire_and_forget stat(std::string filepath, ReactPromise promise) noexcept; + winrt::fire_and_forget stat(std::wstring filePath, ReactPromise promise) noexcept; REACT_METHOD(readFile); // Implemented - winrt::fire_and_forget readFile(std::string filePath, ReactPromise promise) noexcept; + winrt::fire_and_forget readFile(std::wstring filePath, ReactPromise promise) noexcept; REACT_METHOD(read); // Implemented winrt::fire_and_forget read( - std::string filePath, + std::wstring filePath, uint32_t length, uint64_t position, ReactPromise promise) noexcept; REACT_METHOD(hash); // Implemented - winrt::fire_and_forget hash(std::string filepath, std::string algorithm, ReactPromise promise) noexcept; + winrt::fire_and_forget hash(std::wstring filePath, std::string algorithm, ReactPromise promise) noexcept; REACT_METHOD(writeFile); // Implemented winrt::fire_and_forget writeFile( - std::string filePath, - std::string base64Content, + std::wstring filePath, + std::wstring base64Content, JSValueObject options, ReactPromise promise) noexcept; REACT_METHOD(appendFile); // Implemented, no unit tests winrt::fire_and_forget appendFile( - std::string filepath, - std::string base64Content, + std::wstring filePath, + std::wstring base64Content, ReactPromise promise ) noexcept; REACT_METHOD(write); // Implemented winrt::fire_and_forget write( - std::string filePath, - std::string base64Content, + std::wstring filePath, + std::wstring base64Content, int position, ReactPromise promise) noexcept; @@ -153,16 +153,22 @@ struct ReactNativeModule winrt::fire_and_forget uploadFiles(JSValueObject options, ReactPromise promise) noexcept; REACT_METHOD(touch); // Implemented - void touch(std::string filepath, int64_t mtime, int64_t ctime, bool modifyCreationTime, ReactPromise promise) noexcept; + void touch(std::wstring filePath, int64_t mtime, int64_t ctime, bool modifyCreationTime, ReactPromise promise) noexcept; REACT_EVENT(TimedEvent, L"TimedEventCpp"); std::function TimedEvent; REACT_EVENT(emitDownloadBegin, L"DownloadBegin"); std::function emitDownloadBegin; + + REACT_METHOD(addListener); + void addListener(std::string eventName) noexcept; + + REACT_METHOD(removeListeners); + void removeListeners(int count) noexcept; private: - void splitPath(const std::string& fullPath, winrt::hstring& directoryPath, winrt::hstring& fileName) noexcept; + void splitPath(const std::wstring& fullPath, winrt::hstring& directoryPath, winrt::hstring& fileName) noexcept; winrt::Windows::Foundation::IAsyncAction ProcessDownloadRequestAsync(ReactPromise promise, winrt::Windows::Web::Http::HttpRequestMessage request, std::wstring_view filePath, int32_t jobId, int64_t progressInterval, int64_t progressDivider);