* GSWDatabase/WODisplayGroup.m

fix format string and NSArray / NSMutableArray bugs
    * GSWeb/GNUmakefile
    * GSWeb/GSWApplication.h
    * GSWeb/GSWApplication.m
      replace GSWMultiKeyDictionary with GSWDictionary
    * GSWeb/GSWDefaultAdaptor.m
      limit _workerThreadCountMax to 16 for now
    * GSWeb/GSWDeployedBundle.*, GSWResourceManager.*
      replace GSWMultiKeyDictionary with GSWDictionary
    * GSWeb/GSWDictionary
      new class using NSMutableDictionary internally.
    * GSWeb/GSWImageInfo.m
      fix leak
    * GSWeb/GSWRequest.m
      fix leak
    * GSWeb/GSWUtils.m
      fix leak
    * GSWeb/GSWWOCompatibility.h
      remove GSWMultiKeyDictionary
    * GSWeb/GSWWorkerThread.m
      some cleanups but still does not run in MT on FreeBSD.
    * GSWeb/NSString+Trimming.m
      fix leaks
    * Tests/gsweb/GNUmakefile.postamble
    * Tests/gsweb/GNUmakefile.super
    * Tests/gsweb/GSWDictionary/TestInfo
    * Tests/gsweb/GSWDictionary/general.m
      new files
This commit is contained in:
David Wetzel 2017-12-25 00:25:03 -05:00
parent 3d5a52e699
commit a8eccb4273
27 changed files with 526 additions and 2033 deletions

30
ChangeLog Normal file → Executable file
View file

@ -1,3 +1,33 @@
2017-12-25 David Wetzel <dave@turbocat.de>
* GSWDatabase/WODisplayGroup.m
fix format string and NSArray / NSMutableArray bugs
* GSWeb/GNUmakefile
* GSWeb/GSWApplication.h
* GSWeb/GSWApplication.m
replace GSWMultiKeyDictionary with GSWDictionary
* GSWeb/GSWDefaultAdaptor.m
limit _workerThreadCountMax to 16 for now
* GSWeb/GSWDeployedBundle.*, GSWResourceManager.*
replace GSWMultiKeyDictionary with GSWDictionary
* GSWeb/GSWDictionary
new class using NSMutableDictionary internally.
* GSWeb/GSWImageInfo.m
fix leak
* GSWeb/GSWRequest.m
fix leak
* GSWeb/GSWUtils.m
fix leak
* GSWeb/GSWWOCompatibility.h
remove GSWMultiKeyDictionary
* GSWeb/GSWWorkerThread.m
some cleanups but still does not run in MT on FreeBSD.
* GSWeb/NSString+Trimming.m
fix leaks
* Tests/gsweb/GNUmakefile.postamble
* Tests/gsweb/GNUmakefile.super
* Tests/gsweb/GSWDictionary/TestInfo
* Tests/gsweb/GSWDictionary/general.m
new files
2017-12-04 David Wetzel <dave@turbocat.de>
* GSWAdaptors/Apache2/mod_gsw.c
add support for /wo/showapps

View file

