/****************************************************************************** * Copyright (c) 2008-2012 Transmission authors and contributors * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ #import "FileListNode.h" @interface FileListNode (Private) - (instancetype)initWithFolder:(BOOL)isFolder name:(NSString*)name path:(NSString*)path torrent:(Torrent*)torrent; @end @implementation FileListNode { NSMutableIndexSet* _indexes; NSImage* _icon; NSMutableArray* _children; } - (instancetype)initWithFolderName:(NSString*)name path:(NSString*)path torrent:(Torrent*)torrent { if ((self = [self initWithFolder:YES name:name path:path torrent:torrent])) { _children = [[NSMutableArray alloc] init]; _size = 0; } return self; } - (instancetype)initWithFileName:(NSString*)name path:(NSString*)path size:(uint64_t)size index:(NSUInteger)index torrent:(Torrent*)torrent { if ((self = [self initWithFolder:NO name:name path:path torrent:torrent])) { _size = size; [_indexes addIndex:index]; } return self; } - (void)insertChild:(FileListNode*)child { NSAssert(_isFolder, @"method can only be invoked on folders"); [_children addObject:child]; } - (void)insertIndex:(NSUInteger)index withSize:(uint64_t)size { NSAssert(_isFolder, @"method can only be invoked on folders"); [_indexes addIndex:index]; _size += size; } - (id)copyWithZone:(NSZone*)zone { //this object is essentially immutable after initial setup return self; } - (NSString*)description { if (!_isFolder) { return [NSString stringWithFormat:@"%@ (%ld)", _name, _indexes.firstIndex]; } else { return [NSString stringWithFormat:@"%@ (folder: %@)", _name, _indexes]; } } - (NSImage*)icon { if (!_icon) { _icon = [NSWorkspace.sharedWorkspace iconForFileType:_isFolder ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : _name.pathExtension]; } return _icon; } - (NSMutableArray*)children { NSAssert(_isFolder, @"method can only be invoked on folders"); return _children; } - (NSIndexSet*)indexes { return _indexes; } - (BOOL)updateFromOldName:(NSString*)oldName toNewName:(NSString*)newName inPath:(NSString*)path { NSParameterAssert(oldName != nil); NSParameterAssert(newName != nil); NSParameterAssert(path != nil); NSArray* lookupPathComponents = path.pathComponents; NSArray* thesePathComponents = self.path.pathComponents; if ([lookupPathComponents isEqualToArray:thesePathComponents]) //this node represents what's being renamed { if ([oldName isEqualToString:self.name]) { _name = [newName copy]; _icon = nil; return YES; } } else if (lookupPathComponents.count < thesePathComponents.count) //what's being renamed is part of this node's path { lookupPathComponents = [lookupPathComponents arrayByAddingObject:oldName]; BOOL const allSame = NSNotFound == [lookupPathComponents indexOfObjectWithOptions:NSEnumerationConcurrent passingTest:^BOOL(NSString* name, NSUInteger idx, BOOL* stop) { return ![name isEqualToString:thesePathComponents[idx]]; }]; if (allSame) { NSString* oldPathPrefix = [path stringByAppendingPathComponent:oldName]; NSString* newPathPrefix = [path stringByAppendingPathComponent:newName]; _path = [_path stringByReplacingCharactersInRange:NSMakeRange(0, oldPathPrefix.length) withString:newPathPrefix]; return YES; } } return NO; } @end @implementation FileListNode (Private) - (instancetype)initWithFolder:(BOOL)isFolder name:(NSString*)name path:(NSString*)path torrent:(Torrent*)torrent { if ((self = [super init])) { _isFolder = isFolder; _name = [name copy]; _path = [path copy]; _indexes = [[NSMutableIndexSet alloc] init]; _torrent = torrent; } return self; } @end