Tidyup categories

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@16478 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2003-04-17 06:20:17 +00:00
parent 7d7789f3fd
commit b283c8d930
14 changed files with 161 additions and 53 deletions

View file

@ -1,3 +1,25 @@
2003-04-17 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/gnustep/base/GSCategories.h:
* Headers/gnustep/base/NSCalendarDate.h:
* Headers/gnustep/base/NSData.h:
* Headers/gnustep/base/NSObject.h:
* Headers/gnustep/base/NSString.h:
* Headers/gnustep/base/NSValue.h:
* Headers/gnustep/base/Foundation.h:
Tidied use of GSCategories.
2003-04-16 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/gnustep/base/NSUserDefaults.h: remove timer ivar, now unused.
* Source/NSRunLoop.m: Support a housekeeping timer which is ignored
for purposes of deciding whether the loop shoiuld terminate.
* Source/NSThread.m: Set up housekeeping timer to trigger housekeeping
notifications in the default mode of the runloop of the main thread.
* Source/NSUserDefaults.m: Use housekeeping notifications to trigger
synchronise rather than using timers ... avoid circular dependencies.
Thanks to Derek Zhou for bug report.
2003-04-15 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSData.m: Experimantal disable ReadFile and WriteFile on MINGW

View file

@ -90,7 +90,5 @@
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSZone.h>
#include <gnustep/base/GSCategories.h>
#include <gnustep/base/GSObjCRuntime.h>
#endif /* __Foundation_h_GNUSTEP_BASE_INCLUDE */

View file

@ -26,29 +26,26 @@
*/
#ifndef NO_GNUSTEP
#ifndef NeXT_Foundation_LIBRARY
#include <Foundation/NSCalendarDate.h>
#include <Foundation/NSData.h>
#include <Foundation/NSString.h>
#include <Foundation/NSValue.h>
#else
/* The following ifndef prevents the categories declared in this file being
* seen in GNUstep code. This is necessary because those category
* declarations are also present in the header files for the corresponding
* classes in GNUstep. The separate category declarations in this file
* are only needed for software using the GNUstep Additions library
* without the main GNUstep base library.
*/
#ifndef GNUSTEP
#include <Foundation/Foundation.h>
#endif
@interface NSCalendarDate (GSCategories)
- (int) weekOfYear;
@end
@interface NSData (GSCategories)
- (NSString*) hexadecimalRepresentation;
- (id) initWithHexadecimalRepresentation: (NSString*)string;
- (NSData*) md5Digest;
@end
@interface NSString (GSCategories)
@ -75,19 +72,17 @@
+ (NSValue*) valueFromString: (NSString *)string;
@end
/* This is also defined in NSObject.h, but added here for use with the
additions library */
#ifndef NSOBJECT_GSCATEGORIES_INTERFACE
@interface NSObject (GSCategories)
- notImplemented:(SEL)aSel;
- (id) subclassResponsibility: (SEL)aSel;
- (id) shouldNotImplement: (SEL)aSel;
- (NSComparisonResult) compare: (id)anObject;
@end
#endif
#endif /* GNUSTEP */
#ifndef GS_MAX_OBJECTS_FROM_STACK
/**
@ -235,5 +230,4 @@
})
#endif /* NO_GNUSTEP */
#endif /* INCLUDED_GS_CATEGORIES_H */

View file

@ -105,6 +105,11 @@
@end
#ifndef NO_GNUSTEP
@interface NSCalendarDate (GSCategories)
- (int) weekOfYear;
@end
@interface NSCalendarDate (GregorianDate)
- (int) lastDayOfGregorianMonth: (int)month year: (int)year;

View file

@ -116,6 +116,12 @@
#ifndef NO_GNUSTEP
@interface NSData (GSCategories)
- (NSString*) hexadecimalRepresentation;
- (id) initWithHexadecimalRepresentation: (NSString*)string;
- (NSData*) md5Digest;
@end
/*
* We include special support for coding/decoding - adding methods for
* serializing/deserializing type-tags and cross-references.
@ -250,6 +256,7 @@
@end
#ifndef NO_GNUSTEP
@interface NSMutableData (GNUstepExtensions)
/*
* Capacity management - GNUstep gives you control over the size of

View file

@ -291,12 +291,10 @@ GS_EXPORT NSRecursiveLock *gnustep_global_lock;
- (id) write: (TypedStream*)aStream;
@end
#define NSOBJECT_GSCATEGORIES_INTERFACE
@interface NSObject (GSCategories)
- notImplemented:(SEL)aSel;
- (id) subclassResponsibility: (SEL)aSel;
- (id) shouldNotImplement: (SEL)aSel;
- (NSComparisonResult) compare: (id)anObject;
@end

View file

@ -369,6 +369,27 @@ extern struct objc_class _NSConstantStringClassReference;
@interface NSMutableString (GNUstep)
- (NSString*) immutableProxy;
@end
@interface NSString (GSCategories)
- (NSString*) stringByDeletingPrefix: (NSString*)prefix;
- (NSString*) stringByDeletingSuffix: (NSString*)suffix;
- (NSString*) stringByTrimmingLeadSpaces;
- (NSString*) stringByTrimmingTailSpaces;
- (NSString*) stringByTrimmingSpaces;
- (NSString*) stringByReplacingString: (NSString*)replace
withString: (NSString*)by;
@end
@interface NSMutableString (GSCategories)
- (void) deleteSuffix: (NSString*)suffix;
- (void) deletePrefix: (NSString*)prefix;
- (void) replaceString: (NSString*)replace
withString: (NSString*)by;
- (void) trimLeadSpaces;
- (void) trimTailSpaces;
- (void) trimSpaces;
@end
#endif /* NO_GNUSTEP */
#endif /* __NSString_h_GNUSTEP_BASE_INCLUDE */

