cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tripodsan <...@git.apache.org>
Subject [GitHub] cordova-plugin-file pull request: updated support for the OS X pla...
Date Wed, 30 Apr 2014 20:19:08 GMT
Github user tripodsan commented on a diff in the pull request:

    https://github.com/apache/cordova-plugin-file/pull/42#discussion_r12163564
  
    --- Diff: src/osx/CDVLocalFilesystem.m ---
    @@ -0,0 +1,719 @@
    +/*
    + 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 "CDVLocalFilesystem.h"
    +#import <Cordova/CDV.h>
    +#import <sys/xattr.h>
    +
    +@implementation CDVLocalFilesystem
    +@synthesize name=_name, fsRoot=_fsRoot;
    +
    +- (id) initWithName:(NSString *)name root:(NSString *)fsRoot
    +{
    +    if (self) {
    +        _name = name;
    +        _fsRoot = fsRoot;
    +    }
    +    return self;
    +}
    +
    +/*
    + * IN
    + *  NSString localURI
    + * OUT
    + *  CDVPluginResult result containing a file or directoryEntry for the localURI, or an
error if the
    + *   URI represents a non-existent path, or is unrecognized or otherwise malformed.
    + */
    +- (CDVPluginResult *)entryForLocalURI:(CDVFilesystemURL *)url
    +{
    +    CDVPluginResult* result = nil;
    +    NSDictionary* entry = [self makeEntryForLocalURL:url];
    +    if (entry) {
    +        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:entry];
    +    } else {
    +        // return NOT_FOUND_ERR
    +        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
    +    }
    +    return result;
    +}
    +- (NSDictionary *)makeEntryForLocalURL:(CDVFilesystemURL *)url {
    +    NSString *path = [self filesystemPathForURL:url];
    +    NSFileManager* fileMgr = [[NSFileManager alloc] init];
    +    BOOL isDir = NO;
    +    // see if exists and is file or dir
    +    BOOL bExists = [fileMgr fileExistsAtPath:path isDirectory:&isDir];
    +    if (bExists) {
    +        return [self makeEntryForPath:url.fullPath fileSystemName:url.fileSystemName
isDirectory:isDir];
    +    } else {
    +        return nil;
    +    }
    +}
    +- (NSDictionary*)makeEntryForPath:(NSString*)fullPath fileSystemName:(NSString *)fsName
