Logo Search packages:      
Sourcecode: zipper.app version File versions

ZipArchive.m

#import <Foundation/Foundation.h>
#import "ZipArchive.h"
#import "FileInfo.h"
#import "NSString+Custom.h"
#import "Preferences.h"
#import "NSArray+Custom.h"

// if the output contains this string in the first line, we have to use a different
// parsing routine
#define MINI_UNZIP_IDENTIFIER @"MiniUnz"

@interface ZipArchive (PrivateAPI)
- (NSData *)dataByRunningUnzip;
- (NSArray *)listUnzipContents:(NSArray *)lines;
@end

@implementation ZipArchive : Archive

/**
 * register our supported file extensions with superclass.
 */
+ (void)initialize
{
      [self registerFileExtension:@"zip" forArchiveClass:self];
      [self registerFileExtension:@"jar" forArchiveClass:self];
}

+ (NSString *)unarchiveExecutable
{
      return [Preferences zipExecutable];
}

+ (BOOL)hasRatio;
{
      // unzip does provide info about the compression ratio
      return YES;
}

+ (NSString *)archiveType
{
      return @"Zip";
}

//------------------------------------------------------------------------------
// expanding the archive
//------------------------------------------------------------------------------
- (int)expandFiles:(NSArray *)files withPathInfo:(BOOL)usePathInfo toPath:(NSString *)path
{
      FileInfo *fileInfo;
      NSMutableArray *args;
            
      args = [NSMutableArray array];
      // be really quiet
      [args addObject:@"-qq"];
      // overwrite without warning
      [args addObject:@"-o"];
      if (usePathInfo == NO)
      {
            // junk paths
            [args addObject:@"-j"];
      }
      [args addObject:[self path]]; 
      
      if (files != nil)
      {
            NSEnumerator *cursor = [files objectEnumerator];
            while ((fileInfo = [cursor nextObject]) != nil)
            {
                  [args addObject:[fileInfo fullPath]];
            }
      }
      
      // destination dir
      [args addObject:@"-d"];
      [args addObject:path];
      return [self runUnarchiverWithArguments:args];
}

- (NSArray *)listContents
{    
    NSData *data = [self dataByRunningUnzip];
    NSString *string = [[[NSString alloc] initWithData:data 
            encoding:NSASCIIStringEncoding] autorelease];   
    NSArray *lines = [string componentsSeparatedByString:@"\n"];
    
    if ([[lines objectAtIndex:0] containsString:MINI_UNZIP_IDENTIFIER])
    {
            // take out the first 6 lines (header)
            lines = [lines subarrayWithRange:NSMakeRange(6, [lines count] - 6)];
    }
    else
    {
        // take out first 3 lines (header) and last 2 lines (footer)
      lines = [lines subarrayWithRange:NSMakeRange(3, [lines count] - 3)];
          lines = [lines subarrayWithRange:NSMakeRange(0, [lines count] - 3)];
    }
    
    return [self listUnzipContents:lines];
}

- (NSArray *)listUnzipContents:(NSArray *)lines
{    
    NSEnumerator *cursor;
    NSString *line;
      NSMutableArray *results = [NSMutableArray array];
          
    cursor = [lines objectEnumerator];
    while ((line = [cursor nextObject]) != nil)
    {
        int length, index;
        NSString *path, *date, *time, *ratio, *checksum;
        NSCalendarDate *calendarDate;
        FileInfo *info;
        NSArray *components;
            
            if ([line length] == 0)
            {
                  continue;
            }
            
            components = [line componentsSeparatedByString:@" "];
            components = [components arrayByRemovingEmptyStrings];
            length = [[components objectAtIndex:0] intValue];
            ratio = [components objectAtIndex:3];

            // extract the path. The checksum is the last token before the full path 
            // (which can contain blanks) 
            checksum = [components objectAtIndex:6];
            index = [line rangeOfString:checksum].location;
            index += [checksum length];
            path = [[line substringFromIndex:index] stringByRemovingWhitespaceFromBeginning];
            
            date = [components objectAtIndex:4];
            time = [components objectAtIndex:5];            
        date = [NSString stringWithFormat:@"%@ %@", date, time];
        calendarDate = [NSCalendarDate dateWithString:date calendarFormat:@"%m-%d-%y %H:%M"];

            // we skip plain directory entries
            if ([path hasSuffix:@"/"] == NO)
            {
                  info = [FileInfo newWithPath:path date:calendarDate 
                        size:[NSNumber numberWithInt:length] ratio:ratio];
              [results addObject:info];
            } 
    }
    return results;
}

//------------------------------------------------------------------------------
// private API
//------------------------------------------------------------------------------
- (NSData *)dataByRunningUnzip
{
      NSArray *args = [NSArray arrayWithObjects:@"-lv", [self path], nil];
      return [self dataByRunningUnachiverWithArguments:args];
}

@end

Generated by  Doxygen 1.6.0   Back to index