From c625d92f28452648e1f4134446ad524bbc09150c Mon Sep 17 00:00:00 2001 From: Jakub Skowron Date: Tue, 23 Jan 2018 13:19:10 +0100 Subject: [PATCH] [Filesystem] Add support for ISO-8859-1 Latin-1 encoding in FileReadString and FileWriteString Change-Id: I2cd7942481619989891c3019d3f7d4325b962892 Signed-off-by: Jakub Skowron --- src/filesystem/filesystem_instance.cc | 38 +++++++++++++++++++++------ src/filesystem/js/file_stream.js | 16 +++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/filesystem/filesystem_instance.cc b/src/filesystem/filesystem_instance.cc index f7beef21..dc698bb8 100644 --- a/src/filesystem/filesystem_instance.cc +++ b/src/filesystem/filesystem_instance.cc @@ -175,6 +175,13 @@ static void decode_binary_from_string(const std::string& str, std::vector(); size_t offset = static_cast(args.get("offset").get()); size_t length = args.contains("length") ? (size_t)args.get("length").get() : NPOS; + const std::string& encoding = + args.contains("encoding") ? args.get("encoding").get() : "utf-8"; try { - std::vector out_data = read_file(location, offset, length); - out_data.push_back('\0'); - const char* str = (const char*)out_data.data(); + std::vector buf = read_file(location, offset, length); - // TODO: support iso-8859-1 (latin-1) encoding - ReportSuccess(picojson::value{str}, out); + if (encoding == "iso-8859-1") { + out["result"] = picojson::value(picojson::string_type, true); + latin1::to_utf8(buf, out["result"].get()); + ReportSuccess(out); + } else { // default: UTF-8 + buf.push_back('\0'); + const char* str = (const char*)buf.data(); + ReportSuccess(picojson::value{str}, out); + } } catch (std::runtime_error& e) { LoggerE("Cannot read file %s, cause: %s", location.c_str(), e.what()); PrepareError(FilesystemError::Other, out); @@ -385,15 +398,24 @@ void FilesystemInstance::FileWriteString(const picojson::value& args, picojson:: CHECK_EXIST(args, "data", out) CHECK_EXIST(args, "offset", out) CHECK_EXIST(args, "rewrite", out) - CHECK_EXIST(args, "encoding", out) const std::string& location = args.get("location").get(); const std::string& str = args.get("data").get(); size_t offset = static_cast(args.get("offset").get()); bool rewrite = static_cast(args.get("rewrite").get()); + const std::string& encoding = + args.contains("encoding") ? args.get("encoding").get() : "utf-8"; try { - write_file((const std::uint8_t*)str.c_str(), str.length(), location, offset, rewrite); + if (encoding == "iso-8859-1") { + std::vector data; + latin1::from_utf8(str, data); + write_file(data.data(), data.size(), location, offset, rewrite); + } else { // default: UTF-8 + const std::uint8_t* buf = (const std::uint8_t*)str.c_str(); + std::size_t len = str.length(); + write_file(buf, len, location, offset, rewrite); + } } catch (std::runtime_error& e) { LoggerE("Cannot write to file %s, cause: %s", location.c_str(), e.what()); PrepareError(FilesystemError::Other, out); diff --git a/src/filesystem/js/file_stream.js b/src/filesystem/js/file_stream.js index a81ead30..7703a887 100644 --- a/src/filesystem/js/file_stream.js +++ b/src/filesystem/js/file_stream.js @@ -243,6 +243,18 @@ FileStream.prototype.readBase64 = function() { return base64_encode(readBytes.apply(this, arguments)); }; +function check_characters_outside_latin1(str) { + var len = str.length; + for (var i = 0; i < len; ++i) { + if (str.charCodeAt(i) > 255) { + throw new WebAPIException( + WebAPIException.IO_ERR, + 'Invalid character at ' + i + ': ' + str.charAt(i) + ' (not ISO-8859-1)' + ); + } + } +} + function write() { var args = validator_.validateArgs(arguments, [ { @@ -269,6 +281,10 @@ function write() { rewrite: this._rewrite }; + if (data.encoding == 'iso-8859-1') { + check_characters_outside_latin1(data.data); + } + var result = native_.callSync('File_writeString', data); if (native_.isFailure(result)) { -- 2.34.1