diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 06a224f457ab50..28de85f7ba2f22 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -199,6 +199,8 @@ void CatalystInstanceImpl::jniLoadScriptFromAssets( sourceURL, loadSynchronously); return; + } else if (Instance::isIndexedRAMBundle(&script)) { + instance_->loadRAMBundleFromString(std::move(script), sourceURL); } else { instance_->loadScriptFromString(std::move(script), sourceURL, loadSynchronously); } diff --git a/ReactCommon/cxxreact/Instance.cpp b/ReactCommon/cxxreact/Instance.cpp index ad5069238d6e32..81996813893b92 100644 --- a/ReactCommon/cxxreact/Instance.cpp +++ b/ReactCommon/cxxreact/Instance.cpp @@ -108,6 +108,24 @@ bool Instance::isIndexedRAMBundle(const char *sourcePath) { return parseTypeFromHeader(header) == ScriptTag::RAMBundle; } +bool Instance::isIndexedRAMBundle(std::unique_ptr* script) { + BundleHeader header; + strncpy(reinterpret_cast(&header), script->get()->c_str(), sizeof(header)); + + return parseTypeFromHeader(header) == ScriptTag::RAMBundle; +} + +void Instance::loadRAMBundleFromString(std::unique_ptr script, const std::string& sourceURL) { + auto bundle = folly::make_unique(std::move(script)); + auto startupScript = bundle->getStartupCode(); + auto registry = RAMBundleRegistry::singleBundleRegistry(std::move(bundle)); + loadRAMBundle( + std::move(registry), + std::move(startupScript), + sourceURL, + true); +} + void Instance::loadRAMBundleFromFile(const std::string& sourcePath, const std::string& sourceURL, bool loadSynchronously) { diff --git a/ReactCommon/cxxreact/Instance.h b/ReactCommon/cxxreact/Instance.h index b72729660ff601..b129ee7e633287 100644 --- a/ReactCommon/cxxreact/Instance.h +++ b/ReactCommon/cxxreact/Instance.h @@ -47,6 +47,8 @@ class RN_EXPORT Instance { void loadScriptFromString(std::unique_ptr string, std::string sourceURL, bool loadSynchronously); static bool isIndexedRAMBundle(const char *sourcePath); + static bool isIndexedRAMBundle(std::unique_ptr* string); + void loadRAMBundleFromString(std::unique_ptr script, const std::string& sourceURL); void loadRAMBundleFromFile(const std::string& sourcePath, const std::string& sourceURL, bool loadSynchronously); diff --git a/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp b/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp index 6c2e7e87c7eb26..65c73a11aef7c5 100644 --- a/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp +++ b/ReactCommon/cxxreact/JSIndexedRAMBundle.cpp @@ -6,7 +6,8 @@ #include "JSIndexedRAMBundle.h" #include - +#include +#include #include namespace facebook { @@ -18,14 +19,30 @@ std::function(std::string)> JSIndexedRAMBundl }; } -JSIndexedRAMBundle::JSIndexedRAMBundle(const char *sourcePath) : - m_bundle (sourcePath, std::ios_base::in) { +JSIndexedRAMBundle::JSIndexedRAMBundle(const char *sourcePath) { + m_bundle = std::make_unique(sourcePath, std::ifstream::binary); if (!m_bundle) { throw std::ios_base::failure( folly::to("Bundle ", sourcePath, - "cannot be opened: ", m_bundle.rdstate())); + "cannot be opened: ", m_bundle->rdstate())); } + init(); +} + +JSIndexedRAMBundle::JSIndexedRAMBundle(std::unique_ptr script) { + // tmpStream is needed because m_bundle is std::istream type + // which has no member 'write' + std::unique_ptr tmpStream = std::make_unique(); + tmpStream->write(script->c_str(), script->size()); + m_bundle = std::move(tmpStream); + if (!m_bundle) { + throw std::ios_base::failure( + folly::to("Bundle from string cannot be opened: ", m_bundle->rdstate())); + } + init(); +} +void JSIndexedRAMBundle::init() { // read in magic header, number of entries, and length of the startup section uint32_t header[3]; static_assert( @@ -78,12 +95,12 @@ std::string JSIndexedRAMBundle::getModuleCode(const uint32_t id) const { } void JSIndexedRAMBundle::readBundle(char *buffer, const std::streamsize bytes) const { - if (!m_bundle.read(buffer, bytes)) { - if (m_bundle.rdstate() & std::ios::eofbit) { + if (!m_bundle->read(buffer, bytes)) { + if (m_bundle->rdstate() & std::ios::eofbit) { throw std::ios_base::failure("Unexpected end of RAM Bundle file"); } throw std::ios_base::failure( - folly::to("Error reading RAM Bundle: ", m_bundle.rdstate())); + folly::to("Error reading RAM Bundle: ", m_bundle->rdstate())); } } @@ -92,9 +109,9 @@ void JSIndexedRAMBundle::readBundle( const std::streamsize bytes, const std::ifstream::pos_type position) const { - if (!m_bundle.seekg(position)) { + if (!m_bundle->seekg(position)) { throw std::ios_base::failure( - folly::to("Error reading RAM Bundle: ", m_bundle.rdstate())); + folly::to("Error reading RAM Bundle: ", m_bundle->rdstate())); } readBundle(buffer, bytes); } diff --git a/ReactCommon/cxxreact/JSIndexedRAMBundle.h b/ReactCommon/cxxreact/JSIndexedRAMBundle.h index be6b27f7a84576..2f2db3b708fc26 100644 --- a/ReactCommon/cxxreact/JSIndexedRAMBundle.h +++ b/ReactCommon/cxxreact/JSIndexedRAMBundle.h @@ -5,7 +5,7 @@ #pragma once -#include +#include #include #include @@ -24,6 +24,7 @@ class RN_EXPORT JSIndexedRAMBundle : public JSModulesUnbundle { // Throws std::runtime_error on failure. JSIndexedRAMBundle(const char *sourceURL); + JSIndexedRAMBundle(std::unique_ptr script); // Throws std::runtime_error on failure. std::unique_ptr getStartupCode(); @@ -51,14 +52,15 @@ class RN_EXPORT JSIndexedRAMBundle : public JSModulesUnbundle { } }; + void init(); std::string getModuleCode(const uint32_t id) const; void readBundle(char *buffer, const std::streamsize bytes) const; void readBundle( char *buffer, const std::streamsize bytes, - const std::ifstream::pos_type position) const; + const std::istream::pos_type position) const; - mutable std::ifstream m_bundle; + mutable std::unique_ptr m_bundle; ModuleTable m_table; size_t m_baseOffset; std::unique_ptr m_startupCode;