1#import <Foundation/Foundation.h> 2#import "LzxArchive.h" 3#import "FileInfo.h" 4#import "NSString+Custom.h" 5#import "Preferences.h" 6#import "NSArray+Custom.h" 7 8@interface LzxArchive (PrivateAPI) 9- (NSData *)dataByRunningLzx; 10@end 11 12@implementation LzxArchive : Archive 13 14/** 15 * register our supported file extensions with our superclass. 16 */ 17+ (void)initialize 18{ 19 [self registerFileExtension:@"lzx" forArchiveClass:self]; 20} 21 22+ (NSString *)unarchiveExecutable 23{ 24 return [Preferences lzxExecutable]; 25} 26 27/** 28 * lzx archives can only be unpacked with path info 29 */ 30+ (BOOL)canExtractWithoutFullPath 31{ 32 return NO; 33} 34 35/** 36 * lzx archives <em>do not</em> contain info about compression ratio. 37 */ 38+ (BOOL)hasRatio; 39{ 40 return NO; 41} 42 43+ (ArchiveType)archiveType 44{ 45 return LZX; 46} 47 48//------------------------------------------------------------------------------ 49// expanding the archive 50//------------------------------------------------------------------------------ 51/** 52 * the unlzx command does not allow to unpack single files from the archive. We 53 * resort to unpacking the entire archive instead ... 54 */ 55- (int)expandFiles:(NSArray *)files withPathInfo:(BOOL)usePathInfo toPath:(NSString *)path 56{ 57 NSArray *args; 58 59 args = [NSArray arrayWithObjects:@"-x", @"--", [self path], nil]; 60 return [[self class] runUnarchiverWithArguments:args inDirectory:path]; 61} 62 63- (NSArray *)listContents 64{ 65 NSEnumerator *cursor; 66 NSString *line; 67 68 NSMutableArray *results = [NSMutableArray array]; 69 NSData *data = [self dataByRunningLzx]; 70 NSString *string = [[[NSString alloc] initWithData:data 71 encoding:NSASCIIStringEncoding] autorelease]; 72 NSArray *lines = [string componentsSeparatedByString:@"\n"]; 73 74 // take out first 2 lines (header) and last 2 lines (footer) 75 lines = [lines subarrayWithRange:NSMakeRange(2, [lines count] - 2)]; 76 lines = [lines subarrayWithRange:NSMakeRange(0, [lines count] - 3)]; 77 78 cursor = [lines objectEnumerator]; 79 while ((line = [cursor nextObject]) != nil) 80 { 81 NSArray *components; 82 int length; 83 NSString *path, *dateString, *timeString; 84 NSCalendarDate *date; 85 FileInfo *info; 86 87 components = [line componentsSeparatedByString:@" "]; 88 components = [components arrayByRemovingEmptyStrings]; 89 90 timeString = [components objectAtIndex:2]; 91 if ([timeString isEqual:@"Merged"]) 92 { 93 // skip lines that continue "Merged" in the time column, they contain no usable info 94 continue; 95 } 96 97 length = [[components objectAtIndex:0] intValue]; 98 path = [components objectAtIndex:5]; 99 if ([path hasPrefix:@"\""]) 100 { 101 path = [path substringFromIndex:1]; 102 } 103 if ([path hasSuffix:@"\""]) 104 { 105 path = [path substringToIndex:[path length] - 1]; 106 } 107 108 dateString = [components objectAtIndex:3]; 109 dateString = [NSString stringWithFormat:@"%@ %@", dateString, timeString]; 110 date = [NSCalendarDate dateWithString:dateString calendarFormat:@"%d-%b-%Y %H:%M:%S"]; 111 112 info = [FileInfo newWithPath:path date:date size:[NSNumber numberWithInt:length]]; 113 [results addObject:info]; 114 } 115 116 return results; 117} 118 119//------------------------------------------------------------------------------ 120// private API 121//------------------------------------------------------------------------------ 122- (NSData *)dataByRunningLzx 123{ 124 NSData *data; 125 126 NSArray *args = [NSArray arrayWithObjects:@"-v", @"--", [self path], nil]; 127 data = [self dataByRunningUnachiverWithArguments:args]; 128 return data; 129} 130 131@end 132