View file

@ -107,7 +107,6 @@ GS_EXPORT NSString* const NSLocale;
the M$ hell. God help the Win95/WinNT users of NSUserDefaults ;-)
To Do:
- ask somebody to test it for M$;
- polish & optimize;
- when tested, fix NSBundle (the system languages stuff);
- write docs : -(
@ -124,7 +123,6 @@ GS_EXPORT NSString* const NSLocale;
NSDictionary *_dictionaryRep; // Cached dictionary representation
NSString *_defaultsDatabase;
NSDate *_lastSync;
NSTimer *_tickingTimer; // for synchronization
NSRecursiveLock *_lock;
NSDistributedLock *_fileLock;
}
@ -168,7 +166,7 @@ GS_EXPORT NSString* const NSLocale;
/* Returning the Search List */
- (NSMutableArray*) searchList;
- (void)setSearchList: (NSArray*)newList;
- (void) setSearchList: (NSArray*)newList;
/* Maintaining Persistent Domains */
- (NSDictionary*) persistentDomainForName: (NSString*)domainName;

View file

@ -118,6 +118,11 @@
@end
#ifndef NO_GNUSTEP
@interface NSNumber(GSCategories)
+ (NSValue*) valueFromString: (NSString *)string;
@end
/* Note: This method is not in the OpenStep spec, but they makes
subclassing easier. */
@interface NSValue (Subclassing)

View file

@ -176,6 +176,8 @@ _arg_addr(NSInvocation *inv, int index)
/**
* Returns an invocation instance which can be used to send messages to
* a target object using the described signature.<br />
* You must set the target and selector (using -setTarget: and -setSelector:)
* before you attempt to use the invocation.<br />
* Raises an NSInvalidArgumentException if the signature is nil.
*/
+ (NSInvocation*) invocationWithMethodSignature: (NSMethodSignature*)_signature
@ -734,6 +736,8 @@ _arg_addr(NSInvocation *inv, int index)
/** <init /><override-subclass />
* Initialised an invocation instance which can be used to send messages to
* a target object using aSignature.<br />
* You must set the target and selector (using -setTarget: and -setSelector:)
* before you attempt to use the invocation.<br />
* Raises an NSInvalidArgumentException if aSignature is nil.
*/
- (id) initWithMethodSignature: (NSMethodSignature*)aSignature

View file

@ -604,7 +604,6 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt)
info = GSIArrayItemAtIndex(watchers, i).obj;
if (info->_invalidated == YES)
{
GSIArrayRemoveItemAtIndex(watchers, i);
continue;
}
@ -1622,7 +1621,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt)
+ (NSRunLoop*) currentRunLoop
{
extern NSRunLoop *GSRunLoopForThread();
extern NSRunLoop *GSRunLoopForThread();
return GSRunLoopForThread(nil);
}
@ -1709,6 +1708,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt)
*/
- (NSDate*) limitDateForMode: (NSString*)mode
{
extern NSTimer *GSHousekeeper();
GSRunLoopCtxt *context = NSMapGet(_contextMap, mode);
NSDate *when = nil;
@ -1825,6 +1825,32 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt)
min_watcher = nil;
}
}
/*
* If there is nothing being watched, and no valid timers
* other than the housekeeper, we set min_timer to nil so
* that the housekeeper timer does not keep the runloop
* active. It's a special case set up in NSThread.m
*/
if (min_watcher == nil && min_timer != nil
&& min_timer == GSHousekeeper())
{
unsigned count = GSIArrayCount(timers);
while (count-- > 1)
{
NSTimer *tmp = GSIArrayItemAtIndex(timers, 0).obj;
if (timerInvalidated(tmp) == YES)
{
GSIArrayRemoveItemAtIndex(timers, count);
}
}
if (GSIArrayCount(timers) == 1)
{
min_timer = nil;
}
}
_currentMode = savedMode;
}
NS_HANDLER

View file

