You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by st...@apache.org on 2013/12/05 01:58:18 UTC

[4/9] git commit: CB-5466: Update FileTransfer plugin to accept filesystem urls

CB-5466: Update FileTransfer plugin to accept filesystem urls


Project: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/commit/2f1411f5
Tree: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/tree/2f1411f5
Diff: http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/diff/2f1411f5

Branch: refs/heads/master
Commit: 2f1411f5dc37854ded35ee31671e66b380b8117f
Parents: 60f96e0
Author: Ian Clelland <ic...@chromium.org>
Authored: Fri Nov 22 09:40:56 2013 -0500
Committer: Ian Clelland <ic...@chromium.org>
Committed: Fri Nov 22 10:31:38 2013 -0500

----------------------------------------------------------------------
 src/ios/CDVFileTransfer.h |   1 +
 src/ios/CDVFileTransfer.m | 129 ++++++++++++++++++++++-------------------
 www/FileTransfer.js       |   1 +
 3 files changed, 71 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/blob/2f1411f5/src/ios/CDVFileTransfer.h
----------------------------------------------------------------------
diff --git a/src/ios/CDVFileTransfer.h b/src/ios/CDVFileTransfer.h
index 8e8211d..aa1cf9e 100644
--- a/src/ios/CDVFileTransfer.h
+++ b/src/ios/CDVFileTransfer.h
@@ -71,6 +71,7 @@ extern NSString* const kOptionsKeyCookie;
 @property (nonatomic, copy) NSString* objectId;
 @property (nonatomic, copy) NSString* source;
 @property (nonatomic, copy) NSString* target;
+@property (nonatomic, copy) NSURL* targetURL;
 @property (nonatomic, copy) NSString* mimeType;
 @property (assign) int responseCode; // atomic
 @property (nonatomic, assign) long long bytesTransfered;

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/blob/2f1411f5/src/ios/CDVFileTransfer.m
----------------------------------------------------------------------
diff --git a/src/ios/CDVFileTransfer.m b/src/ios/CDVFileTransfer.m
index f1fd4d3..2eec342 100644
--- a/src/ios/CDVFileTransfer.m
+++ b/src/ios/CDVFileTransfer.m
@@ -20,12 +20,15 @@
 #import <Cordova/CDV.h>
 #import "CDVFileTransfer.h"
 #import "CDVFile.h"
+#import "CDVLocalFilesystem.h"
 
 #import <AssetsLibrary/ALAsset.h>
 #import <AssetsLibrary/ALAssetRepresentation.h>
 #import <AssetsLibrary/ALAssetsLibrary.h>
 #import <CFNetwork/CFNetwork.h>
 
+extern CDVFile *filePlugin;
+
 @interface CDVFileTransfer ()
 // Sets the requests headers for the request.
 - (void)applyRequestHeaders:(NSDictionary*)headers toRequest:(NSMutableURLRequest*)req;
@@ -270,52 +273,48 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
 
 - (void)fileDataForUploadCommand:(CDVInvokedUrlCommand*)command
 {
-    NSString* target = (NSString*)[command.arguments objectAtIndex:0];
+    NSString* source = (NSString*)[command.arguments objectAtIndex:0];
+    NSString* server = [command.arguments objectAtIndex:1];
     NSError* __autoreleasing err = nil;
 
-    // return unsupported result for assets-library URLs
-    if ([target hasPrefix:kCDVAssetsLibraryPrefix]) {
-        // 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* fileData = [NSData dataWithBytesNoCopy:buffer length:bufferSize freeWhenDone:YES];
-                [self uploadData:fileData command:command];
-            } else {
+    CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:source];
+    NSObject<CDVFileSystem> *fs;
+    if (sourceURL) {
+        // Try to get a CDVFileSystem which will handle this file.
+        // This requires talking to the current CDVFile plugin.
+        fs = [filePlugin filesystemForURL:sourceURL];
+    }
+    if (fs) {
+        [fs readFileAtURL:sourceURL start:0 end:-1 callback:^(NSData *fileData, NSString *mimeType, CDVFileError err) {
+            if (err) {
                 // We couldn't find the asset.  Send the appropriate error.
-                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
+                CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];
                 [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+            }  else {
+                [self uploadData:fileData command:command];
             }
-        };
-        ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError* error) {
-            // Retrieving the asset failed for some reason.  Send the appropriate error.
-            CDVPluginResult* 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:target] resultBlock:resultBlock failureBlock:failureBlock];
+        }];
         return;
     } else {
         // Extract the path part out of a file: URL.
-        NSString* filePath = [target hasPrefix:@"/"] ? [target copy] : [[NSURL URLWithString:target] path];
+        NSString* filePath = [source hasPrefix:@"/"] ? [source copy] : [[NSURL URLWithString:source] path];
         if (filePath == nil) {
             // We couldn't find the asset.  Send the appropriate error.
-            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
+            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];
             [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
             return;
         }
-
+        
         // Memory map the file so that it can be read efficiently even if it is large.
         NSData* fileData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&err];
