2003-05-14 Manuel Guesdon <mguesdon@orange-concept.com>

* GSWeb.framework/GSWRequest.h/.m:
		o added ivar _browserAcceptedEncodings
		o added -browserAcceptedEncodings
		o modified browserLanguages to use quality indicator
	* GSWeb.framework/GSWConstants.h/.m:
		o added GSWHTTPHeader_AcceptEncoding
	* GSWeb.framework/GSWResponse.h/.m:
		o added ivar _acceptedEncodings
		o added -acceptedEncodings
		o added -setAcceptedEncodings:
	* GSWeb.framework/GSWComponentRequestHandler.m:
		o set request  browserAcceptedEncodings to response
	* GSWeb.framework/GSWComponent.m:
		o set request  browserAcceptedEncodings to response
	* GSWeb.framework/NSData+Compress.h/.m:
		o added
	* config.h.in
		o added HAVE_ZLIB


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@16718 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Manuel Guesdon 2003-05-14 08:30:22 +00:00
parent 7654257195
commit 1e88f582b9
25 changed files with 527 additions and 46 deletions

View file

@ -1,3 +1,23 @@
2003-05-14 Manuel Guesdon <mguesdon@orange-concept.com>
* GSWeb.framework/GSWRequest.h/.m:
o added ivar _browserAcceptedEncodings
o added -browserAcceptedEncodings
o modified browserLanguages to use quality indicator
* GSWeb.framework/GSWConstants.h/.m:
o added GSWHTTPHeader_AcceptEncoding
* GSWeb.framework/GSWResponse.h/.m:
o added ivar _acceptedEncodings
o added -acceptedEncodings
o added -setAcceptedEncodings:
* GSWeb.framework/GSWComponentRequestHandler.m:
o set request browserAcceptedEncodings to response
* GSWeb.framework/GSWComponent.m:
o set request browserAcceptedEncodings to response
* GSWeb.framework/NSData+Compress.h/.m:
o added
* config.h.in
o added HAVE_ZLIB
2003-05-14 Manuel Guesdon <mguesdon@orange-concept.com>
* GSWeb.framework/GSWResourceManager.m:
o added warning in ISOLanguagesFromGSLanguages

View file

@ -63,7 +63,7 @@ FileLinkWithPath: GSWHyperlink
FileLinkWithURL: GSWHyperlink
{
src=fileInfo.fileURL;
href = fileInfo.fileURL;
string= ^string;
target = ^target;
};

View file

@ -187,6 +187,7 @@ GSWGeometricRegion.m \
GSWFileUpload.m \
GSWResourceURL.m \
GSWProcFS.m \
NSData+Compress.m \
stacktrace.m \
attach.m
GSWeb_wo_OBJC_FILES = $(GSWeb_OBJC_FILES)
@ -304,6 +305,7 @@ GSWGeometricRegion.h \
GSWFileUpload.h \
GSWResourceURL.h \
GSWProcFS.h \
NSData+Compress.h \
GSWWOCompatibility.h

View file

@ -178,6 +178,8 @@ RCS_ID("$Id$")
(void*)self];
};
@end
//====================================================================
@implementation GSWActiveImage (GSWActiveImageA)
-(GSWAssociation*)hitTestX:(int)x

View file

@ -368,6 +368,7 @@ static NSMutableArray* associationsLogsHandlerClasses=nil;
return assoc;
};
@end
//====================================================================
@implementation GSWAssociation (GSWAssociationHandlers)
//--------------------------------------------------------------------

View file

@ -1581,6 +1581,8 @@ associationsKeys:(NSArray*)associationsKeys
NSDebugMLLog(@"GSWComponent",@"request=%@",request);
httpVersion=(request ? [request httpVersion] : @"HTTP/1.0");
[response setHTTPVersion:httpVersion];
if (request)
[response setAcceptedEncodings:[request browserAcceptedEncodings]];
[response setHeader:@"text/html"
forKey:@"content-type"];
NSDebugMLLog(@"GSWComponent",@"response=%@",response);

View file

@ -380,6 +380,7 @@ RCS_ID("$Id$")
}
httpVersion=[request httpVersion];
[response setHTTPVersion:httpVersion];
[response setAcceptedEncodings:[request browserAcceptedEncodings]];
[response setHeader:@"text/html"
forKey:@"content-type"];
[aContext _setResponse:response];

