Fixes for memory leak in property-list parsing and in NSTimeZone

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4762 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-08-25 16:12:36 +00:00
parent 921c2240ef
commit 6812c6aa5f
2 changed files with 206 additions and 157 deletions

View file

@ -1,6 +1,7 @@
Wed Aug 25 15:44:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Wed Aug 25 17:08:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
Fixes for memory leak in property-list parsing from dawn. Fixes for memory leak in property-list parsing and in NSTimeZone
merged in from dawn.
Wed Aug 25 11:37:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Wed Aug 25 11:37:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>

View file

@ -18,7 +18,7 @@
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/* We use a implementation independent of the system, since POSIX /* We use a implementation independent of the system, since POSIX
functions for time zones are woefully inadequate for implementing functions for time zones are woefully inadequate for implementing
@ -60,6 +60,7 @@
#include <Foundation/NSUtilities.h> #include <Foundation/NSUtilities.h>
#include <Foundation/NSZone.h> #include <Foundation/NSZone.h>
#include <Foundation/NSBundle.h> #include <Foundation/NSBundle.h>
#include <Foundation/NSMapTable.h>
#define NOID #define NOID
#include "tzfile.h" #include "tzfile.h"
@ -116,7 +117,7 @@ static NSMutableDictionary *zoneDictionary;
static NSDictionary *fake_abbrev_dict; static NSDictionary *fake_abbrev_dict;
/* Lock for creating time zones. */ /* Lock for creating time zones. */
static NSLock *zone_mutex; static NSRecursiveLock *zone_mutex;
/* Decode the four bytes at PTR as a signed integer in network byte order. /* Decode the four bytes at PTR as a signed integer in network byte order.
@ -145,7 +146,7 @@ decode (const void *ptr)
NSEnumerator *dict_enum; NSEnumerator *dict_enum;
} }
- initWithDict: (NSDictionary*)aDict; - (id) initWithDict: (NSDictionary*)aDict;
@end @end
@ -160,7 +161,7 @@ decode (const void *ptr)
char detail_index; // Index of time zone detail char detail_index; // Index of time zone detail
} }
- initWithTime: (int)aTime withIndex: (char)anIndex; - (id) initWithTime: (int)aTime withIndex: (char)anIndex;
- (int) transTime; - (int) transTime;
- (char) detailIndex; - (char) detailIndex;
@end @end
@ -173,7 +174,8 @@ decode (const void *ptr)
NSArray *details; // Time zone details NSArray *details; // Time zone details
} }
- initWithName: (NSString*)aName withTransitions: (NSArray*)trans - (id) initWithName: (NSString*)aName
withTransitions: (NSArray*)trans
withDetails: (NSArray*)zoneDetails; withDetails: (NSArray*)zoneDetails;
@end @end
@ -185,7 +187,7 @@ decode (const void *ptr)
int offset; // Offset from UTC in seconds. int offset; // Offset from UTC in seconds.
} }
- initWithOffset: (int)anOffset; - (id) initWithOffset: (int)anOffset;
@end @end
@ -197,8 +199,10 @@ decode (const void *ptr)
BOOL is_dst; // Is it daylight savings time? BOOL is_dst; // Is it daylight savings time?
} }
- initWithTimeZone: (NSTimeZone*)aZone withAbbrev: (NSString*)anAbbrev - (id) initWithTimeZone: (NSTimeZone*)aZone
withOffset: (int)anOffset withDST: (BOOL)isDST; withAbbrev: (NSString*)anAbbrev
withOffset: (int)anOffset
withDST: (BOOL)isDST;
@end @end
/* Private methods for obtaining resource file names. */ /* Private methods for obtaining resource file names. */
@ -239,7 +243,7 @@ decode (const void *ptr)
@implementation NSInternalAbbrevDict @implementation NSInternalAbbrevDict
+ allocWithZone: (NSZone*)zone + (id) allocWithZone: (NSZone*)zone
{ {
return NSAllocateObject(self, 0, zone); return NSAllocateObject(self, 0, zone);
} }
@ -277,12 +281,11 @@ decode (const void *ptr)
- (NSString*) description - (NSString*) description
{ {
return [NSString return [NSString stringWithFormat: @"%@(%d, %d)",
stringWithFormat: @"%@(%d, %d)",
[self class], trans_time, (int)detail_index]; [self class], trans_time, (int)detail_index];
} }
- initWithTime: (int)aTime withIndex: (char)anIndex - (id) initWithTime: (int)aTime withIndex: (char)anIndex
{ {
[super init]; [super init];
trans_time = aTime; trans_time = aTime;
@ -309,8 +312,11 @@ decode (const void *ptr)
withTransitions: (NSArray*)trans withTransitions: (NSArray*)trans
withDetails: (NSArray*)zoneDetails withDetails: (NSArray*)zoneDetails
{ {
NSZone *z;
[super init]; [super init];
name = RETAIN(aName); z = [self zone];
name = [aName copyWithZone: z];
transitions = RETAIN(trans); transitions = RETAIN(trans);
details = RETAIN(zoneDetails); details = RETAIN(zoneDetails);
return self; return self;
@ -399,19 +405,48 @@ decode (const void *ptr)
@implementation NSConcreteAbsoluteTimeZone @implementation NSConcreteAbsoluteTimeZone
- initWithOffset: (int)anOffset static NSMapTable *absolutes = 0;
+ (void) initialize
{
if (self == [NSConcreteAbsoluteTimeZone class])
{
absolutes = NSCreateMapTable(NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
}
}
- (id) initWithOffset: (int)anOffset
{
NSConcreteAbsoluteTimeZone *z;
[zone_mutex lock];
z = (NSConcreteAbsoluteTimeZone*)NSMapGet(absolutes, (void*)(gsaddr)anOffset);
if (z)
{
RETAIN(z);
RELEASE(self);
}
else
{ {
[super init]; [super init];
name = [NSString stringWithFormat: @"%d", anOffset]; name = [[NSString alloc] initWithFormat: @"%d", anOffset];
detail = [[NSConcreteTimeZoneDetail alloc] detail = [[NSConcreteTimeZoneDetail alloc]
initWithTimeZone: self withAbbrev: name initWithTimeZone: self withAbbrev: name
withOffset: anOffset withDST: NO]; withOffset: anOffset withDST: NO];
offset = anOffset; offset = anOffset;
return self; z = self;
NSMapInsert(absolutes, (void*)(gsaddr)anOffset, (void*)z);
}
[zone_mutex unlock];
return z;
} }
- (void) dealloc - (void) dealloc
{ {
[zone_mutex lock];
NSMapRemove(absolutes, (void*)(gsaddr)offset);
[zone_mutex unlock];
RELEASE(name); RELEASE(name);
RELEASE(detail); RELEASE(detail);
[super dealloc]; [super dealloc];
@ -423,11 +458,14 @@ decode (const void *ptr)
[aCoder encodeObject: name]; [aCoder encodeObject: name];
} }
- initWithCoder: aDecoder - (id) initWithCoder: aDecoder
{ {
self = [super initWithCoder: aDecoder]; self = [super initWithCoder: aDecoder];
[aDecoder decodeValueOfObjCType: @encode(id) at: &name]; [aDecoder decodeValueOfObjCType: @encode(id) at: &name];
offset = [name intValue]; offset = [name intValue];
detail = [[NSConcreteTimeZoneDetail alloc]
initWithTimeZone: self withAbbrev: name
withOffset: offset withDST: NO];
return self; return self;
} }
@ -451,8 +489,10 @@ decode (const void *ptr)
@implementation NSConcreteTimeZoneDetail @implementation NSConcreteTimeZoneDetail
- initWithTimeZone: (NSTimeZone*)aZone withAbbrev: (NSString*)anAbbrev - (id) initWithTimeZone: (NSTimeZone*)aZone
withOffset: (int)anOffset withDST: (BOOL)isDST withAbbrev: (NSString*)anAbbrev
withOffset: (int)anOffset
withDST: (BOOL)isDST
{ {
[super init]; [super init];
timeZone = RETAIN(aZone); timeZone = RETAIN(aZone);
@ -527,7 +567,7 @@ decode (const void *ptr)
{ {
id localZoneString = nil; id localZoneString = nil;
zone_mutex = [NSLock new]; zone_mutex = [NSRecursiveLock new];
zoneDictionary = [[NSMutableDictionary alloc] init]; zoneDictionary = [[NSMutableDictionary alloc] init];
localZoneString = [[NSUserDefaults standardUserDefaults] localZoneString = [[NSUserDefaults standardUserDefaults]
@ -571,6 +611,7 @@ decode (const void *ptr)
NSLog(@"Using time zone with absolute offset 0."); NSLog(@"Using time zone with absolute offset 0.");
localTimeZone = [NSTimeZone timeZoneForSecondsFromGMT: 0]; localTimeZone = [NSTimeZone timeZoneForSecondsFromGMT: 0];
} }
RETAIN(localTimeZone);
fake_abbrev_dict = [[NSInternalAbbrevDict alloc] init]; fake_abbrev_dict = [[NSInternalAbbrevDict alloc] init];
} }
@ -596,7 +637,7 @@ decode (const void *ptr)
/* We simply return the following because an existing time zone with /* We simply return the following because an existing time zone with
the given offset might not always have the same offset (daylight the given offset might not always have the same offset (daylight
savings time, change in standard time, etc.). */ savings time, change in standard time, etc.). */
return [[NSConcreteAbsoluteTimeZone alloc] initWithOffset: seconds]; return AUTORELEASE([[NSConcreteAbsoluteTimeZone alloc] initWithOffset: seconds]);
} }
+ (NSTimeZoneDetail*) timeZoneWithAbbreviation: (NSString*)abbreviation + (NSTimeZoneDetail*) timeZoneWithAbbreviation: (NSString*)abbreviation
@ -659,6 +700,7 @@ decode (const void *ptr)
} }
NS_DURING NS_DURING
{
zone = [NSConcreteTimeZone alloc]; zone = [NSConcreteTimeZone alloc];
/* Open file. */ /* Open file. */
@ -685,7 +727,7 @@ decode (const void *ptr)
if (fread(trans, 4, n_trans, file) != n_trans if (fread(trans, 4, n_trans, file) != n_trans
|| fread(type_idxs, 1, n_trans, file) != n_trans) || fread(type_idxs, 1, n_trans, file) != n_trans)
[NSException raise: fileException format: errMess]; [NSException raise: fileException format: errMess];
transArray = [[NSMutableArray alloc] initWithCapacity: n_trans]; transArray = [NSMutableArray arrayWithCapacity: n_trans];
for (i = 0; i < n_trans; i++) for (i = 0; i < n_trans; i++)
[transArray [transArray
addObject: [[NSInternalTimeTransition alloc] addObject: [[NSInternalTimeTransition alloc]
@ -722,7 +764,7 @@ decode (const void *ptr)
NSZoneFree(NSDefaultMallocZone(), zone_abbrevs); NSZoneFree(NSDefaultMallocZone(), zone_abbrevs);
/* Create time zone details. */ /* Create time zone details. */
detailsArray = [[NSMutableArray alloc] initWithCapacity: n_types]; detailsArray = [NSMutableArray arrayWithCapacity: n_types];
for (i = 0; i < n_types; i++) for (i = 0; i < n_types; i++)
{ {
NSConcreteTimeZoneDetail *detail; NSConcreteTimeZoneDetail *detail;
@ -738,18 +780,24 @@ decode (const void *ptr)
NSZoneFree(NSDefaultMallocZone(), abbrevsArray); NSZoneFree(NSDefaultMallocZone(), abbrevsArray);
NSZoneFree(NSDefaultMallocZone(), types); NSZoneFree(NSDefaultMallocZone(), types);
[zone initWithName: [aTimeZoneName copy] withTransitions: transArray [zone initWithName: aTimeZoneName
withTransitions: transArray
withDetails: detailsArray]; withDetails: detailsArray];
[zoneDictionary setObject: zone forKey: aTimeZoneName]; [zoneDictionary setObject: zone forKey: [zone timeZoneName]];
}
NS_HANDLER NS_HANDLER
{
if (zone != nil) if (zone != nil)
RELEASE(zone); RELEASE(zone);
zone = nil;
if ([localException name] != fileException) if ([localException name] != fileException)
[localException raise]; [localException raise];
zone = nil;
NSLog(@"Unable to obtain time zone `%@'.", aTimeZoneName); NSLog(@"Unable to obtain time zone `%@'.", aTimeZoneName);
}
NS_ENDHANDLER NS_ENDHANDLER
RELEASE(zone); /* retained in zoneDictionary. */
if (file != NULL) if (file != NULL)
fclose(file); fclose(file);
[zone_mutex unlock]; [zone_mutex unlock];
@ -766,7 +814,7 @@ decode (const void *ptr)
if (aTimeZone == nil) if (aTimeZone == nil)
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
format: @"Nil time zone specified."]; format: @"Nil time zone specified."];
ASSIGN(aTimeZone, localTimeZone); ASSIGN(localTimeZone, aTimeZone);
} }
+ (NSDictionary*) abbreviationDictionary + (NSDictionary*) abbreviationDictionary
@ -840,7 +888,7 @@ decode (const void *ptr)
return regionsArray; return regionsArray;
for (i = 0; i < 24; i++) for (i = 0; i < 24; i++)
temp_array[i] = [[NSMutableArray alloc] init]; temp_array[i] = [NSMutableArray array];
fileName = [NSTimeZone getRegionsFile]; fileName = [NSTimeZone getRegionsFile];
#if defined(__WIN32__) #if defined(__WIN32__)
@ -853,7 +901,7 @@ decode (const void *ptr)
raise: NSInternalInconsistencyException raise: NSInternalInconsistencyException
format: @"Failed to open time zone regions array file."]; format: @"Failed to open time zone regions array file."];
while (fscanf(file, "%d %s", &index, name) == 2) while (fscanf(file, "%d %s", &index, name) == 2)
[temp_array[index] addObject: [[NSString alloc] initWithCString: name]]; [temp_array[index] addObject: [NSString stringWithCString: name]];
fclose(file); fclose(file);
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24]; regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
return regionsArray; return regionsArray;