-
+        
         if (err != nil) {
-            NSLog(@"Error opening file %@: %@", target, err);
+            NSLog(@"Error opening file %@: %@", source, err);
+            CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:NOT_FOUND_ERR AndSource:source AndTarget:server]];
+            [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
+        } else {
+            [self uploadData:fileData command:command];
         }
-        [self uploadData:fileData command:command];
     }
 }
 
@@ -359,47 +358,43 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
 - (void)download:(CDVInvokedUrlCommand*)command
 {
     DLog(@"File Transfer downloading file...");
-    NSString* sourceUrl = [command.arguments objectAtIndex:0];
-    NSString* filePath = [command.arguments objectAtIndex:1];
+    NSString* source = [command.arguments objectAtIndex:0];
+    NSString* target = [command.arguments objectAtIndex:1];
     BOOL trustAllHosts = [[command.arguments objectAtIndex:2 withDefault:[NSNumber numberWithBool:YES]] boolValue]; // allow self-signed certs
     NSString* objectId = [command.arguments objectAtIndex:3];
     NSDictionary* headers = [command.arguments objectAtIndex:4 withDefault:nil];
 
-    // return unsupported result for assets-library URLs
-    if ([filePath hasPrefix:kCDVAssetsLibraryPrefix]) {
-        CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_MALFORMED_URL_EXCEPTION messageAsString:@"download not supported for assets-library URLs."];
-        [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
-        return;
-    }
-
     CDVPluginResult* result = nil;
     CDVFileTransferError errorCode = 0;
 
-    NSURL* file;
+    NSURL* targetURL;
 
-    if ([filePath hasPrefix:@"/"]) {
-        file = [NSURL fileURLWithPath:filePath];
+    if ([target hasPrefix:@"/"]) {
+        targetURL = [NSURL fileURLWithPath:target];
     } else {
-        file = [NSURL URLWithString:filePath];
+        targetURL = [NSURL URLWithString:target];
     }
 
-    NSURL* url = [NSURL URLWithString:sourceUrl];
+    NSURL* sourceURL = [NSURL URLWithString:source];
 
-    if (!url) {
+    if (!sourceURL) {
         errorCode = INVALID_URL_ERR;
-        NSLog(@"File Transfer Error: Invalid server URL %@", sourceUrl);
-    } else if (![file isFileURL]) {
-        errorCode = FILE_NOT_FOUND_ERR;
-        NSLog(@"File Transfer Error: Invalid file path or URL %@", filePath);
+        NSLog(@"File Transfer Error: Invalid server URL %@", source);
+    } else if (![targetURL isFileURL]) {
+        CDVFilesystemURL *fsURL = [CDVFilesystemURL fileSystemURLWithString:target];
+        if (!fsURL) {
+           errorCode = FILE_NOT_FOUND_ERR;
+           NSLog(@"File Transfer Error: Invalid file path or URL %@", target);
+        }
     }
 
     if (errorCode > 0) {
-        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:sourceUrl AndTarget:filePath]];
+        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[self createFileTransferError:errorCode AndSource:source AndTarget:target]];
         [self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
         return;
     }
 
-    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
+    NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:sourceURL];
     [self applyRequestHeaders:headers toRequest:req];
 
     CDVFileTransferDelegate* delegate = [[CDVFileTransferDelegate alloc] init];
@@ -407,8 +402,9 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
     delegate.direction = CDV_TRANSFER_DOWNLOAD;
     delegate.callbackId = command.callbackId;
     delegate.objectId = objectId;
