//
//  RAZipper.m
//  RAZipper
//
//  Created by Ricci Adams on Sat Dec 07 2002.
//  Copyright (c) 2002 Carpe Stellarem. All rights reserved.
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.

//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

#import "RAZipper.h"
#import "zlib.h"

@implementation RAZipper

+(NSData *) dataForCompressedData:(NSData *)data {
    NSData	*dataToReturn	= nil;
    
    const void	*cBuffer 	= [data bytes];
    unsigned	cLen		= [data length];
    Bytef	*uBuffer	= NULL;
    uLongf 	uLen		= cLen;
    int 	err;
    
    do {
	uLen *= 2;		// Double the buffer size each iteration through the loop
	
	if (uBuffer = malloc(uLen)) {
	    err = uncompress(uBuffer, &uLen, cBuffer, cLen);
	    
	    if (err == Z_OK)
		dataToReturn = [NSData dataWithBytes:uBuffer length:uLen];
		
	    if (err == Z_MEM_ERROR || err == Z_DATA_ERROR)
		dataToReturn = nil;
	    
	    free(uBuffer);
	} else {
	    return nil;
	}
    } while (err == Z_BUF_ERROR);	// If the buffer wasn't big enough this time, repeat the loop
    
    return dataToReturn;   
}

+(NSString *) stringForCompressedData:(NSData *)data {
    NSData	*uncompressedData	= [self dataForCompressedData:data];
    NSString	*stringToReturn		= nil;
    char	*bytes			= NULL;
    unsigned	len			= [uncompressedData length];
    
    bytes = malloc(len);
    [uncompressedData getBytes:bytes];
    
    stringToReturn = [NSString stringWithCString:bytes length:len];
    
    free (bytes);
    
    return stringToReturn;
}

+(NSData *) compressedDataForData:(NSData *)data {
    NSData	*returnData	= nil;

    char 	*uBuffer	= nil;
    unsigned 	uLen		= [data length];
    Byte	*cBuffer 	= NULL;
    uLong	cLen		= uLen;
    int 	err;

    uBuffer = malloc(uLen);
    [data getBytes:uBuffer];    

    do {
	cLen *= 2;		// Double the buffer size each iteration through the loop
	
	if (cBuffer = malloc(cLen)) {
	    err = compress(cBuffer, &cLen, (const Bytef *)uBuffer, uLen);
	
	    if (err == Z_OK)
		returnData = [NSData dataWithBytes:cBuffer length:(unsigned)cLen];
	    
	    if (err == Z_MEM_ERROR)
		returnData = nil;
	
	    free(cBuffer);
	} else {
	    return nil;
	}
	
    } while (err == Z_BUF_ERROR);	// If the buffer wasn't big enough this time, repeat the loop

    free(uBuffer);

    return returnData;
}

+(NSData *) compressedDataForString:(NSString *)aString {
    return [self compressedDataForData:[aString dataUsingEncoding:NSASCIIStringEncoding]];
}



@end