View file

@ -144,7 +144,7 @@ Bindings
object_get_class_name(self),
(void*)self];
};
@end
//====================================================================
@implementation GSWConditional (GSWConditionalA)

View file

@ -27,7 +27,7 @@
#define _GSWebConfig_h__
#ifdef GSWEB_WONAMES
#import "GSWWOCompatibility.h"
#include "GSWWOCompatibility.h"
#endif
#define GSLOCK_DELAY_S 360

View file

@ -123,6 +123,7 @@ extern NSString* GSWHTTPHeader_Method[2];
extern NSString* GSWHTTPHeader_MethodPost;
extern NSString* GSWHTTPHeader_MethodGet;
extern NSString* GSWHTTPHeader_AcceptLanguage;
extern NSString* GSWHTTPHeader_AcceptEncoding;
extern NSString* GSWHTTPHeader_ContentType;
extern NSString* GSWHTTPHeader_FormURLEncoded;
extern NSString* GSWHTTPHeader_MultipartFormData;

View file

@ -130,6 +130,7 @@ NSString* GSWHTTPHeader_RequestScheme[2]={ @"x-gsweb-request-scheme", @"x-webobj
NSString* GSWHTTPHeader_MethodPost=@"POST";
NSString* GSWHTTPHeader_MethodGet=@"GET";
NSString* GSWHTTPHeader_AcceptLanguage=@"accept-language";
NSString* GSWHTTPHeader_AcceptEncoding=@"accept-encoding";
NSString* GSWHTTPHeader_ContentType=@"content-type";
NSString* GSWHTTPHeader_FormURLEncoded=@"application/x-www-form-urlencoded";
NSString* GSWHTTPHeader_MultipartFormData=@"multipart/form-data";

View file

@ -34,8 +34,8 @@
#if !GDL2
#ifdef TCSDB
#import <TCSimpleDB/TCSimpleDB.h>
#import <TCSimpleDB/EODefines.h>
#include <TCSimpleDB/TCSimpleDB.h>
#include <TCSimpleDB/EODefines.h>
#else // TCSDB
#include <eoaccess/EOModel.h>
#include <eoaccess/EOEntity.h>
@ -63,13 +63,13 @@
#define EODataSource EODatabaseDataSource
#endif
#else
#import <EOControl/EOQualifier.h>
#import <EOControl/EOEditingContext.h>
#import <EOControl/EODataSource.h>
#import <EOControl/EODetailDataSource.h>
#import <EOControl/EOKeyValueArchiver.h>
#import <EOControl/EONull.h>
#import <EOAccess/EODatabaseDataSource.h>
#include <EOControl/EOQualifier.h>
#include <EOControl/EOEditingContext.h>
#include <EOControl/EODataSource.h>
#include <EOControl/EODetailDataSource.h>
#include <EOControl/EOKeyValueArchiver.h>
#include <EOControl/EONull.h>
#include <EOAccess/EODatabaseDataSource.h>
#endif
@interface GSWDisplayGroup : NSObject <NSCoding>

View file

@ -188,7 +188,7 @@ RCS_ID("$Id$")
{
NSString* parametersList=@"'action' or 'href' or 'pageName' or 'directActionName' or 'actionClass'";
if (!WOStrictFlag)
parametersList=[parametersList stringByAppendingFormat:@"'redirectURL' or 'filename' or 'data'"];
parametersList=[parametersList stringByAppendingFormat:@" or 'redirectURL' or 'filename' or 'data'"];
ExceptionRaise(@"GSWHyperlink",
@"You need to specify at least %@ parameter",
parametersList);

View file

@ -172,6 +172,7 @@ RCS_ID("$Id$")
object_get_class_name(self),
(void*)self];
};
@end
//====================================================================
@implementation GSWImageButton (GSWImageButtonA)

View file