@ -70,7 +70,7 @@ static BOOL globalDefaultForValidatesChangesImmediately = NO;
@interface NSArray (Indexes)
-(NSArray*)indexesOfObjectsIdenticalTo:(NSArray*)objects;
-(NSArray*)objectsAtIndexesArray:(NSArray*)indexes;
-(NSMutableArray*)objectsAtIndexesArray:(NSArray*)indexes;
-(BOOL)isEqualByObjectPointer:(NSArray*)otherArray;
@end
@ -1286,7 +1286,7 @@ shouldRedisplayForEditingContextChangeNotification:notification];
if (index>[_displayedObjects count])
{
[[NSException exceptionWithName:NSInvalidArgumentException
reason:[NSString stringWithFormat:@"%@ %@: index %u is beyond the bounds of %d",
reason:[NSString stringWithFormat:@"%@ %@: index %d is beyond the bounds of %lu",
[self class],NSStringFromSelector(_cmd),
index,[_displayedObjects count]]
userInfo:nil] raise];
@ -2088,7 +2088,7 @@ createObjectFailedForDataSource:_dataSource];
- (BOOL)setSelectionIndexes:(NSArray *)selection
{
BOOL retValue=NO;
NSArray* selectedObjects = nil;
NSMutableArray* selectedObjects = nil;
NSArray* sortedSelection = nil;
BOOL isSelectionChanged = NO;
BOOL isSelectedObjectsChanged = NO;
@ -2516,38 +2516,36 @@ createObjectFailedForDataSource:_dataSource];
return indexes;
}
-(NSArray*)objectsAtIndexesArray:(NSArray*)indexes
-(NSMutableArray*)objectsAtIndexesArray:(NSArray*)indexes
{
NSArray* objects=nil;
NSMutableArray* objects=nil;
NSUInteger selfCount=[self count];
if ([self count]>0)
{
NSUInteger indexesCount=[indexes count];
if (indexesCount>0)
{
NSUInteger indexesCount=[indexes count];
if (indexesCount>0)
{
NSMutableArray* tmpObjects=nil;
NSUInteger i=0;
IMP indexes_oaiIMP=NULL;
IMP self_oaiIMP=NULL;
for(i=0;i<indexesCount;i++)
{
id indexObject=GSWeb_objectAtIndexWithImpPtr(indexes,&indexes_oaiIMP,i);
int index=[indexObject intValue];
if (index<selfCount)
{
id object=GSWeb_objectAtIndexWithImpPtr(self,&self_oaiIMP,index);
if (tmpObjects)
[tmpObjects addObject:object];
else
tmpObjects=(NSMutableArray*)[NSMutableArray arrayWithObject:object];
}
}
if (tmpObjects)
objects=[NSArray arrayWithArray:tmpObjects];
}
NSMutableArray* tmpObjects=nil;
NSUInteger i=0;
IMP indexes_oaiIMP=NULL;
IMP self_oaiIMP=NULL;
for(i=0;i<indexesCount;i++)
{
id indexObject=GSWeb_objectAtIndexWithImpPtr(indexes,&indexes_oaiIMP,i);
int index=[indexObject intValue];
if (index<selfCount)
{
id object=GSWeb_objectAtIndexWithImpPtr(self,&self_oaiIMP,index);
if (tmpObjects)
[tmpObjects addObject:object];
else
tmpObjects=(NSMutableArray*)[NSMutableArray arrayWithObject:object];
}
}
}
}
if (!objects)
objects=[NSArray array];
objects=[NSMutableArray array];
return objects;
}

View file

@ -79,6 +79,7 @@ WebObjects_RESOURCE_DIRS = $(GSWeb_RESOURCE_DIRS)
# The Bundle Objective-C source files to be compiled
GSWeb_OBJC_FILES = \
GSWDictionary.m \
GSWDebug.m \
GSWConstants.m \
GSWTemporaryElement.m \
@ -106,7 +107,6 @@ GSWApplication+Defaults.m \
GSWAssociation.m \
GSWComponent.m \
GSWContext.m \
GSWMultiKeyDictionary.m \
GSWDynamicElement.m \
GSWDynamicGroup.m \
GSWElement.m \
@ -211,6 +211,7 @@ WebObjects_OBJC_FILES = $(GSWeb_OBJC_FILES)
# The framework installed header files
GSWeb_HEADER_FILES = \
GSWDictionary.h \
GSWeb.h \
GSWActiveImage.h \
GSWAdaptor.h \
@ -266,7 +267,6 @@ GSWInput.h \
GSWJavaScript.h \
GSWKeyValueAssociation.h \
GSWMailDelivery.h \
GSWMultiKeyDictionary.h \
GSWNestedList.h \
GSWTemporaryElement.h \
GSWBaseParser.h \

View file