isDirectory:(BOOL)isDir
    +{
    +    NSMutableDictionary* dirEntry = [NSMutableDictionary dictionaryWithCapacity:5];
    +    NSString* lastPart = [[self stripQueryParametersFromPath:fullPath] lastPathComponent];
    +    if (isDir && ![fullPath hasSuffix:@"/"]) {
    +        fullPath = [fullPath stringByAppendingString:@"/"];
    +    }
    +    [dirEntry setObject:[NSNumber numberWithBool:!isDir]  forKey:@"isFile"];
    +    [dirEntry setObject:[NSNumber numberWithBool:isDir]  forKey:@"isDirectory"];
    +    [dirEntry setObject:fullPath forKey:@"fullPath"];
    +    [dirEntry setObject:lastPart forKey:@"name"];
    +    [dirEntry setObject: [NSNumber numberWithInt:([fsName isEqualToString:@"temporary"]
? 0 : 1)] forKey: @"filesystem"];
    +    [dirEntry setObject:fsName forKey: @"filesystemName"];
    +    dirEntry[@"nativeURL"] = [[NSURL fileURLWithPath:[self filesystemPathForFullPath:fullPath]]
absoluteString];
    +
    +
    +    return dirEntry;
    +}
    +
    +- (NSString *)stripQueryParametersFromPath:(NSString *)fullPath
    +{
    +    NSRange questionMark = [fullPath rangeOfString:@"?"];
    +    if (questionMark.location != NSNotFound) {
    +        return [fullPath substringWithRange:NSMakeRange(0,questionMark.location)];
    +    }
    +    return fullPath;
    +}
    +
    +- (NSString *)filesystemPathForFullPath:(NSString *)fullPath
    +{
    +    NSString *path = nil;
    +    NSString *strippedFullPath = [self stripQueryParametersFromPath:fullPath];
    +    path = [NSString stringWithFormat:@"%@%@", self.fsRoot, strippedFullPath];
    +    if ([path length] > 1 && [path hasSuffix:@"/"]) {
    +      path = [path substringToIndex:([path length]-1)];
    +    }
    +    return path;
    +}
    +/*
    + * IN
    + *  NSString localURI
    + * OUT
    + *  NSString full local filesystem path for the represented file or directory, or nil
if no such path is possible
    + *  The file or directory does not necessarily have to exist. nil is returned if the
filesystem type is not recognized,
    + *  or if the URL is malformed.
    + * The incoming URI should be properly escaped (no raw spaces, etc. URI percent-encoding
is expected).
    + */
    +- (NSString *)filesystemPathForURL:(CDVFilesystemURL *)url
    +{
    +    return [self filesystemPathForFullPath:url.fullPath];
    +}
    +
    +- (CDVFilesystemURL *)URLforFullPath:(NSString *)fullPath
    +{
    +    if (fullPath) {
    +        if ([fullPath hasPrefix:@"/"]) {
    +            return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@"%@://localhost/%@%@",
kCDVFilesystemURLPrefix, self.name, fullPath]];
    +        }
    +        return [CDVFilesystemURL fileSystemURLWithString:[NSString stringWithFormat:@"%@://localhost/%@/%@",
kCDVFilesystemURLPrefix, self.name, fullPath]];
    +    }
    +    return nil;
    +}
    +
    +- (CDVFilesystemURL *)URLforFilesystemPath:(NSString *)path
    +{
    +    return [self URLforFullPath:[[self fullPathForFileSystemPath:path] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    +
    +}
    +
    +- (NSString *)normalizePath:(NSString *)rawPath
    +{
    +    // If this is an absolute path, the first path component will be '/'. Skip it if
that's the case
    +    BOOL isAbsolutePath = [rawPath hasPrefix:@"/"];
    +    if (isAbsolutePath) {
    +        rawPath = [rawPath substringFromIndex:1];
    +    }
    +    NSMutableArray *components = [NSMutableArray arrayWithArray:[rawPath pathComponents]];
    +    for (int index = 0; index < [components count]; ++index) {
    +        if ([[components objectAtIndex:index] isEqualToString:@".."]) {
    +            [components removeObjectAtIndex:index];
    +            if (index > 0) {
    +                [components removeObjectAtIndex:index-1];
    +                --index;
    +            }
    +        }
    +    }
    +
    +    if (isAbsolutePath) {
    +        return [NSString stringWithFormat:@"/%@", [components componentsJoinedByString:@"/"]];
    +    } else {
    +        return [components componentsJoinedByString:@"/"];
    +    }
    +
    +
    +}
    +
    +- (CDVPluginResult *)getFileForURL:(CDVFilesystemURL *)baseURI requestedPath:(NSString
*)requestedPath options:(NSDictionary *)options
    +{
    +    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 {
    +        // Build new fullPath for the requested resource.
    +        // We concatenate the two paths together, and then scan the resulting string
to remove
    +        // parent ("..") references. Any parent references at the beginning of the string
are
    +        // silently removed.
    +        NSString *combinedPath = [baseURI.fullPath stringByAppendingPathComponent:[requestedPath
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    +        combinedPath = [self normalizePath:combinedPath];
    +        CDVFilesystemURL* requestedURL = [self URLforFullPath:combinedPath];
    +        
    +        NSFileManager* fileMgr = [[NSFileManager alloc] init];
    +        BOOL bIsDir;
    +        BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:requestedURL]
isDirectory:&bIsDir];
    +        if (bExists && (create == NO) && (bIsDir == !bDirRequest)) {
    +            // path exists and is not 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:[self filesystemPathForURL:requestedURL]
withIntermediateDirectories:NO attributes:nil error:&pError];
    +                } else {
    +                    // create the empty file
    +                    bSuccess = [fileMgr createFileAtPath:[self filesystemPathForURL:requestedURL]
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
makeEntryForPath:requestedURL.fullPath fileSystemName:baseURI.fileSystemName isDirectory:bDirRequest]];
    +            }
    +        } // are all possible conditions met?
    +    }
    +
    +    if (errorCode > 0) {
    +        // create error callback
    +        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:errorCode];
    +    }
    +    return result;
    +
    +}
    +
    +- (CDVPluginResult*)getParentForURL:(CDVFilesystemURL *)localURI
    +{
    +    CDVPluginResult* result = nil;
    +    CDVFilesystemURL *newURI = nil;
    +    if ([localURI.fullPath isEqualToString:@""]) {
    +        // return self
    +        newURI = localURI;
    +    } else {
    +        newURI = [CDVFilesystemURL fileSystemURLWithURL:[localURI.url URLByDeletingLastPathComponent]];
/* TODO: UGLY - FIX */
    +    }
    +    NSFileManager* fileMgr = [[NSFileManager alloc] init];
    +    BOOL bIsDir;
    +    BOOL bExists = [fileMgr fileExistsAtPath:[self filesystemPathForURL:newURI] isDirectory:&bIsDir];
    +    if (bExists) {
    +        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self
makeEntryForPath:newURI.fullPath fileSystemName:newURI.fileSystemName isDirectory:bIsDir]];
    +    } else {
    +        // invalid path or file does not exist
    +        result = [CDVPluginResult resultWithStatus:CDVCommandStatus_IO_EXCEPTION messageAsInt:NOT_FOUND_ERR];
    +    }
    +    return result;
    +}
    +
    +- (void)getMetadataForURL:(CDVFilesystemURL *)url callback:(void (^)(CDVPluginResult
*))callback
    +{
    +
    +    NSFileManager* fileMgr = [[NSFileManager alloc] init];
    +    NSError* __autoreleasing error = nil;
    +
    +    CDVPluginResult *result;
    +    NSDictionary* fileAttribs = [fileMgr attributesOfItemAtPath:[self  filesystemPathForURL:url]
error:&error];
    +
    +    if (fileAttribs) {
    +        // Ensure that directories (and other non-regular files) report size of 0
    +        unsigned long long size = ([fileAttribs fileType] == NSFileTypeRegular ? [fileAttribs
fileSize] : 0);
    +        NSDate* modDate = [fileAttribs fileModificationDate];
    +        if (modDate) {
    +            result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:@{@"modificationTime":
@([modDate timeIntervalSince1970] * 1000), @"size": @(size)}];
    +        }
    +    } 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];
    +    }
    +    callback(result);
    +}
    +
    +- (CDVPluginResult*)setMetadataForURL:(CDVFilesystemURL *)localURI withObject:(NSDictionary
*)options
    +{
    +    BOOL ok = NO;
    +
    +    NSString* filePath = [self filesystemPathForURL:localURI];
    +    // 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]]) {
    +			NSURL* url = [NSURL fileURLWithPath:filePath];
    --- End diff --
    
    wrong indentation.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

Mime
View raw message