@ -174,6 +174,8 @@ Bindings
(void*)self];
};
@end
//====================================================================
/*

View file

@ -136,6 +136,8 @@ RCS_ID("$Id$")
(void*)self];
};
@end
//====================================================================
@implementation GSWRepetition (GSWRepetitionA)
@ -204,10 +206,15 @@ RCS_ID("$Id$")
[tmpStopIndexValue class]);
*stopIndexValuePtr=[tmpStopIndexValue intValue];
NSDebugMLLog(@"gswdync",@"*stopIndexValuePtr=%d",(*stopIndexValuePtr));
if ((*countValuePtr)>((*stopIndexValuePtr)+1))
*countValuePtr=(*stopIndexValuePtr)+1;
if (_count) // if not count, just take start and stop index
{
if ((*countValuePtr)>((*stopIndexValuePtr)+1))
*countValuePtr=(*stopIndexValuePtr)+1;
else
*stopIndexValuePtr=(*countValuePtr)-1;
}
else
*stopIndexValuePtr=(*countValuePtr)-1;
*countValuePtr=(*stopIndexValuePtr)+1;
NSDebugMLLog(@"gswdync",@"*stopIndexValuePtr=%d",(*stopIndexValuePtr));
NSDebugMLLog(@"gswdync",@"*countValuePtr=%d",(*countValuePtr));
}

View file

@ -34,6 +34,29 @@
//====================================================================
/** A class to handle value and quality like for Accept-Language or
Accept-Encoding
Cf RFC 2616 (http://www.rfc-editor.org/rfc/rfc2616.txt)
**/
@interface GSWValueQualityHeaderPart : NSObject
{
NSString* _value;
float _quality;
}
+(NSArray*)valuesFromHeaderString:(NSString*)string;
+(GSWValueQualityHeaderPart*)valueQualityHeaderPartWithString:(NSString*)string;
+(GSWValueQualityHeaderPart*)valueQualityHeaderPartWithValue:(NSString*)value
qualityString:(NSString*)qualityString;
-(id)initWithString:(NSString*)string;
-(id)initWithValue:(NSString*)value
qualityString:(NSString*)qualityString;
-(NSString*)value;
-(float)quality;
-(int)compareOnQualityDesc:(GSWValueQualityHeaderPart*)qv;
@end
//====================================================================
/** HTTP request class **/
@interface GSWRequest : NSObject <NSCopying>
{
@private
@ -52,6 +75,7 @@
NSString* _applicationURLPrefix;
NSArray* _requestHandlerPathArray;
NSArray* _browserLanguages;
NSArray* _browserAcceptedEncodings;
int _requestType;
BOOL _isUsingWebServer;
BOOL _formValueEncodingDetectionEnabled;
@ -79,6 +103,7 @@
-(NSString*)httpVersion;
-(NSString*)method;
-(NSArray*)browserLanguages;
-(NSArray*)browserAcceptedEncodings;
-(NSArray*)requestHandlerPathArray;
-(NSString*)uri;
-(NSString*)urlProtocol;//NDFN

View file

@ -35,6 +35,155 @@ RCS_ID("$Id$")
#include "GSWeb.h"
#include <Foundation/GSMime.h>
//====================================================================
@implementation GSWValueQualityHeaderPart
/** Returns an array of values ordered by quality descending **/
+(NSArray*)valuesFromHeaderString:(NSString*)string
{
NSArray* values=nil;
NSArray* valuesAndQualities=nil;
int count=0;
LOGObjectFnStart();
valuesAndQualities=[string componentsSeparatedByString:@","];
count=[valuesAndQualities count];
NSDebugMLog(@"string=%@",string);
if (count>0)
{
int i=0;
NSMutableArray* qvs=[NSMutableArray array];
for(i=0;i<count;i++)
{
NSString* string=[valuesAndQualities objectAtIndex:i];
GSWValueQualityHeaderPart* qv=[GSWValueQualityHeaderPart
valueQualityHeaderPartWithString:string];
NSDebugMLog(@"string=%@",string);
NSDebugMLog(@"qv=%@",qv);
if ([[qv value]length]>0)
[qvs addObject:qv];
};
count=[qvs count];
if (count>0)
{
//Sor oon quality desc
[qvs sortUsingSelector:@selector(compareOnQualityDesc:)];
//Remove Duplicates
int i=0;
for(i=0;i<count;i++)
{
int j=0;
NSString* value=[[qvs objectAtIndex:i] value];
for(j=i+1;j<count;j++)
{
NSString* value2=[[qvs objectAtIndex:j] value];
if ([value2 isEqual:value])
{
[qvs removeObjectAtIndex:j];
count--;
};
};
};
//Finally keep only values
values=[qvs valueForKey:@"value"];
};
};
NSDebugMLog(@"values=%@",values);
LOGObjectFnStop();
return values;
};
+(GSWValueQualityHeaderPart*)valueQualityHeaderPartWithString:(NSString*)string
{
return [[[self alloc]initWithString:string]autorelease];
};
+(GSWValueQualityHeaderPart*)valueQualityHeaderPartWithValue:(NSString*)value
qualityString:(NSString*)qualityString
{
return [[[self alloc]initWithValue:value
qualityString:qualityString]autorelease];
};
-(id)initWithString:(NSString*)string
{
NSString* value=nil;
NSString* qualityString=nil;
string=[string stringByTrimmingSpaces];
NSRange qualitySeparatorRange=[string rangeOfString:@";q="];
if (qualitySeparatorRange.length>0)
{
if (qualitySeparatorRange.location==0)
{
LOGError(@"value/quality string: '%@'",string);
}
else
{
value=[string substringToIndex:qualitySeparatorRange.location];
if (qualitySeparatorRange.location
+qualitySeparatorRange.length<[string length])
qualityString=[string substringFromIndex:qualitySeparatorRange.location
+qualitySeparatorRange.length];
};
}
else
value=string;
return [self initWithValue:value
qualityString:qualityString];
};
-(id)initWithValue:(NSString*)value
qualityString:(NSString*)qualityString
{
if ((self=[self init]))
{
ASSIGN(_value,value);
qualityString=[qualityString stringByTrimmingSpaces];
if ([qualityString length]>0)
_quality=[qualityString floatValue];
else
_quality=1;
};
return self;
};
-(void)dealloc
{
DESTROY(_value);
[super dealloc];
};
-(NSString*)description
{
return [NSString stringWithFormat: @"<%s %p : %@: %.1f>",
object_get_class_name(self),
(void*)self,
_value,
_quality];
}
-(NSString*)value
{
return _value;
};
-(float)quality
{
return _quality;
};
-(int)compareOnQualityDesc:(GSWValueQualityHeaderPart*)qv
{
float quality=[self quality];
float qvQuality=[qv quality];
if (quality>qvQuality)
return NSOrderedAscending;
else if (quality<qvQuality)
return NSOrderedDescending;
else
return NSOrderedSame;
};
@end
//====================================================================
@implementation GSWRequest
@ -56,7 +205,6 @@ RCS_ID("$Id$")
NSDebugMLLog(@"requests",@"method=%@",_method);
ASSIGNCOPY(_httpVersion,aVersion);
ASSIGNCOPY(_headers,headers);
//NSLog(@"HEADERS=%@",_headers);
_defaultFormValueEncoding=NSISOLatin1StringEncoding;
_formValueEncoding=NSISOLatin1StringEncoding;
[self _initCookieDictionary];//NDFN
@ -116,6 +264,8 @@ RCS_ID("$Id$")
DESTROY(_requestHandlerPathArray);
NSDebugFLog0(@"Release GSWRequest browserLanguages");
DESTROY(_browserLanguages);
NSDebugFLog0(@"Release GSWRequest browserAcceptedEncodings");
DESTROY(_browserAcceptedEncodings);
NSDebugFLog0(@"Release GSWRequest super");
[super dealloc];
};
@ -140,6 +290,7 @@ RCS_ID("$Id$")
ASSIGNCOPY(clone->_applicationURLPrefix,_applicationURLPrefix);
ASSIGNCOPY(clone->_requestHandlerPathArray,_requestHandlerPathArray);
ASSIGNCOPY(clone->_browserLanguages,_browserLanguages);
ASSIGNCOPY(clone->_browserAcceptedEncodings,_browserAcceptedEncodings);
clone->_requestType=_requestType;
clone->_isUsingWebServer=_isUsingWebServer;
clone->_formValueEncodingDetectionEnabled=_formValueEncodingDetectionEnabled;
@ -314,34 +465,11 @@ RCS_ID("$Id$")
NSDebugMLLog(@"requests",@"lang header:%@",header);
if (header)
{
NSArray* languages=[header componentsSeparatedByString:@","];
NSArray* languages=[GSWValueQualityHeaderPart valuesFromHeaderString:header];
if (!languages)
{
LOGError0(@"No languages");
};
/*
// NSDebugMLLog(@"requests",@"languages:%@",languages);
if ([languages count]>0)
{
int i=0;
NSString* fromLanguage=nil;
NSString* toLanguage=nil;
browserLanguages=[NSMutableArray array];
for(i=0;i<[languages count];i++)
{
fromLanguage=[[languages objectAtIndex:i] lowercaseString];
// NSDebugMLLog(@"requests",@"fromLanguage:%@",fromLanguage);
toLanguage=[globalLanguages objectForKey:fromLanguage];
// NSDebugMLLog(@"requests",@"toLanguage:%@",toLanguage);
[browserLanguages addObject:toLanguage];
};
};
};
if (browserLanguages)
browserLanguages=[NSArray arrayWithArray:browserLanguages];
else
browserLanguages=[[NSArray new]autorelease];
*/
browserLanguages=(NSMutableArray*)[GSWResourceManager GSLanguagesFromISOLanguages:languages];
NSDebugMLLog(@"requests",@"browserLanguages:%@",browserLanguages);
if (browserLanguages)
@ -379,6 +507,28 @@ RCS_ID("$Id$")
return _browserLanguages;
};
//--------------------------------------------------------------------
-(NSArray*)browserAcceptedEncodings
{
//OK
LOGObjectFnStart();
if (!_browserAcceptedEncodings)
{
NSString* header=[self headerForKey:GSWHTTPHeader_AcceptEncoding];
NSDebugMLLog(@"requests",@"accept encoding header:%@",header);
if (header)
{
NSArray* values=[GSWValueQualityHeaderPart valuesFromHeaderString:header];
if (!values)
values=[NSArray array];
ASSIGN(_browserAcceptedEncodings,values);
};
NSDebugMLLog(@"requests",@"browserAcceptedEncodings:%@",_browserAcceptedEncodings);
};
LOGObjectFnStop();
return _browserAcceptedEncodings;
};
//--------------------------------------------------------------------
-(NSArray*)requestHandlerPathArray
{

View file

@ -1,8 +1,8 @@
/* GSWResourceManager.h - GSWeb: Class GSWResourceManager
Copyright (C) 1999-2002 Free Software Foundation, Inc.
Copyright (C) 1999-2003 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Jan 1999
Date: Jan 1999
This file is part of the GNUstep Web Library.
@ -49,8 +49,6 @@ extern NSDictionary* globalMime;
BOOL _applicationRequiresJavaVirtualMachine;
};
-(void)dealloc;
-(id)init;
-(NSString*)description;
-(void)_initFrameworkProjectBundles;
@ -140,7 +138,7 @@ extern NSDictionary* globalMime;
-(void)flushDataCache;
-(void)setURLValuedElementData:(GSWURLValuedElementData*)data_;
-(void)setURLValuedElementData:(GSWURLValuedElementData*)data;
-(void)setData:(NSData*)data
forKey:(NSString*)key

View file

@ -47,6 +47,7 @@
NSMutableArray* _contentFaults;
NSMutableData* _contentData;
NSStringEncoding _contentEncoding;
NSArray* _acceptedEncodings;
NSDictionary* _userInfo;
NSMutableArray* _cookies;
BOOL _isClientCachingDisabled;
@ -64,6 +65,7 @@
-(NSArray*)headerKeys;
-(NSArray*)headersForKey:(NSString*)key;
-(NSString*)httpVersion;
-(NSArray*)acceptedEncodings;
-(void)setContent:(NSData*)someData;
-(void)setHeader:(NSString*)header
forKey:(NSString*)key;
@ -74,6 +76,7 @@
-(void)setHTTPVersion:(NSString*)version;
-(void)setStatus:(unsigned int)status;
-(void)setUserInfo:(NSDictionary*)userInfo;
-(void)setAcceptedEncodings:(NSArray*)acceptedEncodings;
-(unsigned int)status;
-(NSDictionary*)userInfo;
-(NSString*)description;

View file

@ -33,6 +33,7 @@
RCS_ID("$Id$")
#include "GSWeb.h"
#include "NSData+Compress.h"
//====================================================================
@implementation GSWResponse
@ -91,6 +92,7 @@ static NSArray* cacheControlHeaderValues=nil;
DESTROY(_contentFaults);
// NSDebugFLog0(@"Release Response contentData");
DESTROY(_contentData);
DESTROY(_acceptedEncodings);
// NSDebugFLog0(@"Release Response userInfo");
DESTROY(_userInfo);
//NSDebugFLog0(@"Release Response cookies");
@ -111,6 +113,7 @@ static NSArray* cacheControlHeaderValues=nil;
ASSIGNCOPY(clone->_contentFaults,_contentFaults);
ASSIGNCOPY(clone->_contentData,_contentData);
clone->_contentEncoding=_contentEncoding;
ASSIGNCOPY(clone->_acceptedEncodings,_acceptedEncodings);
ASSIGNCOPY(clone->_userInfo,_userInfo);
ASSIGNCOPY(clone->_cookies,_cookies);
clone->_isClientCachingDisabled=_isClientCachingDisabled;
@ -190,6 +193,12 @@ static NSArray* cacheControlHeaderValues=nil;
return _httpVersion;
};
//--------------------------------------------------------------------
-(NSArray*)acceptedEncodings
{
return _acceptedEncodings;
};
//--------------------------------------------------------------------
// setContent:
@ -279,6 +288,12 @@ static NSArray* cacheControlHeaderValues=nil;
ASSIGN(_httpVersion,version);
};
//--------------------------------------------------------------------
-(void)setAcceptedEncodings:(NSArray*)acceptedEncodings
{
ASSIGN(_acceptedEncodings,acceptedEncodings);
};
//--------------------------------------------------------------------
// setStatus:
@ -669,7 +684,44 @@ static NSArray* cacheControlHeaderValues=nil;
{
LOGError(); //TODO
}; */
dataLength=[_contentData length];
#ifdef HAVE_ZLIB
// Now we see if we can gzip the content
if (dataLength>1024) // min length: 1024
{
// we could do better by having parameters for types
NSString* contentType=[self headerForKey:@"content-type"];
if ([contentType isEqualTo:@"text/html"])
{
NSString* contentEncoding=[self headerForKey:@"content-encoding"];
// we could do better by handling compress,...
if ([contentEncoding length]==0 // Not already encoded
&& [_acceptedEncodings containsObject:@"gzip"])
{
NSDate* compressStartDate=[NSDate date];
NSData* compressedData=[_contentData deflate];
NSDebugMLog(@"compressedData=%@",compressedData);
if (compressedData)
{
#ifdef DEBUG
NSDate* compressStopDate=[NSDate date];
NSString* sizeInfoHeader=[NSString stringWithFormat:@"deflate from %d to %d in %0.3f s",
dataLength,
[compressedData length],
[compressStopDate timeIntervalSinceDate:compressStartDate]];
[self setHeader:sizeInfoHeader
forKey:@"deflate-info"];
#endif
ASSIGN(_contentData,compressedData);
dataLength=[_contentData length];
[self setHeader:@"gzip"
forKey:@"content-encoding"];
};
};
};
};
#endif
dataLengthString=[NSString stringWithFormat:@"%d",
dataLength];
[self setHeader:dataLengthString

View file

@ -0,0 +1,42 @@
/** NSData+Compress.h - <title>GSWeb: NSData / zlib</title>
Copyright (C) 2003 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: May 2003
$Revision$
$Date$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
// $Id$
#ifndef _NSData_Compress_h__
#define _NSData_Compress_h__
#ifdef HAVE_ZLIB
//====================================================================
@interface NSData (GSWZLib)
-(NSData*)deflate;
@end
#endif
#endif //_NSData_Compress_h__

View file

@ -0,0 +1,169 @@
/** NSData+Compress.m - <title>GSWeb: NSData / zlib</title>
Copyright (C) 2003 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: May 2003
$Revision$
$Date$
$Id$
This file is part of the GNUstep Web Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
</license>
**/
#include "config.h"
RCS_ID("$Id$")
#include "GSWeb.h"
#ifdef HAVE_ZLIB
#include <zlib.h>
void GZPutLong(void* ptr,uLong value)
{
int n;
for (n = 0; n < 4; n++)
{
((unsigned char*)ptr)[n]=(value & 0xff);
value >>= 8;
}
};
static char gzMagic[2]= {0x1f, 0x8b}; // gzip magic header
static int gzHeaderSize=10;
//====================================================================
@implementation NSData (GSWZLib)
-(NSData*)deflate
{
NSMutableData* outData=nil;
z_stream c_stream; // compression stream
int err=Z_OK;
unsigned int selfLength=[self length];
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit2(&c_stream,
Z_BEST_COMPRESSION,
Z_DEFLATED,
-15,
9,
Z_DEFAULT_STRATEGY);
if (err!=Z_OK)
{
LOGError(@"deflateInit2 error: %d",err);
}
else
{
const void* inBytes=[self bytes];
NSMutableData* outTempData=[NSMutableData dataWithCapacity:max(1024,selfLength/10)];
void* outTempBytes=[outTempData bytes];
void* outBytes=NULL;
uLong crc = crc32(0L, Z_NULL, 0);
unsigned flushedData=0;
crc = crc32(crc,inBytes,selfLength);//calculate crc
outData=[NSMutableData dataWithCapacity:gzHeaderSize];
// gzip nead header !
[outData setLength:gzHeaderSize];
outBytes=[outData bytes];
((unsigned char*)outBytes)[0]=gzMagic[0];
((unsigned char*)outBytes)[1]=gzMagic[1];
((unsigned char*)outBytes)[2]=Z_DEFLATED;
((unsigned char*)outBytes)[3]=0; //flags
((unsigned char*)outBytes)[4]=0; //time
((unsigned char*)outBytes)[5]=0;//time
((unsigned char*)outBytes)[6]=0;//time
((unsigned char*)outBytes)[7]=0;//time
((unsigned char*)outBytes)[8]=2;//binary
((unsigned char*)outBytes)[9]=0x3;//OS
c_stream.next_in = inBytes;
c_stream.avail_in = (uInt)selfLength;
[outTempData setLength:[outTempData capacity]];
c_stream.next_out = outTempBytes;
c_stream.avail_out = (uInt)[outTempData capacity];
do
{
err = deflate(&c_stream, Z_NO_FLUSH);
if (err!=Z_OK)
{
LOGError(@"deflate error: %d",err);
}
else
{
if (c_stream.avail_out==0)
{
[outData appendData:outTempData];
flushedData+=[outTempData length];
c_stream.next_out = outTempBytes;
c_stream.avail_out = (uInt)[outTempData capacity];
[outTempData setLength:[outTempData capacity]];
};
};
}
while (c_stream.avail_in>0 && err==Z_OK);
if (err==Z_OK)
{
do
{
err = deflate(&c_stream, Z_FINISH);
if (err==Z_STREAM_END || err==Z_OK)
{
[outTempData setLength:c_stream.total_out-flushedData];
[outData appendData:outTempData];
flushedData+=[outTempData length];
c_stream.next_out = outTempBytes;
c_stream.avail_out = (uInt)[outTempData capacity];
[outTempData setLength:[outTempData capacity]];
}
else
{
LOGError(@"deflate error: %d",err);
};
} while (err == Z_OK);
};
if (err==Z_STREAM_END || err==Z_OK)
{
[outTempData setLength:8];
GZPutLong(outTempBytes, crc);
GZPutLong(outTempBytes+4, selfLength);
[outData appendData:outTempData];
};
err = deflateEnd(&c_stream);
if (err!=Z_OK)
{
LOGError(@"deflateEnd error: %d",err);
}
};
return outData;
}
@end
#endif

View file

@ -199,6 +199,7 @@ RCS_ID("$Id$")
//NSDebugMLog(@"dataHex %p=%@",dataHex,dataHex);
return dataHex;
};
@end
//====================================================================
@implementation NSString (stringWithObject)

View file

@ -27,6 +27,7 @@
#undef HAVE_LIBWRAP
#undef HAVE_GDL2
#define HAVE_ZLIB 1
#define RCS_ID(name) \
static const char rcsId[] = name; \