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 [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to