@ -68,7 +68,7 @@ GSWEB_EXPORT BOOL WOStrictFlag;
@class GSWResponse;
@class GSWAssociation;
@class GSWComponentDefinition;
@class GSWMultiKeyDictionary;
@class GSWDictionary;
@class GSWActionRequestHandler;
@class GSWAction;
@ -77,7 +77,7 @@ GSWEB_EXPORT BOOL WOStrictFlag;
{
NSArray* _adaptors;
GSWSessionStore* _sessionStore;
GSWMultiKeyDictionary* _componentDefinitionCache;
GSWDictionary* _componentDefinitionCache;
NSTimeInterval _timeOut;
NSDate* _startDate;
NSDate* _lastAccessDate;

View file

@ -252,14 +252,6 @@ int GSWApplicationMain(NSString* applicationClassName,
_globalAutoreleasePool = pool;
}
//--------------------------------------------------------------------
+(id)init
{
id ret=[[self superclass]init];
[GSWAssociation addLogHandlerClasse:[self class]];
return ret;
};
//--------------------------------------------------------------------
// FIXME: do we need to dealloc a CLASS??? looks strange to me -- dw
//+(void)dealloc
@ -280,6 +272,8 @@ int GSWApplicationMain(NSString* applicationClassName,
if ((self=[super init]))
{
[GSWAssociation addLogHandlerClasse:[self class]];
_selfLock=[NSRecursiveLock new];
_globalLock=[NSRecursiveLock new];
@ -323,7 +317,7 @@ int GSWApplicationMain(NSString* applicationClassName,
//call adaptorsDispatchRequestsConcurrently
_activeSessionsCountLock=[NSLock new];
_componentDefinitionCache=[GSWMultiKeyDictionary new];
_componentDefinitionCache=[[GSWDictionary alloc] init];
[self setResourceManager:[self createResourceManager]];
[self setStatisticsStore:[self createStatisticsStore]];
@ -826,7 +820,7 @@ int GSWApplicationMain(NSString* applicationClassName,
NSString* language=nil;
int iLanguage=0;
int languagesCount=0;
languagesCount=[languages count];
for(iLanguage=0;iLanguage<languagesCount && !componentDefinition;iLanguage++)

View file

@ -103,6 +103,9 @@ static GSWResponse * static_lastDitchErrorResponse = nil;
_isMultiThreadEnabled=[[arguments objectForKey:GSWOPT_MultiThreadEnabled] boolValue];
ASSIGN(_adaptorHost,[arguments objectForKey:GSWOPT_AdaptorHost[GSWebNamingConv]]);
// for now...
_workerThreadCountMax = 16;
if ((_workerThreadCountMax <1) || (_isMultiThreadEnabled == NO)) {
_workerThreadCountMax = 1;
_isMultiThreadEnabled = NO;

View file

@ -42,7 +42,7 @@
NSString* _wrapperName;
NSString* _projectName;
BOOL _isFramework;
GSWMultiKeyDictionary* _relativePathsCache;
GSWDictionary* _relativePathsCache;
NSMutableDictionary* _absolutePathsCache;
NSMutableDictionary* _urlsCache;
NSRecursiveLock* _selfLock;

View file

@ -34,6 +34,7 @@
#include "GSWeb.h"
#include <GNUstepBase/NSThread+GNUstepBase.h>
#include <GNUstepBase/NSObject+GNUstepBase.h>
#include "GSWPrivate.h"
//====================================================================
@ -50,7 +51,7 @@
_isFramework=[_bundlePath hasSuffix:GSFrameworkSuffix];//Ok ?
_relativePathsCache=[GSWMultiKeyDictionary new];
_relativePathsCache=[GSWDictionary new];
_absolutePathsCache=[NSMutableDictionary new];
_urlsCache=[NSMutableDictionary new];
#ifndef NDEBUG

52
GSWeb/GSWDictionary.h Executable file
View file

@ -0,0 +1,52 @@
/** GSWDictionary.h
Copyright (C) 2007 Free Software Foundation, Inc.
Written by: David Wetzel <dave@turbocat.de>
Date: 20-Dec-2017
This file is part of the GNUstep Web Library.
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.
**/
#ifndef _GSWebDICTIONARY_h__
#define _GSWebDICTIONARY_h__
@interface GSWDictionary : NSObject
{
}
+ (instancetype)dictionary;
- (NSUInteger) count;
-(id)objectForKeys:(NSString*)keys,...;
-(id)objectForKeyArray:(NSArray *)keys;
-(void)setObject:(id)object
forKeys:(id)keys,...;
-(void)setObject:(id)object
forKeyArray:(NSArray *)keys;
- (void)removeObjectForKeyArray:(NSArray *)keys;
- (void)removeObjectForKeys:(NSString*)keys,...;
@end
#endif // _GSWebDICTIONARY_h__

181
GSWeb/GSWDictionary.m Executable file
View file

@ -0,0 +1,181 @@
/** GSWDictionary.m
Copyright (C) 2007 Free Software Foundation, Inc.
Written by: David Wetzel <dave@turbocat.de>
Date: 20-Dec-2017
This file is part of the GNUstep Web Library.
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.
**/
#include <Foundation/Foundation.h>
#include "GSWDictionary.h"
#define GLUESTRING @"🎃"
@interface GSWDictionary()
@property (strong, nonatomic) NSMutableDictionary *storageDict;
@end
@implementation GSWDictionary
+ (instancetype) dictionary
{
return AUTORELEASE([[self alloc] init]);
}
- (instancetype) init
{
self = [super init];
[self setStorageDict:[NSMutableDictionary dictionary]];
return self;
}
- (NSUInteger) count
{
return [_storageDict count];
}
- (NSString*) combindedKeyWithKeys:(NSString**) keys
count:(unsigned)count
{
unsigned i = 0;
NSMutableString * returnStr = [NSMutableString string];
for (; i < count; i++) {
[returnStr appendString:keys[i]];
if (i< count -1) {
[returnStr appendString:GLUESTRING];
}
}
return returnStr;
}
- (NSString*) combindedKeyWithKeys:(NSArray*) keys
{
return [keys componentsJoinedByString:GLUESTRING];
}
-(id) objectForKeys:(id*)keys
count:(unsigned)count
{
id object=nil;
if (count == 0) {
return nil;
}
object = [_storageDict objectForKey:[self combindedKeyWithKeys:keys
count:count]];
return object;
}
-(id)objectForKeys:(id)keys,...;
{
id object;
GS_USEIDLIST(keys,object = [self objectForKeys:__objects
count: __count]);
return object;
}
-(id)objectForKeyArray:(NSArray*)keys
{
id returnObj = nil;
unsigned count = [keys count];
if (count == 0) {
return nil;
}
NSRange range = NSMakeRange(0, count);
id * myKeys = malloc(sizeof(id) * range.length);
[keys getObjects:myKeys range:range];
returnObj = [self objectForKeys:myKeys
count:count];
free(myKeys);
return returnObj;
}
-(void)setObject:(id)object
forKeys:(id)keys,...
{
NSString * myKey;
GS_USEIDLIST(keys,myKey = [self combindedKeyWithKeys:__objects
count: __count]);
[_storageDict setObject:object
forKey:myKey];
}
-(void)setObject:(id)object
forKeyArray:(NSArray*)keys
{
unsigned count = [keys count];
NSString * myKey;
if ((!object) || (!keys) || (count < 1)) {
[NSException raise:NSInvalidArgumentException
format:@"%s:need object and keys",__PRETTY_FUNCTION__];
}
NSRange range = NSMakeRange(0, count);
id * myKeys = malloc(sizeof(id) * range.length);
[keys getObjects:myKeys range:range];
myKey = [self combindedKeyWithKeys:myKeys
count:count];
free(myKeys);
[_storageDict setObject:object
forKey:myKey];
}
- (void)removeObjectForKeyArray:(NSArray*)keys
{
unsigned count = [keys count];
if ((!keys) || (count < 1)) {
return;
}
NSString * myKey;
NSRange range = NSMakeRange(0, count);
id * myKeys = malloc(sizeof(id) * range.length);
[keys getObjects:myKeys range:range];
myKey = [self combindedKeyWithKeys:myKeys
count:count];
free(myKeys);
[_storageDict removeObjectForKey:myKey];
}
- (void)removeObjectForKeys:(NSString*)keys,...
{
NSString * myKey;
GS_USEIDLIST(keys,myKey = [self combindedKeyWithKeys:__objects
count: __count]);
[_storageDict removeObjectForKey:myKey];
}
@end

View file

@ -73,7 +73,7 @@ static NSDictionary *extensionClassDict = nil;
{
NSString *extension = [filename pathExtension];
Class cls = [self subclassForExtension: extension];
return [[cls alloc] initWithContentsOfFile: filename];
return [[[cls alloc] initWithContentsOfFile: filename] autorelease];
}
+ (NSArray *)supportedExtensions
{

View file

@ -1,123 +0,0 @@
/** GSWMultiKeyDictionary.h - <title>GSWeb: Class GSWMultiKeyDictionary</title>
Copyright (C) 1999-2004 Free Software Foundation, Inc.
Written by: Manuel Guesdon <mguesdon@orange-concept.com>
Date: Mar 1999
$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 _GSWMultiKeyDictionary_h__
#define _GSWMultiKeyDictionary_h__
//==============================================================================
@interface GSWMultiKeyDictionary : NSObject
{
void* _mapBase;
};
+(id)dictionary;
-(id)initWithCapacity:(NSUInteger)capacity;
-(void)setObject:(id)object
forKeys:(id)keys,...;
-(void)setObject:(id)object
forKeysArray:(NSArray*)keys;
-(void)setObject:(id)object
forKeys:(id*)keys
count:(unsigned)count;
-(id)objectForKeys:(id)keys,...;
-(id)objectForKeysArray:(NSArray*)keys;
-(id)objectForKeys:(id*)keys
count:(unsigned)count;
-(void)removeAllObjects;
-(void)removeObjectForKeys:(id)keys,...;
-(void)removeObjectForKeysArray:(NSArray*)keys;
-(void)removeObjectForKeys:(id*)keys
count:(unsigned)count;
-(void)removeAllSubObjectsForKeys:(id)key,...;
-(void)removeAllSubObjectsForKeys:(id*)keys
count:(unsigned)count;
-(void)removeAllSubObjectsForKeysArray:(NSArray*)keysArray;
-(void)makeObjectsPerformSelector:(SEL)selector;
-(void)makeObjectsPerformSelector:(SEL)selector
withObject:(id)object;
-(void)makeObjectsPerformSelector:(SEL)selector
withObject:(id)object1
withObject:(id)object2;
-(NSEnumerator*)objectEnumerator;
-(NSArray*)allValues;
-(NSArray*)allSubValuesForKeys:(id)keys,...;
-(NSArray*)allSubValuesForKeysArray:(NSArray*)keys;
-(NSArray*)allSubValuesForKeys:(id*)keys
count:(unsigned)count;
@end
#define GSWCacheFlags_expiresOnFirstAccess 0x00000001
@interface GSWCache : GSWMultiKeyDictionary
{
NSTimeInterval _defaultDuration;
unsigned int _defaultFlags;
}
+(GSWCache*)cacheWithDefaultDuration:(NSTimeInterval)defaultDuration
defaultFlags:(unsigned int)defaultFlags;
+(GSWCache*)cache;
-(id)initWithDefaultDuration:(NSTimeInterval)defaultDuration
defaultFlags:(unsigned int)defaultFlags;
-(void)deleteExpiredEntries;
-(void)setObject:(id)object
withDuration:(NSTimeInterval)duration
forKey:(id)key;
-(void)setObject:(id)object
withDuration:(NSTimeInterval)duration
forKeys:(id)key,...;
-(void)setObject:(id)object
withDuration:(NSTimeInterval)duration
forKeys:(id*)keys
count:(unsigned)count;
@end
#endif // _GSWMultiKeyDictionary_h__

File diff suppressed because it is too large Load diff

3
GSWeb/GSWPrivate.h Normal file → Executable file
View file

@ -27,8 +27,6 @@
</license>
**/
// $Id$
/*
* Private declarations of private methods in GSWeb.
@ -43,6 +41,7 @@
#ifndef _GSWPrivate_h__
#define _GSWPrivate_h__
#include "GSWDictionary.h"
#include "GSWComponentDefinition.h"
#include "GSWComponent.h"
#include "GSWApplication.h"

View file

@ -1802,23 +1802,24 @@ static NSString * __AJAX_FORM_SUBMIT_KEY = @"AJAX_SUBMIT_BUTTON_NAME";
[(NSMutableArray*)parts replaceObjectAtIndex:i
withObject:tmpData];
};
for(i=0;i<partsCount;i++)
{
tmpData=GSWeb_objectAtIndexWithImpPtr(parts,&oaiIMP,i);
if ([tmpData length]<400)
{
NSString* dataString=nil;
dataString=[[[NSString alloc]initWithData:tmpData
encoding:[self formValueEncoding]]autorelease];
}
else
{
};
};
return parts;
#warning checkme -- dw
// for(i=0;i<partsCount;i++)
// {
// tmpData=GSWeb_objectAtIndexWithImpPtr(parts,&oaiIMP,i);
// if ([tmpData length]<400)
// {
// NSString* dataString=nil;
// dataString=[[[NSString alloc]initWithData:tmpData
// encoding:[self formValueEncoding]]autorelease];
//
// }
// else
// {
// };
// };
return [parts autorelease];
};
//--------------------------------------------------------------------

View file

@ -43,7 +43,7 @@ GSWEB_EXPORT NSDictionary* globalMime;
NSMutableDictionary* _appURLs;
NSMutableDictionary* _frameworkURLs;
NSMutableDictionary* _appPaths;
GSWMultiKeyDictionary* _frameworkPaths;
GSWDictionary* _frameworkPaths;
NSMutableDictionary* _urlValuedElementsData;
NSMutableDictionary* _stringsTablesByFrameworkByLanguageByName;//NDFN
NSMutableDictionary* _stringsTableArraysByFrameworkByLanguageByName;//NDFN

View file

@ -34,6 +34,7 @@
#include "GSWeb.h"
#include <GNUstepBase/NSObject+GNUstepBase.h>
#include <GNUstepBase/NSString+GNUstepBase.h>
#include "GSWPrivate.h"
static NSString * NONESTR = @"NONE";
static NSString * localNotFoundMarker=@"NOTFOUND";
@ -170,7 +171,7 @@ NSMutableDictionary *globalURLCache = nil;
_appURLs=[NSMutableDictionary new];
_frameworkURLs=[NSMutableDictionary new];
_appPaths=[NSMutableDictionary new];
_frameworkPaths=[GSWMultiKeyDictionary new];
_frameworkPaths=[GSWDictionary new];
_urlValuedElementsData=[NSMutableDictionary new];
_stringsTablesByFrameworkByLanguageByName=[NSMutableDictionary new];
_stringsTableArraysByFrameworkByLanguageByName=[NSMutableDictionary new];

View file

@ -1630,7 +1630,7 @@ NSString* GSWGetDefaultDocRoot()
{
NSMutableData* tmpdata=[self mutableCopy];
[tmpdata deleteFirstBytesCount:bytesCount];
return [NSData dataWithData:tmpdata];
return [NSData dataWithData:[tmpdata autorelease]];
};
//--------------------------------------------------------------------
@ -1638,7 +1638,7 @@ NSString* GSWGetDefaultDocRoot()
{
NSMutableData* tmpdata=[self mutableCopy];
[tmpdata deleteLastBytesCount:bytesCount];
return [NSData dataWithData:tmpdata];
return [NSData dataWithData:[tmpdata autorelease]];
};
@end

2
GSWeb/GSWWOCompatibility.h Normal file → Executable file
View file

@ -64,7 +64,6 @@
/* private */
#define GSWComponentDefinition WOComponentDefinition
#define GSWBundle WOBundle
#define GSWMultiKeyDictionary WOMultiKeyDictionary
#define GSWElementID WOElementIDString
#define GSWAjaxRequestHandler WOAjaxRequestHandler
#define GSWComponentRequestHandler WOComponentRequestHandler
@ -82,7 +81,6 @@
#define GSWDeployedBundle WODeployedBundle
#define GSWProjectBundle WOProjectBundle
#define GSWSessionTimeOut WOSessionTimeOut
#define GSWMultiKeyDictionary WOMultiKeyDictionary
#define GSWTemplateParser WOTemplateParser
#define GSWDynamicURLString WODynamicURLString
#define GSWBindingNameAssociation WOBindingNameAssociation

View file

@ -66,32 +66,15 @@ static NSString *REQUEST_ID = @"x-webobjects-request-id";
}
}
/**
* drain all vars that have been created in the thread.
*/
-(void)drain
{
DESTROY(_pool);
}
-(void)dealloc
{
// TODO: add vars!
DESTROY(_t);
DESTROY(_serverSocket);
DESTROY(_currentSocket);
// NSThread * _t;
_app = nil;
_mtAdaptor = nil;
// we are NOT draining our _pool here we do it before the thread is gone.
// otherwise, we get nice
// *** attempt to pop an unknown autorelease pool
// messages -- dw
[super dealloc];
[super dealloc];
}
@ -99,39 +82,42 @@ static NSString *REQUEST_ID = @"x-webobjects-request-id";
adaptor:(GSWAdaptor*)adaptor
stream:(NSFileHandle*)stream
{
if ((self = [self init])) {
_app = application;
_mtAdaptor = (GSWDefaultAdaptor*)adaptor;
ASSIGN(_serverSocket,stream);
_keepAlive=NO;
_maxSocketIdleTime=900; // 300 ms
_isMultiThreadEnabled = [adaptor isMultiThreadEnabled];
if (_isMultiThreadEnabled) {
_t = [[NSThread alloc] initWithTarget:self
selector:@selector(runOnce)
object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector:@selector(threadWillExit:)
name:NSThreadWillExitNotification
object: _t];
_runFlag = YES;
[_t start];
} else {
_runFlag = YES;
[self runOnce];
if ((self = [self init])) {
_app = application;
_mtAdaptor = (GSWDefaultAdaptor*)adaptor;
ASSIGN(_serverSocket,stream);
_keepAlive=NO;
_maxSocketIdleTime=900; // 300 ms
_isMultiThreadEnabled = [adaptor isMultiThreadEnabled];
if (_isMultiThreadEnabled) {
_t = [[NSThread alloc] initWithTarget:self
selector:@selector(runOnce)
object:nil];
[[NSNotificationCenter defaultCenter] addObserver: self
selector:@selector(threadWillExit:)
name:NSThreadWillExitNotification
object: _t];
_runFlag = YES;
[_t start];
[_t autorelease];
} else {
_runFlag = YES;
_pool = [[NSAutoreleasePool alloc] init];
[self runOnce];
DESTROY(_pool);
}
}
}
return self;
return self;
}
- (void)threadWillExit:(NSNotification*)notification
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
[_mtAdaptor workerThreadWillExit:self];
[_mtAdaptor workerThreadWillExit:self];
_mtAdaptor = nil;
[[NSNotificationCenter defaultCenter] removeObserver: self];
}
//PRIVATE!
@ -146,76 +132,68 @@ static NSString *REQUEST_ID = @"x-webobjects-request-id";
-(void)runOnce
{
GSWRequest *request = nil;
struct timeval timeout;
GSWResponse *response;
if ((!_runFlag) || (_serverSocket == nil)) {
return;
}
_pool = [[NSAutoreleasePool alloc] init];
_errorOnRead = NO;
// _maxSocketIdleTime is milisecs!
timeout.tv_sec = 0;
timeout.tv_usec = _maxSocketIdleTime * 1000;
NS_DURING {
setsockopt([_serverSocket fileDescriptor], SOL_SOCKET, SO_RCVTIMEO, &timeout,sizeof(timeout));
GSWRequest *request = nil;
struct timeval timeout;
GSWResponse *response;
request = [GSWHTTPIO readRequestFromFromHandle: _serverSocket];
} NS_HANDLER {
_errorOnRead = YES;
NSLog(@"%s -- dropping connection reason: %@",__PRETTY_FUNCTION__, [localException reason]);
} NS_ENDHANDLER;
// "womp" is the request handler key used by the WOTaskD contacing your app
if ((_errorOnRead || (request == nil)) ||
((([[_app class] isDirectConnectEnabled] == NO) && ([request isUsingWebServer] == NO)) &&
([@"womp" isEqual:[request requestHandlerKey]] == NO))) {
goto done;
}
_processingRequest = YES;
_dispatchError = NO;
NS_DURING {
response = [_app dispatchRequest:request];
} NS_HANDLER {
NSLog(@"%s -- Exception occurred while responding to client: %@",
__PRETTY_FUNCTION__, [localException description]);
_dispatchError = YES;
response = [GSWDefaultAdaptor _lastDitchErrorResponse];
} NS_ENDHANDLER;
if (response) {
NSString * reqid = [request headerForKey:REQUEST_ID];
if (reqid) {
[response setHeader:reqid forKey:REQUEST_ID];
if ((!_runFlag) || (_serverSocket == nil)) {
return;
}
_errorOnRead = NO;
// _maxSocketIdleTime is milisecs!
timeout.tv_sec = 0;
timeout.tv_usec = _maxSocketIdleTime * 1000;
NS_DURING {
// request = [GSWHTTPIO readRequestFromFromHandle: _serverSocket];
[GSWHTTPIO sendResponse:response
toHandle: _serverSocket
request:request];
setsockopt([_serverSocket fileDescriptor], SOL_SOCKET, SO_RCVTIMEO, &timeout,sizeof(timeout));
request = [GSWHTTPIO readRequestFromFromHandle: _serverSocket];
} NS_HANDLER {
NSLog(@"%s -- Exception while sending response: %@",
__PRETTY_FUNCTION__, [localException description]);
_errorOnRead = YES;
NSLog(@"%s -- dropping connection reason: %@",__PRETTY_FUNCTION__, [localException reason]);
} NS_ENDHANDLER;
}
done:
[self _closeSocket];
_processingRequest = NO;
[self drain];
if (_isMultiThreadEnabled) {
[NSThread exit];
}
// "womp" is the request handler key used by the WOTaskD contacing your app
if ((_errorOnRead || (request == nil)) ||
((([[_app class] isDirectConnectEnabled] == NO) && ([request isUsingWebServer] == NO)) &&
([@"womp" isEqual:[request requestHandlerKey]] == NO))) {
goto done;
}
_processingRequest = YES;
_dispatchError = NO;
NS_DURING {
response = [_app dispatchRequest:request];
} NS_HANDLER {
NSLog(@"%s -- Exception occurred while responding to client: %@",
__PRETTY_FUNCTION__, [localException description]);
_dispatchError = YES;
response = [GSWDefaultAdaptor _lastDitchErrorResponse];
} NS_ENDHANDLER;
if (response) {
NSString * reqid = [request headerForKey:REQUEST_ID];
if (reqid) {
[response setHeader:reqid forKey:REQUEST_ID];
}
NS_DURING {
[GSWHTTPIO sendResponse:response
toHandle: _serverSocket
request:request];
} NS_HANDLER {
NSLog(@"%s -- Exception while sending response: %@",
__PRETTY_FUNCTION__, [localException description]);
} NS_ENDHANDLER;
}
done:
[self _closeSocket];
_processingRequest = NO;
}

4
GSWeb/GSWeb.h Normal file → Executable file
View file

@ -83,7 +83,6 @@
#include "GSWConfig.h"
@class EOEditingContext;
@class GSWAdaptor;
@class GSWApplication;
@class GSWAssociation;
@ -101,7 +100,6 @@
@class GSWRequestHandler;
@class GSWComponentDefinition;
//@class GSWBundle;
@class GSWMultiKeyDictionary;
@class GSWCookie;
@class GSWElementID;
@class GSWAction;
@ -129,7 +127,6 @@
@class GSWDeployedBundle;
@class GSWProjectBundle;
@class GSWSessionTimeOut;
@class GSWMultiKeyDictionary;
@class GSWTemplateParser;
@class GSWDynamicURLString;
@class GSWBindingNameAssociation;
@ -249,7 +246,6 @@
#include "GSWServerSessionStore.h"
#include "GSWDeployedBundle.h"
#include "GSWProjectBundle.h"
#include "GSWMultiKeyDictionary.h"
#include "GSWDynamicURLString.h"
#include "GSWBindingNameAssociation.h"
#include "GSWURLValuedElementData.h"

View file

@ -53,6 +53,8 @@
[nonNumberCS addCharactersInString:@".Ee-+"];
[nonNumberCS invert];
nonNumberRange = [self rangeOfCharacterFromSet:nonNumberCS];
[nonNumberCS release];
return (nonNumberRange.length<=0);
};
@ -66,6 +68,7 @@
[nonNumberCS addCharactersInString:@".-+"];
[nonNumberCS invert];
nonNumberRange = [self rangeOfCharacterFromSet:nonNumberCS];
[nonNumberCS release];
return (nonNumberRange.length<=0);
};
@ -95,6 +98,8 @@
[nonNumberCS addCharactersInString:@".+"];
[nonNumberCS invert];
nonNumberRange = [self rangeOfCharacterFromSet:nonNumberCS];
[nonNumberCS release];
return (nonNumberRange.length<=0);
};
@ -126,6 +131,8 @@
mutableCopy];
[numberCS addCharactersInString:@".-+"];
numberRange = [self rangeOfCharacterFromSet:numberCS];
[numberCS release];
return (numberRange.location==0 && numberRange.length>0);
};

View file

@ -0,0 +1,32 @@
#
# GNUmakefile.postamble for base tests
#
# Find all all subdirectories and run a clean in them independently
#
after-clean::
$(ECHO_NOTHING)\
RUNDIR=`pwd`; \
TESTDIRS=`find . -type d`; \
for dir in $$TESTDIRS __done; do \
if [ $$dir != . -a -f $$dir/GNUmakefile ]; then \
echo Cleaning $$dir; cd $$dir; make clean; cd $$RUNDIR; \
fi \
done \
$(END_ECHO)
after-distclean::
$(ECHO_NOTHING)\
RUNDIR=`pwd`; \
TESTDIRS=`find . -type d`; \
for dir in $$TESTDIRS __done; do \
if [ $$dir != . -a -f $$dir/GNUmakefile ]; then \
echo Cleaning $$dir; cd $$dir; make distclean; \
if [ \! -f IGNORE ]; then \
$(RM) GNUmakefile; \
fi; \
cd $$RUNDIR; \
fi \
done \
$(END_ECHO)

View file

@ -0,0 +1,15 @@
# This is here to force the test sourcecode to be treated as UTF-8
# irrespective of the locale the testsuite is being run in. That
# allows any UTF-8 characters in the source to be handled correctly
# by the compiler. Of course, all test files need to be written in
# UTF-8 encoding for this to make sense.
ADDITIONAL_OBJC_FLAGS+="-finput-charset=UTF-8"
include $(GNUSTEP_MAKEFILES)/Auxiliary/gsweb_wo.make
#ADDITIONAL_TOOL_LIBS += $(AUXILIARY_GSW_LIBS)
#ADDITIONAL_TOOL_LIBS += -lWebObjects
ADDITIONAL_TOOL_LIBS+=-lWebObjects

View file

View file

@ -0,0 +1,55 @@
#include <Foundation/Foundation.h>
#include <WebObjects/GSWDictionary.h>
#include <objc/runtime.h>
#include "Testing.h"
int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
// Class gswDictClass0 = [GSWDictionary class];
Class gswDictClass = NSClassFromString(@"GSWDictionary");
id dict = [gswDictClass new];
PASS(dict != nil, "GSWDictionary dictionary created");
PASS([dict count] == 0, "count is 0");
NSString * helloString = @"Hello";
[dict setObject:helloString
forKeys:@"Hello.wo",@"DE", nil];
PASS([dict count] == 1, "count is 1 after adding one object");
id myObj = [dict objectForKeyArray:@[@"Hello.wo",@"DE"]];
PASS([myObj isEqualTo:helloString], "objectForKeyArray works");
myObj = [dict objectForKeyArray:@[@"Hello.wo",@"FR"]];
PASS(myObj == nil, "objectForKeyArray does not find non-existing rows");
[dict removeObjectForKeyArray:@[@"Hello.wo",@"FR"]];
PASS([dict count] == 1, "count is still 1 after trying to remove one object for non-existing key");
[dict removeObjectForKeyArray:@[@"Hello.wo",@"DE"]];
PASS([dict count] == 0, "count is 0 after removing object using removeObjectForKeyArray:");
[dict setObject:helloString
forKeys:@"Hello.wo",@"IT",@"DK", nil];
[dict removeObjectForKeys:@"Hello.wo",@"IT",@"DK", nil];
PASS([dict count] == 0, "count is 0 after removing object using removeObjectForKeys:");
//NSLog(@"%@",dict);
[arp release]; arp = nil;
return 0;
}

0
Tests/gsweb/TestInfo Normal file
View file