mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
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:
parent
7d7789f3fd
commit
b283c8d930
14 changed files with 161 additions and 53 deletions
22
ChangeLog
22
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -105,6 +105,11 @@
|
|||
@end
|
||||
|
||||
#ifndef NO_GNUSTEP
|
||||
|
||||
@interface NSCalendarDate (GSCategories)
|
||||
- (int) weekOfYear;
|
||||
@end
|
||||
|
||||
@interface NSCalendarDate (GregorianDate)
|
||||
|
||||
- (int) lastDayOfGregorianMonth: (int)month year: (int)year;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: ¬ atIndex: 2];
|
||||
[inv retainArguments];
|
||||
|
||||
housekeeper = [NSTimer timerWithTimeInterval: 30.0
|
||||
invocation: inv
|
||||
repeats: YES];
|
||||
[r addTimer: housekeeper forMode: NSDefaultRunLoopMode];
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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*
|
||||
|
|
Loading…
Reference in a new issue