diff --git a/es2panda/util/helpers.cpp b/es2panda/util/helpers.cpp index 3eb0d69326e6422da00e3d534d5281865c30bec2..96ed83273055c42af963df0e7528e5dbaf1584c8 100644 --- a/es2panda/util/helpers.cpp +++ b/es2panda/util/helpers.cpp @@ -521,7 +521,8 @@ void Helpers::OptimizeProgram(panda::pandasm::Program *prog, const std::string bool Helpers::ReadFileToBuffer(const std::string &file, std::stringstream &ss) { - std::ifstream inputStream(panda::os::file::File::GetExtendedFilePath(file), std::ios::binary); + std::ifstream inputStream = Helpers::FileStream( + panda::os::file::File::GetExtendedFilePath(file), std::ios::binary); if (inputStream.fail()) { std::cerr << "Failed to read file to buffer: " << file << std::endl; return false; @@ -591,4 +592,32 @@ std::string Helpers::GetHashString(std::string str) return std::to_string(result); } +#ifdef PANDA_TARGET_WINDOWS +std::wstring Helpers::Utf8ToUtf16(const std::string &utf8) +{ + std::wstring utf16; + if (utf8.empty()) { + return utf16; + } + + if (utf8.length() > static_cast(std::numeric_limits::max())) { + std::cerr << "Length of filename: " << utf8 << " is too long" << std::endl; + return utf16; + } + + const int utf8Length = static_cast(utf8.length()); + constexpr DWORD kFlags = MB_ERR_INVALID_CHARS; + const int utf16Length = MultiByteToWideChar(CP_UTF8, kFlags, utf8.data(), utf8Length, nullptr, 0); + + if (utf16Length == 0) { + std::cerr << "The filename: " << utf8 << " is not a valid utf8 encoding string" << std::endl; + return utf16; + } + + utf16.resize(utf16Length); + MultiByteToWideChar(CP_UTF8, kFlags, utf8.data(), utf8Length, &utf16[0], utf16Length); + return utf16; +} +#endif + } // namespace panda::es2panda::util diff --git a/es2panda/util/helpers.h b/es2panda/util/helpers.h index 5d06cac59fca657bc0079a26db12910269bc13b3..d36142445d50f78e85498d964936cd541d24cece 100644 --- a/es2panda/util/helpers.h +++ b/es2panda/util/helpers.h @@ -97,6 +97,9 @@ public: static bool ReadFileToBuffer(const std::string &file, std::stringstream &ss); static void ScanDirectives(ir::ScriptFunction *func, const lexer::LineIndex &lineIndex); static std::string GetHashString(std::string str); + static std::wstring Utf8ToUtf16(const std::string &utf8); + template + static T FileStream(const std::string &str, Args &&...args); static const uint32_t INVALID_INDEX = 4294967295L; static const uint32_t MAX_INT32 = 2147483647; @@ -131,6 +134,19 @@ T Helpers::BaseName(T const &path, T const &delims) return path.substr(path.find_last_of(delims) + 1); } +template +T Helpers::FileStream(const std::string &str, Args &&...args) +{ + T fileStream; +#ifdef PANDA_TARGET_WINDOWS + std::wstring filename = Helpers::Utf8ToUtf16(str); +#else //for linux and mac + std::string filename = str; +#endif + fileStream.open(filename.c_str(), args...); + return fileStream; +} + } // namespace panda::es2panda::util #endif diff --git a/merge_abc/BUILD.gn b/merge_abc/BUILD.gn index 3d5ff772ad678f5623484f0133eafc02367a0a69..76f2f741787fbc1314f9db0a1781fdd313249957 100644 --- a/merge_abc/BUILD.gn +++ b/merge_abc/BUILD.gn @@ -201,6 +201,7 @@ ohos_executable("merge_abc") { deps = [ ":panda_assembly_proto_static", "$ark_third_party_root/icu/icu4c:static_icuuc", + "../es2panda:es2panda_lib", ] if (!is_cross_platform_build) { diff --git a/merge_abc/src/protobufSnapshotGenerator.cpp b/merge_abc/src/protobufSnapshotGenerator.cpp index 8d18f4b45fc7511613e303e9c50b17c60374a7df..f377d501be96d72f04be17da112aa86ce4dd627e 100644 --- a/merge_abc/src/protobufSnapshotGenerator.cpp +++ b/merge_abc/src/protobufSnapshotGenerator.cpp @@ -16,6 +16,7 @@ #include "assemblyProgramProto.h" #include "assembly-program.h" #include "protobufSnapshotGenerator.h" +#include "util/helpers.h" namespace panda::proto { void ProtobufSnapshotGenerator::GenerateSnapshot(const panda::pandasm::Program &program, const std::string &outputName) @@ -24,7 +25,8 @@ void ProtobufSnapshotGenerator::GenerateSnapshot(const panda::pandasm::Program & Program::Serialize(program, protoProgram); - std::fstream output(panda::os::file::File::GetExtendedFilePath(outputName), + std::fstream output = panda::es2panda::util::Helpers::FileStream( + panda::os::file::File::GetExtendedFilePath(outputName), std::ios::out | std::ios::trunc | std::ios::binary); if (!output) { std::cerr << "Failed to create: " << outputName << std::endl; @@ -37,7 +39,9 @@ void ProtobufSnapshotGenerator::GenerateSnapshot(const panda::pandasm::Program & void ProtobufSnapshotGenerator::GenerateProgram(const std::string &inputName, panda::pandasm::Program &prog, panda::ArenaAllocator *allocator) { - std::fstream input(panda::os::file::File::GetExtendedFilePath(inputName), std::ios::in | std::ios::binary); + std::fstream input = panda::es2panda::util::Helpers::FileStream( + panda::os::file::File::GetExtendedFilePath(inputName), + std::ios::in | std::ios::binary); if (!input) { std::cerr << "Failed to open: " << inputName << std::endl; return; @@ -53,7 +57,8 @@ void ProtobufSnapshotGenerator::GenerateProgram(const std::string &inputName, pa panda::es2panda::util::ProgramCache *ProtobufSnapshotGenerator::GetCacheContext(const std::string &cacheFilePath, panda::ArenaAllocator *allocator) { - std::fstream input(panda::os::file::File::GetExtendedFilePath(cacheFilePath), + std::fstream input = panda::es2panda::util::Helpers::FileStream( + panda::os::file::File::GetExtendedFilePath(cacheFilePath), std::ios::in | std::ios::binary); if (!input) { return nullptr; @@ -81,7 +86,8 @@ void ProtobufSnapshotGenerator::UpdateCacheFile(const panda::es2panda::util::Pro auto *protoProgram = protoCache.mutable_program(); Program::Serialize(programCache->program, *protoProgram); - std::fstream output(panda::os::file::File::GetExtendedFilePath(cacheFilePath), + std::fstream output = panda::es2panda::util::Helpers::FileStream( + panda::os::file::File::GetExtendedFilePath(cacheFilePath), std::ios::out | std::ios::trunc | std::ios::binary); if (!output) { std::cerr << "Failed to create cache file: " << cacheFilePath << std::endl;