-    delegate.source = sourceUrl;
-    delegate.target = filePath;
+    delegate.source = source;
+    delegate.target = target;
+    delegate.targetURL = targetURL;
     delegate.trustAllHosts = trustAllHosts;
 
     delegate.connection = [NSURLConnection connectionWithRequest:req delegate:delegate];
@@ -521,8 +517,6 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
     NSString* downloadResponse = nil;
     NSMutableDictionary* uploadResult;
     CDVPluginResult* result = nil;
-    BOOL bDirRequest = NO;
-    CDVFile* file;
 
     NSLog(@"File Transfer Finished with response code %d", self.responseCode);
 
@@ -548,8 +542,7 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
             self.targetFileHandle = nil;
             DLog(@"File Transfer Download success");
 
-            file = [[CDVFile alloc] init];
-            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[file getDirectoryEntry:target isDirectory:bDirRequest]];
+            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[filePlugin makeEntryForURL:self.targetURL]];
         } else {
             downloadResponse = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
             result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:[command createFileTransferError:CONNECTION_ERR AndSource:source AndTarget:target AndHttpStatus:self.responseCode AndBody:downloadResponse]];
@@ -618,7 +611,23 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
     }
     if ((self.direction == CDV_TRANSFER_DOWNLOAD) && (self.responseCode >= 200) && (self.responseCode < 300)) {
         // Download response is okay; begin streaming output to file
-        NSString* parentPath = [self.target stringByDeletingLastPathComponent];
+        NSString *filePath = nil;
+        CDVFilesystemURL *sourceURL = [CDVFilesystemURL fileSystemURLWithString:self.target];
+        if (sourceURL && sourceURL.fileSystemType != -1) {
+            // This requires talking to the current CDVFile plugin
+            NSObject<CDVFileSystem> *fs = [filePlugin.fileSystems objectAtIndex:sourceURL.fileSystemType];
+            filePath = [fs filesystemPathForURL:sourceURL];
+        } else {
+            // Extract the path part out of a file: URL.
+            NSString* filePath = [self.target hasPrefix:@"/"] ? [self.target copy] : [[NSURL URLWithString:self.target] path];
+            if (filePath == nil) {
+                // We couldn't find the asset.  Send the appropriate error.
+                [self cancelTransferWithError:connection errorMessage:[NSString stringWithFormat:@"Could not create target file"]];
+                return;
+            }
+        }
+
+        NSString* parentPath = [filePath stringByDeletingLastPathComponent];
 
         // create parent directories if needed
         if ([[NSFileManager defaultManager] createDirectoryAtPath:parentPath withIntermediateDirectories:YES attributes:nil error:&error] == NO) {
@@ -630,16 +639,16 @@ static CFIndex WriteDataToStream(NSData* data, CFWriteStreamRef stream)
             return;
         }
         // create target file
-        if ([[NSFileManager defaultManager] createFileAtPath:self.target contents:nil attributes:nil] == NO) {
+        if ([[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil] == NO) {
             [self cancelTransferWithError:connection errorMessage:@"Could not create target file"];
             return;
         }
         // open target file for writing
-        self.targetFileHandle = [NSFileHandle fileHandleForWritingAtPath:self.target];
+        self.targetFileHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
         if (self.targetFileHandle == nil) {
             [self cancelTransferWithError:connection errorMessage:@"Could not open target file for writing"];
         }
-        DLog(@"Streaming to file %@", target);
+        DLog(@"Streaming to file %@", filePath);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer/blob/2f1411f5/www/FileTransfer.js
----------------------------------------------------------------------
diff --git a/www/FileTransfer.js b/www/FileTransfer.js
index 66a1c4b..d6690fe 100644
--- a/www/FileTransfer.js
+++ b/www/FileTransfer.js
@@ -184,6 +184,7 @@ FileTransfer.prototype.download = function(source, target, successCallback, erro
             entry.isFile = result.isFile;
             entry.name = result.name;
             entry.fullPath = result.fullPath;
+            entry.filesystem = new FileSystem(result.filesystem == window.PERSISTENT ? 'persistent' : 'temporary');
             successCallback(entry);
         }
     };