| /* |
| 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 <Cordova/CDV.h> |
| #import "CDVFile.h" |
| #import "CDVLocalFilesystem.h" |
| #import "CDVAssetLibraryFilesystem.h" |
| #import <objc/message.h> |
| |
| static NSString* toBase64(NSData* data) { |
| SEL s1 = NSSelectorFromString(@"cdv_base64EncodedString"); |
| SEL s2 = NSSelectorFromString(@"base64EncodedString"); |
| SEL s3 = NSSelectorFromString(@"base64EncodedStringWithOptions:"); |
| |
| if ([data respondsToSelector:s1]) { |
| NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s1]; |
| return func(data, s1); |
| } else if ([data respondsToSelector:s2]) { |
| NSString* (*func)(id, SEL) = (void *)[data methodForSelector:s2]; |
| return func(data, s2); |
| } else if ([data respondsToSelector:s3]) { |
| NSString* (*func)(id, SEL, NSUInteger) = (void *)[data methodForSelector:s3]; |
| return func(data, s3, 0); |
| } else { |
| return nil; |
| } |
| } |
| |
| CDVFile *filePlugin = nil; |
| |
| extern NSString * const NSURLIsExcludedFromBackupKey __attribute__((weak_import)); |
| |
| #ifndef __IPHONE_5_1 |
| NSString* const NSURLIsExcludedFromBackupKey = @"NSURLIsExcludedFromBackupKey"; |
| #endif |
| |
| NSString* const kCDVFilesystemURLPrefix = @"cdvfile"; |
| |
| @implementation CDVFilesystemURL |
| @synthesize url=_url; |
| @synthesize fileSystemName=_fileSystemName; |
| @synthesize fullPath=_fullPath; |
| |
| - (id) initWithString:(NSString *)strURL |
| { |
| if ( self = [super init] ) { |
| NSURL *decodedURL = [NSURL URLWithString:strURL]; |
| return [self initWithURL:decodedURL]; |
| } |
| return nil; |
| } |
| |
| -(id) initWithURL:(NSURL *)URL |
| { |
| if ( self = [super init] ) { |
| self.url = URL; |
| self.fileSystemName = [self filesystemNameForLocalURI:URL]; |
| self.fullPath = [self fullPathForLocalURI:URL]; |
| } |
| return self; |
| } |
| |
| /* |
| * IN |
| * NSString localURI |
| * OUT |
| * NSString FileSystem Name for this URI, or nil if it is not recognized. |
| */ |
| - (NSString *)filesystemNameForLocalURI:(NSURL *)uri |
| { |
| if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@"localhost"]) { |
| NSArray *pathComponents = [uri pathComponents]; |
| if (pathComponents != nil && pathComponents.count > 1) { |
| return [pathComponents objectAtIndex:1]; |
| } |
| } else if ([[uri scheme] isEqualToString:kCDVAssetsLibraryScheme]) { |
| return @"assets-library"; |
| } |
| return nil; |
| } |
| |
| /* |
| * IN |
| * NSString localURI |
| * OUT |
| * NSString fullPath component suitable for an Entry object. |
| * The incoming URI should be properly escaped. The returned fullPath is unescaped. |
| */ |
| - (NSString *)fullPathForLocalURI:(NSURL *)uri |
| { |
| if ([[uri scheme] isEqualToString:kCDVFilesystemURLPrefix] && [[uri host] isEqualToString:@"localhost"]) { |
| NSString *path = [uri path]; |
| if ([uri query]) { |
| path = [NSString stringWithFormat:@"%@?%@", path, [uri query]]; |
| } |
| NSRange slashRange = [path rangeOfString:@"/" options:0 range:NSMakeRange(1, path.length-1)]; |
| if (slashRange.location == NSNotFound) { |
| return @""; |
| } |
| return [path substringFromIndex:slashRange.location]; |
| } else if ([[uri scheme] isEqualToString:kCDVAssetsLibraryScheme]) { |
| return [[uri absoluteString] substringFromIndex:[kCDVAssetsLibraryScheme length]+2]; |
| } |
| return nil; |
| } |
| |
| + (CDVFilesystemURL *)fileSystemURLWithString:(NSString *)strURL |
| { |
| return [[CDVFilesystemURL alloc] initWithString:strURL]; |
| } |
| |
| + (CDVFilesystemURL *)fileSystemURLWithURL:(NSURL *)URL |
| { |
| return [[CDVFilesystemURL alloc] initWithURL:URL]; |
| } |
| |
| - (NSString *)absoluteURL |
| { |
| return [NSString stringWithFormat:@"cdvfile://localhost/%@%@", self.fileSystemName, self.fullPath]; |
| } |
| |
| @end |
| |
| @implementation CDVFilesystemURLProtocol |
| |
| + (BOOL)canInitWithRequest:(NSURLRequest*)request |
| { |
| NSURL* url = [request URL]; |
| return [[url scheme] isEqualToString:kCDVFilesystemURLPrefix]; |
| } |
| |
| + (NSURLRequest*)canonicalRequestForRequest:(NSURLRequest*)request |
| { |
| return request; |
| } |
| |
| + (BOOL)requestIsCacheEquivalent:(NSURLRequest*)requestA toRequest:(NSURLRequest*)requestB |
| { |
| return [[[requestA URL] resourceSpecifier] isEqualToString:[[requestB URL] resourceSpecifier]]; |
| } |
| |
| - (void)startLoading |
| { |
| CDVFilesystemURL* url = [CDVFilesystemURL fileSystemURLWithURL:[[self request] URL]]; |
| NSObject<CDVFileSystem> *fs = [filePlugin filesystemForURL:url]; |
| __weak CDVFilesystemURLProtocol* weakSelf = self; |
| |
| [fs readFileAtURL:url start:0 end:-1 callback:^void(NSData *data, NSString *mimetype, CDVFileError error) { |
| NSMutableDictionary* responseHeaders = [[NSMutableDictionary alloc] init]; |
| responseHeaders[@"Cache-Control"] = @"no-cache"; |
| |
| if (!error) { |
| responseHeaders[@"Content-Type"] = mimetype; |
| NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:200 HTTPVersion:@"HTTP/1.1"headerFields:responseHeaders]; |
| [[weakSelf client] URLProtocol:weakSelf didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; |
| [[weakSelf client] URLProtocol:weakSelf didLoadData:data]; |
| [[weakSelf client] URLProtocolDidFinishLoading:weakSelf]; |
| } else { |
| NSURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:url.url statusCode:404 HTTPVersion:@"HTTP/1.1"headerFields:responseHeaders]; |
| [[weakSelf client] URLProtocol:weakSelf didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; |
| [[weakSelf client] URLProtocolDidFinishLoading:weakSelf]; |
| } |
| }]; |
| } |
| |
| - (void)stopLoading |
| {} |
| |
| - (NSCachedURLResponse *)connection:(NSURLConnection *)connection |
| willCacheResponse:(NSCachedURLResponse*)cachedResponse { |
| return nil; |
| } |
| |
| @end |
| |
| |
| @implementation CDVFile |
| |
| @synthesize rootDocsPath, appDocsPath, appLibraryPath, appTempPath, userHasAllowed, fileSystems=fileSystems_; |
| |
| - (void)registerFilesystem:(NSObject<CDVFileSystem> *)fs { |
| __weak CDVFile* weakSelf = self; |
| SEL sel = NSSelectorFromString(@"urlTransformer"); |
| // for backwards compatibility - we check if this property is there |
| // we create a wrapper block because the urlTransformer property |
| // on the commandDelegate might be set dynamically at a future time |
| // (and not dependent on plugin loading order) |
| if ([self.commandDelegate respondsToSelector:sel]) { |
| fs.urlTransformer = ^NSURL*(NSURL* urlToTransform) { |
| // grab the block from the commandDelegate |
| NSURL* (^urlTransformer)(NSURL*) = ((id(*)(id, SEL))objc_msgSend)(weakSelf.commandDelegate, sel); |
| // if block is not null, we call it |
| if (urlTransformer) { |
| return urlTransformer(urlToTransform); |
| } else { // else we return the same url |
| return urlToTransform; |
| } |
| }; |
| } |
| [fileSystems_ addObject:fs]; |
| } |
| |
| - (NSObject<CDVFileSystem> *)fileSystemByName:(NSString *)fsName |
| { |
| if (self.fileSystems != nil) { |
| for (NSObject<CDVFileSystem> *fs in self.fileSystems) { |
| if ([fs.name isEqualToString:fsName]) { |
| return fs; |
| } |
| } |
| } |
| return nil; |
| } |
| |
| - (NSObject<CDVFileSystem> *)filesystemForURL:(CDVFilesystemURL *)localURL { |
| if (localURL.fileSystemName == nil) return nil; |
| @try { |
| return [self fileSystemByName:localURL.fileSystemName]; |
| } |
| @catch (NSException *e) { |
| return nil; |
| } |
| } |
| |
| - (NSArray *)getExtraFileSystemsPreference:(UIViewController *)vc |
| { |
| NSString *filesystemsStr = nil; |
| if([self.viewController isKindOfClass:[CDVViewController class]]) { |
| CDVViewController *vc = (CDVViewController *)self.viewController; |
| NSDictionary *settings = [vc settings]; |
| filesystemsStr = [settings[@"iosextrafilesystems"] lowercaseString]; |
| } |
| if (!filesystemsStr) { |
| filesystemsStr = @"library,library-nosync,documents,documents-nosync,cache,bundle,root"; |
| } |
| return [filesystemsStr componentsSeparatedByString:@","]; |
| } |
| |
| - (void)makeNonSyncable:(NSString*)path { |
| [[NSFileManager defaultManager] createDirectoryAtPath:path |
| withIntermediateDirectories:YES |
| attributes:nil |
| error:nil]; |
| NSURL* url = [NSURL fileURLWithPath:path]; |
| [url setResourceValue: [NSNumber numberWithBool: YES] |
| forKey: NSURLIsExcludedFromBackupKey error:nil]; |
| |
| } |
| |
| - (void)registerExtraFileSystems:(NSArray *)filesystems fromAvailableSet:(NSDictionary *)availableFileSystems |
| { |
| NSMutableSet *installedFilesystems = [[NSMutableSet alloc] initWithCapacity:7]; |
| |
| /* Build non-syncable directories as necessary */ |
| for (NSString *nonSyncFS in @[@"library-nosync", @"documents-nosync"]) { |
| if ([filesystems containsObject:nonSyncFS]) { |
| [self makeNonSyncable:availableFileSystems[nonSyncFS]]; |
| } |
| } |
| |
| /* Register filesystems in order */ |
| for (NSString *fsName in filesystems) { |
| if (![installedFilesystems containsObject:fsName]) { |
| NSString *fsRoot = availableFileSystems[fsName]; |
| if (fsRoot) { |
| [filePlugin registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:fsName root:fsRoot]]; |
| [installedFilesystems addObject:fsName]; |
| } else { |
| NSLog(@"Unrecognized extra filesystem identifier: %@", fsName); |
| } |
| } |
| } |
| } |
| |
| - (NSDictionary *)getAvailableFileSystems |
| { |
| NSString *libPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]; |
| NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; |
| return @{ |
| @"library": libPath, |
| @"library-nosync": [libPath stringByAppendingPathComponent:@"NoCloud"], |
| @"documents": docPath, |
| @"documents-nosync": [docPath stringByAppendingPathComponent:@"NoCloud"], |
| @"cache": [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0], |
| @"bundle": [[NSBundle mainBundle] bundlePath], |
| @"root": @"/" |
| }; |
| } |
| |
| - (void)pluginInitialize |
| { |
| filePlugin = self; |
| [NSURLProtocol registerClass:[CDVFilesystemURLProtocol class]]; |
| |
| fileSystems_ = [[NSMutableArray alloc] initWithCapacity:3]; |
| |
| // Get the Library directory path |
| NSArray* paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); |
| self.appLibraryPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"files"]; |
| |
| // Get the Temporary directory path |
| self.appTempPath = [NSTemporaryDirectory()stringByStandardizingPath]; // remove trailing slash from NSTemporaryDirectory() |
| |
| // Get the Documents directory path |
| paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); |
| self.rootDocsPath = [paths objectAtIndex:0]; |
| self.appDocsPath = [self.rootDocsPath stringByAppendingPathComponent:@"files"]; |
| |
| |
| NSString *location = nil; |
| if([self.viewController isKindOfClass:[CDVViewController class]]) { |
| CDVViewController *vc = (CDVViewController *)self.viewController; |
| NSMutableDictionary *settings = vc.settings; |
| location = [[settings objectForKey:@"iospersistentfilelocation"] lowercaseString]; |
| } |
| if (location == nil) { |
| // Compatibilty by default (if the config preference is not set, or |
| // if we're not embedded in a CDVViewController somehow.) |
| location = @"compatibility"; |
| } |
| |
| NSError *error; |
| if ([[NSFileManager defaultManager] createDirectoryAtPath:self.appTempPath |
| withIntermediateDirectories:YES |
| attributes:nil |
| error:&error]) { |
| [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@"temporary" root:self.appTempPath]]; |
| } else { |
| NSLog(@"Unable to create temporary directory: %@", error); |
| } |
| if ([location isEqualToString:@"library"]) { |
| if ([[NSFileManager defaultManager] createDirectoryAtPath:self.appLibraryPath |
| withIntermediateDirectories:YES |
| attributes:nil |
| error:&error]) { |
| [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@"persistent" root:self.appLibraryPath]]; |
| } else { |
| NSLog(@"Unable to create library directory: %@", error); |
| } |
| } else if ([location isEqualToString:@"compatibility"]) { |
| /* |
| * Fall-back to compatibility mode -- this is the logic implemented in |
| * earlier versions of this plugin, and should be maintained here so |
| * that apps which were originally deployed with older versions of the |
| * plugin can continue to provide access to files stored under those |
| * versions. |
| */ |
| [self registerFilesystem:[[CDVLocalFilesystem alloc] initWithName:@"persistent" root:self.rootDocsPath]]; |
| } else { |
| NSAssert(false, |
| @"File plugin configuration error: Please set iosPersistentFileLocation in config.xml to one of \"library\" (for new applications) or \"compatibility\" (for compatibility with previous versions)"); |
| } |
| [self registerFilesystem:[[CDVAssetLibraryFilesystem alloc] initWithName:@"assets-library"]]; |
| |
| [self registerExtraFileSystems:[self getExtraFileSystemsPreference:self.viewController] |
| fromAvailableSet:[self getAvailableFileSystems]]; |
| |
| } |
| |
| - (CDVFilesystemURL *)fileSystemURLforArg:(NSString *)urlArg |
| { |
| CDVFilesystemURL* ret = nil; |
| if ([urlArg hasPrefix:@"file://"]) { |
| /* This looks like a file url. Get the path, and see if any handlers recognize it. */ |
| NSURL *fileURL = [NSURL URLWithString:urlArg]; |
| NSURL *resolvedFileURL = [fileURL URLByResolvingSymlinksInPath]; |
| NSString *path = [resolvedFileURL path]; |
| ret = [self fileSystemURLforLocalPath:path]; |
| } else { |
| ret = [CDVFilesystemURL fileSystemURLWithString:urlArg]; |
| } |
| return ret; |
| } |
| |
| - (CDVFilesystemURL *)fileSystemURLforLocalPath:(NSString *)localPath |
| { |
| CDVFilesystemURL *localURL = nil; |
| NSUInteger shortestFullPath = 0; |
| |
| // Try all installed filesystems, in order. Return the most match url. |
| for (id object in self.fileSystems) { |
| if ([object respondsToSelector:@selector(URLforFilesystemPath:)]) { |
| CDVFilesystemURL *url = [object URLforFilesystemPath:localPath]; |
| if (url){ |
| // A shorter fullPath would imply that the filesystem is a better match for the local path |
| if (!localURL || ([[url fullPath] length] < shortestFullPath)) { |
| localURL = url; |
| shortestFullPath = [[url fullPath] length]; |
| } |
| } |
| } |
| } |
| return localURL; |
| } |
| |
| - (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; |
| } |
| |
| /* 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 |
| { |
| // arguments |
| NSString* strType = [command argumentAtIndex:0]; |
| unsigned long long size = [[command argumentAtIndex:1] longLongValue]; |
| |
| int type = [strType intValue]; |
| CDVPluginResult* result = nil; |
| |
| if (type >= self.fileSystems.count) { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR]; |
| NSLog(@"No filesystem of type requested"); |
| } else { |
| NSString* fullPath = @"/"; |
| // check for avail space for size request |
| NSNumber* pNumAvail = [self checkFreeDiskSpace:self.rootDocsPath]; |
| // NSLog(@"Free space: %@", [NSString stringWithFormat:@"%qu", [ pNumAvail unsignedLongLongValue ]]); |
| if (pNumAvail && ([pNumAvail unsignedLongLongValue] < size)) { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:QUOTA_EXCEEDED_ERR]; |
| } else { |
| NSObject<CDVFileSystem> *rootFs = [self.fileSystems objectAtIndex:type]; |
| if (rootFs == nil) { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:NOT_FOUND_ERR]; |
| NSLog(@"No filesystem of type requested"); |
| } else { |
| NSMutableDictionary* fileSystem = [NSMutableDictionary dictionaryWithCapacity:2]; |
| [fileSystem setObject:rootFs.name forKey:@"name"]; |
| NSDictionary* dirEntry = [self makeEntryForPath:fullPath fileSystemName:rootFs.name isDirectory:YES]; |
| [fileSystem setObject:dirEntry forKey:@"root"]; |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:fileSystem]; |
| } |
| } |
| } |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| |
| - (void)requestAllFileSystems:(CDVInvokedUrlCommand*)command |
| { |
| NSMutableArray* ret = [[NSMutableArray alloc] init]; |
| for (NSObject<CDVFileSystem>* root in fileSystems_) { |
| [ret addObject:[self makeEntryForPath:@"/" fileSystemName:root.name isDirectory:YES]]; |
| } |
| CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:ret]; |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| - (void)requestAllPaths:(CDVInvokedUrlCommand*)command |
| { |
| NSString* libPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0]; |
| NSString* libPathSync = [libPath stringByAppendingPathComponent:@"Cloud"]; |
| NSString* libPathNoSync = [libPath stringByAppendingPathComponent:@"NoCloud"]; |
| NSString* docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; |
| NSString* storagePath = [libPath stringByDeletingLastPathComponent]; |
| NSString* cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; |
| |
| // Create the directories if necessary. |
| [[NSFileManager defaultManager] createDirectoryAtPath:libPathSync withIntermediateDirectories:YES attributes:nil error:nil]; |
| [[NSFileManager defaultManager] createDirectoryAtPath:libPathNoSync withIntermediateDirectories:YES attributes:nil error:nil]; |
| // Mark NoSync as non-iCloud. |
| [[NSURL fileURLWithPath:libPathNoSync] setResourceValue: [NSNumber numberWithBool: YES] |
| forKey: NSURLIsExcludedFromBackupKey error:nil]; |
| |
| NSDictionary* ret = @{ |
| @"applicationDirectory": [[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]] absoluteString], |
| @"applicationStorageDirectory": [[NSURL fileURLWithPath:storagePath] absoluteString], |
| @"dataDirectory": [[NSURL fileURLWithPath:libPathNoSync] absoluteString], |
| @"syncedDataDirectory": [[NSURL fileURLWithPath:libPathSync] absoluteString], |
| @"documentsDirectory": [[NSURL fileURLWithPath:docPath] absoluteString], |
| @"cacheDirectory": [[NSURL fileURLWithPath:cachePath] absoluteString], |
| @"tempDirectory": [[NSURL fileURLWithPath:NSTemporaryDirectory()] absoluteString] |
| }; |
| |
| CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:ret]; |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| /* Creates and returns a dictionary representing an Entry Object |
| * |
| * IN: |
| * NSString* fullPath of the entry |
| * int fsType - 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 |
| * NSString* filesystemName - FileSystem name -- actual filesystem will be created on the JS side if necessary, to avoid |
| * creating circular reference (FileSystem contains DirectoryEntry which contains FileSystem.....!!) |
| */ |
| - (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName isDirectory:(BOOL)isDir |
| { |
| NSObject<CDVFileSystem> *fs = [self fileSystemByName:fsName]; |
| return [fs makeEntryForPath:fullPath isDirectory:isDir]; |
| } |
| |
| - (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)localURL |
| { |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURL]; |
| return [fs makeEntryForLocalURL:localURL]; |
| } |
| |
| - (NSDictionary *)makeEntryForURL:(NSURL *)URL |
| { |
| CDVFilesystemURL* fsURL = [self fileSystemURLforArg:[URL absoluteString]]; |
| return [self makeEntryForLocalURL:fsURL]; |
| } |
| |
| /* |
| * Given a URI determine the File System information associated with it and return an appropriate W3C entry object |
| * IN |
| * NSString* localURI: Should be an escaped local filesystem 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* localURIstr = [command argumentAtIndex:0]; |
| CDVPluginResult* result; |
| |
| localURIstr = [self encodePath:localURIstr]; //encode path before resolving |
| CDVFilesystemURL* inputURI = [self fileSystemURLforArg:localURIstr]; |
| |
| if (inputURI == nil || inputURI.fileSystemName == nil) { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR]; |
| } else { |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:inputURI]; |
| if (fs == nil) { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:ENCODING_ERR]; |
| } else { |
| result = [fs entryForLocalURI:inputURI]; |
| } |
| } |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| //encode path with percent escapes |
| -(NSString *)encodePath:(NSString *)path |
| { |
| NSString *decodedPath = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; //decode incase it's already encoded to avoid encoding twice |
| return [decodedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; |
| } |
| |
| |
| /* Part of DirectoryEntry interface, creates or returns the specified directory |
| * IN: |
| * NSString* localURI - local filesystem URI 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 = [command argumentAtIndex: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* baseURI - local filesytem URI for the base directory to search |
| * NSString* requestedPath - file to be created/returned; may be absolute path or relative path |
| * NSDictionary* options - 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 |
| { |
| NSString* baseURIstr = [command argumentAtIndex:0]; |
| CDVFilesystemURL* baseURI = [self fileSystemURLforArg:baseURIstr]; |
| NSString* requestedPath = [command argumentAtIndex:1]; |
| NSDictionary* options = [command argumentAtIndex:2 withDefault:nil]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:baseURI]; |
| CDVPluginResult* result = [fs getFileForURL:baseURI requestedPath:requestedPath options:options]; |
| |
| |
| [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* localURI |
| * NSMutableDictionary* options |
| * empty |
| */ |
| - (void)getParent:(CDVInvokedUrlCommand*)command |
| { |
| // arguments are URL encoded |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| CDVPluginResult* result = [fs getParentForURL:localURI]; |
| |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| /* |
| * set MetaData of entry |
| * Currently we only support "com.apple.MobileBackup" (boolean) |
| */ |
| - (void)setMetadata:(CDVInvokedUrlCommand*)command |
| { |
| // arguments |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSDictionary* options = [command argumentAtIndex:1 withDefault:nil]; |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| CDVPluginResult* result = [fs setMetadataForURL:localURI withObject:options]; |
| |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| /* removes the directory or file entry |
| * IN: |
| * NSArray* arguments |
| * 0 - NSString* localURI |
| * |
| * 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 |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| CDVPluginResult* result = nil; |
| |
| if ([localURI.fullPath isEqualToString:@""]) { |
| // error if try to remove top level (documents or tmp) dir |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR]; |
| } else { |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| result = [fs removeFileAtURL:localURI]; |
| } |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| /* recursively removes the directory |
| * IN: |
| * NSArray* arguments |
| * 0 - NSString* localURI |
| * |
| * 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 |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| CDVPluginResult* result = nil; |
| |
| if ([localURI.fullPath isEqualToString:@""]) { |
| // error if try to remove top level (documents or tmp) dir |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NO_MODIFICATION_ALLOWED_ERR]; |
| } else { |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| result = [fs recursiveRemoveFileAtURL:localURI]; |
| } |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| - (void)copyTo:(CDVInvokedUrlCommand*)command |
| { |
| [self doCopyMove:command isCopy:YES]; |
| } |
| |
| - (void)moveTo:(CDVInvokedUrlCommand*)command |
| { |
| [self doCopyMove:command isCopy:NO]; |
| } |
| |
| /* Copy/move a file or directory to a new location |
| * IN: |
| * NSArray* arguments |
| * 0 - NSString* URL of entry to copy |
| * 1 - NSString* URL of the directory into which to copy/move the entry |
| * 2 - Optionally, the new name of the entry, defaults to the current name |
| * BOOL - bCopy YES if copy, NO if move |
| */ |
| - (void)doCopyMove:(CDVInvokedUrlCommand*)command isCopy:(BOOL)bCopy |
| { |
| NSArray* arguments = command.arguments; |
| |
| // arguments |
| NSString* srcURLstr = [command argumentAtIndex:0]; |
| NSString* destURLstr = [command argumentAtIndex:1]; |
| |
| CDVPluginResult *result; |
| |
| if (!srcURLstr || !destURLstr) { |
| // either no source or no destination provided |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| return; |
| } |
| |
| CDVFilesystemURL* srcURL = [self fileSystemURLforArg:srcURLstr]; |
| CDVFilesystemURL* destURL = [self fileSystemURLforArg:destURLstr]; |
| |
| NSObject<CDVFileSystem> *srcFs = [self filesystemForURL:srcURL]; |
| NSObject<CDVFileSystem> *destFs = [self filesystemForURL:destURL]; |
| |
| // optional argument; use last component from srcFullPath if new name not provided |
| NSString* newName = ([arguments count] > 2) ? [command argumentAtIndex:2] : [srcURL.url lastPathComponent]; |
| if ([newName rangeOfString:@":"].location != NSNotFound) { |
| // invalid chars in new name |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:ENCODING_ERR]; |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| return; |
| } |
| |
| __weak CDVFile* weakSelf = self; |
| [self.commandDelegate runInBackground:^ { |
| [destFs copyFileToURL:destURL withName:newName fromFileSystem:srcFs atURL:srcURL copy:bCopy callback:^(CDVPluginResult* result) { |
| [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| }]; |
| }]; |
| |
| } |
| |
| - (void)getFileMetadata:(CDVInvokedUrlCommand*)command |
| { |
| // arguments |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| __weak CDVFile* weakSelf = self; |
| [fs getFileMetadataForURL:localURI callback:^(CDVPluginResult* result) { |
| [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| }]; |
| } |
| |
| - (void)readEntries:(CDVInvokedUrlCommand*)command |
| { |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| CDVPluginResult *result = [fs readEntriesAtURL:localURI]; |
| |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| /* 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 |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSString* encoding = [command argumentAtIndex:1]; |
| NSInteger start = [[command argumentAtIndex:2] integerValue]; |
| NSInteger end = [[command argumentAtIndex:3] integerValue]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| |
| if (fs == nil) { |
| CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR]; |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| return; |
| } |
| |
| // 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; |
| } |
| |
| __weak CDVFile* weakSelf = self; |
| |
| [self.commandDelegate runInBackground:^ { |
| [fs readFileAtURL:localURI 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]; |
| } |
| |
| [weakSelf.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 |
| { |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSInteger start = [[command argumentAtIndex:1] integerValue]; |
| NSInteger end = [[command argumentAtIndex:2] integerValue]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| |
| __weak CDVFile* weakSelf = self; |
| [self.commandDelegate runInBackground:^ { |
| [fs readFileAtURL:localURI start:start end:end callback:^(NSData* data, NSString* mimeType, CDVFileError errorCode) { |
| CDVPluginResult* result = nil; |
| if (data != nil) { |
| NSString* b64Str = toBase64(data); |
| NSString* output = [NSString stringWithFormat:@"data:%@;base64,%@", mimeType, b64Str]; |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:output]; |
| } else { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode]; |
| } |
| |
| [weakSelf.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 |
| { |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSInteger start = [[command argumentAtIndex:1] integerValue]; |
| NSInteger end = [[command argumentAtIndex:2] integerValue]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| |
| __weak CDVFile* weakSelf = self; |
| |
| [self.commandDelegate runInBackground:^ { |
| [fs readFileAtURL:localURI 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]; |
| } |
| |
| [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| }]; |
| }]; |
| } |
| |
| - (void)readAsBinaryString:(CDVInvokedUrlCommand*)command |
| { |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| NSInteger start = [[command argumentAtIndex:1] integerValue]; |
| NSInteger end = [[command argumentAtIndex:2] integerValue]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| |
| __weak CDVFile* weakSelf = self; |
| |
| [self.commandDelegate runInBackground:^ { |
| [fs readFileAtURL:localURI 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]; |
| } |
| |
| [weakSelf.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| }]; |
| }]; |
| } |
| |
| |
| - (void)truncate:(CDVInvokedUrlCommand*)command |
| { |
| // arguments |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| unsigned long long pos = (unsigned long long)[[command argumentAtIndex:1] longLongValue]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| CDVPluginResult *result = [fs truncateFileAtURL:localURI atPosition:pos]; |
| |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| /* write |
| * IN: |
| * NSArray* arguments |
| * 0 - NSString* localURI of file to write to |
| * 1 - NSString* or NSData* data to write |
| * 2 - NSNumber* position to begin writing |
| */ |
| - (void)write:(CDVInvokedUrlCommand*)command |
| { |
| __weak CDVFile* weakSelf = self; |
| |
| [self.commandDelegate runInBackground:^ { |
| NSString* callbackId = command.callbackId; |
| |
| // arguments |
| CDVFilesystemURL* localURI = [self fileSystemURLforArg:command.arguments[0]]; |
| id argData = [command argumentAtIndex:1]; |
| unsigned long long pos = (unsigned long long)[[command argumentAtIndex:2] longLongValue]; |
| |
| NSObject<CDVFileSystem> *fs = [self filesystemForURL:localURI]; |
| |
| |
| [fs truncateFileAtURL:localURI atPosition:pos]; |
| CDVPluginResult *result; |
| if ([argData isKindOfClass:[NSString class]]) { |
| NSData *encData = [argData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; |
| result = [fs writeToFileAtURL:localURI withData:encData append:YES]; |
| } else if ([argData isKindOfClass:[NSData class]]) { |
| result = [fs writeToFileAtURL:localURI withData:argData append:YES]; |
| } else { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Invalid parameter type"]; |
| } |
| [weakSelf.commandDelegate sendPluginResult:result callbackId:callbackId]; |
| }]; |
| } |
| |
| #pragma mark Methods for converting between URLs and paths |
| |
| - (NSString *)filesystemPathForURL:(CDVFilesystemURL *)localURL |
| { |
| for (NSObject<CDVFileSystem> *fs in self.fileSystems) { |
| if ([fs.name isEqualToString:localURL.fileSystemName]) { |
| if ([fs respondsToSelector:@selector(filesystemPathForURL:)]) { |
| return [fs filesystemPathForURL:localURL]; |
| } |
| } |
| } |
| return nil; |
| } |
| |
| #pragma mark Undocumented Filesystem API |
| |
| - (void)testFileExists:(CDVInvokedUrlCommand*)command |
| { |
| // arguments |
| NSString* argPath = [command argumentAtIndex: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 argumentAtIndex: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.rootDocsPath]; |
| |
| 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]; |
| } |
| |
| #pragma mark Compatibility with older File API |
| |
| - (NSString*)getMimeTypeFromPath:(NSString*)fullPath |
| { |
| return [CDVLocalFilesystem getMimeTypeFromPath:fullPath]; |
| } |
| |
| - (NSDictionary *)getDirectoryEntry:(NSString *)localPath isDirectory:(BOOL)bDirRequest |
| { |
| CDVFilesystemURL *localURL = [self fileSystemURLforLocalPath:localPath]; |
| return [self makeEntryForPath:localURL.fullPath fileSystemName:localURL.fileSystemName isDirectory:bDirRequest]; |
| } |
| |
| #pragma mark Internal methods for testing |
| // Internal methods for testing: Get the on-disk location of a local filesystem url. |
| // [Currently used for testing file-transfer] |
| |
| - (void)_getLocalFilesystemPath:(CDVInvokedUrlCommand*)command |
| { |
| CDVFilesystemURL* localURL = [self fileSystemURLforArg:command.arguments[0]]; |
| |
| NSString* fsPath = [self filesystemPathForURL:localURL]; |
| CDVPluginResult* result; |
| if (fsPath) { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:fsPath]; |
| } else { |
| result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Cannot resolve URL to a file"]; |
| } |
| [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; |
| } |
| |
| @end |