//
//  Wow.m
//  Crazy
//
//  Created by Henry Mason on 10/17/04.
//  Copyright 2004 Henry Mason. All rights reserved.
//

#import "GzipAwareString.h"


@implementation NSString (GzipAwareString)

+ (NSString *)stringWithContentsOfURL:(NSURL *)url
{
    NSString    *string;
    
    string = [[NSString alloc] initWithData:[[self class] gunzipedDataFromData:[NSData dataWithContentsOfURL:url]] encoding:NSASCIIStringEncoding];
    
    return [string autorelease];        
}

+ (BOOL)isDataCompressed:(NSData *)data
{
    int bufsize = 100;
    if ([data length] < bufsize) bufsize = [data length];
    char *buffer = malloc(bufsize * sizeof(char));
    [data getBytes:buffer length:bufsize];
    int i;
    for (i=0;i<bufsize;i++) {
        char ch = buffer[i];
        if (ch == '<') return NO; // not compressed, probably HTML
        if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') return YES; // starts with something other than whitespace and '<', not HTML
    }
    return NO; // all whitespace in the first 100 chars, not compressed.
}

+ (NSData *)gunzipedDataFromData:(NSData *)compressedData
{
    NSTask  *gunzip;
    NSPipe  *compressedDataPipe, *uncompressedDataPipe;
    
    if (![[self class] isDataCompressed:compressedData]) return compressedData;
    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
    gunzip = [[NSTask alloc] init];
    
    compressedDataPipe = [NSPipe pipe];
    uncompressedDataPipe = [NSPipe pipe];
    
    [gunzip setLaunchPath:@"/usr/bin/gunzip"];
    [gunzip setArguments:[NSArray arrayWithObject:@"-f"]];
    
    [gunzip setStandardInput:compressedDataPipe];
    [gunzip setStandardOutput:uncompressedDataPipe];
    
    [gunzip launch];
    
    NSFileHandle *writerHandle = [compressedDataPipe fileHandleForWriting];
    [writerHandle writeData:compressedData];
    
    [writerHandle closeFile];
    
    int maxToRead = (1024 * 1024);
    
    NSFileHandle    *readerFileHandle = [uncompressedDataPipe fileHandleForReading];
    NSMutableData   *uncompressedData = [NSMutableData data];
    
    do {
        NSData  *dataToRead;
        
        dataToRead = [readerFileHandle availableData];
        
        if (dataToRead && [dataToRead length]) {
            [uncompressedData appendData:dataToRead];
        } else {
            break;
        }
        
    } while ([uncompressedData length] < maxToRead);
    
    [gunzip terminate];
    [gunzip release];
    
    NSData *newData = [[NSData alloc] initWithData:uncompressedData];
    [pool release];
    [newData autorelease];
    if (!newData || ![newData length]) newData = compressedData;
    return newData;
}


@end
