[File] FileWriter implementation updated to handle different data types.
authorPawel Andruszkiewicz <p.andruszkie@samsung.com>
Tue, 10 Nov 2015 12:12:46 +0000 (13:12 +0100)
committerPawel Andruszkiewicz <p.andruszkie@samsung.com>
Tue, 10 Nov 2015 12:22:31 +0000 (13:22 +0100)
[Verification] Code compiles, pass rate: 132/140.

Change-Id: Icd65e7eba5a674faa8fedb50daf5a48ecd88ec2a
Signed-off-by: Pawel Andruszkiewicz <p.andruszkie@samsung.com>
src/file/js/FileWriter.js

index 56e718a..b606a3b 100644 (file)
@@ -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