From d9b9c1d574eb586ee5cebee34034e2384138a99a Mon Sep 17 00:00:00 2001 From: Pawel Andruszkiewicz Date: Tue, 10 Nov 2015 13:12:46 +0100 Subject: [PATCH] [File] FileWriter implementation updated to handle different data types. [Verification] Code compiles, pass rate: 132/140. Change-Id: Icd65e7eba5a674faa8fedb50daf5a48ecd88ec2a Signed-off-by: Pawel Andruszkiewicz --- src/file/js/FileWriter.js | 75 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/src/file/js/FileWriter.js b/src/file/js/FileWriter.js index 56e718a..b606a3b 100644 --- a/src/file/js/FileWriter.js +++ b/src/file/js/FileWriter.js @@ -21,11 +21,67 @@ cordova.define('cordova-plugin-file.tizen.FileWriter', function(require, exports var utils_ = xwalk.utils; var native_ = new utils_.NativeManager(extension); +// https://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array +function toUTF8Array(str) { + var utf8 = []; + for (var i = 0; i < str.length; ++i) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) utf8.push(charcode); + else if (charcode < 0x800) { + utf8.push(0xc0 | (charcode >> 6), + 0x80 | (charcode & 0x3f)); + } + else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | (charcode >> 12), + 0x80 | ((charcode>>6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + // surrogate pair + else { + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + (((charcode & 0x3ff)<<10) + | (str.charCodeAt(i) & 0x3ff)); + utf8.push(0xf0 | (charcode >>18), + 0x80 | ((charcode>>12) & 0x3f), + 0x80 | ((charcode>>6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + } + return utf8; +} + module.exports = { write: function(successCallback, errorCallback, args) { var uri = args[0]; var data = args[1]; var position = args[2]; + var isBinary = args[3]; + + if (!isBinary) { + if ('string' === typeof data) { + // convert to UTF-8, as this is the default encoding for read operations + data = toUTF8Array(data); + } else { + // we don't support other types + errorCallback && errorCallback(FileError.TYPE_MISMATCH_ERR); + return; + } + } else { + if (data instanceof ArrayBuffer) { + var a = new Uint8Array(data); + data = []; + for (var i = 0; i < a.length; ++i) { + data.push(a[i]); + } + } else { + // we don't support other types + errorCallback && errorCallback(FileError.TYPE_MISMATCH_ERR); + return; + } + } var onSuccess = function (file) { if (file.isDirectory) { @@ -36,10 +92,18 @@ module.exports = { var openStreamSuccess = function (stream) { try { stream.position = position; - stream.write(data); + stream.writeBytes(data); var length = stream.position - position; stream.close(); - successCallback && successCallback(length); + + // The cordova documentation points to: http://dev.w3.org/2009/dap/file-system/file-writer.html + // This spec states that file length after write operation should be the greater of + // (pre-write length) and (pre-write position + data.size), however + // the cordova implementation sets it to the latter. In order to accommodate + // for this, we need to truncate after write... + module.exports.truncate(function() { + successCallback && successCallback(length); + }, errorCallback, [uri, stream.position]); } catch (error) { errorCallback && errorCallback(ConvertTizenFileError(error)); } @@ -68,14 +132,9 @@ module.exports = { }, truncate: function(successCallback, errorCallback, args) { - var uriPrefix = 'file://'; - var uri = args[0]; + var uri = rootsUtils.getFullPath(args[0]); var length = args[1]; - if (uri.indexOf(uriPrefix) === 0) { - uri = uri.substr(uriPrefix.length); - } - var callArgs = { 'uri': uri, 'length': length -- 2.7.4