diff --git a/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp b/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp index fd39dcc2d..5f4bbb95f 100644 --- a/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp +++ b/native/cpp/CommonCpp/NativeModules/CommUtilsModule.cpp @@ -1,31 +1,106 @@ #include "CommUtilsModule.h" #include +#include +#include namespace comm { using namespace facebook::react; CommUtilsModule::CommUtilsModule(std::shared_ptr jsInvoker) : CommUtilsModuleSchemaCxxSpecJSI(jsInvoker), utilsThread(std::make_unique("utils")) { } jsi::Value CommUtilsModule::writeBufferToFile( jsi::Runtime &rt, jsi::String path, jsi::Object data) { - return jsi::Value::undefined(); + auto arrayBuffer = data.getArrayBuffer(rt); + auto size = arrayBuffer.size(rt); + auto dataPtr = arrayBuffer.data(rt); + auto filePath = path.utf8(rt); + return createPromiseAsJSIValue( + rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = [=, &innerRt]() { + std::string error; + try { + std::ofstream file; + file.exceptions(std::fstream::failbit | std::fstream::badbit); + file.open(filePath, std::ios::binary); + file.write((char *)dataPtr, size); + file.close(); + } catch (const std::exception &e) { + error = "Failed to write file " + filePath + ": " + e.what(); + } + + this->jsInvoker_->invokeAsync([error, promise]() { + if (error.size()) { + promise->reject(error); + } else { + promise->resolve(jsi::Value::undefined()); + } + }); + }; + this->utilsThread->scheduleTask(job); + }); } jsi::Value CommUtilsModule::readBufferFromFile(jsi::Runtime &rt, jsi::String path) { - return jsi::Value::undefined(); + auto filePath = path.utf8(rt); + return createPromiseAsJSIValue( + rt, [=](jsi::Runtime &innerRt, std::shared_ptr promise) { + taskType job = [=, &innerRt]() { + std::string error; + std::streampos file_size; + std::shared_ptr data{nullptr}; + try { + // Open a file + std::ifstream file; + file.exceptions(std::fstream::failbit | std::fstream::badbit); + file.open(filePath, std::ios::binary); + + // Get file size + std::streampos current_pos = file.tellg(); + file.seekg(0, std::ios::end); + file_size = file.tellg(); + file.seekg(current_pos); + + // Read file content + data = std::shared_ptr{new uint8_t[file_size]}; + file.read((char *)data.get(), file_size); + file.close(); + } catch (const std::exception &e) { + error = "Failed to read file " + filePath + ": " + e.what(); + } + + this->jsInvoker_->invokeAsync([=, &innerRt]() { + if (error.size()) { + promise->reject(error); + return; + } + auto arrayBuffer = + innerRt.global() + .getPropertyAsFunction(innerRt, "ArrayBuffer") + // ArrayBuffer constructor takes one parameter: byte length + .callAsConstructor( + innerRt, {static_cast(file_size)}) + .asObject(innerRt) + .getArrayBuffer(innerRt); + auto bufferPtr = arrayBuffer.data(innerRt); + memcpy((void *)bufferPtr, data.get(), file_size); + promise->resolve(std::move(arrayBuffer)); + }); + }; + this->utilsThread->scheduleTask(job); + }); } jsi::String CommUtilsModule::base64EncodeBuffer(jsi::Runtime &rt, jsi::Object data) { return jsi::String::createFromAscii(rt, "unimplemented"); } } // namespace comm