@ -42,6 +42,7 @@
#include <Foundation/NSNotificationQueue.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSConnection.h>
#include <Foundation/NSInvocation.h>
@class GSPerformHolder;
@ -197,6 +198,22 @@ GSCurrentThreadDictionary()
return GSDictionaryForThread(nil);
}
/*
* The special timer which we set up in the run loop of the main thread
* to perform housekeeping duties. NSRunLoop needs to call this private
* function so it knows about the housekeeping timer and won't keep the
* loop running just to do housekeeping.
*
* The NSUserDefaults system registers as an observer of GSHousekeeping
* notifications in order to synchronise the in-memory cache and the
* on-disk database.
*/
static NSTimer *housekeeper = nil;
NSTimer *GSHousekeeper()
{
return housekeeper;
}
/**
* Returns the runloop for the specified thread (or, if t is nil,
* for the current thread). Creates a new runloop if necessary.<br />
@ -217,6 +234,30 @@ GSRunLoopForThread(NSThread *t)
r = [NSRunLoop new];
[d setObject: r forKey: key];
RELEASE(r);
if (t == nil || t == defaultThread)
{
NSNotificationCenter *ctr;
NSNotification *not;
NSInvocation *inv;
SEL sel;
ctr = [NSNotificationCenter defaultCenter];
not = [NSNotification notificationWithName: @"GSHousekeeping"
object: r
userInfo: nil];
sel = @selector(postNotification:);
inv = [NSInvocation invocationWithMethodSignature:
[ctr methodSignatureForSelector: sel]];
[inv setTarget: ctr];
[inv setSelector: sel];
[inv setArgument: &not atIndex: 2];
[inv retainArguments];
housekeeper = [NSTimer timerWithTimeInterval: 30.0
invocation: inv
repeats: YES];
[r addTimer: housekeeper forMode: NSDefaultRunLoopMode];
}
}
}
return r;

View file

@ -92,7 +92,7 @@ static Class NSDate_class;
}
/**
* Create a timer wchich will fire after ti seconds and, if f is YES,
* Create a timer which will fire after ti seconds and, if f is YES,
* every ti seconds thereafter. On firing, invocation will be performed.<br />
* NB. To make the timer operate, you must add it to a run loop.
*/
@ -111,7 +111,7 @@ static Class NSDate_class;
/**
* Create a timer wchich will fire after ti seconds and, if f is YES,
* every ti seconds thereafter. On firing, the target object will be
* sent a message specified by selector and with the object info as an
* sent a message specified by selector and with the value info as an
* argument.<br />
* NB. To make the timer operate, you must add it to a run loop.
*/

View file

@ -130,7 +130,6 @@ static void updateCache(NSUserDefaults *self)
- (void) __createStandardSearchList;
- (NSDictionary*) __createArgumentDictionary;
- (void) __changePersistentDomain: (NSString*)domainName;
- (void) __timerTicked: (NSTimer*)tim;
@end
/**
@ -522,7 +521,8 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */
[tempDefaults setSearchList: sList];
RELEASE(sList);
currLang = [tempDefaults stringArrayForKey: @"NSLanguages"];
AUTORELEASE(tempDefaults);
AUTORELEASE(RETAIN(currLang));
RELEASE(tempDefaults);
}
}
else
@ -825,15 +825,17 @@ static NSString *pathForUser(NSString *user)
setObject: [NSMutableDictionaryClass dictionaryWithCapacity: 10]
forKey: NSRegistrationDomain];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(synchronize)
name: @"GSHousekeeping"
object: nil];
return self;
}
- (void) dealloc
{
if (_tickingTimer != nil)
{
[_tickingTimer invalidate];
}
[[NSNotificationCenter defaultCenter] removeObserver: self];
RELEASE(_lastSync);
RELEASE(_searchList);
RELEASE(_persDomains);
@ -1364,15 +1366,6 @@ static BOOL isPlistObject(id o)
}
}
if (_tickingTimer == nil)
{
_tickingTimer = [NSTimer scheduledTimerWithTimeInterval: 30
target: self
selector: @selector(__timerTicked:)
userInfo: nil
repeats: NO];
}
/*
* If we haven't changed anything, we only need to synchronise if
* the on-disk database has been changed by someone else.
@ -1397,8 +1390,12 @@ static BOOL isPlistObject(id o)
{
NSDate *mod;
/*
* If the database was modified since the last synchronisation
* we need to read it.
*/
mod = [attr objectForKey: NSFileModificationDate];
if (mod !=nil && [_lastSync earlierDate: mod] != _lastSync)
if (mod != nil && [_lastSync laterDate: mod] != _lastSync)
{
wantRead = YES;
}
@ -1806,14 +1803,6 @@ static BOOL isPlistObject(id o)
}
[_lock unlock];
}
- (void) __timerTicked: (NSTimer*)tim
{
if (tim == _tickingTimer)
_tickingTimer = nil;
[self synchronize];
}
@end
NSDictionary*