summaryrefslogtreecommitdiff
path: root/plugins/org.apache.cordova.file/src
diff options
context:
space:
mode:
authorPliablePixels <pliablepixels@gmail.com>2015-06-25 16:10:07 -0400
committerPliablePixels <pliablepixels@gmail.com>2015-06-25 16:10:07 -0400
commit65e7255c868bed3bb950e7e36ab786934edc559f (patch)
tree085a58a4bc4a55111803dde9ab412dec9e9a8bb1 /plugins/org.apache.cordova.file/src
parent855a0e8ddc273b58066530a1b55a946021dfc56e (diff)
https now works with self-signed certificates (needs provisioning though)
Diffstat (limited to 'plugins/org.apache.cordova.file/src')
-rw-r--r--plugins/org.apache.cordova.file/src/android/DirectoryManager.java133
-rw-r--r--plugins/org.apache.cordova.file/src/android/EncodingException.java29
-rw-r--r--plugins/org.apache.cordova.file/src/android/FileExistsException.java29
-rw-r--r--plugins/org.apache.cordova.file/src/android/FileHelper.java158
-rwxr-xr-xplugins/org.apache.cordova.file/src/android/FileUtils.java1191
-rw-r--r--plugins/org.apache.cordova.file/src/android/InvalidModificationException.java30
-rw-r--r--plugins/org.apache.cordova.file/src/android/NoModificationAllowedException.java29
-rw-r--r--plugins/org.apache.cordova.file/src/android/TypeMismatchException.java30
-rw-r--r--plugins/org.apache.cordova.file/src/blackberry10/index.js10
-rw-r--r--plugins/org.apache.cordova.file/src/ios/CDVFile.h107
-rw-r--r--plugins/org.apache.cordova.file/src/ios/CDVFile.m1417
-rw-r--r--plugins/org.apache.cordova.file/src/windows8/FileProxy.js845
-rw-r--r--plugins/org.apache.cordova.file/src/wp/File.cs1676
13 files changed, 0 insertions, 5684 deletions
diff --git a/plugins/org.apache.cordova.file/src/android/DirectoryManager.java b/plugins/org.apache.cordova.file/src/android/DirectoryManager.java
deleted file mode 100644
index bcc005b2..00000000
--- a/plugins/org.apache.cordova.file/src/android/DirectoryManager.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-package org.apache.cordova.file;
-
-import android.os.Environment;
-import android.os.StatFs;
-
-import java.io.File;
-
-/**
- * This class provides file directory utilities.
- * All file operations are performed on the SD card.
- *
- * It is used by the FileUtils class.
- */
-public class DirectoryManager {
-
- @SuppressWarnings("unused")
- private static final String LOG_TAG = "DirectoryManager";
-
- /**
- * Determine if a file or directory exists.
- * @param name The name of the file to check.
- * @return T=exists, F=not found
- */
- public static boolean testFileExists(String name) {
- boolean status;
-
- // If SD card exists
- if ((testSaveLocationExists()) && (!name.equals(""))) {
- File path = Environment.getExternalStorageDirectory();
- File newPath = constructFilePaths(path.toString(), name);
- status = newPath.exists();
- }
- // If no SD card
- else {
- status = false;
- }
- return status;
- }
-
- /**
- * Get the free disk space
- *
- * @return Size in KB or -1 if not available
- */
- public static long getFreeDiskSpace(boolean checkInternal) {
- String status = Environment.getExternalStorageState();
- long freeSpace = 0;
-
- // If SD card exists
- if (status.equals(Environment.MEDIA_MOUNTED)) {
- freeSpace = freeSpaceCalculation(Environment.getExternalStorageDirectory().getPath());
- }
- else if (checkInternal) {
- freeSpace = freeSpaceCalculation("/");
- }
- // If no SD card and we haven't been asked to check the internal directory then return -1
- else {
- return -1;
- }
-
- return freeSpace;
- }
-
- /**
- * Given a path return the number of free KB
- *
- * @param path to the file system
- * @return free space in KB
- */
- private static long freeSpaceCalculation(String path) {
- StatFs stat = new StatFs(path);
- long blockSize = stat.getBlockSize();
- long availableBlocks = stat.getAvailableBlocks();
- return availableBlocks * blockSize / 1024;
- }
-
- /**
- * Determine if SD card exists.
- *
- * @return T=exists, F=not found
- */
- public static boolean testSaveLocationExists() {
- String sDCardStatus = Environment.getExternalStorageState();
- boolean status;
-
- // If SD card is mounted
- if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
- status = true;
- }
-
- // If no SD card
- else {
- status = false;
- }
- return status;
- }
-
- /**
- * Create a new file object from two file paths.
- *
- * @param file1 Base file path
- * @param file2 Remaining file path
- * @return File object
- */
- private static File constructFilePaths (String file1, String file2) {
- File newPath;
- if (file2.startsWith(file1)) {
- newPath = new File(file2);
- }
- else {
- newPath = new File(file1 + "/" + file2);
- }
- return newPath;
- }
-}
diff --git a/plugins/org.apache.cordova.file/src/android/EncodingException.java b/plugins/org.apache.cordova.file/src/android/EncodingException.java
deleted file mode 100644
index e9e1653b..00000000
--- a/plugins/org.apache.cordova.file/src/android/EncodingException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-package org.apache.cordova.file;
-
-@SuppressWarnings("serial")
-public class EncodingException extends Exception {
-
- public EncodingException(String message) {
- super(message);
- }
-
-}
diff --git a/plugins/org.apache.cordova.file/src/android/FileExistsException.java b/plugins/org.apache.cordova.file/src/android/FileExistsException.java
deleted file mode 100644
index 5c4d83dc..00000000
--- a/plugins/org.apache.cordova.file/src/android/FileExistsException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-package org.apache.cordova.file;
-
-@SuppressWarnings("serial")
-public class FileExistsException extends Exception {
-
- public FileExistsException(String msg) {
- super(msg);
- }
-
-}
diff --git a/plugins/org.apache.cordova.file/src/android/FileHelper.java b/plugins/org.apache.cordova.file/src/android/FileHelper.java
deleted file mode 100644
index 867f128c..00000000
--- a/plugins/org.apache.cordova.file/src/android/FileHelper.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-package org.apache.cordova.file;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.webkit.MimeTypeMap;
-
-import org.apache.cordova.CordovaInterface;
-import org.apache.cordova.LOG;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-
-public class FileHelper {
- private static final String LOG_TAG = "FileUtils";
- private static final String _DATA = "_data";
-
- /**
- * Returns the real path of the given URI string.
- * If the given URI string represents a content:// URI, the real path is retrieved from the media store.
- *
- * @param uriString the URI string of the audio/image/video
- * @param cordova the current application context
- * @return the full path to the file
- */
- @SuppressWarnings("deprecation")
- public static String getRealPath(String uriString, CordovaInterface cordova) {
- String realPath = null;
-
- if (uriString.startsWith("content://")) {
- String[] proj = { _DATA };
- Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
- int column_index = cursor.getColumnIndexOrThrow(_DATA);
- cursor.moveToFirst();
- realPath = cursor.getString(column_index);
- if (realPath == null) {
- LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
- }
- } else if (uriString.startsWith("file://")) {
- realPath = uriString.substring(7);
- if (realPath.startsWith("/android_asset/")) {
- LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
- realPath = null;
- }
- } else {
- realPath = uriString;
- }
-
- return realPath;
- }
-
- /**
- * Returns the real path of the given URI.
- * If the given URI is a content:// URI, the real path is retrieved from the media store.
- *
- * @param uri the URI of the audio/image/video
- * @param cordova the current application context
- * @return the full path to the file
- */
- public static String getRealPath(Uri uri, CordovaInterface cordova) {
- return FileHelper.getRealPath(uri.toString(), cordova);
- }
-
- /**
- * Returns an input stream based on given URI string.
- *
- * @param uriString the URI string from which to obtain the input stream
- * @param cordova the current application context
- * @return an input stream into the data at the given URI or null if given an invalid URI string
- * @throws IOException
- */
- public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova) throws IOException {
- if (uriString.startsWith("content")) {
- Uri uri = Uri.parse(uriString);
- return cordova.getActivity().getContentResolver().openInputStream(uri);
- } else if (uriString.startsWith("file://")) {
- int question = uriString.indexOf("?");
- if (question > -1) {
- uriString = uriString.substring(0,question);
- }
- if (uriString.startsWith("file:///android_asset/")) {
- Uri uri = Uri.parse(uriString);
- String relativePath = uri.getPath().substring(15);
- return cordova.getActivity().getAssets().open(relativePath);
- } else {
- return new FileInputStream(getRealPath(uriString, cordova));
- }
- } else {
- return new FileInputStream(getRealPath(uriString, cordova));
- }
- }
-
- /**
- * Removes the "file://" prefix from the given URI string, if applicable.
- * If the given URI string doesn't have a "file://" prefix, it is returned unchanged.
- *
- * @param uriString the URI string to operate on
- * @return a path without the "file://" prefix
- */
- public static String stripFileProtocol(String uriString) {
- if (uriString.startsWith("file://")) {
- uriString = uriString.substring(7);
- }
- return uriString;
- }
-
- public static String getMimeTypeForExtension(String path) {
- String extension = path;
- int lastDot = extension.lastIndexOf('.');
- if (lastDot != -1) {
- extension = extension.substring(lastDot + 1);
- }
- // Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
- extension = extension.toLowerCase(Locale.getDefault());
- if (extension.equals("3ga")) {
- return "audio/3gpp";
- }
- return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
- }
-
- /**
- * Returns the mime type of the data specified by the given URI string.
- *
- * @param uriString the URI string of the data
- * @return the mime type of the specified data
- */
- public static String getMimeType(String uriString, CordovaInterface cordova) {
- String mimeType = null;
-
- Uri uri = Uri.parse(uriString);
- if (uriString.startsWith("content://")) {
- mimeType = cordova.getActivity().getContentResolver().getType(uri);
- } else {
- mimeType = getMimeTypeForExtension(uri.getPath());
- }
-
- return mimeType;
- }
-}
diff --git a/plugins/org.apache.cordova.file/src/android/FileUtils.java b/plugins/org.apache.cordova.file/src/android/FileUtils.java
deleted file mode 100755
index 9a9452fb..00000000
--- a/plugins/org.apache.cordova.file/src/android/FileUtils.java
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-package org.apache.cordova.file;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.MediaStore;
-import android.util.Base64;
-import android.util.Log;
-
-import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaPlugin;
-import org.apache.cordova.PluginResult;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.nio.channels.FileChannel;
-
-/**
- * This class provides SD card file and directory services to JavaScript.
- * Only files on the SD card can be accessed.
- */
-public class FileUtils extends CordovaPlugin {
- private static final String LOG_TAG = "FileUtils";
-
- public static int NOT_FOUND_ERR = 1;
- public static int SECURITY_ERR = 2;
- public static int ABORT_ERR = 3;
-
- public static int NOT_READABLE_ERR = 4;
- public static int ENCODING_ERR = 5;
- public static int NO_MODIFICATION_ALLOWED_ERR = 6;
- public static int INVALID_STATE_ERR = 7;
- public static int SYNTAX_ERR = 8;
- public static int INVALID_MODIFICATION_ERR = 9;
- public static int QUOTA_EXCEEDED_ERR = 10;
- public static int TYPE_MISMATCH_ERR = 11;
- public static int PATH_EXISTS_ERR = 12;
-
- public static int TEMPORARY = 0;
- public static int PERSISTENT = 1;
- public static int RESOURCE = 2;
- public static int APPLICATION = 3;
-
- private interface FileOp {
- void run( ) throws Exception;
- }
-
- /**
- * Executes the request and returns whether the action was valid.
- *
- * @param action The action to execute.
- * @param args JSONArray of arguments for the plugin.
- * @param callbackContext The callback context used when calling back into JavaScript.
- * @return True if the action was valid, false otherwise.
- */
- public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException {
- if (action.equals("testSaveLocationExists")) {
- threadhelper( new FileOp( ){
- public void run() {
- boolean b = DirectoryManager.testSaveLocationExists();
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
- }
- },callbackContext);
- }
- else if (action.equals("getFreeDiskSpace")) {
- threadhelper( new FileOp( ){
- public void run() {
- long l = DirectoryManager.getFreeDiskSpace(false);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, l));
- }
- },callbackContext);
- }
- else if (action.equals("testFileExists")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() {
- boolean b = DirectoryManager.testFileExists(fname);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
- }
- }, callbackContext);
- }
- else if (action.equals("testDirectoryExists")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() {
- boolean b = DirectoryManager.testFileExists(fname);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, b));
- }
- }, callbackContext);
- }
- else if (action.equals("readAsText")) {
- final String encoding = args.getString(1);
- final int start = args.getInt(2);
- final int end = args.getInt(3);
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() {
- readFileAs(fname, start, end, callbackContext, encoding, PluginResult.MESSAGE_TYPE_STRING);
- }
- }, callbackContext);
- }
- else if (action.equals("readAsDataURL")) {
- final int start = args.getInt(1);
- final int end = args.getInt(2);
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() {
- readFileAs(fname, start, end, callbackContext, null, -1);
- }
- }, callbackContext);
- }
- else if (action.equals("readAsArrayBuffer")) {
- final int start = args.getInt(1);
- final int end = args.getInt(2);
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() {
- readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_ARRAYBUFFER);
- }
- },callbackContext);
- }
- else if (action.equals("readAsBinaryString")) {
- final int start = args.getInt(1);
- final int end = args.getInt(2);
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() {
- readFileAs(fname, start, end, callbackContext, null, PluginResult.MESSAGE_TYPE_BINARYSTRING);
- }
- }, callbackContext);
- }
- else if (action.equals("write")) {
- final String fname=args.getString(0);
- final String data=args.getString(1);
- final int offset=args.getInt(2);
- final Boolean isBinary=args.getBoolean(3);
- threadhelper( new FileOp( ){
- public void run() throws FileNotFoundException, IOException, NoModificationAllowedException {
- long fileSize = write(fname, data, offset, isBinary);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
- }
- }, callbackContext);
- }
- else if (action.equals("truncate")) {
- final String fname=args.getString(0);
- final int offset=args.getInt(1);
- threadhelper( new FileOp( ){
- public void run( ) throws FileNotFoundException, IOException, NoModificationAllowedException {
- long fileSize = truncateFile(fname, offset);
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, fileSize));
- }
- }, callbackContext);
- }
- else if (action.equals("requestFileSystem")) {
- final int fstype=args.getInt(0);
- final long size = args.optLong(1);
- threadhelper( new FileOp( ){
- public void run() throws IOException, JSONException {
- if (size != 0 && size > (DirectoryManager.getFreeDiskSpace(true) * 1024)) {
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, FileUtils.QUOTA_EXCEEDED_ERR));
- } else {
- JSONObject obj = requestFileSystem(fstype);
- callbackContext.success(obj);
- }
- }
- }, callbackContext);
- }
- else if (action.equals("resolveLocalFileSystemURI")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws IOException, JSONException {
- JSONObject obj = resolveLocalFileSystemURI(fname);
- callbackContext.success(obj);
- }
- },callbackContext);
- }
- else if (action.equals("getMetadata")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws FileNotFoundException, JSONException {
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, getMetadata(fname)));
- }
- }, callbackContext);
- }
- else if (action.equals("getFileMetadata")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws FileNotFoundException, JSONException {
- JSONObject obj = getFileMetadata(fname);
- callbackContext.success(obj);
- }
- },callbackContext);
- }
- else if (action.equals("getParent")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws JSONException {
- JSONObject obj = getParent(fname);
- callbackContext.success(obj);
- }
- },callbackContext);
- }
- else if (action.equals("getDirectory")) {
- final String dirname=args.getString(0);
- final String fname=args.getString(1);
- threadhelper( new FileOp( ){
- public void run() throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
- JSONObject obj = getFile(dirname, fname, args.optJSONObject(2), true);
- callbackContext.success(obj);
- }
- },callbackContext);
- }
- else if (action.equals("getFile")) {
- final String dirname=args.getString(0);
- final String fname=args.getString(1);
- threadhelper( new FileOp( ){
- public void run() throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
- JSONObject obj = getFile(dirname, fname, args.optJSONObject(2), false);
- callbackContext.success(obj);
- }
- },callbackContext);
- }
- else if (action.equals("remove")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws NoModificationAllowedException, InvalidModificationException {
- boolean success= remove(fname);
- if (success) {
- notifyDelete(fname);
- callbackContext.success();
- } else {
- callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
- }
- }
- },callbackContext);
- }
- else if (action.equals("removeRecursively")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws FileExistsException {
- boolean success = removeRecursively(fname);
- if (success) {
- callbackContext.success();
- } else {
- callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
- }
- }
- },callbackContext);
- }
- else if (action.equals("moveTo")) {
- final String fname=args.getString(0);
- final String newParent=args.getString(1);
- final String newName=args.getString(2);
- threadhelper( new FileOp( ){
- public void run() throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
- JSONObject entry = transferTo(fname, newParent, newName, true);
- callbackContext.success(entry);
- }
- },callbackContext);
- }
- else if (action.equals("copyTo")) {
- final String fname=args.getString(0);
- final String newParent=args.getString(1);
- final String newName=args.getString(2);
- threadhelper( new FileOp( ){
- public void run() throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
- JSONObject entry = transferTo(fname, newParent, newName, false);
- callbackContext.success(entry);
- }
- },callbackContext);
- }
- else if (action.equals("readEntries")) {
- final String fname=args.getString(0);
- threadhelper( new FileOp( ){
- public void run() throws FileNotFoundException, JSONException {
- JSONArray entries = readEntries(fname);
- callbackContext.success(entries);
- }
- },callbackContext);
- }
- else {
- return false;
- }
- return true;
- }
-
- /* helper to execute functions async and handle the result codes
- *
- */
- private void threadhelper(final FileOp f, final CallbackContext callbackContext){
- cordova.getThreadPool().execute(new Runnable() {
- public void run() {
- try {
- f.run();
- } catch ( Exception e) {
- e.printStackTrace();
- if( e instanceof EncodingException){
- callbackContext.error(FileUtils.ENCODING_ERR);
- } else if(e instanceof FileNotFoundException) {
- callbackContext.error(FileUtils.NOT_FOUND_ERR);
- } else if(e instanceof FileExistsException) {
- callbackContext.error(FileUtils.PATH_EXISTS_ERR);
- } else if(e instanceof NoModificationAllowedException ) {
- callbackContext.error(FileUtils.NO_MODIFICATION_ALLOWED_ERR);
- } else if(e instanceof InvalidModificationException ) {
- callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);
- } else if(e instanceof MalformedURLException ) {
- callbackContext.error(FileUtils.ENCODING_ERR);
- } else if(e instanceof IOException ) {
- callbackContext.error(FileUtils.INVALID_MODIFICATION_ERR);
- } else if(e instanceof EncodingException ) {
- callbackContext.error(FileUtils.ENCODING_ERR);
- } else if(e instanceof TypeMismatchException ) {
- callbackContext.error(FileUtils.TYPE_MISMATCH_ERR);
- }
- }
- }
- });
- }
-
- /**
- * Need to check to see if we need to clean up the content store
- *
- * @param filePath the path to check
- */
- private void notifyDelete(String filePath) {
- String newFilePath = FileHelper.getRealPath(filePath, cordova);
- try {
- this.cordova.getActivity().getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
- MediaStore.Images.Media.DATA + " = ?",
- new String[] { newFilePath });
- } catch (UnsupportedOperationException t) {
- // Was seeing this on the File mobile-spec tests on 4.0.3 x86 emulator.
- // The ContentResolver applies only when the file was registered in the
- // first case, which is generally only the case with images.
- }
- }
-
- /**
- * Allows the user to look up the Entry for a file or directory referred to by a local URI.
- *
- * @param url of the file/directory to look up
- * @return a JSONObject representing a Entry from the filesystem
- * @throws MalformedURLException if the url is not valid
- * @throws FileNotFoundException if the file does not exist
- * @throws IOException if the user can't read the file
- * @throws JSONException
- */
- @SuppressWarnings("deprecation")
- private JSONObject resolveLocalFileSystemURI(String url) throws IOException, JSONException {
- String decoded = URLDecoder.decode(url, "UTF-8");
-
- File fp = null;
-
- // Handle the special case where you get an Android content:// uri.
- if (decoded.startsWith("content:")) {
- Cursor cursor = this.cordova.getActivity().managedQuery(Uri.parse(decoded), new String[] { MediaStore.Images.Media.DATA }, null, null, null);
- // Note: MediaStore.Images/Audio/Video.Media.DATA is always "_data"
- int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
- cursor.moveToFirst();
- fp = new File(cursor.getString(column_index));
- } else {
- // Test to see if this is a valid URL first
- @SuppressWarnings("unused")
- URL testUrl = new URL(decoded);
-
- if (decoded.startsWith("file://")) {
- int questionMark = decoded.indexOf("?");
- if (questionMark < 0) {
- fp = new File(decoded.substring(7, decoded.length()));
- } else {
- fp = new File(decoded.substring(7, questionMark));
- }
- } else {
- fp = new File(decoded);
- }
- }
-
- if (!fp.exists()) {
- throw new FileNotFoundException();
- }
- if (!fp.canRead()) {
- throw new IOException();
- }
- return getEntry(fp);
- }
-
- /**
- * Read the list of files from this directory.
- *
- * @param fileName the directory to read from
- * @return a JSONArray containing JSONObjects that represent Entry objects.
- * @throws FileNotFoundException if the directory is not found.
- * @throws JSONException
- */
- private JSONArray readEntries(String fileName) throws FileNotFoundException, JSONException {
- File fp = createFileObject(fileName);
-
- if (!fp.exists()) {
- // The directory we are listing doesn't exist so we should fail.
- throw new FileNotFoundException();
- }
-
- JSONArray entries = new JSONArray();
-
- if (fp.isDirectory()) {
- File[] files = fp.listFiles();
- for (int i = 0; i < files.length; i++) {
- if (files[i].canRead()) {
- entries.put(getEntry(files[i]));
- }
- }
- }
-
- return entries;
- }
-
- /**
- * A setup method that handles the move/copy of files/directories
- *
- * @param fileName to be copied/moved
- * @param newParent is the location where the file will be copied/moved to
- * @param newName for the file directory to be called, if null use existing file name
- * @param move if false do a copy, if true do a move
- * @return a Entry object
- * @throws NoModificationAllowedException
- * @throws IOException
- * @throws InvalidModificationException
- * @throws EncodingException
- * @throws JSONException
- * @throws FileExistsException
- */
- private JSONObject transferTo(String fileName, String newParent, String newName, boolean move) throws JSONException, NoModificationAllowedException, IOException, InvalidModificationException, EncodingException, FileExistsException {
- String newFileName = FileHelper.getRealPath(fileName, cordova);
- newParent = FileHelper.getRealPath(newParent, cordova);
-
- // Check for invalid file name
- if (newName != null && newName.contains(":")) {
- throw new EncodingException("Bad file name");
- }
-
- File source = new File(newFileName);
-
- if (!source.exists()) {
- // The file/directory we are copying doesn't exist so we should fail.
- throw new FileNotFoundException("The source does not exist");
- }
-
- File destinationDir = new File(newParent);
- if (!destinationDir.exists()) {
- // The destination does not exist so we should fail.
- throw new FileNotFoundException("The source does not exist");
- }
-
- // Figure out where we should be copying to
- File destination = createDestination(newName, source, destinationDir);
-
- //Log.d(LOG_TAG, "Source: " + source.getAbsolutePath());
- //Log.d(LOG_TAG, "Destin: " + destination.getAbsolutePath());
-
- // Check to see if source and destination are the same file
- if (source.getAbsolutePath().equals(destination.getAbsolutePath())) {
- throw new InvalidModificationException("Can't copy a file onto itself");
- }
-
- if (source.isDirectory()) {
- if (move) {
- return moveDirectory(source, destination);
- } else {
- return copyDirectory(source, destination);
- }
- } else {
- if (move) {
- JSONObject newFileEntry = moveFile(source, destination);
-
- // If we've moved a file given its content URI, we need to clean up.
- if (fileName.startsWith("content://")) {
- notifyDelete(fileName);
- }
-
- return newFileEntry;
- } else {
- return copyFile(source, destination);
- }
- }
- }
-
- /**
- * Creates the destination File object based on name passed in
- *
- * @param newName for the file directory to be called, if null use existing file name
- * @param fp represents the source file
- * @param destination represents the destination file
- * @return a File object that represents the destination
- */
- private File createDestination(String newName, File fp, File destination) {
- File destFile = null;
-
- // I know this looks weird but it is to work around a JSON bug.
- if ("null".equals(newName) || "".equals(newName)) {
- newName = null;
- }
-
- if (newName != null) {
- destFile = new File(destination.getAbsolutePath() + File.separator + newName);
- } else {
- destFile = new File(destination.getAbsolutePath() + File.separator + fp.getName());
- }
- return destFile;
- }
-
- /**
- * Copy a file
- *
- * @param srcFile file to be copied
- * @param destFile destination to be copied to
- * @return a FileEntry object
- * @throws IOException
- * @throws InvalidModificationException
- * @throws JSONException
- */
- private JSONObject copyFile(File srcFile, File destFile) throws IOException, InvalidModificationException, JSONException {
- // Renaming a file to an existing directory should fail
- if (destFile.exists() && destFile.isDirectory()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- copyAction(srcFile, destFile);
-
- return getEntry(destFile);
- }
-
- /**
- * Moved this code into it's own method so moveTo could use it when the move is across file systems
- */
- private void copyAction(File srcFile, File destFile)
- throws FileNotFoundException, IOException {
- FileInputStream istream = new FileInputStream(srcFile);
- FileOutputStream ostream = new FileOutputStream(destFile);
- FileChannel input = istream.getChannel();
- FileChannel output = ostream.getChannel();
-
- try {
- input.transferTo(0, input.size(), output);
- } finally {
- istream.close();
- ostream.close();
- input.close();
- output.close();
- }
- }
-
- /**
- * Copy a directory
- *
- * @param srcDir directory to be copied
- * @param destinationDir destination to be copied to
- * @return a DirectoryEntry object
- * @throws JSONException
- * @throws IOException
- * @throws NoModificationAllowedException
- * @throws InvalidModificationException
- */
- private JSONObject copyDirectory(File srcDir, File destinationDir) throws JSONException, IOException, NoModificationAllowedException, InvalidModificationException {
- // Renaming a file to an existing directory should fail
- if (destinationDir.exists() && destinationDir.isFile()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- // Check to make sure we are not copying the directory into itself
- if (isCopyOnItself(srcDir.getAbsolutePath(), destinationDir.getAbsolutePath())) {
- throw new InvalidModificationException("Can't copy itself into itself");
- }
-
- // See if the destination directory exists. If not create it.
- if (!destinationDir.exists()) {
- if (!destinationDir.mkdir()) {
- // If we can't create the directory then fail
- throw new NoModificationAllowedException("Couldn't create the destination directory");
- }
- }
-
-
- for (File file : srcDir.listFiles()) {
- File destination = new File(destinationDir.getAbsoluteFile() + File.separator + file.getName());
- if (file.isDirectory()) {
- copyDirectory(file, destination);
- } else {
- copyFile(file, destination);
- }
- }
-
- return getEntry(destinationDir);
- }
-
- /**
- * Check to see if the user attempted to copy an entry into its parent without changing its name,
- * or attempted to copy a directory into a directory that it contains directly or indirectly.
- *
- * @param srcDir
- * @param destinationDir
- * @return
- */
- private boolean isCopyOnItself(String src, String dest) {
-
- // This weird test is to determine if we are copying or moving a directory into itself.
- // Copy /sdcard/myDir to /sdcard/myDir-backup is okay but
- // Copy /sdcard/myDir to /sdcard/myDir/backup should throw an INVALID_MODIFICATION_ERR
- if (dest.startsWith(src) && dest.indexOf(File.separator, src.length() - 1) != -1) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Move a file
- *
- * @param srcFile file to be copied
- * @param destFile destination to be copied to
- * @return a FileEntry object
- * @throws IOException
- * @throws InvalidModificationException
- * @throws JSONException
- */
- private JSONObject moveFile(File srcFile, File destFile) throws IOException, JSONException, InvalidModificationException {
- // Renaming a file to an existing directory should fail
- if (destFile.exists() && destFile.isDirectory()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- // Try to rename the file
- if (!srcFile.renameTo(destFile)) {
- // Trying to rename the file failed. Possibly because we moved across file system on the device.
- // Now we have to do things the hard way
- // 1) Copy all the old file
- // 2) delete the src file
- copyAction(srcFile, destFile);
- if (destFile.exists()) {
- srcFile.delete();
- } else {
- throw new IOException("moved failed");
- }
- }
-
- return getEntry(destFile);
- }
-
- /**
- * Move a directory
- *
- * @param srcDir directory to be copied
- * @param destinationDir destination to be copied to
- * @return a DirectoryEntry object
- * @throws JSONException
- * @throws IOException
- * @throws InvalidModificationException
- * @throws NoModificationAllowedException
- * @throws FileExistsException
- */
- private JSONObject moveDirectory(File srcDir, File destinationDir) throws IOException, JSONException, InvalidModificationException, NoModificationAllowedException, FileExistsException {
- // Renaming a file to an existing directory should fail
- if (destinationDir.exists() && destinationDir.isFile()) {
- throw new InvalidModificationException("Can't rename a file to a directory");
- }
-
- // Check to make sure we are not copying the directory into itself
- if (isCopyOnItself(srcDir.getAbsolutePath(), destinationDir.getAbsolutePath())) {
- throw new InvalidModificationException("Can't move itself into itself");
- }
-
- // If the destination directory already exists and is empty then delete it. This is according to spec.
- if (destinationDir.exists()) {
- if (destinationDir.list().length > 0) {
- throw new InvalidModificationException("directory is not empty");
- }
- }
-
- // Try to rename the directory
- if (!srcDir.renameTo(destinationDir)) {
- // Trying to rename the directory failed. Possibly because we moved across file system on the device.
- // Now we have to do things the hard way
- // 1) Copy all the old files
- // 2) delete the src directory
- copyDirectory(srcDir, destinationDir);
- if (destinationDir.exists()) {
- removeDirRecursively(srcDir);
- } else {
- throw new IOException("moved failed");
- }
- }
-
- return getEntry(destinationDir);
- }
-
- /**
- * Deletes a directory and all of its contents, if any. In the event of an error
- * [e.g. trying to delete a directory that contains a file that cannot be removed],
- * some of the contents of the directory may be deleted.
- * It is an error to attempt to delete the root directory of a filesystem.
- *
- * @param filePath the directory to be removed
- * @return a boolean representing success of failure
- * @throws FileExistsException
- */
- private boolean removeRecursively(String filePath) throws FileExistsException {
- File fp = createFileObject(filePath);
-
- // You can't delete the root directory.
- if (atRootDirectory(filePath)) {
- return false;
- }
-
- return removeDirRecursively(fp);
- }
-
- /**
- * Loops through a directory deleting all the files.
- *
- * @param directory to be removed
- * @return a boolean representing success of failure
- * @throws FileExistsException
- */
- private boolean removeDirRecursively(File directory) throws FileExistsException {
- if (directory.isDirectory()) {
- for (File file : directory.listFiles()) {
- removeDirRecursively(file);
- }
- }
-
- if (!directory.delete()) {
- throw new FileExistsException("could not delete: " + directory.getName());
- } else {
- return true;
- }
- }
-
- /**
- * Deletes a file or directory. It is an error to attempt to delete a directory that is not empty.
- * It is an error to attempt to delete the root directory of a filesystem.
- *
- * @param filePath file or directory to be removed
- * @return a boolean representing success of failure
- * @throws NoModificationAllowedException
- * @throws InvalidModificationException
- */
- private boolean remove(String filePath) throws NoModificationAllowedException, InvalidModificationException {
- File fp = createFileObject(filePath);
-
- // You can't delete the root directory.
- if (atRootDirectory(filePath)) {
- throw new NoModificationAllowedException("You can't delete the root directory");
- }
-
- // You can't delete a directory that is not empty
- if (fp.isDirectory() && fp.list().length > 0) {
- throw new InvalidModificationException("You can't delete a directory that is not empty.");
- }
-
- return fp.delete();
- }
-
- /**
- * Creates or looks up a file.
- *
- * @param dirPath base directory
- * @param fileName file/directory to lookup or create
- * @param options specify whether to create or not
- * @param directory if true look up directory, if false look up file
- * @return a Entry object
- * @throws FileExistsException
- * @throws IOException
- * @throws TypeMismatchException
- * @throws EncodingException
- * @throws JSONException
- */
- private JSONObject getFile(String dirPath, String fileName, JSONObject options, boolean directory) throws FileExistsException, IOException, TypeMismatchException, EncodingException, JSONException {
- boolean create = false;
- boolean exclusive = false;
- if (options != null) {
- create = options.optBoolean("create");
- if (create) {
- exclusive = options.optBoolean("exclusive");
- }
- }
-
- // Check for a ":" character in the file to line up with BB and iOS
- if (fileName.contains(":")) {
- throw new EncodingException("This file has a : in it's name");
- }
-
- File fp = createFileObject(dirPath, fileName);
-
- if (create) {
- if (exclusive && fp.exists()) {
- throw new FileExistsException("create/exclusive fails");
- }
- if (directory) {
- fp.mkdir();
- } else {
- fp.createNewFile();
- }
- if (!fp.exists()) {
- throw new FileExistsException("create fails");
- }
- }
- else {
- if (!fp.exists()) {
- throw new FileNotFoundException("path does not exist");
- }
- if (directory) {
- if (fp.isFile()) {
- throw new TypeMismatchException("path doesn't exist or is file");
- }
- } else {
- if (fp.isDirectory()) {
- throw new TypeMismatchException("path doesn't exist or is directory");
- }
- }
- }
-
- // Return the directory
- return getEntry(fp);
- }
-
- /**
- * If the path starts with a '/' just return that file object. If not construct the file
- * object from the path passed in and the file name.
- *
- * @param dirPath root directory
- * @param fileName new file name
- * @return
- */
- private File createFileObject(String dirPath, String fileName) {
- File fp = null;
- if (fileName.startsWith("/")) {
- fp = new File(fileName);
- } else {
- dirPath = FileHelper.getRealPath(dirPath, cordova);
- fp = new File(dirPath + File.separator + fileName);
- }
- return fp;
- }
-
- /**
- * Look up the parent DirectoryEntry containing this Entry.
- * If this Entry is the root of its filesystem, its parent is itself.
- *
- * @param filePath
- * @return
- * @throws JSONException
- */
- private JSONObject getParent(String filePath) throws JSONException {
- filePath = FileHelper.getRealPath(filePath, cordova);
-
- if (atRootDirectory(filePath)) {
- return getEntry(filePath);
- }
- return getEntry(new File(filePath).getParent());
- }
-
- /**
- * Checks to see if we are at the root directory. Useful since we are
- * not allow to delete this directory.
- *
- * @param filePath to directory
- * @return true if we are at the root, false otherwise.
- */
- private boolean atRootDirectory(String filePath) {
- filePath = FileHelper.getRealPath(filePath, cordova);
-
- if (filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + cordova.getActivity().getPackageName() + "/cache") ||
- filePath.equals(Environment.getExternalStorageDirectory().getAbsolutePath()) ||
- filePath.equals("/data/data/" + cordova.getActivity().getPackageName())) {
- return true;
- }
- return false;
- }
-
- /**
- * Create a File object from the passed in path
- *
- * @param filePath
- * @return
- */
- private File createFileObject(String filePath) {
- filePath = FileHelper.getRealPath(filePath, cordova);
-
- File file = new File(filePath);
- return file;
- }
-
- /**
- * Look up metadata about this entry.
- *
- * @param filePath to entry
- * @return a long
- * @throws FileNotFoundException
- */
- private long getMetadata(String filePath) throws FileNotFoundException {
- File file = createFileObject(filePath);
-
- if (!file.exists()) {
- throw new FileNotFoundException("Failed to find file in getMetadata");
- }
-
- return file.lastModified();
- }
-
- /**
- * Returns a File that represents the current state of the file that this FileEntry represents.
- *
- * @param filePath to entry
- * @return returns a JSONObject represent a W3C File object
- * @throws FileNotFoundException
- * @throws JSONException
- */
- private JSONObject getFileMetadata(String filePath) throws FileNotFoundException, JSONException {
- File file = createFileObject(filePath);
-
- if (!file.exists()) {
- throw new FileNotFoundException("File: " + filePath + " does not exist.");
- }
-
- JSONObject metadata = new JSONObject();
- metadata.put("size", file.length());
- metadata.put("type", FileHelper.getMimeType(filePath, cordova));
- metadata.put("name", file.getName());
- metadata.put("fullPath", filePath);
- metadata.put("lastModifiedDate", file.lastModified());
-
- return metadata;
- }
-
- /**
- * Requests a filesystem in which to store application data.
- *
- * @param type of file system requested
- * @return a JSONObject representing the file system
- * @throws IOException
- * @throws JSONException
- */
- private JSONObject requestFileSystem(int type) throws IOException, JSONException {
- JSONObject fs = new JSONObject();
- if (type == TEMPORARY) {
- File fp;
- fs.put("name", "temporary");
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- fp = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
- "/Android/data/" + cordova.getActivity().getPackageName() + "/cache/");
- // Create the cache dir if it doesn't exist.
- fp.mkdirs();
- fs.put("root", getEntry(Environment.getExternalStorageDirectory().getAbsolutePath() +
- "/Android/data/" + cordova.getActivity().getPackageName() + "/cache/"));
- } else {
- fp = new File("/data/data/" + cordova.getActivity().getPackageName() + "/cache/");
- // Create the cache dir if it doesn't exist.
- fp.mkdirs();
- fs.put("root", getEntry("/data/data/" + cordova.getActivity().getPackageName() + "/cache/"));
- }
- }
- else if (type == PERSISTENT) {
- fs.put("name", "persistent");
- if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- fs.put("root", getEntry(Environment.getExternalStorageDirectory()));
- } else {
- fs.put("root", getEntry("/data/data/" + cordova.getActivity().getPackageName()));
- }
- }
- else {
- throw new IOException("No filesystem of type requested");
- }
-
- return fs;
- }
-
- /**
- * Returns a JSON object representing the given File.
- *
- * @param file the File to convert
- * @return a JSON representation of the given File
- * @throws JSONException
- */
- public static JSONObject getEntry(File file) throws JSONException {
- JSONObject entry = new JSONObject();
-
- entry.put("isFile", file.isFile());
- entry.put("isDirectory", file.isDirectory());
- entry.put("name", file.getName());
- entry.put("fullPath", "file://" + file.getAbsolutePath());
- // The file system can't be specified, as it would lead to an infinite loop.
- // entry.put("filesystem", null);
-
- return entry;
- }
-
- /**
- * Returns a JSON Object representing a directory on the device's file system
- *
- * @param path to the directory
- * @return
- * @throws JSONException
- */
- private JSONObject getEntry(String path) throws JSONException {
- return getEntry(new File(path));
- }
-
- /**
- * Read the contents of a file.
- * This is done in a background thread; the result is sent to the callback.
- *
- * @param filename The name of the file.
- * @param start Start position in the file.
- * @param end End position to stop at (exclusive).
- * @param callbackContext The context through which to send the result.
- * @param encoding The encoding to return contents as. Typical value is UTF-8. (see http://www.iana.org/assignments/character-sets)
- * @param resultType The desired type of data to send to the callback.
- * @return Contents of file.
- */
- public void readFileAs(final String filename, final int start, final int end, final CallbackContext callbackContext, final String encoding, final int resultType) {
- this.cordova.getThreadPool().execute(new Runnable() {
- public void run() {
- try {
- byte[] bytes = readAsBinaryHelper(filename, start, end);
-
- PluginResult result;
- switch (resultType) {
- case PluginResult.MESSAGE_TYPE_STRING:
- result = new PluginResult(PluginResult.Status.OK, new String(bytes, encoding));
- break;
- case PluginResult.MESSAGE_TYPE_ARRAYBUFFER:
- result = new PluginResult(PluginResult.Status.OK, bytes);
- break;
- case PluginResult.MESSAGE_TYPE_BINARYSTRING:
- result = new PluginResult(PluginResult.Status.OK, bytes, true);
- break;
- default: // Base64.
- String contentType = FileHelper.getMimeType(filename, cordova);
- byte[] base64 = Base64.encode(bytes, Base64.NO_WRAP);
- String s = "data:" + contentType + ";base64," + new String(base64, "US-ASCII");
- result = new PluginResult(PluginResult.Status.OK, s);
- }
-
- callbackContext.sendPluginResult(result);
- } catch (FileNotFoundException e) {
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_FOUND_ERR));
- } catch (IOException e) {
- Log.d(LOG_TAG, e.getLocalizedMessage());
- callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, NOT_READABLE_ERR));
- }
- }
- });
- }
-
- /**
- * Read the contents of a file as binary.
- * This is done synchronously; the result is returned.
- *
- * @param filename The name of the file.
- * @param start Start position in the file.
- * @param end End position to stop at (exclusive).
- * @return Contents of the file as a byte[].
- * @throws IOException
- */
- private byte[] readAsBinaryHelper(String filename, int start, int end) throws IOException {
- int numBytesToRead = end - start;
- byte[] bytes = new byte[numBytesToRead];
- InputStream inputStream = FileHelper.getInputStreamFromUriString(filename, cordova);
- int numBytesRead = 0;
-
- if (start > 0) {
- inputStream.skip(start);
- }
-
- while (numBytesToRead > 0 && (numBytesRead = inputStream.read(bytes, numBytesRead, numBytesToRead)) >= 0) {
- numBytesToRead -= numBytesRead;
- }
-
- return bytes;
- }
-
- /**
- * Write contents of file.
- *
- * @param filename The name of the file.
- * @param data The contents of the file.
- * @param offset The position to begin writing the file.
- * @param isBinary True if the file contents are base64-encoded binary data
- * @throws FileNotFoundException, IOException
- * @throws NoModificationAllowedException
- */
- /**/
- public long write(String filename, String data, int offset, boolean isBinary) throws FileNotFoundException, IOException, NoModificationAllowedException {
- if (filename.startsWith("content://")) {
- throw new NoModificationAllowedException("Couldn't write to file given its content URI");
- }
-
- filename = FileHelper.getRealPath(filename, cordova);
-
- boolean append = false;
- if (offset > 0) {
- this.truncateFile(filename, offset);
- append = true;
- }
-
- byte[] rawData;
- if (isBinary) {
- rawData = Base64.decode(data, Base64.DEFAULT);
- } else {
- rawData = data.getBytes();
- }
- ByteArrayInputStream in = new ByteArrayInputStream(rawData);
- try
- {
- FileOutputStream out = new FileOutputStream(filename, append);
- byte buff[] = new byte[rawData.length];
- in.read(buff, 0, buff.length);
- out.write(buff, 0, rawData.length);
- out.flush();
- out.close();
- }
- catch (NullPointerException e)
- {
- // This is a bug in the Android implementation of the Java Stack
- NoModificationAllowedException realException = new NoModificationAllowedException(filename);
- throw realException;
- }
-
- return rawData.length;
- }
-
- /**
- * Truncate the file to size
- *
- * @param filename
- * @param size
- * @throws FileNotFoundException, IOException
- * @throws NoModificationAllowedException
- */
- private long truncateFile(String filename, long size) throws FileNotFoundException, IOException, NoModificationAllowedException {
- if (filename.startsWith("content://")) {
- throw new NoModificationAllowedException("Couldn't truncate file given its content URI");
- }
-
- filename = FileHelper.getRealPath(filename, cordova);
-
- RandomAccessFile raf = new RandomAccessFile(filename, "rw");
- try {
- if (raf.length() >= size) {
- FileChannel channel = raf.getChannel();
- channel.truncate(size);
- return size;
- }
-
- return raf.length();
- } finally {
- raf.close();
- }
- }
-}
diff --git a/plugins/org.apache.cordova.file/src/android/InvalidModificationException.java b/plugins/org.apache.cordova.file/src/android/InvalidModificationException.java
deleted file mode 100644
index 8f6bec59..00000000
--- a/plugins/org.apache.cordova.file/src/android/InvalidModificationException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-
-package org.apache.cordova.file;
-
-@SuppressWarnings("serial")
-public class InvalidModificationException extends Exception {
-
- public InvalidModificationException(String message) {
- super(message);
- }
-
-}
diff --git a/plugins/org.apache.cordova.file/src/android/NoModificationAllowedException.java b/plugins/org.apache.cordova.file/src/android/NoModificationAllowedException.java
deleted file mode 100644
index 627eafb5..00000000
--- a/plugins/org.apache.cordova.file/src/android/NoModificationAllowedException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-package org.apache.cordova.file;
-
-@SuppressWarnings("serial")
-public class NoModificationAllowedException extends Exception {
-
- public NoModificationAllowedException(String message) {
- super(message);
- }
-
-}
diff --git a/plugins/org.apache.cordova.file/src/android/TypeMismatchException.java b/plugins/org.apache.cordova.file/src/android/TypeMismatchException.java
deleted file mode 100644
index 1315f9a9..00000000
--- a/plugins/org.apache.cordova.file/src/android/TypeMismatchException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-
-package org.apache.cordova.file;
-
-@SuppressWarnings("serial")
-public class TypeMismatchException extends Exception {
-
- public TypeMismatchException(String message) {
- super(message);
- }
-
-}
diff --git a/plugins/org.apache.cordova.file/src/blackberry10/index.js b/plugins/org.apache.cordova.file/src/blackberry10/index.js
deleted file mode 100644
index 914d9663..00000000
--- a/plugins/org.apache.cordova.file/src/blackberry10/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-module.exports = {
- setSandbox : function (success, fail, args, env) {
- require("lib/webview").setSandbox(JSON.parse(decodeURIComponent(args[0])));
- new PluginResult(args, env).noResult(false);
- },
-
- isSandboxed : function (success, fail, args, env) {
- new PluginResult(args, env).ok(require("lib/webview").getSandbox() === "1");
- }
-};
diff --git a/plugins/org.apache.cordova.file/src/ios/CDVFile.h b/plugins/org.apache.cordova.file/src/ios/CDVFile.h
deleted file mode 100644
index 54d25f08..00000000
--- a/plugins/org.apache.cordova.file/src/ios/CDVFile.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-#import <Foundation/Foundation.h>
-#import <Cordova/CDVPlugin.h>
-
-enum CDVFileError {
- NO_ERROR = 0,
- NOT_FOUND_ERR = 1,
- SECURITY_ERR = 2,
- ABORT_ERR = 3,
- NOT_READABLE_ERR = 4,
- ENCODING_ERR = 5,
- NO_MODIFICATION_ALLOWED_ERR = 6,
- INVALID_STATE_ERR = 7,
- SYNTAX_ERR = 8,
- INVALID_MODIFICATION_ERR = 9,
- QUOTA_EXCEEDED_ERR = 10,
- TYPE_MISMATCH_ERR = 11,
- PATH_EXISTS_ERR = 12
-};
-typedef int CDVFileError;
-
-enum CDVFileSystemType {
- TEMPORARY = 0,
- PERSISTENT = 1
-};
-typedef int CDVFileSystemType;
-
-extern NSString* const kCDVAssetsLibraryPrefix;
-
-@interface CDVFile : CDVPlugin {
- NSString* appDocsPath;
- NSString* appLibraryPath;
- NSString* appTempPath;
- NSString* persistentPath;
- NSString* temporaryPath;
-
- BOOL userHasAllowed;
-}
-- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath;
-- (NSString*)getAppPath:(NSString*)pathFragment;
-// -(NSString*) getFullPath: (NSString*)pathFragment;
-- (void)requestFileSystem:(CDVInvokedUrlCommand*)command;
-- (NSDictionary*)getDirectoryEntry:(NSString*)fullPath isDirectory:(BOOL)isDir;
-- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command;
-- (void)getDirectory:(CDVInvokedUrlCommand*)command;
-- (void)getFile:(CDVInvokedUrlCommand*)command;
-- (void)getParent:(CDVInvokedUrlCommand*)command;
-- (void)getMetadata:(CDVInvokedUrlCommand*)command;
-- (void)removeRecursively:(CDVInvokedUrlCommand*)command;
-- (void)remove:(CDVInvokedUrlCommand*)command;
-- (CDVPluginResult*)doRemove:(NSString*)fullPath;
-- (void)copyTo:(CDVInvokedUrlCommand*)command;
-- (void)moveTo:(CDVInvokedUrlCommand*)command;
-- (BOOL)canCopyMoveSrc:(NSString*)src ToDestination:(NSString*)dest;
-- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy;
-// - (void) toURI:(CDVInvokedUrlCommand*)command;
-- (void)getFileMetadata:(CDVInvokedUrlCommand*)command;
-- (void)readEntries:(CDVInvokedUrlCommand*)command;
-
-- (void)readAsText:(CDVInvokedUrlCommand*)command;
-- (void)readAsDataURL:(CDVInvokedUrlCommand*)command;
-- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command;
-- (NSString*)getMimeTypeFromPath:(NSString*)fullPath;
-- (void)write:(CDVInvokedUrlCommand*)command;
-- (void)testFileExists:(CDVInvokedUrlCommand*)command;
-- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command;
-// - (void) createDirectory:(CDVInvokedUrlCommand*)command;
-// - (void) deleteDirectory:(CDVInvokedUrlCommand*)command;
-// - (void) deleteFile:(CDVInvokedUrlCommand*)command;
-- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command;
-- (void)truncate:(CDVInvokedUrlCommand*)command;
-
-// - (BOOL) fileExists:(NSString*)fileName;
-// - (BOOL) directoryExists:(NSString*)dirName;
-- (void)writeToFile:(NSString*)fileName withData:(NSData*)data append:(BOOL)shouldAppend callback:(NSString*)callbackId;
-- (void)writeToFile:(NSString*)fileName withString:(NSString*)data encoding:(NSStringEncoding)encoding append:(BOOL)shouldAppend callback:(NSString*)callbackId;
-- (unsigned long long)truncateFile:(NSString*)filePath atPosition:(unsigned long long)pos;
-
-@property (nonatomic, strong) NSString* appDocsPath;
-@property (nonatomic, strong) NSString* appLibraryPath;
-@property (nonatomic, strong) NSString* appTempPath;
-@property (nonatomic, strong) NSString* persistentPath;
-@property (nonatomic, strong) NSString* temporaryPath;
-@property BOOL userHasAllowed;
-
-@end
-
-#define kW3FileTemporary @"temporary"
-#define kW3FilePersistent @"persistent"
diff --git a/plugins/org.apache.cordova.file/src/ios/CDVFile.m b/plugins/org.apache.cordova.file/src/ios/CDVFile.m
deleted file mode 100644
index 6b2602d3..00000000
--- a/plugins/org.apache.cordova.file/src/ios/CDVFile.m
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-#import "CDVFile.h"
-#import <Cordova/CDV.h>
-#import <AssetsLibrary/ALAsset.h>
-#import <AssetsLibrary/ALAssetRepresentation.h>
-#import <AssetsLibrary/ALAssetsLibrary.h>
-#import <MobileCoreServices/MobileCoreServices.h>
-#import <sys/xattr.h>
-
-extern NSString * const NSURLIsExcludedFromBackupKey __attribute__((weak_import));
-
-#ifndef __IPHONE_5_1
- NSString* const NSURLIsExcludedFromBackupKey = @"NSURLIsExcludedFromBackupKey";
-#endif
-
-NSString* const kCDVAssetsLibraryPrefix = @"assets-library://";
-
-@implementation CDVFile
-
-@synthesize appDocsPath, appLibraryPath, appTempPath, persistentPath, temporaryPath, userHasAllowed;
-
-- (id)initWithWebView:(UIWebView*)theWebView
-{
- self = (CDVFile*)[super initWithWebView:theWebView];
- if (self) {
- // get the documents directory path
- NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- self.appDocsPath = [paths objectAtIndex:0];
-
- paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
- self.appLibraryPath = [paths objectAtIndex:0];
-
- self.appTempPath = [NSTemporaryDirectory()stringByStandardizingPath]; // remove trailing slash from NSTemporaryDirectory()
-
- self.persistentPath = [NSString stringWithFormat:@"/%@", [self.appDocsPath lastPathComponent]];
- self.temporaryPath = [NSString stringWithFormat:@"/%@", [self.appTempPath lastPathComponent]];
- // NSLog(@"docs: %@ - temp: %@", self.appDocsPath, self.appTempPath);
- }
-
- return self;
-}
-
-- (NSNumber*)checkFreeDiskSpace:(NSString*)appPath
-{
- NSFileManager* fMgr = [[NSFileManager alloc] init];
-
- NSError* __autoreleasing pError = nil;
-
- NSDictionary* pDict = [fMgr attributesOfFileSystemForPath:appPath error:&pError];
- NSNumber* pNumAvail = (NSNumber*)[pDict objectForKey:NSFileSystemFreeSize];
-
- return pNumAvail;
-}
-
-// figure out if the pathFragment represents a persistent of temporary directory and return the full application path.
-// returns nil if path is not persistent or temporary
-- (NSString*)getAppPath:(NSString*)pathFragment
-{
- NSString* appPath = nil;
- NSRange rangeP = [pathFragment rangeOfString:self.persistentPath];
- NSRange rangeT = [pathFragment rangeOfString:self.temporaryPath];
-
- if ((rangeP.location != NSNotFound) && (rangeT.location != NSNotFound)) {
- // we found both in the path, return whichever one is first
- if (rangeP.length < rangeT.length) {
- appPath = self.appDocsPath;
- } else {
- appPath = self.appTempPath;
- }
- } else if (rangeP.location != NSNotFound) {
- appPath = self.appDocsPath;
- } else if (rangeT.location != NSNotFound) {
- appPath = self.appTempPath;
- }
- return appPath;
-}
-
-/* get the full path to this resource
- * IN
- * NSString* pathFragment - full Path from File or Entry object (includes system path info)
- * OUT
- * NSString* fullPath - full iOS path to this resource, nil if not found
- */
-
-/* Was here in order to NOT have to return full path, but W3C synchronous DirectoryEntry.toURI() killed that idea since I can't call into iOS to
- * resolve full URI. Leaving this code here in case W3C spec changes.
--(NSString*) getFullPath: (NSString*)pathFragment
-{
- return pathFragment;
- NSString* fullPath = nil;
- NSString *appPath = [ self getAppPath: pathFragment];
- if (appPath){
-
- // remove last component from appPath
- NSRange range = [appPath rangeOfString:@"/" options: NSBackwardsSearch];
- NSString* newPath = [appPath substringToIndex:range.location];
- // add pathFragment to get test Path
- fullPath = [newPath stringByAppendingPathComponent:pathFragment];
- }
- return fullPath;
-} */
-
-/* Request the File System info
- *
- * IN:
- * arguments[0] - type (number as string)
- * TEMPORARY = 0, PERSISTENT = 1;
- * arguments[1] - size
- *
- * OUT:
- * Dictionary representing FileSystem object
- * name - the human readable directory name
- * root = DirectoryEntry object
- * bool isDirectory
- * bool isFile
- * string name
- * string fullPath
- * fileSystem = FileSystem object - !! ignored because creates circular reference !!
- */
-
-- (void)requestFileSystem:(CDVInvokedUrlCommand*)command
-{
- NSArray* arguments = command.arguments;
-
- // arguments
- NSString* strType = [arguments objectAtIndex:0];
- unsigned long long size = [[arguments objectAtIndex:1] longLongValue];
-
- int type = [strType intValue];
- CDVPluginResult* result = nil;
-
- if (type > 1) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR];
- NSLog(@"iOS only supports TEMPORARY and PERSISTENT file systems");
- } else {
- // NSString* fullPath = [NSString stringWithFormat:@"/%@", (type == 0 ? [self.appTempPath lastPathComponent] : [self.appDocsPath lastPathComponent])];
- NSString* fullPath = (type == 0 ? self.appTempPath : self.appDocsPath);
- // check for avail space for size request
- NSNumber* pNumAvail = [self checkFreeDiskSpace:fullPath];
- // NSLog(@"Free space: %@", [NSString stringWithFormat:@"%qu", [ pNumAvail unsignedLongLongValue ]]);
- if (pNumAvail && ([pNumAvail unsignedLongLongValue] < size)) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:QUOTA_EXCEEDED_ERR];
- } else {
- NSMutableDictionary* fileSystem = [NSMutableDictionary dictionaryWithCapacity:2];
- [fileSystem setObject:(type == TEMPORARY ? kW3FileTemporary : kW3FilePersistent) forKey:@"name"];
- NSDictionary* dirEntry = [self getDirectoryEntry:fullPath isDirectory:YES];
- [fileSystem setObject:dirEntry forKey:@"root"];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem];
- }
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/* Creates a dictionary representing an Entry Object
- *
- * IN:
- * NSString* fullPath of the entry
- * FileSystem type
- * BOOL isDirectory - YES if this is a directory, NO if is a file
- * OUT:
- * NSDictionary*
- Entry object
- * bool as NSNumber isDirectory
- * bool as NSNumber isFile
- * NSString* name - last part of path
- * NSString* fullPath
- * fileSystem = FileSystem object - !! ignored because creates circular reference FileSystem contains DirectoryEntry which contains FileSystem.....!!
- */
-- (NSDictionary*)getDirectoryEntry:(NSString*)fullPath isDirectory:(BOOL)isDir
-{
- NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:4];
- NSString* lastPart = [fullPath lastPathComponent];
-
- [dirEntry setObject:[NSNumber numberWithBool:!isDir] forKey:@"isFile"];
- [dirEntry setObject:[NSNumber numberWithBool:isDir] forKey:@"isDirectory"];
- // NSURL* fileUrl = [NSURL fileURLWithPath:fullPath];
- // [dirEntry setObject: [fileUrl absoluteString] forKey: @"fullPath"];
- [dirEntry setObject:fullPath forKey:@"fullPath"];
- [dirEntry setObject:lastPart forKey:@"name"];
-
- return dirEntry;
-}
-
-/*
- * Given a URI determine the File System information associated with it and return an appropriate W3C entry object
- * IN
- * NSString* fileURI - currently requires full file URI
- * OUT
- * Entry object
- * bool isDirectory
- * bool isFile
- * string name
- * string fullPath
- * fileSystem = FileSystem object - !! ignored because creates circular reference FileSystem contains DirectoryEntry which contains FileSystem.....!!
- */
-- (void)resolveLocalFileSystemURI:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* inputUri = [command.arguments objectAtIndex:0];
-
- // don't know if string is encoded or not so unescape
- NSString* cleanUri = [inputUri stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- // now escape in order to create URL
- NSString* strUri = [cleanUri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- NSURL* testUri = [NSURL URLWithString:strUri];
- CDVPluginResult* result = nil;
-
- if (!testUri) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR];
- } else if ([testUri isFileURL]) {
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- NSString* path = [testUri path];
- // NSLog(@"url path: %@", path);
- BOOL isDir = NO;
- // see if exists and is file or dir
- BOOL bExists = [fileMgr fileExistsAtPath:path isDirectory:&isDir];
- if (bExists) {
- // see if it contains docs path or temp path
- NSString* foundFullPath = nil;
- if ([path hasPrefix:self.appDocsPath]) {
- foundFullPath = self.appDocsPath;
- } else if ([path hasPrefix:self.appTempPath]) {
- foundFullPath = self.appTempPath;
- }
-
- if (foundFullPath == nil) {
- // error SECURITY_ERR - not one of the two paths types supported
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:SECURITY_ERR];
- } else {
- NSDictionary* fileSystem = [self getDirectoryEntry:path isDirectory:isDir];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem];
- }
- } else {
- // return NOT_FOUND_ERR
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- }
- } else if ([strUri hasPrefix:@"assets-library://"]) {
- NSDictionary* fileSystem = [self getDirectoryEntry:strUri isDirectory:NO];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem];
- } else {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR];
- }
-
- if (result != nil) {
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }
-}
-
-/* Part of DirectoryEntry interface, creates or returns the specified directory
- * IN:
- * NSString* fullPath - full path for this directory
- * NSString* path - directory to be created/returned; may be full path or relative path
- * NSDictionary* - Flags object
- * boolean as NSNumber create -
- * if create is true and directory does not exist, create dir and return directory entry
- * if create is true and exclusive is true and directory does exist, return error
- * if create is false and directory does not exist, return error
- * if create is false and the path represents a file, return error
- * boolean as NSNumber exclusive - used in conjunction with create
- * if exclusive is true and create is true - specifies failure if directory already exists
- *
- *
- */
-- (void)getDirectory:(CDVInvokedUrlCommand*)command
-{
- NSMutableArray* arguments = [NSMutableArray arrayWithArray:command.arguments];
- NSMutableDictionary* options = nil;
-
- if ([arguments count] >= 3) {
- options = [arguments objectAtIndex:2 withDefault:nil];
- }
- // add getDir to options and call getFile()
- if (options != nil) {
- options = [NSMutableDictionary dictionaryWithDictionary:options];
- } else {
- options = [NSMutableDictionary dictionaryWithCapacity:1];
- }
- [options setObject:[NSNumber numberWithInt:1] forKey:@"getDir"];
- if ([arguments count] >= 3) {
- [arguments replaceObjectAtIndex:2 withObject:options];
- } else {
- [arguments addObject:options];
- }
- CDVInvokedUrlCommand* subCommand =
- [[CDVInvokedUrlCommand alloc] initWithArguments:arguments
- callbackId:command.callbackId
- className:command.className
- methodName:command.methodName];
-
- [self getFile:subCommand];
-}
-
-/* Part of DirectoryEntry interface, creates or returns the specified file
- * IN:
- * NSString* fullPath - full path for this file
- * NSString* path - file to be created/returned; may be full path or relative path
- * NSDictionary* - Flags object
- * boolean as NSNumber create -
- * if create is true and file does not exist, create file and return File entry
- * if create is true and exclusive is true and file does exist, return error
- * if create is false and file does not exist, return error
- * if create is false and the path represents a directory, return error
- * boolean as NSNumber exclusive - used in conjunction with create
- * if exclusive is true and create is true - specifies failure if file already exists
- *
- *
- */
-- (void)getFile:(CDVInvokedUrlCommand*)command
-{
- // arguments are URL encoded
- NSString* fullPath = [command.arguments objectAtIndex:0];
- NSString* requestedPath = [command.arguments objectAtIndex:1];
- NSDictionary* options = [command.arguments objectAtIndex:2 withDefault:nil];
-
- // return unsupported result for assets-library URLs
- if ([fullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"getFile not supported for assets-library URLs."];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- CDVPluginResult* result = nil;
- BOOL bDirRequest = NO;
- BOOL create = NO;
- BOOL exclusive = NO;
- int errorCode = 0; // !!! risky - no error code currently defined for 0
-
- if ([options valueForKeyIsNumber:@"create"]) {
- create = [(NSNumber*)[options valueForKey:@"create"] boolValue];
- }
- if ([options valueForKeyIsNumber:@"exclusive"]) {
- exclusive = [(NSNumber*)[options valueForKey:@"exclusive"] boolValue];
- }
-
- if ([options valueForKeyIsNumber:@"getDir"]) {
- // this will not exist for calls directly to getFile but will have been set by getDirectory before calling this method
- bDirRequest = [(NSNumber*)[options valueForKey:@"getDir"] boolValue];
- }
- // see if the requested path has invalid characters - should we be checking for more than just ":"?
- if ([requestedPath rangeOfString:@":"].location != NSNotFound) {
- errorCode = ENCODING_ERR;
- } else {
- // was full or relative path provided?
- NSRange range = [requestedPath rangeOfString:fullPath];
- BOOL bIsFullPath = range.location != NSNotFound;
-
- NSString* reqFullPath = nil;
-
- if (!bIsFullPath) {
- reqFullPath = [fullPath stringByAppendingPathComponent:requestedPath];
- } else {
- reqFullPath = requestedPath;
- }
-
- // NSLog(@"reqFullPath = %@", reqFullPath);
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- BOOL bIsDir;
- BOOL bExists = [fileMgr fileExistsAtPath:reqFullPath isDirectory:&bIsDir];
- if (bExists && (create == NO) && (bIsDir == !bDirRequest)) {
- // path exists and is of requested type - return TYPE_MISMATCH_ERR
- errorCode = TYPE_MISMATCH_ERR;
- } else if (!bExists && (create == NO)) {
- // path does not exist and create is false - return NOT_FOUND_ERR
- errorCode = NOT_FOUND_ERR;
- } else if (bExists && (create == YES) && (exclusive == YES)) {
- // file/dir already exists and exclusive and create are both true - return PATH_EXISTS_ERR
- errorCode = PATH_EXISTS_ERR;
- } else {
- // if bExists and create == YES - just return data
- // if bExists and create == NO - just return data
- // if !bExists and create == YES - create and return data
- BOOL bSuccess = YES;
- NSError __autoreleasing* pError = nil;
- if (!bExists && (create == YES)) {
- if (bDirRequest) {
- // create the dir
- bSuccess = [fileMgr createDirectoryAtPath:reqFullPath withIntermediateDirectories:NO attributes:nil error:&pError];
- } else {
- // create the empty file
- bSuccess = [fileMgr createFileAtPath:reqFullPath contents:nil attributes:nil];
- }
- }
- if (!bSuccess) {
- errorCode = ABORT_ERR;
- if (pError) {
- NSLog(@"error creating directory: %@", [pError localizedDescription]);
- }
- } else {
- // NSLog(@"newly created file/dir (%@) exists: %d", reqFullPath, [fileMgr fileExistsAtPath:reqFullPath]);
- // file existed or was created
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getDirectoryEntry:reqFullPath isDirectory:bDirRequest]];
- }
- } // are all possible conditions met?
- }
-
- if (errorCode > 0) {
- // create error callback
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- }
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/*
- * Look up the parent Entry containing this Entry.
- * If this Entry is the root of its filesystem, its parent is itself.
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath
- * NSMutableDictionary* options
- * empty
- */
-- (void)getParent:(CDVInvokedUrlCommand*)command
-{
- // arguments are URL encoded
- NSString* fullPath = [command.arguments objectAtIndex:0];
-
- // we don't (yet?) support getting the parent of an asset
- if ([fullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_READABLE_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- CDVPluginResult* result = nil;
- NSString* newPath = nil;
-
- if ([fullPath isEqualToString:self.appDocsPath] || [fullPath isEqualToString:self.appTempPath]) {
- // return self
- newPath = fullPath;
- } else {
- // since this call is made from an existing Entry object - the parent should already exist so no additional error checking
- // remove last component and return Entry
- NSRange range = [fullPath rangeOfString:@"/" options:NSBackwardsSearch];
- newPath = [fullPath substringToIndex:range.location];
- }
-
- if (newPath) {
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- BOOL bIsDir;
- BOOL bExists = [fileMgr fileExistsAtPath:newPath isDirectory:&bIsDir];
- if (bExists) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getDirectoryEntry:newPath isDirectory:bIsDir]];
- }
- }
- if (!result) {
- // invalid path or file does not exist
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/*
- * get MetaData of entry
- * Currently MetaData only includes modificationTime.
- */
-- (void)getMetadata:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
- __block CDVPluginResult* result = nil;
-
- if ([argPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- // In this case, we need to use an asynchronous method to retrieve the file.
- // Because of this, we can't just assign to `result` and send it at the end of the method.
- // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
- if (asset) {
- // We have the asset! Retrieve the metadata and send it off.
- NSDate* date = [asset valueForProperty:ALAssetPropertyDate];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:[date timeIntervalSince1970] * 1000];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- } else {
- // We couldn't find the asset. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }
- };
- // TODO(maxw): Consider making this a class variable since it's the same every time.
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
- // Retrieving the asset failed for some reason. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- };
-
- ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
- [assetsLibrary assetForURL:[NSURL URLWithString:argPath] resultBlock:resultBlock failureBlock:failureBlock];
- return;
- }
-
- NSString* testPath = argPath; // [self getFullPath: argPath];
-
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- NSError* __autoreleasing error = nil;
-
- NSDictionary* fileAttribs = [fileMgr attributesOfItemAtPath:testPath error:&error];
-
- if (fileAttribs) {
- NSDate* modDate = [fileAttribs fileModificationDate];
- if (modDate) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDouble:[modDate timeIntervalSince1970] * 1000];
- }
- } else {
- // didn't get fileAttribs
- CDVFileError errorCode = ABORT_ERR;
- NSLog(@"error getting metadata: %@", [error localizedDescription]);
- if ([error code] == NSFileNoSuchFileError) {
- errorCode = NOT_FOUND_ERR;
- }
- // log [NSNumber numberWithDouble: theMessage] objCtype to see what it returns
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errorCode];
- }
- if (!result) {
- // invalid path or file does not exist
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/*
- * set MetaData of entry
- * Currently we only support "com.apple.MobileBackup" (boolean)
- */
-- (void)setMetadata:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* filePath = [command.arguments objectAtIndex:0];
- NSDictionary* options = [command.arguments objectAtIndex:1 withDefault:nil];
- CDVPluginResult* result = nil;
- BOOL ok = NO;
-
- // setMetadata doesn't make sense for asset library files
- if (![filePath hasPrefix:kCDVAssetsLibraryPrefix]) {
- // we only care about this iCloud key for now.
- // set to 1/true to skip backup, set to 0/false to back it up (effectively removing the attribute)
- NSString* iCloudBackupExtendedAttributeKey = @"com.apple.MobileBackup";
- id iCloudBackupExtendedAttributeValue = [options objectForKey:iCloudBackupExtendedAttributeKey];
-
- if ((iCloudBackupExtendedAttributeValue != nil) && [iCloudBackupExtendedAttributeValue isKindOfClass:[NSNumber class]]) {
- if (IsAtLeastiOSVersion(@"5.1")) {
- NSURL* url = [NSURL fileURLWithPath:filePath];
- NSError* __autoreleasing error = nil;
-
- ok = [url setResourceValue:[NSNumber numberWithBool:[iCloudBackupExtendedAttributeValue boolValue]] forKey:NSURLIsExcludedFromBackupKey error:&error];
- } else { // below 5.1 (deprecated - only really supported in 5.01)
- u_int8_t value = [iCloudBackupExtendedAttributeValue intValue];
- if (value == 0) { // remove the attribute (allow backup, the default)
- ok = (removexattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], 0) == 0);
- } else { // set the attribute (skip backup)
- ok = (setxattr([filePath fileSystemRepresentation], [iCloudBackupExtendedAttributeKey cStringUsingEncoding:NSUTF8StringEncoding], &value, sizeof(value), 0, 0) == 0);
- }
- }
- }
- }
-
- if (ok) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
- } else {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/* removes the directory or file entry
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath
- *
- * returns NO_MODIFICATION_ALLOWED_ERR if is top level directory or no permission to delete dir
- * returns INVALID_MODIFICATION_ERR if is non-empty dir or asset library file
- * returns NOT_FOUND_ERR if file or dir is not found
-*/
-- (void)remove:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* fullPath = [command.arguments objectAtIndex:0];
- CDVPluginResult* result = nil;
- CDVFileError errorCode = 0; // !! 0 not currently defined
-
- // return error for assets-library URLs
- if ([fullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- errorCode = INVALID_MODIFICATION_ERR;
- } else if ([fullPath isEqualToString:self.appDocsPath] || [fullPath isEqualToString:self.appTempPath]) {
- // error if try to remove top level (documents or tmp) dir
- errorCode = NO_MODIFICATION_ALLOWED_ERR;
- } else {
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- BOOL bIsDir = NO;
- BOOL bExists = [fileMgr fileExistsAtPath:fullPath isDirectory:&bIsDir];
- if (!bExists) {
- errorCode = NOT_FOUND_ERR;
- }
- if (bIsDir && ([[fileMgr contentsOfDirectoryAtPath:fullPath error:nil] count] != 0)) {
- // dir is not empty
- errorCode = INVALID_MODIFICATION_ERR;
- }
- }
- if (errorCode > 0) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- } else {
- // perform actual remove
- result = [self doRemove:fullPath];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/* recursively removes the directory
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath
- *
- * returns NO_MODIFICATION_ALLOWED_ERR if is top level directory or no permission to delete dir
- * returns NOT_FOUND_ERR if file or dir is not found
- */
-- (void)removeRecursively:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* fullPath = [command.arguments objectAtIndex:0];
-
- // return unsupported result for assets-library URLs
- if ([fullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"removeRecursively not supported for assets-library URLs."];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- CDVPluginResult* result = nil;
-
- // error if try to remove top level (documents or tmp) dir
- if ([fullPath isEqualToString:self.appDocsPath] || [fullPath isEqualToString:self.appTempPath]) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];
- } else {
- result = [self doRemove:fullPath];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/* remove the file or directory (recursively)
- * IN:
- * NSString* fullPath - the full path to the file or directory to be removed
- * NSString* callbackId
- * called from remove and removeRecursively - check all pubic api specific error conditions (dir not empty, etc) before calling
- */
-
-- (CDVPluginResult*)doRemove:(NSString*)fullPath
-{
- CDVPluginResult* result = nil;
- BOOL bSuccess = NO;
- NSError* __autoreleasing pError = nil;
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
-
- @try {
- bSuccess = [fileMgr removeItemAtPath:fullPath error:&pError];
- if (bSuccess) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
- } else {
- // see if we can give a useful error
- CDVFileError errorCode = ABORT_ERR;
- NSLog(@"error getting metadata: %@", [pError localizedDescription]);
- if ([pError code] == NSFileNoSuchFileError) {
- errorCode = NOT_FOUND_ERR;
- } else if ([pError code] == NSFileWriteNoPermissionError) {
- errorCode = NO_MODIFICATION_ALLOWED_ERR;
- }
-
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- }
- } @catch(NSException* e) { // NSInvalidArgumentException if path is . or ..
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:SYNTAX_ERR];
- }
-
- return result;
-}
-
-- (void)copyTo:(CDVInvokedUrlCommand*)command
-{
- [self doCopyMove:command isCopy:YES];
-}
-
-- (void)moveTo:(CDVInvokedUrlCommand*)command
-{
- [self doCopyMove:command isCopy:NO];
-}
-
-/**
- * Helper function to check to see if the user attempted to copy an entry into its parent without changing its name,
- * or attempted to copy a directory into a directory that it contains directly or indirectly.
- *
- * IN:
- * NSString* srcDir
- * NSString* destinationDir
- * OUT:
- * YES copy/ move is allows
- * NO move is onto itself
- */
-- (BOOL)canCopyMoveSrc:(NSString*)src ToDestination:(NSString*)dest
-{
- // This weird test is to determine if we are copying or moving a directory into itself.
- // Copy /Documents/myDir to /Documents/myDir-backup is okay but
- // Copy /Documents/myDir to /Documents/myDir/backup not okay
- BOOL copyOK = YES;
- NSRange range = [dest rangeOfString:src];
-
- if (range.location != NSNotFound) {
- NSRange testRange = {range.length - 1, ([dest length] - range.length)};
- NSRange resultRange = [dest rangeOfString:@"/" options:0 range:testRange];
- if (resultRange.location != NSNotFound) {
- copyOK = NO;
- }
- }
- return copyOK;
-}
-
-/* Copy/move a file or directory to a new location
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath of entry
- * 1 - NSString* newName the new name of the entry, defaults to the current name
- * NSMutableDictionary* options - DirectoryEntry to which to copy the entry
- * BOOL - bCopy YES if copy, NO if move
- *
- */
-- (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy
-{
- NSArray* arguments = command.arguments;
-
- // arguments
- NSString* srcFullPath = [arguments objectAtIndex:0];
- NSString* destRootPath = [arguments objectAtIndex:1];
- // optional argument
- NSString* newName = ([arguments count] > 2) ? [arguments objectAtIndex:2] : [srcFullPath lastPathComponent]; // use last component from appPath if new name not provided
-
- __block CDVPluginResult* result = nil;
- CDVFileError errCode = 0; // !! Currently 0 is not defined, use this to signal error !!
-
- /*NSString* destRootPath = nil;
- NSString* key = @"fullPath";
- if([options valueForKeyIsString:key]){
- destRootPath = [options objectForKey:@"fullPath"];
- }*/
-
- if (!destRootPath) {
- // no destination provided
- errCode = NOT_FOUND_ERR;
- } else if ([newName rangeOfString:@":"].location != NSNotFound) {
- // invalid chars in new name
- errCode = ENCODING_ERR;
- } else {
- NSString* newFullPath = [destRootPath stringByAppendingPathComponent:newName];
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- if ([newFullPath isEqualToString:srcFullPath]) {
- // source and destination can not be the same
- errCode = INVALID_MODIFICATION_ERR;
- } else if ([srcFullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- if (bCopy) {
- // Copying (as opposed to moving) an assets library file is okay.
- // In this case, we need to use an asynchronous method to retrieve the file.
- // Because of this, we can't just assign to `result` and send it at the end of the method.
- // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
- if (asset) {
- // We have the asset! Get the data and try to copy it over.
- if (![fileMgr fileExistsAtPath:destRootPath]) {
- // The destination directory doesn't exist.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- } else if ([fileMgr fileExistsAtPath:newFullPath]) {
- // A file already exists at the destination path.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:PATH_EXISTS_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- // We're good to go! Write the file to the new destination.
- ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- Byte* buffer = (Byte*)malloc([assetRepresentation size]);
- NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
- NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
- [data writeToFile:newFullPath atomically:YES];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getDirectoryEntry:newFullPath isDirectory:NO]];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- } else {
- // We couldn't find the asset. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }
- };
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
- // Retrieving the asset failed for some reason. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- };
-
- ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
- [assetsLibrary assetForURL:[NSURL URLWithString:srcFullPath] resultBlock:resultBlock failureBlock:failureBlock];
- return;
- } else {
- // Moving an assets library file is not doable, since we can't remove it.
- errCode = INVALID_MODIFICATION_ERR;
- }
- } else {
- BOOL bSrcIsDir = NO;
- BOOL bDestIsDir = NO;
- BOOL bNewIsDir = NO;
- BOOL bSrcExists = [fileMgr fileExistsAtPath:srcFullPath isDirectory:&bSrcIsDir];
- BOOL bDestExists = [fileMgr fileExistsAtPath:destRootPath isDirectory:&bDestIsDir];
- BOOL bNewExists = [fileMgr fileExistsAtPath:newFullPath isDirectory:&bNewIsDir];
- if (!bSrcExists || !bDestExists) {
- // the source or the destination root does not exist
- errCode = NOT_FOUND_ERR;
- } else if (bSrcIsDir && (bNewExists && !bNewIsDir)) {
- // can't copy/move dir to file
- errCode = INVALID_MODIFICATION_ERR;
- } else { // no errors yet
- NSError* __autoreleasing error = nil;
- BOOL bSuccess = NO;
- if (bCopy) {
- if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFullPath] /*[newFullPath hasPrefix:srcFullPath]*/) {
- // can't copy dir into self
- errCode = INVALID_MODIFICATION_ERR;
- } else if (bNewExists) {
- // the full destination should NOT already exist if a copy
- errCode = PATH_EXISTS_ERR;
- } else {
- bSuccess = [fileMgr copyItemAtPath:srcFullPath toPath:newFullPath error:&error];
- }
- } else { // move
- // iOS requires that destination must not exist before calling moveTo
- // is W3C INVALID_MODIFICATION_ERR error if destination dir exists and has contents
- //
- if (!bSrcIsDir && (bNewExists && bNewIsDir)) {
- // can't move a file to directory
- errCode = INVALID_MODIFICATION_ERR;
- } else if (bSrcIsDir && ![self canCopyMoveSrc:srcFullPath ToDestination:newFullPath]) { // [newFullPath hasPrefix:srcFullPath]){
- // can't move a dir into itself
- errCode = INVALID_MODIFICATION_ERR;
- } else if (bNewExists) {
- if (bNewIsDir && ([[fileMgr contentsOfDirectoryAtPath:newFullPath error:NULL] count] != 0)) {
- // can't move dir to a dir that is not empty
- errCode = INVALID_MODIFICATION_ERR;
- newFullPath = nil; // so we won't try to move
- } else {
- // remove destination so can perform the moveItemAtPath
- bSuccess = [fileMgr removeItemAtPath:newFullPath error:NULL];
- if (!bSuccess) {
- errCode = INVALID_MODIFICATION_ERR; // is this the correct error?
- newFullPath = nil;
- }
- }
- } else if (bNewIsDir && [newFullPath hasPrefix:srcFullPath]) {
- // can't move a directory inside itself or to any child at any depth;
- errCode = INVALID_MODIFICATION_ERR;
- newFullPath = nil;
- }
-
- if (newFullPath != nil) {
- bSuccess = [fileMgr moveItemAtPath:srcFullPath toPath:newFullPath error:&error];
- }
- }
- if (bSuccess) {
- // should verify it is there and of the correct type???
- NSDictionary* newEntry = [self getDirectoryEntry:newFullPath isDirectory:bSrcIsDir]; // should be the same type as source
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:newEntry];
- } else {
- errCode = INVALID_MODIFICATION_ERR; // catch all
- if (error) {
- if (([error code] == NSFileReadUnknownError) || ([error code] == NSFileReadTooLargeError)) {
- errCode = NOT_READABLE_ERR;
- } else if ([error code] == NSFileWriteOutOfSpaceError) {
- errCode = QUOTA_EXCEEDED_ERR;
- } else if ([error code] == NSFileWriteNoPermissionError) {
- errCode = NO_MODIFICATION_ALLOWED_ERR;
- }
- }
- }
- }
- }
- }
- if (errCode > 0) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errCode];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-/* return the URI to the entry
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath of entry
- * 1 - desired mime type of entry - ignored - always returns file://
- */
-
-/* Not needed since W3C toURI is synchronous. Leaving code here for now in case W3C spec changes.....
-- (void) toURI:(CDVInvokedUrlCommand*)command
-{
- NSString* callbackId = command.callbackId;
- NSString* argPath = [command.arguments objectAtIndex:0];
- PluginResult* result = nil;
- NSString* jsString = nil;
-
- NSString* fullPath = [self getFullPath: argPath];
- if (fullPath) {
- // do we need to make sure the file actually exists?
- // create file uri
- NSString* strUri = [fullPath stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
- NSURL* fileUrl = [NSURL fileURLWithPath:strUri];
- if (fileUrl) {
- result = [PluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: [fileUrl absoluteString]];
- jsString = [result toSuccessCallbackString:callbackId];
- } // else NOT_FOUND_ERR
- }
- if(!jsString) {
- // was error
- result = [PluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt: NOT_FOUND_ERR cast: @"window.localFileSystem._castError"];
- jsString = [result toErrorCallbackString:callbackId];
- }
-
- [self writeJavascript:jsString];
-}*/
-- (void)getFileMetadata:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
-
- __block CDVPluginResult* result = nil;
-
- NSString* fullPath = argPath; // [self getFullPath: argPath];
-
- if (fullPath) {
- if ([fullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- // In this case, we need to use an asynchronous method to retrieve the file.
- // Because of this, we can't just assign to `result` and send it at the end of the method.
- // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
- if (asset) {
- // We have the asset! Populate the dictionary and send it off.
- NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];
- ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:[assetRepresentation size]] forKey:@"size"];
- [fileInfo setObject:argPath forKey:@"fullPath"];
- NSString* filename = [assetRepresentation filename];
- [fileInfo setObject:filename forKey:@"name"];
- [fileInfo setObject:[self getMimeTypeFromPath:filename] forKey:@"type"];
- NSDate* creationDate = [asset valueForProperty:ALAssetPropertyDate];
- NSNumber* msDate = [NSNumber numberWithDouble:[creationDate timeIntervalSince1970] * 1000];
- [fileInfo setObject:msDate forKey:@"lastModifiedDate"];
-
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- } else {
- // We couldn't find the asset. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }
- };
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
- // Retrieving the asset failed for some reason. Send the appropriate error.
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsString:[error localizedDescription]];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- };
-
- ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
- [assetsLibrary assetForURL:[NSURL URLWithString:argPath] resultBlock:resultBlock failureBlock:failureBlock];
- return;
- } else {
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- BOOL bIsDir = NO;
- // make sure it exists and is not a directory
- BOOL bExists = [fileMgr fileExistsAtPath:fullPath isDirectory:&bIsDir];
- if (!bExists || bIsDir) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- } else {
- // create dictionary of file info
- NSError* __autoreleasing error = nil;
- NSDictionary* fileAttrs = [fileMgr attributesOfItemAtPath:fullPath error:&error];
- NSMutableDictionary* fileInfo = [NSMutableDictionary dictionaryWithCapacity:5];
- [fileInfo setObject:[NSNumber numberWithUnsignedLongLong:[fileAttrs fileSize]] forKey:@"size"];
- [fileInfo setObject:argPath forKey:@"fullPath"];
- [fileInfo setObject:@"" forKey:@"type"]; // can't easily get the mimetype unless create URL, send request and read response so skipping
- [fileInfo setObject:[argPath lastPathComponent] forKey:@"name"];
- NSDate* modDate = [fileAttrs fileModificationDate];
- NSNumber* msDate = [NSNumber numberWithDouble:[modDate timeIntervalSince1970] * 1000];
- [fileInfo setObject:msDate forKey:@"lastModifiedDate"];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileInfo];
- }
- }
- }
- if (!result) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_INSTANTIATION_EXCEPTION];
- }
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-- (void)readEntries:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* fullPath = [command.arguments objectAtIndex:0];
-
- // return unsupported result for assets-library URLs
- if ([fullPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"readEntries not supported for assets-library URLs."];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- CDVPluginResult* result = nil;
-
- NSFileManager* fileMgr = [[NSFileManager alloc] init];
- NSError* __autoreleasing error = nil;
- NSArray* contents = [fileMgr contentsOfDirectoryAtPath:fullPath error:&error];
-
- if (contents) {
- NSMutableArray* entries = [NSMutableArray arrayWithCapacity:1];
- if ([contents count] > 0) {
- // create an Entry (as JSON) for each file/dir
- for (NSString* name in contents) {
- // see if is dir or file
- NSString* entryPath = [fullPath stringByAppendingPathComponent:name];
- BOOL bIsDir = NO;
- [fileMgr fileExistsAtPath:entryPath isDirectory:&bIsDir];
- NSDictionary* entryDict = [self getDirectoryEntry:entryPath isDirectory:bIsDir];
- [entries addObject:entryDict];
- }
- }
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:entries];
- } else {
- // assume not found but could check error for more specific error conditions
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
- }
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-- (void)readFileWithPath:(NSString*)path start:(NSInteger)start end:(NSInteger)end callback:(void (^)(NSData*, NSString* mimeType, CDVFileError))callback
-{
- if (path == nil) {
- callback(nil, nil, SYNTAX_ERR);
- } else {
- [self.commandDelegate runInBackground:^ {
- if ([path hasPrefix:kCDVAssetsLibraryPrefix]) {
- // In this case, we need to use an asynchronous method to retrieve the file.
- // Because of this, we can't just assign to `result` and send it at the end of the method.
- // Instead, we return after calling the asynchronous method and send `result` in each of the blocks.
- ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset* asset) {
- if (asset) {
- // We have the asset! Get the data and send it off.
- ALAssetRepresentation* assetRepresentation = [asset defaultRepresentation];
- Byte* buffer = (Byte*)malloc([assetRepresentation size]);
- NSUInteger bufferSize = [assetRepresentation getBytes:buffer fromOffset:0.0 length:[assetRepresentation size] error:nil];
- NSData* data = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
- NSString* MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)[assetRepresentation UTI], kUTTagClassMIMEType);
-
- callback(data, MIMEType, NO_ERROR);
- } else {
- callback(nil, nil, NOT_FOUND_ERR);
- }
- };
- ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
- // Retrieving the asset failed for some reason. Send the appropriate error.
- NSLog(@"Error: %@", error);
- callback(nil, nil, SECURITY_ERR);
- };
-
- ALAssetsLibrary* assetsLibrary = [[ALAssetsLibrary alloc] init];
- [assetsLibrary assetForURL:[NSURL URLWithString:path] resultBlock:resultBlock failureBlock:failureBlock];
- } else {
- NSString* mimeType = [self getMimeTypeFromPath:path];
- if (mimeType == nil) {
- mimeType = @"*/*";
- }
- NSFileHandle* file = [NSFileHandle fileHandleForReadingAtPath:path];
- if (start > 0) {
- [file seekToFileOffset:start];
- }
-
- NSData* readData;
- if (end < 0) {
- readData = [file readDataToEndOfFile];
- } else {
- readData = [file readDataOfLength:(end - start)];
- }
-
- [file closeFile];
-
- callback(readData, mimeType, readData != nil ? NO_ERROR : NOT_FOUND_ERR);
- }
- }];
- }
-}
-
-/* read and return file data
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath
- * 1 - NSString* encoding
- * 2 - NSString* start
- * 3 - NSString* end
- */
-- (void)readAsText:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* path = [command argumentAtIndex:0];
- NSString* encoding = [command argumentAtIndex:1];
- NSInteger start = [[command argumentAtIndex:2] integerValue];
- NSInteger end = [[command argumentAtIndex:3] integerValue];
-
- // TODO: implement
- if ([@"UTF-8" caseInsensitiveCompare : encoding] != NSOrderedSame) {
- NSLog(@"Only UTF-8 encodings are currently supported by readAsText");
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
- CDVPluginResult* result = nil;
- if (data != nil) {
- NSString* str = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSUTF8StringEncoding freeWhenDone:NO];
- // Check that UTF8 conversion did not fail.
- if (str != nil) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:str];
- result.associatedObject = data;
- } else {
- errorCode = ENCODING_ERR;
- }
- }
- if (result == nil) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- }
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }];
-}
-
-/* Read content of text file and return as base64 encoded data url.
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath
- * 1 - NSString* start
- * 2 - NSString* end
- *
- * Determines the mime type from the file extension, returns ENCODING_ERR if mimetype can not be determined.
- */
-
-- (void)readAsDataURL:(CDVInvokedUrlCommand*)command
-{
- NSString* path = [command argumentAtIndex:0];
- NSInteger start = [[command argumentAtIndex:1] integerValue];
- NSInteger end = [[command argumentAtIndex:2] integerValue];
-
- [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
- CDVPluginResult* result = nil;
- if (data != nil) {
- // TODO: Would be faster to base64 encode directly to the final string.
- NSString* output = [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, [data base64EncodedString]];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output];
- } else {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- }
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }];
-}
-
-/* Read content of text file and return as an arraybuffer
- * IN:
- * NSArray* arguments
- * 0 - NSString* fullPath
- * 1 - NSString* start
- * 2 - NSString* end
- */
-
-- (void)readAsArrayBuffer:(CDVInvokedUrlCommand*)command
-{
- NSString* path = [command argumentAtIndex:0];
- NSInteger start = [[command argumentAtIndex:1] integerValue];
- NSInteger end = [[command argumentAtIndex:2] integerValue];
-
- [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
- CDVPluginResult* result = nil;
- if (data != nil) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArrayBuffer:data];
- } else {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- }
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }];
-}
-
-- (void)readAsBinaryString:(CDVInvokedUrlCommand*)command
-{
- NSString* path = [command argumentAtIndex:0];
- NSInteger start = [[command argumentAtIndex:1] integerValue];
- NSInteger end = [[command argumentAtIndex:2] integerValue];
-
- [self readFileWithPath:path start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) {
- CDVPluginResult* result = nil;
- if (data != nil) {
- NSString* payload = [[NSString alloc] initWithBytesNoCopy:(void*)[data bytes] length:[data length] encoding:NSASCIIStringEncoding freeWhenDone:NO];
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
- result.associatedObject = data;
- } else {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
- }
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- }];
-}
-
-/* helper function to get the mimeType from the file extension
- * IN:
- * NSString* fullPath - filename (may include path)
- * OUT:
- * NSString* the mime type as type/subtype. nil if not able to determine
- */
-- (NSString*)getMimeTypeFromPath:(NSString*)fullPath
-{
- NSString* mimeType = nil;
-
- if (fullPath) {
- CFStringRef typeId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[fullPath pathExtension], NULL);
- if (typeId) {
- mimeType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass(typeId, kUTTagClassMIMEType);
- if (!mimeType) {
- // special case for m4a
- if ([(__bridge NSString*)typeId rangeOfString : @"m4a-audio"].location != NSNotFound) {
- mimeType = @"audio/mp4";
- } else if ([[fullPath pathExtension] rangeOfString:@"wav"].location != NSNotFound) {
- mimeType = @"audio/wav";
- }
- }
- CFRelease(typeId);
- }
- }
- return mimeType;
-}
-
-- (void)truncate:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
- unsigned long long pos = (unsigned long long)[[command.arguments objectAtIndex:1] longLongValue];
-
- // assets-library files can't be truncated
- if ([argPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- NSString* appFile = argPath; // [self getFullPath:argPath];
-
- unsigned long long newPos = [self truncateFile:appFile atPosition:pos];
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:newPos];
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-- (unsigned long long)truncateFile:(NSString*)filePath atPosition:(unsigned long long)pos
-{
- unsigned long long newPos = 0UL;
-
- NSFileHandle* file = [NSFileHandle fileHandleForWritingAtPath:filePath];
-
- if (file) {
- [file truncateFileAtOffset:(unsigned long long)pos];
- newPos = [file offsetInFile];
- [file synchronizeFile];
- [file closeFile];
- }
- return newPos;
-}
-
-/* write
- * IN:
- * NSArray* arguments
- * 0 - NSString* file path to write to
- * 1 - NSString* or NSData* data to write
- * 2 - NSNumber* position to begin writing
- */
-- (void)write:(CDVInvokedUrlCommand*)command
-{
- NSString* callbackId = command.callbackId;
- NSArray* arguments = command.arguments;
-
- // arguments
- NSString* argPath = [arguments objectAtIndex:0];
- id argData = [arguments objectAtIndex:1];
- unsigned long long pos = (unsigned long long)[[arguments objectAtIndex:2] longLongValue];
-
- // text can't be written into assets-library files
- if ([argPath hasPrefix:kCDVAssetsLibraryPrefix]) {
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR];
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
- return;
- }
-
- NSString* fullPath = argPath; // [self getFullPath:argPath];
-
- [self truncateFile:fullPath atPosition:pos];
-
- if ([argData isKindOfClass:[NSString class]]) {
- [self writeToFile:fullPath withString:argData encoding:NSUTF8StringEncoding append:YES callback:callbackId];
- } else if ([argData isKindOfClass:[NSData class]]) {
- [self writeToFile:fullPath withData:argData append:YES callback:callbackId];
- } else {
- CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Invalid parameter type"];
- [self.commandDelegate sendPluginResult:result callbackId:callbackId];
- }
-
-}
-
-- (void)writeToFile:(NSString*)filePath withData:(NSData*)encData append:(BOOL)shouldAppend callback:(NSString*)callbackId
-{
- CDVPluginResult* result = nil;
- CDVFileError errCode = INVALID_MODIFICATION_ERR;
- int bytesWritten = 0;
-
- if (filePath) {
- NSOutputStream* fileStream = [NSOutputStream outputStreamToFileAtPath:filePath append:shouldAppend];
- if (fileStream) {
- NSUInteger len = [encData length];
- [fileStream open];
-
- bytesWritten = [fileStream write:[encData bytes] maxLength:len];
-
- [fileStream close];
- if (bytesWritten > 0) {
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:bytesWritten];
- // } else {
- // can probably get more detailed error info via [fileStream streamError]
- // errCode already set to INVALID_MODIFICATION_ERR;
- // bytesWritten = 0; // may be set to -1 on error
- }
- } // else fileStream not created return INVALID_MODIFICATION_ERR
- } else {
- // invalid filePath
- errCode = NOT_FOUND_ERR;
- }
- if (!result) {
- // was an error
- result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:errCode];
- }
- [self.commandDelegate sendPluginResult:result callbackId:callbackId];
-}
-
-- (void)writeToFile:(NSString*)filePath withString:(NSString*)stringData encoding:(NSStringEncoding)encoding append:(BOOL)shouldAppend callback:(NSString*)callbackId
-{
- [self writeToFile:filePath withData:[stringData dataUsingEncoding:encoding allowLossyConversion:YES] append:shouldAppend callback:callbackId];
-}
-
-- (void)testFileExists:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
-
- // Get the file manager
- NSFileManager* fMgr = [NSFileManager defaultManager];
- NSString* appFile = argPath; // [ self getFullPath: argPath];
-
- BOOL bExists = [fMgr fileExistsAtPath:appFile];
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(bExists ? 1 : 0)];
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-- (void)testDirectoryExists:(CDVInvokedUrlCommand*)command
-{
- // arguments
- NSString* argPath = [command.arguments objectAtIndex:0];
-
- // Get the file manager
- NSFileManager* fMgr = [[NSFileManager alloc] init];
- NSString* appFile = argPath; // [self getFullPath: argPath];
- BOOL bIsDir = NO;
- BOOL bExists = [fMgr fileExistsAtPath:appFile isDirectory:&bIsDir];
-
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:((bExists && bIsDir) ? 1 : 0)];
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-// Returns number of bytes available via callback
-- (void)getFreeDiskSpace:(CDVInvokedUrlCommand*)command
-{
- // no arguments
-
- NSNumber* pNumAvail = [self checkFreeDiskSpace:self.appDocsPath];
-
- NSString* strFreeSpace = [NSString stringWithFormat:@"%qu", [pNumAvail unsignedLongLongValue]];
- // NSLog(@"Free space is %@", strFreeSpace );
-
- CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:strFreeSpace];
-
- [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-}
-
-@end
diff --git a/plugins/org.apache.cordova.file/src/windows8/FileProxy.js b/plugins/org.apache.cordova.file/src/windows8/FileProxy.js
deleted file mode 100644
index 1445ae70..00000000
--- a/plugins/org.apache.cordova.file/src/windows8/FileProxy.js
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var cordova = require('cordova');
-var Entry = require('./Entry'),
- File = require('./File'),
- FileEntry = require('./FileEntry'),
- FileError = require('./FileError'),
- DirectoryEntry = require('./DirectoryEntry'),
- Flags = require('./Flags'),
- FileSystem = require('./FileSystem'),
- LocalFileSystem = require('./LocalFileSystem');
-
-module.exports = {
-
- getFileMetadata:function(win,fail,args) {
- var fullPath = args[0];
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fullPath).done(
- function (storageFile) {
- storageFile.getBasicPropertiesAsync().then(
- function (basicProperties) {
- win(new File(storageFile.name, storageFile.path, storageFile.fileType, basicProperties.dateModified, basicProperties.size));
- }, function () {
- fail && fail(FileError.NOT_READABLE_ERR);
- }
- );
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- },
-
- getMetadata:function(success,fail,args) {
- var fullPath = args[0];
-
- var dealFile = function (sFile) {
- Windows.Storage.StorageFile.getFileFromPathAsync(fullPath).then(
- function (storageFile) {
- return storageFile.getBasicPropertiesAsync();
- },
- function () {
- fail && fail(FileError.NOT_READABLE_ERR);
- }
- // get the basic properties of the file.
- ).then(
- function (basicProperties) {
- success(basicProperties.dateModified);
- },
- function () {
- fail && fail(FileError.NOT_READABLE_ERR);
- }
- );
- };
-
- var dealFolder = function (sFolder) {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).then(
- function (storageFolder) {
- return storageFolder.getBasicPropertiesAsync();
- },
- function () {
- fail && fail(FileError.NOT_READABLE_ERR);
- }
- // get the basic properties of the folder.
- ).then(
- function (basicProperties) {
- success(basicProperties.dateModified);
- },
- function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- };
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fullPath).then(
- // the path is file.
- function (sFile) {
- dealFile(sFile);
- },
- // the path is folder
- function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).then(
- function (sFolder) {
- dealFolder(sFolder);
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- );
- },
-
- getParent:function(win,fail,args) { // ["fullPath"]
- var fullPath = args[0];
-
- var storageFolderPer = Windows.Storage.ApplicationData.current.localFolder;
- var storageFolderTem = Windows.Storage.ApplicationData.current.temporaryFolder;
-
- if (fullPath == storageFolderPer.path) {
- win(new DirectoryEntry(storageFolderPer.name, storageFolderPer.path));
- return;
- } else if (fullPath == storageFolderTem.path) {
- win(new DirectoryEntry(storageFolderTem.name, storageFolderTem.path));
- return;
- }
- var splitArr = fullPath.split(new RegExp(/\/|\\/g));
-
- var popItem = splitArr.pop();
-
- var result = new DirectoryEntry(popItem, fullPath.substr(0, fullPath.length - popItem.length - 1));
- Windows.Storage.StorageFolder.getFolderFromPathAsync(result.fullPath).done(
- function () { win(result); },
- function () { fail && fail(FileError.INVALID_STATE_ERR); }
- );
- },
-
- readAsText:function(win,fail,args) {
- var fileName = args[0];
- var enc = args[1];
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fileName).done(
- function (storageFile) {
- var value = Windows.Storage.Streams.UnicodeEncoding.utf8;
- if (enc == 'Utf16LE' || enc == 'utf16LE') {
- value = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
- }else if (enc == 'Utf16BE' || enc == 'utf16BE') {
- value = Windows.Storage.Streams.UnicodeEncoding.utf16BE;
- }
- Windows.Storage.FileIO.readTextAsync(storageFile, value).done(
- function (fileContent) {
- win(fileContent);
- },
- function () {
- fail && fail(FileError.ENCODING_ERR);
- }
- );
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- },
-
- readAsDataURL:function(win,fail,args) {
- var fileName = args[0];
-
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fileName).then(
- function (storageFile) {
- Windows.Storage.FileIO.readBufferAsync(storageFile).done(
- function (buffer) {
- var strBase64 = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(buffer);
- //the method encodeToBase64String will add "77u/" as a prefix, so we should remove it
- if(String(strBase64).substr(0,4) == "77u/") {
- strBase64 = strBase64.substr(4);
- }
- var mediaType = storageFile.contentType;
- var result = "data:" + mediaType + ";base64," + strBase64;
- win(result);
- }
- );
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- },
-
- getDirectory:function(win,fail,args) {
- var fullPath = args[0];
- var path = args[1];
- var options = args[2];
-
- var flag = "";
- if (options !== null) {
- flag = new Flags(options.create, options.exclusive);
- } else {
- flag = new Flags(false, false);
- }
-
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).then(
- function (storageFolder) {
- if (flag.create === true && flag.exclusive === true) {
- storageFolder.createFolderAsync(path, Windows.Storage.CreationCollisionOption.failIfExists).done(
- function (storageFolder) {
- win(new DirectoryEntry(storageFolder.name, storageFolder.path));
- }, function () {
- fail && fail(FileError.PATH_EXISTS_ERR);
- }
- );
- } else if (flag.create === true && flag.exclusive === false) {
- storageFolder.createFolderAsync(path, Windows.Storage.CreationCollisionOption.openIfExists).done(
- function (storageFolder) {
- win(new DirectoryEntry(storageFolder.name, storageFolder.path));
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }
- );
- } else if (flag.create === false) {
- if (/\?|\\|\*|\||\"|<|>|\:|\//g.test(path)) {
- fail && fail(FileError.ENCODING_ERR);
- return;
- }
-
- storageFolder.getFolderAsync(path).done(
- function (storageFolder) {
- win(new DirectoryEntry(storageFolder.name, storageFolder.path));
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- },
-
- remove:function(win,fail,args) {
- var fullPath = args[0];
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fullPath).then(
- function (sFile) {
- Windows.Storage.StorageFile.getFileFromPathAsync(fullPath).done(function (storageFile) {
- storageFile.deleteAsync().done(win, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
-
- });
- });
- },
- function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).then(
- function (sFolder) {
- var removeEntry = function () {
- var storageFolderTop = null;
-
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).then(
- function (storageFolder) {
- // FileSystem root can't be removed!
- var storageFolderPer = Windows.Storage.ApplicationData.current.localFolder;
- var storageFolderTem = Windows.Storage.ApplicationData.current.temporaryFolder;
- if (fullPath == storageFolderPer.path || fullPath == storageFolderTem.path) {
- fail && fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
- return;
- }
- storageFolderTop = storageFolder;
- return storageFolder.createFileQuery().getFilesAsync();
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
-
- }
- // check sub-files.
- ).then(function (fileList) {
- if (fileList) {
- if (fileList.length === 0) {
- return storageFolderTop.createFolderQuery().getFoldersAsync();
- } else {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }
- }
- // check sub-folders.
- }).then(function (folderList) {
- if (folderList) {
- if (folderList.length === 0) {
- storageFolderTop.deleteAsync().done(win, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
-
- });
- } else {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }
- }
-
- });
- };
- removeEntry();
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- );
- },
-
- removeRecursively:function(successCallback,fail,args) {
- var fullPath = args[0];
-
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).done(function (storageFolder) {
- var storageFolderPer = Windows.Storage.ApplicationData.current.localFolder;
- var storageFolderTem = Windows.Storage.ApplicationData.current.temporaryFolder;
-
- if (storageFolder.path == storageFolderPer.path || storageFolder.path == storageFolderTem.path) {
- fail && fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
- return;
- }
-
- var removeFolders = function (path) {
- return new WinJS.Promise(function (complete) {
- var filePromiseArr = [];
- var storageFolderTop = null;
- Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(
- function (storageFolder) {
- var fileListPromise = storageFolder.createFileQuery().getFilesAsync();
-
- storageFolderTop = storageFolder;
- return fileListPromise;
- }
- // remove all the files directly under the folder.
- ).then(function (fileList) {
- if (fileList !== null) {
- for (var i = 0; i < fileList.length; i++) {
- var filePromise = fileList[i].deleteAsync();
- filePromiseArr.push(filePromise);
- }
- }
- WinJS.Promise.join(filePromiseArr).then(function () {
- var folderListPromise = storageFolderTop.createFolderQuery().getFoldersAsync();
- return folderListPromise;
- // remove empty folders.
- }).then(function (folderList) {
- var folderPromiseArr = [];
- if (folderList.length !== 0) {
- for (var j = 0; j < folderList.length; j++) {
-
- folderPromiseArr.push(removeFolders(folderList[j].path));
- }
- WinJS.Promise.join(folderPromiseArr).then(function () {
- storageFolderTop.deleteAsync().then(complete);
- });
- } else {
- storageFolderTop.deleteAsync().then(complete);
- }
- }, function () { });
- }, function () { });
- });
- };
- removeFolders(storageFolder.path).then(function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(storageFolder.path).then(
- function () {},
- function () {
- if (typeof successCallback !== 'undefined' && successCallback !== null) { successCallback(); }
- });
- });
- });
- },
-
- getFile:function(win,fail,args) {
- var fullPath = args[0];
- var path = args[1];
- var options = args[2];
-
- var flag = "";
- if (options !== null) {
- flag = new Flags(options.create, options.exclusive);
- } else {
- flag = new Flags(false, false);
- }
-
- Windows.Storage.StorageFolder.getFolderFromPathAsync(fullPath).then(
- function (storageFolder) {
- if (flag.create === true && flag.exclusive === true) {
- storageFolder.createFileAsync(path, Windows.Storage.CreationCollisionOption.failIfExists).done(
- function (storageFile) {
- win(new FileEntry(storageFile.name, storageFile.path));
- }, function () {
- fail && fail(FileError.PATH_EXISTS_ERR);
- }
- );
- } else if (flag.create === true && flag.exclusive === false) {
- storageFolder.createFileAsync(path, Windows.Storage.CreationCollisionOption.openIfExists).done(
- function (storageFile) {
- win(new FileEntry(storageFile.name, storageFile.path));
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }
- );
- } else if (flag.create === false) {
- if (/\?|\\|\*|\||\"|<|>|\:|\//g.test(path)) {
- fail && fail(FileError.ENCODING_ERR);
- return;
- }
- storageFolder.getFileAsync(path).done(
- function (storageFile) {
- win(new FileEntry(storageFile.name, storageFile.path));
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- },
-
- readEntries:function(win,fail,args) { // ["fullPath"]
- var path = args[0];
-
- var result = [];
-
- Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(function (storageFolder) {
- var promiseArr = [];
- var index = 0;
- promiseArr[index++] = storageFolder.createFileQuery().getFilesAsync().then(function (fileList) {
- if (fileList !== null) {
- for (var i = 0; i < fileList.length; i++) {
- result.push(new FileEntry(fileList[i].name, fileList[i].path));
- }
- }
- });
- promiseArr[index++] = storageFolder.createFolderQuery().getFoldersAsync().then(function (folderList) {
- if (folderList !== null) {
- for (var j = 0; j < folderList.length; j++) {
- result.push(new FileEntry(folderList[j].name, folderList[j].path));
- }
- }
- });
- WinJS.Promise.join(promiseArr).then(function () {
- win(result);
- });
-
- }, function () { fail && fail(FileError.NOT_FOUND_ERR); });
- },
-
- write:function(win,fail,args) {
- var fileName = args[0];
- var text = args[1];
- var position = args[2];
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fileName).done(
- function (storageFile) {
- Windows.Storage.FileIO.writeTextAsync(storageFile,text,Windows.Storage.Streams.UnicodeEncoding.utf8).done(
- function() {
- win(String(text).length);
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }
- );
- }, function() {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- },
-
- truncate:function(win,fail,args) { // ["fileName","size"]
- var fileName = args[0];
- var size = args[1];
-
- Windows.Storage.StorageFile.getFileFromPathAsync(fileName).done(function(storageFile){
- //the current length of the file.
- var leng = 0;
-
- storageFile.getBasicPropertiesAsync().then(function (basicProperties) {
- leng = basicProperties.size;
- if (Number(size) >= leng) {
- win(this.length);
- return;
- }
- if (Number(size) >= 0) {
- Windows.Storage.FileIO.readTextAsync(storageFile, Windows.Storage.Streams.UnicodeEncoding.utf8).then(function (fileContent) {
- fileContent = fileContent.substr(0, size);
- var fullPath = storageFile.path;
- var name = storageFile.name;
- var entry = new Entry(true, false, name, fullPath);
- var parentPath = "";
- var successCallBack = function (entry) {
- parentPath = entry.fullPath;
- storageFile.deleteAsync().then(function () {
- return Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath);
- }).then(function (storageFolder) {
- storageFolder.createFileAsync(name).then(function (newStorageFile) {
- Windows.Storage.FileIO.writeTextAsync(newStorageFile, fileContent).done(function () {
- win(String(fileContent).length);
- }, function () {
- fail && fail(FileError.NO_MODIFICATION_ALLOWED_ERR);
- });
- });
- });
- };
- entry.getParent(successCallBack, null);
- }, function () { fail && fail(FileError.NOT_FOUND_ERR); });
- }
- });
- }, function () { fail && fail(FileError.NOT_FOUND_ERR); });
- },
-
- copyTo:function(success,fail,args) { // ["fullPath","parent", "newName"]
- var srcPath = args[0];
- var parentFullPath = args[1];
- var name = args[2];
-
- //name can't be invalid
- if (/\?|\\|\*|\||\"|<|>|\:|\//g.test(name)) {
- fail && fail(FileError.ENCODING_ERR);
- return;
- }
- // copy
- var copyFiles = "";
- Windows.Storage.StorageFile.getFileFromPathAsync(srcPath).then(
- function (sFile) {
- copyFiles = function (srcPath, parentPath) {
- var storageFileTop = null;
- Windows.Storage.StorageFile.getFileFromPathAsync(srcPath).then(function (storageFile) {
- storageFileTop = storageFile;
- return Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath);
- }, function () {
-
- fail && fail(FileError.NOT_FOUND_ERR);
- }).then(function (storageFolder) {
- storageFileTop.copyAsync(storageFolder, name, Windows.Storage.NameCollisionOption.failIfExists).then(function (storageFile) {
-
- success(new FileEntry(storageFile.name, storageFile.path));
- }, function () {
-
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- });
- }, function () {
-
- fail && fail(FileError.NOT_FOUND_ERR);
- });
- };
- var copyFinish = function (srcPath, parentPath) {
- copyFiles(srcPath, parentPath);
- };
- copyFinish(srcPath, parentFullPath);
- },
- function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(srcPath).then(
- function (sFolder) {
- copyFiles = function (srcPath, parentPath) {
- var coreCopy = function (storageFolderTop, complete) {
- storageFolderTop.createFolderQuery().getFoldersAsync().then(function (folderList) {
- var folderPromiseArr = [];
- if (folderList.length === 0) { complete(); }
- else {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath).then(function (storageFolderTarget) {
- var tempPromiseArr = [];
- var index = 0;
- for (var j = 0; j < folderList.length; j++) {
- tempPromiseArr[index++] = storageFolderTarget.createFolderAsync(folderList[j].name).then(function (targetFolder) {
- folderPromiseArr.push(copyFiles(folderList[j].path, targetFolder.path));
- });
- }
- WinJS.Promise.join(tempPromiseArr).then(function () {
- WinJS.Promise.join(folderPromiseArr).then(complete);
- });
- });
- }
- });
- };
-
- return new WinJS.Promise(function (complete) {
- var storageFolderTop = null;
- var filePromiseArr = [];
- var fileListTop = null;
- Windows.Storage.StorageFolder.getFolderFromPathAsync(srcPath).then(function (storageFolder) {
- storageFolderTop = storageFolder;
- return storageFolder.createFileQuery().getFilesAsync();
- }).then(function (fileList) {
- fileListTop = fileList;
- if (fileList) {
- return Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath);
- }
- }).then(function (targetStorageFolder) {
- for (var i = 0; i < fileListTop.length; i++) {
- filePromiseArr.push(fileListTop[i].copyAsync(targetStorageFolder));
- }
- WinJS.Promise.join(filePromiseArr).then(function () {
- coreCopy(storageFolderTop, complete);
- });
- });
- });
- };
- var copyFinish = function (srcPath, parentPath) {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath).then(function (storageFolder) {
- storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists).then(function (newStorageFolder) {
- //can't copy onto itself
- if (srcPath == newStorageFolder.path) {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- return;
- }
- //can't copy into itself
- if (srcPath == parentPath) {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- return;
- }
- copyFiles(srcPath, newStorageFolder.path).then(function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(newStorageFolder.path).done(
- function (storageFolder) {
- success(new DirectoryEntry(storageFolder.name, storageFolder.path));
- },
- function () { fail && fail(FileError.NOT_FOUND_ERR); }
- );
- });
- }, function () { fail && fail(FileError.INVALID_MODIFICATION_ERR); });
- }, function () { fail && fail(FileError.INVALID_MODIFICATION_ERR); });
- };
- copyFinish(srcPath, parentFullPath);
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- );
- },
-
- moveTo:function(success,fail,args) {
- var srcPath = args[0];
- var parentFullPath = args[1];
- var name = args[2];
-
-
- //name can't be invalid
- if (/\?|\\|\*|\||\"|<|>|\:|\//g.test(name)) {
- fail && fail(FileError.ENCODING_ERR);
- return;
- }
-
- var moveFiles = "";
- Windows.Storage.StorageFile.getFileFromPathAsync(srcPath).then(
- function (sFile) {
- moveFiles = function (srcPath, parentPath) {
- var storageFileTop = null;
- Windows.Storage.StorageFile.getFileFromPathAsync(srcPath).then(function (storageFile) {
- storageFileTop = storageFile;
- return Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath);
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }).then(function (storageFolder) {
- storageFileTop.moveAsync(storageFolder, name, Windows.Storage.NameCollisionOption.replaceExisting).then(function () {
- success(new FileEntry(name, storageFileTop.path));
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- });
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- });
- };
- var moveFinish = function (srcPath, parentPath) {
- //can't copy onto itself
- if (srcPath == parentPath + "\\" + name) {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- return;
- }
- moveFiles(srcPath, parentFullPath);
- };
- moveFinish(srcPath, parentFullPath);
- },
- function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(srcPath).then(
- function (sFolder) {
- moveFiles = function (srcPath, parentPath) {
- var coreMove = function (storageFolderTop, complete) {
- storageFolderTop.createFolderQuery().getFoldersAsync().then(function (folderList) {
- var folderPromiseArr = [];
- if (folderList.length === 0) {
- // If failed, we must cancel the deletion of folders & files.So here wo can't delete the folder.
- complete();
- }
- else {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath).then(function (storageFolderTarget) {
- var tempPromiseArr = [];
- var index = 0;
- for (var j = 0; j < folderList.length; j++) {
- tempPromiseArr[index++] = storageFolderTarget.createFolderAsync(folderList[j].name).then(function (targetFolder) {
- folderPromiseArr.push(moveFiles(folderList[j].path, targetFolder.path));
- });
- }
- WinJS.Promise.join(tempPromiseArr).then(function () {
- WinJS.Promise.join(folderPromiseArr).then(complete);
- });
- });
- }
- });
- };
- return new WinJS.Promise(function (complete) {
- var storageFolderTop = null;
- Windows.Storage.StorageFolder.getFolderFromPathAsync(srcPath).then(function (storageFolder) {
- storageFolderTop = storageFolder;
- return storageFolder.createFileQuery().getFilesAsync();
- }).then(function (fileList) {
- var filePromiseArr = [];
- Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath).then(function (dstStorageFolder) {
- if (fileList) {
- for (var i = 0; i < fileList.length; i++) {
- filePromiseArr.push(fileList[i].moveAsync(dstStorageFolder));
- }
- }
- WinJS.Promise.join(filePromiseArr).then(function () {
- coreMove(storageFolderTop, complete);
- }, function () { });
- });
- });
- });
- };
- var moveFinish = function (srcPath, parentPath) {
- var originFolderTop = null;
- Windows.Storage.StorageFolder.getFolderFromPathAsync(srcPath).then(function (originFolder) {
- originFolderTop = originFolder;
- return Windows.Storage.StorageFolder.getFolderFromPathAsync(parentPath);
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }).then(function (storageFolder) {
- return storageFolder.createFolderAsync(name, Windows.Storage.CreationCollisionOption.openIfExists);
- }, function () {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- }).then(function (newStorageFolder) {
- //can't move onto directory that is not empty
- newStorageFolder.createFileQuery().getFilesAsync().then(function (fileList) {
- newStorageFolder.createFolderQuery().getFoldersAsync().then(function (folderList) {
- if (fileList.length !== 0 || folderList.length !== 0) {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- return;
- }
- //can't copy onto itself
- if (srcPath == newStorageFolder.path) {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- return;
- }
- //can't copy into itself
- if (srcPath == parentPath) {
- fail && fail(FileError.INVALID_MODIFICATION_ERR);
- return;
- }
- moveFiles(srcPath, newStorageFolder.path).then(function () {
- var successCallback = function () {
- success(new DirectoryEntry(name, newStorageFolder.path));
- };
- var temp = new DirectoryEntry(originFolderTop.name, originFolderTop.path).removeRecursively(successCallback, fail);
-
- }, function () { console.log("error!"); });
- });
- });
- }, function () { fail && fail(FileError.INVALID_MODIFICATION_ERR); });
-
- };
- moveFinish(srcPath, parentFullPath);
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- );
- },
- tempFileSystem:null,
-
- persistentFileSystem:null,
-
- requestFileSystem:function(win,fail,args) {
- var type = args[0];
- var size = args[1];
-
- var filePath = "";
- var result = null;
- var fsTypeName = "";
-
- switch (type) {
- case LocalFileSystem.TEMPORARY:
- filePath = Windows.Storage.ApplicationData.current.temporaryFolder.path;
- fsTypeName = "temporary";
- break;
- case LocalFileSystem.PERSISTENT:
- filePath = Windows.Storage.ApplicationData.current.localFolder.path;
- fsTypeName = "persistent";
- break;
- }
-
- var MAX_SIZE = 10000000000;
- if (size > MAX_SIZE) {
- fail && fail(FileError.QUOTA_EXCEEDED_ERR);
- return;
- }
-
- var fileSystem = new FileSystem(fsTypeName, new DirectoryEntry(fsTypeName, filePath));
- result = fileSystem;
- win(result);
- },
-
- resolveLocalFileSystemURI:function(success,fail,args) {
- var uri = args[0];
-
- var path = uri;
-
- // support for file name with parameters
- if (/\?/g.test(path)) {
- path = String(path).split("?")[0];
- }
-
- // support for encodeURI
- if (/\%5/g.test(path)) {
- path = decodeURI(path);
- }
-
- // support for special path start with file:///
- if (path.substr(0, 8) == "file:///") {
- path = Windows.Storage.ApplicationData.current.localFolder.path + "\\" + String(path).substr(8).split("/").join("\\");
- Windows.Storage.StorageFile.getFileFromPathAsync(path).then(
- function (storageFile) {
- success(new FileEntry(storageFile.name, storageFile.path));
- }, function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(
- function (storageFolder) {
- success(new DirectoryEntry(storageFolder.name, storageFolder.path));
- }, function () {
- fail && fail(FileError.NOT_FOUND_ERR);
- }
- );
- }
- );
- } else {
- Windows.Storage.StorageFile.getFileFromPathAsync(path).then(
- function (storageFile) {
- success(new FileEntry(storageFile.name, storageFile.path));
- }, function () {
- Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(
- function (storageFolder) {
- success(new DirectoryEntry(storageFolder.name, storageFolder.path));
- }, function () {
- fail && fail(FileError.ENCODING_ERR);
- }
- );
- }
- );
- }
- }
-
-};
-
-require("cordova/windows8/commandProxy").add("File",module.exports);
diff --git a/plugins/org.apache.cordova.file/src/wp/File.cs b/plugins/org.apache.cordova.file/src/wp/File.cs
deleted file mode 100644
index 4fc61dde..00000000
--- a/plugins/org.apache.cordova.file/src/wp/File.cs
+++ /dev/null
@@ -1,1676 +0,0 @@
-/*
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Runtime.Serialization;
-using System.Security;
-using System.Text;
-using System.Windows;
-using System.Windows.Resources;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- /// <summary>
- /// Provides access to isolated storage
- /// </summary>
- public class File : BaseCommand
- {
- // Error codes
- public const int NOT_FOUND_ERR = 1;
- public const int SECURITY_ERR = 2;
- public const int ABORT_ERR = 3;
- public const int NOT_READABLE_ERR = 4;
- public const int ENCODING_ERR = 5;
- public const int NO_MODIFICATION_ALLOWED_ERR = 6;
- public const int INVALID_STATE_ERR = 7;
- public const int SYNTAX_ERR = 8;
- public const int INVALID_MODIFICATION_ERR = 9;
- public const int QUOTA_EXCEEDED_ERR = 10;
- public const int TYPE_MISMATCH_ERR = 11;
- public const int PATH_EXISTS_ERR = 12;
-
- // File system options
- public const int TEMPORARY = 0;
- public const int PERSISTENT = 1;
- public const int RESOURCE = 2;
- public const int APPLICATION = 3;
-
- /// <summary>
- /// Temporary directory name
- /// </summary>
- private readonly string TMP_DIRECTORY_NAME = "tmp";
-
- /// <summary>
- /// Represents error code for callback
- /// </summary>
- [DataContract]
- public class ErrorCode
- {
- /// <summary>
- /// Error code
- /// </summary>
- [DataMember(IsRequired = true, Name = "code")]
- public int Code { get; set; }
-
- /// <summary>
- /// Creates ErrorCode object
- /// </summary>
- public ErrorCode(int code)
- {
- this.Code = code;
- }
- }
-
- /// <summary>
- /// Represents File action options.
- /// </summary>
- [DataContract]
- public class FileOptions
- {
- /// <summary>
- /// File path
- /// </summary>
- ///
- private string _fileName;
- [DataMember(Name = "fileName")]
- public string FilePath
- {
- get
- {
- return this._fileName;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._fileName = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Full entryPath
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- /// <summary>
- /// Directory name
- /// </summary>
- [DataMember(Name = "dirName")]
- public string DirectoryName { get; set; }
-
- /// <summary>
- /// Path to create file/directory
- /// </summary>
- [DataMember(Name = "path")]
- public string Path { get; set; }
-
- /// <summary>
- /// The encoding to use to encode the file's content. Default is UTF8.
- /// </summary>
- [DataMember(Name = "encoding")]
- public string Encoding { get; set; }
-
- /// <summary>
- /// Uri to get file
- /// </summary>
- ///
- private string _uri;
- [DataMember(Name = "uri")]
- public string Uri
- {
- get
- {
- return this._uri;
- }
-
- set
- {
- int index = value.IndexOfAny(new char[] { '#', '?' });
- this._uri = index > -1 ? value.Substring(0, index) : value;
- }
- }
-
- /// <summary>
- /// Size to truncate file
- /// </summary>
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- /// <summary>
- /// Data to write in file
- /// </summary>
- [DataMember(Name = "data")]
- public string Data { get; set; }
-
- /// <summary>
- /// Position the writing starts with
- /// </summary>
- [DataMember(Name = "position")]
- public int Position { get; set; }
-
- /// <summary>
- /// Type of file system requested
- /// </summary>
- [DataMember(Name = "type")]
- public int FileSystemType { get; set; }
-
- /// <summary>
- /// New file/directory name
- /// </summary>
- [DataMember(Name = "newName")]
- public string NewName { get; set; }
-
- /// <summary>
- /// Destination directory to copy/move file/directory
- /// </summary>
- [DataMember(Name = "parent")]
- public string Parent { get; set; }
-
- /// <summary>
- /// Options for getFile/getDirectory methods
- /// </summary>
- [DataMember(Name = "options")]
- public CreatingOptions CreatingOpt { get; set; }
-
- /// <summary>
- /// Creates options object with default parameters
- /// </summary>
- public FileOptions()
- {
- this.SetDefaultValues(new StreamingContext());
- }
-
- /// <summary>
- /// Initializes default values for class fields.
- /// Implemented in separate method because default constructor is not invoked during deserialization.
- /// </summary>
- /// <param name="context"></param>
- [OnDeserializing()]
- public void SetDefaultValues(StreamingContext context)
- {
- this.Encoding = "UTF-8";
- this.FilePath = "";
- this.FileSystemType = -1;
- }
- }
-
- /// <summary>
- /// Stores image info
- /// </summary>
- [DataContract]
- public class FileMetadata
- {
- [DataMember(Name = "fileName")]
- public string FileName { get; set; }
-
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- [DataMember(Name = "type")]
- public string Type { get; set; }
-
- [DataMember(Name = "lastModifiedDate")]
- public string LastModifiedDate { get; set; }
-
- [DataMember(Name = "size")]
- public long Size { get; set; }
-
- public FileMetadata(string filePath)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- else if (!isoFile.FileExists(filePath))
- {
- // attempt to get it from the resources
- if (filePath.IndexOf("www") == 0)
- {
- Uri fileUri = new Uri(filePath, UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- this.Size = streamInfo.Stream.Length;
- this.FileName = filePath.Substring(filePath.LastIndexOf("/") + 1);
- this.FullPath = filePath;
- }
- }
- else
- {
- throw new FileNotFoundException("File doesn't exist");
- }
- }
- else
- {
- //TODO get file size the other way if possible
- using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.Read, isoFile))
- {
- this.Size = stream.Length;
- }
- this.FullPath = filePath;
- this.FileName = System.IO.Path.GetFileName(filePath);
- this.LastModifiedDate = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- }
- this.Type = MimeTypeMapper.GetMimeType(this.FileName);
- }
- }
- }
-
- /// <summary>
- /// Represents file or directory modification metadata
- /// </summary>
- [DataContract]
- public class ModificationMetadata
- {
- /// <summary>
- /// Modification time
- /// </summary>
- [DataMember]
- public string modificationTime { get; set; }
- }
-
- /// <summary>
- /// Represents file or directory entry
- /// </summary>
- [DataContract]
- public class FileEntry
- {
-
- /// <summary>
- /// File type
- /// </summary>
- [DataMember(Name = "isFile")]
- public bool IsFile { get; set; }
-
- /// <summary>
- /// Directory type
- /// </summary>
- [DataMember(Name = "isDirectory")]
- public bool IsDirectory { get; set; }
-
- /// <summary>
- /// File/directory name
- /// </summary>
- [DataMember(Name = "name")]
- public string Name { get; set; }
-
- /// <summary>
- /// Full path to file/directory
- /// </summary>
- [DataMember(Name = "fullPath")]
- public string FullPath { get; set; }
-
- public bool IsResource { get; set; }
-
- public static FileEntry GetEntry(string filePath, bool bIsRes=false)
- {
- FileEntry entry = null;
- try
- {
- entry = new FileEntry(filePath, bIsRes);
-
- }
- catch (Exception ex)
- {
- Debug.WriteLine("Exception in GetEntry for filePath :: " + filePath + " " + ex.Message);
- }
- return entry;
- }
-
- /// <summary>
- /// Creates object and sets necessary properties
- /// </summary>
- /// <param name="filePath"></param>
- public FileEntry(string filePath, bool bIsRes = false)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- throw new ArgumentException();
- }
-
- if(filePath.Contains(" "))
- {
- Debug.WriteLine("FilePath with spaces :: " + filePath);
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- IsResource = bIsRes;
- IsFile = isoFile.FileExists(filePath);
- IsDirectory = isoFile.DirectoryExists(filePath);
- if (IsFile)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else if (IsDirectory)
- {
- this.Name = this.GetDirectoryName(filePath);
- if (string.IsNullOrEmpty(Name))
- {
- this.Name = "/";
- }
- }
- else
- {
- if (IsResource)
- {
- this.Name = Path.GetFileName(filePath);
- }
- else
- {
- throw new FileNotFoundException();
- }
- }
-
- try
- {
- this.FullPath = filePath.Replace('\\', '/'); // new Uri(filePath).LocalPath;
- }
- catch (Exception)
- {
- this.FullPath = filePath;
- }
- }
- }
-
- /// <summary>
- /// Extracts directory name from path string
- /// Path should refer to a directory, for example \foo\ or /foo.
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- private string GetDirectoryName(string path)
- {
- if (String.IsNullOrEmpty(path))
- {
- return path;
- }
-
- string[] split = path.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
- if (split.Length < 1)
- {
- return null;
- }
- else
- {
- return split[split.Length - 1];
- }
- }
- }
-
-
- /// <summary>
- /// Represents info about requested file system
- /// </summary>
- [DataContract]
- public class FileSystemInfo
- {
- /// <summary>
- /// file system type
- /// </summary>
- [DataMember(Name = "name", IsRequired = true)]
- public string Name { get; set; }
-
- /// <summary>
- /// Root directory entry
- /// </summary>
- [DataMember(Name = "root", EmitDefaultValue = false)]
- public FileEntry Root { get; set; }
-
- /// <summary>
- /// Creates class instance
- /// </summary>
- /// <param name="name"></param>
- /// <param name="rootEntry"> Root directory</param>
- public FileSystemInfo(string name, FileEntry rootEntry = null)
- {
- Name = name;
- Root = rootEntry;
- }
- }
-
- [DataContract]
- public class CreatingOptions
- {
- /// <summary>
- /// Create file/directory if is doesn't exist
- /// </summary>
- [DataMember(Name = "create")]
- public bool Create { get; set; }
-
- /// <summary>
- /// Generate an exception if create=true and file/directory already exists
- /// </summary>
- [DataMember(Name = "exclusive")]
- public bool Exclusive { get; set; }
-
-
- }
-
- // returns null value if it fails.
- private string[] getOptionStrings(string options)
- {
- string[] optStings = null;
- try
- {
- optStings = JSON.JsonHelper.Deserialize<string[]>(options);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), CurrentCommandCallbackId);
- }
- return optStings;
- }
-
- /// <summary>
- /// Gets amount of free space available for Isolated Storage
- /// </summary>
- /// <param name="options">No options is needed for this method</param>
- public void getFreeDiskSpace(string options)
- {
- string callbackId = getOptionStrings(options)[0];
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isoFile.AvailableFreeSpace), callbackId);
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Check if file exists
- /// </summary>
- /// <param name="options">File path</param>
- public void testFileExists(string options)
- {
- IsDirectoryOrFileExist(options, false);
- }
-
- /// <summary>
- /// Check if directory exists
- /// </summary>
- /// <param name="options">directory name</param>
- public void testDirectoryExists(string options)
- {
- IsDirectoryOrFileExist(options, true);
- }
-
- /// <summary>
- /// Check if file or directory exist
- /// </summary>
- /// <param name="options">File path/Directory name</param>
- /// <param name="isDirectory">Flag to recognize what we should check</param>
- public void IsDirectoryOrFileExist(string options, bool isDirectory)
- {
- string[] args = getOptionStrings(options);
- string callbackId = args[1];
- FileOptions fileOptions = JSON.JsonHelper.Deserialize<FileOptions>(args[0]);
- string filePath = args[0];
-
- if (fileOptions == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- }
-
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isExist;
- if (isDirectory)
- {
- isExist = isoFile.DirectoryExists(fileOptions.DirectoryName);
- }
- else
- {
- isExist = isoFile.FileExists(fileOptions.FilePath);
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, isExist), callbackId);
- }
- }
- catch (IsolatedStorageException) // default handler throws INVALID_MODIFICATION_ERR
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
-
- public void readAsDataURL(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
-
- if (filePath != null)
- {
- try
- {
- string base64URL = null;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string mimeType = MimeTypeMapper.GetMimeType(filePath);
-
- using (IsolatedStorageFileStream stream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
- {
- string base64String = GetFileContent(stream);
- base64URL = "data:" + mimeType + ";base64," + base64String;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, base64URL), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- public void readAsArrayBuffer(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsBinaryString(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- int startPos = int.Parse(optStrings[1]);
- int endPos = int.Parse(optStrings[2]);
- string callbackId = optStrings[3];
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR), callbackId);
- }
-
- public void readAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string filePath = optStrings[0];
- string encStr = optStrings[1];
- int startPos = int.Parse(optStrings[2]);
- int endPos = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- string text = "";
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- readResourceAsText(options);
- return;
- }
- Encoding encoding = Encoding.GetEncoding(encStr);
-
- using (TextReader reader = new StreamReader(isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read), encoding))
- {
- text = reader.ReadToEnd();
- if (startPos < 0)
- {
- startPos = Math.Max(text.Length + startPos, 0);
- }
- else if (startPos > 0)
- {
- startPos = Math.Min(text.Length, startPos);
- }
-
- if (endPos > 0)
- {
- endPos = Math.Min(text.Length, endPos);
- }
- else if (endPos < 0)
- {
- endPos = Math.Max(endPos + text.Length, 0);
- }
-
-
- text = text.Substring(startPos, endPos - startPos);
-
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Reads application resource as a text
- /// </summary>
- /// <param name="options">Path to a resource</param>
- public void readResourceAsText(string options)
- {
- string[] optStrings = getOptionStrings(options);
- string pathToResource = optStrings[0];
- string encStr = optStrings[1];
- int start = int.Parse(optStrings[2]);
- int endMarker = int.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- if (pathToResource.StartsWith("/"))
- {
- pathToResource = pathToResource.Remove(0, 1);
- }
-
- var resource = Application.GetResourceStream(new Uri(pathToResource, UriKind.Relative));
-
- if (resource == null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string text;
- StreamReader streamReader = new StreamReader(resource.Stream);
- text = streamReader.ReadToEnd();
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, text), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- public void truncate(string options)
- {
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- int size = int.Parse(optStrings[1]);
- string callbackId = optStrings[2];
-
- try
- {
- long streamLength = 0;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= size && size <= stream.Length)
- {
- stream.SetLength(size);
- }
- streamLength = stream.Length;
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, streamLength), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- //write:[filePath,data,position,isBinary,callbackId]
- public void write(string options)
- {
- string[] optStrings = getOptionStrings(options);
-
- string filePath = optStrings[0];
- string data = optStrings[1];
- int position = int.Parse(optStrings[2]);
- bool isBinary = bool.Parse(optStrings[3]);
- string callbackId = optStrings[4];
-
- try
- {
- if (string.IsNullOrEmpty(data))
- {
- Debug.WriteLine("Expected some data to be send in the write command to {0}", filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- // create the file if not exists
- if (!isoFile.FileExists(filePath))
- {
- var file = isoFile.CreateFile(filePath);
- file.Close();
- }
-
- using (FileStream stream = new IsolatedStorageFileStream(filePath, FileMode.Open, FileAccess.ReadWrite, isoFile))
- {
- if (0 <= position && position <= stream.Length)
- {
- stream.SetLength(position);
- }
- using (BinaryWriter writer = new BinaryWriter(stream))
- {
- writer.Seek(0, SeekOrigin.End);
- writer.Write(data.ToCharArray());
- }
- }
- }
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, data.Length), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- /// <summary>
- /// Look up metadata about this entry.
- /// </summary>
- /// <param name="options">filePath to entry</param>
- public void getMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK,
- new ModificationMetadata() { modificationTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString() }), callbackId);
- }
- else if (isoFile.DirectoryExists(filePath))
- {
- string modTime = isoFile.GetLastWriteTime(filePath).DateTime.ToString();
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new ModificationMetadata() { modificationTime = modTime }), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
- }
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
-
- }
-
-
- /// <summary>
- /// Returns a File that represents the current state of the file that this FileEntry represents.
- /// </summary>
- /// <param name="filePath">filePath to entry</param>
- /// <returns></returns>
- public void getFileMetadata(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- FileMetadata metaData = new FileMetadata(filePath);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, metaData), callbackId);
- }
- catch (IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_READABLE_ERR), callbackId);
- }
- }
- }
- }
-
- /// <summary>
- /// Look up the parent DirectoryEntry containing this Entry.
- /// If this Entry is the root of IsolatedStorage, its parent is itself.
- /// </summary>
- /// <param name="options"></param>
- public void getParent(string options)
- {
- string[] optStings = getOptionStrings(options);
- string filePath = optStings[0];
- string callbackId = optStings[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- FileEntry entry;
-
- if (isoFile.FileExists(filePath) || isoFile.DirectoryExists(filePath))
- {
-
-
- string path = this.GetParentDirectory(filePath);
- entry = FileEntry.GetEntry(path);
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
-
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- }
-
- public void remove(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (filePath == "/" || filePath == "" || filePath == @"\")
- {
- throw new Exception("Cannot delete root file system") ;
- }
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.FileExists(filePath))
- {
- isoFile.DeleteFile(filePath);
- }
- else
- {
- if (isoFile.DirectoryExists(filePath))
- {
- isoFile.DeleteDirectory(filePath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- return;
- }
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK),callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void removeRecursively(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- }
- else
- {
- if (removeDirRecursively(filePath, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK), callbackId);
- }
- }
- }
- }
-
- public void readEntries(string options)
- {
- string[] args = getOptionStrings(options);
- string filePath = args[0];
- string callbackId = args[1];
-
- if (filePath != null)
- {
- try
- {
- if (string.IsNullOrEmpty(filePath))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION),callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(filePath))
- {
- string path = File.AddSlashToDirectory(filePath);
- List<FileEntry> entries = new List<FileEntry>();
- string[] files = isoFile.GetFileNames(path + "*");
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- foreach (string file in files)
- {
- entries.Add(FileEntry.GetEntry(path + file));
- }
- foreach (string dir in dirs)
- {
- entries.Add(FileEntry.GetEntry(path + dir + "/"));
- }
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entries),callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- }
- }
- }
- }
-
- public void requestFileSystem(string options)
- {
- // TODO: try/catch
- string[] optVals = getOptionStrings(options);
- //FileOptions fileOptions = new FileOptions();
- int fileSystemType = int.Parse(optVals[0]);
- double size = double.Parse(optVals[1]);
- string callbackId = optVals[2];
-
-
- IsolatedStorageFile.GetUserStoreForApplication();
-
- if (size > (10 * 1024 * 1024)) // 10 MB, compier will clean this up!
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
-
- try
- {
- if (size != 0)
- {
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- long availableSize = isoFile.AvailableFreeSpace;
- if (size > availableSize)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, QUOTA_EXCEEDED_ERR), callbackId);
- return;
- }
- }
- }
-
- if (fileSystemType == PERSISTENT)
- {
- // TODO: this should be in it's own folder to prevent overwriting of the app assets, which are also in ISO
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("persistent", FileEntry.GetEntry("/"))), callbackId);
- }
- else if (fileSystemType == TEMPORARY)
- {
- using (IsolatedStorageFile isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (!isoStorage.FileExists(TMP_DIRECTORY_NAME))
- {
- isoStorage.CreateDirectory(TMP_DIRECTORY_NAME);
- }
- }
-
- string tmpFolder = "/" + TMP_DIRECTORY_NAME + "/";
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("temporary", FileEntry.GetEntry(tmpFolder))), callbackId);
- }
- else if (fileSystemType == RESOURCE)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("resource")), callbackId);
- }
- else if (fileSystemType == APPLICATION)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new FileSystemInfo("application")), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- public void resolveLocalFileSystemURI(string options)
- {
-
- string[] optVals = getOptionStrings(options);
- string uri = optVals[0].Split('?')[0];
- string callbackId = optVals[1];
-
- if (uri != null)
- {
- // a single '/' is valid, however, '/someDir' is not, but '/tmp//somedir' and '///someDir' are valid
- if (uri.StartsWith("/") && uri.IndexOf("//") < 0 && uri != "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
- try
- {
- // fix encoded spaces
- string path = Uri.UnescapeDataString(uri);
-
- FileEntry uriEntry = FileEntry.GetEntry(path);
- if (uriEntry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, uriEntry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
- }
-
- public void copyTo(string options)
- {
- TransferTo(options, false);
- }
-
- public void moveTo(string options)
- {
- TransferTo(options, true);
- }
-
- public void getFile(string options)
- {
- GetFileOrDirectory(options, false);
- }
-
- public void getDirectory(string options)
- {
- GetFileOrDirectory(options, true);
- }
-
- #region internal functionality
-
- /// <summary>
- /// Retrieves the parent directory name of the specified path,
- /// </summary>
- /// <param name="path">Path</param>
- /// <returns>Parent directory name</returns>
- private string GetParentDirectory(string path)
- {
- if (String.IsNullOrEmpty(path) || path == "/")
- {
- return "/";
- }
-
- if (path.EndsWith(@"/") || path.EndsWith(@"\"))
- {
- return this.GetParentDirectory(Path.GetDirectoryName(path));
- }
-
- string result = Path.GetDirectoryName(path);
- if (result == null)
- {
- result = "/";
- }
-
- return result;
- }
-
- private bool removeDirRecursively(string fullPath,string callbackId)
- {
- try
- {
- if (fullPath == "/")
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- if (isoFile.DirectoryExists(fullPath))
- {
- string tempPath = File.AddSlashToDirectory(fullPath);
- string[] files = isoFile.GetFileNames(tempPath + "*");
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.DeleteFile(tempPath + file);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(tempPath + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- if (!removeDirRecursively(tempPath + dir, callbackId))
- {
- return false;
- }
- }
- }
- isoFile.DeleteDirectory(fullPath);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR),callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR),callbackId);
- return false;
- }
- }
- return true;
- }
-
- private bool CanonicalCompare(string pathA, string pathB)
- {
- string a = pathA.Replace("//", "/");
- string b = pathB.Replace("//", "/");
-
- return a.Equals(b, StringComparison.OrdinalIgnoreCase);
- }
-
- /*
- * copyTo:["fullPath","parent", "newName"],
- * moveTo:["fullPath","parent", "newName"],
- */
- private void TransferTo(string options, bool move)
- {
- // TODO: try/catch
- string[] optStrings = getOptionStrings(options);
- string fullPath = optStrings[0];
- string parent = optStrings[1];
- string newFileName = optStrings[2];
- string callbackId = optStrings[3];
-
- char[] invalids = Path.GetInvalidPathChars();
-
- if (newFileName.IndexOfAny(invalids) > -1 || newFileName.IndexOf(":") > -1 )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- if ((parent == null) || (string.IsNullOrEmpty(parent)) || (string.IsNullOrEmpty(fullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string parentPath = File.AddSlashToDirectory(parent);
- string currentPath = fullPath;
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFileExist = isoFile.FileExists(currentPath);
- bool isDirectoryExist = isoFile.DirectoryExists(currentPath);
- bool isParentExist = isoFile.DirectoryExists(parentPath);
-
- if ( ( !isFileExist && !isDirectoryExist ) || !isParentExist )
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- string newName;
- string newPath;
- if (isFileExist)
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? Path.GetFileName(currentPath)
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- // sanity check ..
- // cannot copy file onto itself
- if (CanonicalCompare(newPath,currentPath)) //(parent + newFileName))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.DirectoryExists(newPath))
- {
- // there is already a folder with the same name, operation is not allowed
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- return;
- }
- else if (isoFile.FileExists(newPath))
- { // remove destination file if exists, in other case there will be exception
- isoFile.DeleteFile(newPath);
- }
-
- if (move)
- {
- isoFile.MoveFile(currentPath, newPath);
- }
- else
- {
- isoFile.CopyFile(currentPath, newPath, true);
- }
- }
- else
- {
- newName = (string.IsNullOrEmpty(newFileName))
- ? currentPath
- : newFileName;
-
- newPath = Path.Combine(parentPath, newName);
-
- if (move)
- {
- // remove destination directory if exists, in other case there will be exception
- // target directory should be empty
- if (!newPath.Equals(currentPath) && isoFile.DirectoryExists(newPath))
- {
- isoFile.DeleteDirectory(newPath);
- }
-
- isoFile.MoveDirectory(currentPath, newPath);
- }
- else
- {
- CopyDirectory(currentPath, newPath, isoFile);
- }
- }
- FileEntry entry = FileEntry.GetEntry(newPath);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
-
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex, callbackId))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private bool HandleException(Exception ex, string cbId="")
- {
- bool handled = false;
- string callbackId = String.IsNullOrEmpty(cbId) ? this.CurrentCommandCallbackId : cbId;
- if (ex is SecurityException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, SECURITY_ERR), callbackId);
- handled = true;
- }
- else if (ex is FileNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- else if (ex is ArgumentException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- handled = true;
- }
- else if (ex is IsolatedStorageException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, INVALID_MODIFICATION_ERR), callbackId);
- handled = true;
- }
- else if (ex is DirectoryNotFoundException)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- handled = true;
- }
- return handled;
- }
-
- private void CopyDirectory(string sourceDir, string destDir, IsolatedStorageFile isoFile)
- {
- string path = File.AddSlashToDirectory(sourceDir);
-
- bool bExists = isoFile.DirectoryExists(destDir);
-
- if (!bExists)
- {
- isoFile.CreateDirectory(destDir);
- }
-
- destDir = File.AddSlashToDirectory(destDir);
-
- string[] files = isoFile.GetFileNames(path + "*");
-
- if (files.Length > 0)
- {
- foreach (string file in files)
- {
- isoFile.CopyFile(path + file, destDir + file,true);
- }
- }
- string[] dirs = isoFile.GetDirectoryNames(path + "*");
- if (dirs.Length > 0)
- {
- foreach (string dir in dirs)
- {
- CopyDirectory(path + dir, destDir + dir, isoFile);
- }
- }
- }
-
- private void GetFileOrDirectory(string options, bool getDirectory)
- {
- FileOptions fOptions = new FileOptions();
- string[] args = getOptionStrings(options);
-
- fOptions.FullPath = args[0];
- fOptions.Path = args[1];
-
- string callbackId = args[3];
-
- try
- {
- fOptions.CreatingOpt = JSON.JsonHelper.Deserialize<CreatingOptions>(args[2]);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION), callbackId);
- return;
- }
-
- try
- {
- if ((string.IsNullOrEmpty(fOptions.Path)) || (string.IsNullOrEmpty(fOptions.FullPath)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
-
- string path;
-
- if (fOptions.Path.Split(':').Length > 2)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- try
- {
- path = Path.Combine(fOptions.FullPath + "/", fOptions.Path);
- }
- catch (Exception)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ENCODING_ERR), callbackId);
- return;
- }
-
- using (IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication())
- {
- bool isFile = isoFile.FileExists(path);
- bool isDirectory = isoFile.DirectoryExists(path);
- bool create = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Create;
- bool exclusive = (fOptions.CreatingOpt == null) ? false : fOptions.CreatingOpt.Exclusive;
- if (create)
- {
- if (exclusive && (isoFile.FileExists(path) || isoFile.DirectoryExists(path)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, PATH_EXISTS_ERR), callbackId);
- return;
- }
-
- // need to make sure the parent exists
- // it is an error to create a directory whose immediate parent does not yet exist
- // see issue: https://issues.apache.org/jira/browse/CB-339
- string[] pathParts = path.Split('/');
- string builtPath = pathParts[0];
- for (int n = 1; n < pathParts.Length - 1; n++)
- {
- builtPath += "/" + pathParts[n];
- if (!isoFile.DirectoryExists(builtPath))
- {
- Debug.WriteLine(String.Format("Error :: Parent folder \"{0}\" does not exist, when attempting to create \"{1}\"",builtPath,path));
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- return;
- }
- }
-
- if ((getDirectory) && (!isDirectory))
- {
- isoFile.CreateDirectory(path);
- }
- else
- {
- if ((!getDirectory) && (!isFile))
- {
-
- IsolatedStorageFileStream fileStream = isoFile.CreateFile(path);
- fileStream.Close();
- }
- }
- }
- else // (not create)
- {
- if ((!isFile) && (!isDirectory))
- {
- if (path.IndexOf("//www") == 0)
- {
- Uri fileUri = new Uri(path.Remove(0,2), UriKind.Relative);
- StreamResourceInfo streamInfo = Application.GetResourceStream(fileUri);
- if (streamInfo != null)
- {
- FileEntry _entry = FileEntry.GetEntry(fileUri.OriginalString,true);
-
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, _entry), callbackId);
-
- //using (BinaryReader br = new BinaryReader(streamInfo.Stream))
- //{
- // byte[] data = br.ReadBytes((int)streamInfo.Stream.Length);
-
- //}
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
-
-
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- return;
- }
- if (((getDirectory) && (!isDirectory)) || ((!getDirectory) && (!isFile)))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, TYPE_MISMATCH_ERR), callbackId);
- return;
- }
- }
- FileEntry entry = FileEntry.GetEntry(path);
- if (entry != null)
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.OK, entry), callbackId);
- }
- else
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NOT_FOUND_ERR), callbackId);
- }
- }
- }
- catch (Exception ex)
- {
- if (!this.HandleException(ex))
- {
- DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, NO_MODIFICATION_ALLOWED_ERR), callbackId);
- }
- }
- }
-
- private static string AddSlashToDirectory(string dirPath)
- {
- if (dirPath.EndsWith("/"))
- {
- return dirPath;
- }
- else
- {
- return dirPath + "/";
- }
- }
-
- /// <summary>
- /// Returns file content in a form of base64 string
- /// </summary>
- /// <param name="stream">File stream</param>
- /// <returns>Base64 representation of the file</returns>
- private string GetFileContent(Stream stream)
- {
- int streamLength = (int)stream.Length;
- byte[] fileData = new byte[streamLength + 1];
- stream.Read(fileData, 0, streamLength);
- stream.Close();
- return Convert.ToBase64String(fileData);
- }
-
- #endregion
-
- }
-}