From 50af78dc0d6af4b8ac7cda4b17c682c0c706f161 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 | 13 ++++++++++++ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/filesystem/filesystem_instance.cc b/src/filesystem/filesystem_instance.cc index e600274..4f056a3 100644 --- a/src/filesystem/filesystem_instance.cc +++ b/src/filesystem/filesystem_instance.cc @@ -174,6 +174,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); @@ -384,15 +397,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 31812bb..92194a1 100644 --- a/src/filesystem/js/file_stream.js +++ b/src/filesystem/js/file_stream.js @@ -230,6 +230,15 @@ 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, [ { @@ -254,6 +263,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.7.4