mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
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:
parent
921c2240ef
commit
6812c6aa5f
2 changed files with 206 additions and 157 deletions
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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,9 +161,9 @@ 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,8 +174,9 @@ decode (const void *ptr)
|
||||||
NSArray *details; // Time zone details
|
NSArray *details; // Time zone details
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithName: (NSString*)aName withTransitions: (NSArray*)trans
|
- (id) initWithName: (NSString*)aName
|
||||||
withDetails: (NSArray*)zoneDetails;
|
withTransitions: (NSArray*)trans
|
||||||
|
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,16 +199,18 @@ 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. */
|
||||||
@interface NSTimeZone (Private)
|
@interface NSTimeZone (Private)
|
||||||
+ (NSString*)getAbbreviationFile;
|
+ (NSString*) getAbbreviationFile;
|
||||||
+ (NSString*)getRegionsFile;
|
+ (NSString*) getRegionsFile;
|
||||||
+ (NSString*)getLocalTimeFile;
|
+ (NSString*) getLocalTimeFile;
|
||||||
+ (NSString*)getTimeZoneFile: (NSString*)name;
|
+ (NSString*) getTimeZoneFile: (NSString*)name;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -249,7 +253,7 @@ decode (const void *ptr)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned)count
|
- (unsigned) count
|
||||||
{
|
{
|
||||||
return [[NSTimeZone abbreviationMap] count];
|
return [[NSTimeZone abbreviationMap] count];
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -290,12 +293,12 @@ decode (const void *ptr)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)transTime
|
- (int) transTime
|
||||||
{
|
{
|
||||||
return trans_time;
|
return trans_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (char)detailIndex
|
- (char) detailIndex
|
||||||
{
|
{
|
||||||
return detail_index;
|
return detail_index;
|
||||||
}
|
}
|
||||||
|
@ -309,14 +312,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
RELEASE(name);
|
RELEASE(name);
|
||||||
RELEASE(transitions);
|
RELEASE(transitions);
|
||||||
|
@ -389,7 +395,7 @@ decode (const void *ptr)
|
||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)timeZoneName
|
- (NSString*) timeZoneName
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -399,49 +405,81 @@ decode (const void *ptr)
|
||||||
|
|
||||||
@implementation NSConcreteAbsoluteTimeZone
|
@implementation NSConcreteAbsoluteTimeZone
|
||||||
|
|
||||||
- initWithOffset: (int)anOffset
|
static NSMapTable *absolutes = 0;
|
||||||
|
|
||||||
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
[super init];
|
if (self == [NSConcreteAbsoluteTimeZone class])
|
||||||
name = [NSString stringWithFormat: @"%d", anOffset];
|
{
|
||||||
detail = [[NSConcreteTimeZoneDetail alloc]
|
absolutes = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||||
initWithTimeZone: self withAbbrev: name
|
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||||
withOffset: anOffset withDST: NO];
|
}
|
||||||
offset = anOffset;
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (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];
|
||||||
|
name = [[NSString alloc] initWithFormat: @"%d", anOffset];
|
||||||
|
detail = [[NSConcreteTimeZoneDetail alloc]
|
||||||
|
initWithTimeZone: self withAbbrev: name
|
||||||
|
withOffset: anOffset withDST: NO];
|
||||||
|
offset = anOffset;
|
||||||
|
z = self;
|
||||||
|
NSMapInsert(absolutes, (void*)(gsaddr)anOffset, (void*)z);
|
||||||
|
}
|
||||||
|
[zone_mutex unlock];
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)encodeWithCoder: aCoder
|
- (void) encodeWithCoder: aCoder
|
||||||
{
|
{
|
||||||
[super encodeWithCoder: aCoder];
|
[super encodeWithCoder: aCoder];
|
||||||
[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;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSTimeZoneDetail*)timeZoneDetailForDate: (NSDate*)date
|
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||||
{
|
{
|
||||||
return detail;
|
return detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)timeZoneName
|
- (NSString*) timeZoneName
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*)timeZoneDetailArray
|
- (NSArray*) timeZoneDetailArray
|
||||||
{
|
{
|
||||||
return [NSArray arrayWithObject: detail];
|
return [NSArray arrayWithObject: detail];
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -462,14 +502,14 @@ decode (const void *ptr)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
RELEASE(timeZone);
|
RELEASE(timeZone);
|
||||||
RELEASE(abbrev);
|
RELEASE(abbrev);
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)encodeWithCoder: aCoder
|
- (void) encodeWithCoder: aCoder
|
||||||
{
|
{
|
||||||
[super encodeWithCoder: aCoder];
|
[super encodeWithCoder: aCoder];
|
||||||
[aCoder encodeObject: abbrev];
|
[aCoder encodeObject: abbrev];
|
||||||
|
@ -486,32 +526,32 @@ decode (const void *ptr)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSTimeZoneDetail*)timeZoneDetailForDate: (NSDate*)date
|
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||||
{
|
{
|
||||||
return [timeZone timeZoneDetailForDate: date];
|
return [timeZone timeZoneDetailForDate: date];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)timeZoneName
|
- (NSString*) timeZoneName
|
||||||
{
|
{
|
||||||
return [timeZone timeZoneName];
|
return [timeZone timeZoneName];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*)timeZoneDetailArray
|
- (NSArray*) timeZoneDetailArray
|
||||||
{
|
{
|
||||||
return [timeZone timeZoneDetailArray];
|
return [timeZone timeZoneDetailArray];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isDaylightSavingTimeZone
|
- (BOOL) isDaylightSavingTimeZone
|
||||||
{
|
{
|
||||||
return is_dst;
|
return is_dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)timeZoneAbbreviation
|
- (NSString*) timeZoneAbbreviation
|
||||||
{
|
{
|
||||||
return abbrev;
|
return abbrev;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)timeZoneSecondsFromGMT
|
- (int) timeZoneSecondsFromGMT
|
||||||
{
|
{
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
@ -521,13 +561,13 @@ decode (const void *ptr)
|
||||||
|
|
||||||
@implementation NSTimeZone
|
@implementation NSTimeZone
|
||||||
|
|
||||||
+ (void)initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
if (self == [NSTimeZone class])
|
if (self == [NSTimeZone class])
|
||||||
{
|
{
|
||||||
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,35 +611,36 @@ 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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)description
|
- (NSString*) description
|
||||||
{
|
{
|
||||||
return [self timeZoneName];
|
return [self timeZoneName];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSTimeZoneDetail*)defaultTimeZone
|
+ (NSTimeZoneDetail*) defaultTimeZone
|
||||||
{
|
{
|
||||||
return [localTimeZone timeZoneDetailForDate: [NSDate date]];
|
return [localTimeZone timeZoneDetailForDate: [NSDate date]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSTimeZone*)localTimeZone
|
+ (NSTimeZone*) localTimeZone
|
||||||
{
|
{
|
||||||
return localTimeZone;
|
return localTimeZone;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSTimeZone*)timeZoneForSecondsFromGMT: (int)seconds
|
+ (NSTimeZone*) timeZoneForSecondsFromGMT: (int)seconds
|
||||||
{
|
{
|
||||||
/* 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
|
||||||
{
|
{
|
||||||
/* We obtain a time zone from the abbreviation dictionary, get the
|
/* We obtain a time zone from the abbreviation dictionary, get the
|
||||||
time zone detail array, and then obtain the time zone detail we
|
time zone detail array, and then obtain the time zone detail we
|
||||||
|
@ -626,7 +667,7 @@ decode (const void *ptr)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSTimeZone*)timeZoneWithName: (NSString*)aTimeZoneName
|
+ (NSTimeZone*) timeZoneWithName: (NSString*)aTimeZoneName
|
||||||
{
|
{
|
||||||
static NSString *fileException = @"fileException";
|
static NSString *fileException = @"fileException";
|
||||||
static NSString *errMess = @"File read error in NSTimeZone.";
|
static NSString *errMess = @"File read error in NSTimeZone.";
|
||||||
|
@ -659,122 +700,129 @@ decode (const void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_DURING
|
NS_DURING
|
||||||
zone = [NSConcreteTimeZone alloc];
|
{
|
||||||
|
zone = [NSConcreteTimeZone alloc];
|
||||||
|
|
||||||
/* Open file. */
|
/* Open file. */
|
||||||
fileName = [NSTimeZone getTimeZoneFile: aTimeZoneName];
|
fileName = [NSTimeZone getTimeZoneFile: aTimeZoneName];
|
||||||
#if defined(__WIN32__)
|
#if defined(__WIN32__)
|
||||||
file = fopen([fileName fileSystemRepresentation], "rb");
|
file = fopen([fileName fileSystemRepresentation], "rb");
|
||||||
#else
|
#else
|
||||||
file = fopen([fileName fileSystemRepresentation], "r");
|
file = fopen([fileName fileSystemRepresentation], "r");
|
||||||
#endif
|
#endif
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
[NSException raise: fileException format: errMess];
|
[NSException raise: fileException format: errMess];
|
||||||
|
|
||||||
/* Read header. */
|
/* Read header. */
|
||||||
if (fread(&header, sizeof(struct tzhead), 1, file) != 1)
|
if (fread(&header, sizeof(struct tzhead), 1, file) != 1)
|
||||||
[NSException raise: fileException format: errMess];
|
[NSException raise: fileException format: errMess];
|
||||||
|
|
||||||
n_trans = decode(header.tzh_timecnt);
|
n_trans = decode(header.tzh_timecnt);
|
||||||
n_types = decode(header.tzh_typecnt);
|
n_types = decode(header.tzh_typecnt);
|
||||||
names_size = decode(header.tzh_charcnt);
|
names_size = decode(header.tzh_charcnt);
|
||||||
|
|
||||||
/* Read in transitions. */
|
/* Read in transitions. */
|
||||||
trans = NSZoneMalloc(NSDefaultMallocZone(), 4*n_trans);
|
trans = NSZoneMalloc(NSDefaultMallocZone(), 4*n_trans);
|
||||||
type_idxs = NSZoneMalloc(NSDefaultMallocZone(), n_trans);
|
type_idxs = NSZoneMalloc(NSDefaultMallocZone(), n_trans);
|
||||||
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]
|
||||||
initWithTime: decode(trans+(i*4))
|
initWithTime: decode(trans+(i*4))
|
||||||
withIndex: type_idxs[i]]];
|
withIndex: type_idxs[i]]];
|
||||||
NSZoneFree(NSDefaultMallocZone(), trans);
|
NSZoneFree(NSDefaultMallocZone(), trans);
|
||||||
NSZoneFree(NSDefaultMallocZone(), type_idxs);
|
NSZoneFree(NSDefaultMallocZone(), type_idxs);
|
||||||
|
|
||||||
/* Read in time zone details. */
|
/* Read in time zone details. */
|
||||||
types =
|
types =
|
||||||
NSZoneMalloc(NSDefaultMallocZone(), sizeof(struct ttinfo)*n_types);
|
NSZoneMalloc(NSDefaultMallocZone(), sizeof(struct ttinfo)*n_types);
|
||||||
for (i = 0; i < n_types; i++)
|
for (i = 0; i < n_types; i++)
|
||||||
{
|
{
|
||||||
unsigned char x[4];
|
unsigned char x[4];
|
||||||
|
|
||||||
if (fread(x, 1, 4, file) != 4
|
if (fread(x, 1, 4, file) != 4
|
||||||
|| fread(&types[i].isdst, 1, 1, file) != 1
|
|| fread(&types[i].isdst, 1, 1, file) != 1
|
||||||
|| fread(&types[i].abbr_idx, 1, 1, file) != 1)
|
|| fread(&types[i].abbr_idx, 1, 1, file) != 1)
|
||||||
[NSException raise: fileException format: errMess];
|
[NSException raise: fileException format: errMess];
|
||||||
types[i].offset = decode(x);
|
types[i].offset = decode(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in time zone abbreviation strings. */
|
/* Read in time zone abbreviation strings. */
|
||||||
zone_abbrevs = NSZoneMalloc(NSDefaultMallocZone(), names_size);
|
zone_abbrevs = NSZoneMalloc(NSDefaultMallocZone(), names_size);
|
||||||
if (fread(zone_abbrevs, 1, names_size, file) != names_size)
|
if (fread(zone_abbrevs, 1, names_size, file) != names_size)
|
||||||
[NSException raise: fileException format: errMess];
|
[NSException raise: fileException format: errMess];
|
||||||
abbrevsArray = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*names_size);
|
abbrevsArray = NSZoneMalloc(NSDefaultMallocZone(), sizeof(id)*names_size);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < names_size)
|
while (i < names_size)
|
||||||
{
|
{
|
||||||
abbrevsArray[i] = [NSString stringWithCString: zone_abbrevs+i];
|
abbrevsArray[i] = [NSString stringWithCString: zone_abbrevs+i];
|
||||||
i = (strchr(zone_abbrevs+i, '\0')-zone_abbrevs)+1;
|
i = (strchr(zone_abbrevs+i, '\0')-zone_abbrevs)+1;
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|
||||||
detail = [[NSConcreteTimeZoneDetail alloc]
|
detail = [[NSConcreteTimeZoneDetail alloc]
|
||||||
initWithTimeZone: zone
|
initWithTimeZone: zone
|
||||||
withAbbrev: abbrevsArray[(int)types[i].abbr_idx]
|
withAbbrev: abbrevsArray[(int)types[i].abbr_idx]
|
||||||
withOffset: types[i].offset
|
withOffset: types[i].offset
|
||||||
withDST: (types[i].isdst > 0)];
|
withDST: (types[i].isdst > 0)];
|
||||||
[detailsArray addObject: detail];
|
[detailsArray addObject: detail];
|
||||||
RELEASE(detail);
|
RELEASE(detail);
|
||||||
}
|
}
|
||||||
NSZoneFree(NSDefaultMallocZone(), abbrevsArray);
|
NSZoneFree(NSDefaultMallocZone(), abbrevsArray);
|
||||||
NSZoneFree(NSDefaultMallocZone(), types);
|
NSZoneFree(NSDefaultMallocZone(), types);
|
||||||
|
|
||||||
[zone initWithName: [aTimeZoneName copy] withTransitions: transArray
|
[zone initWithName: aTimeZoneName
|
||||||
withDetails: detailsArray];
|
withTransitions: transArray
|
||||||
[zoneDictionary setObject: zone forKey: aTimeZoneName];
|
withDetails: detailsArray];
|
||||||
|
[zoneDictionary setObject: zone forKey: [zone timeZoneName]];
|
||||||
|
}
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
if (zone != nil)
|
{
|
||||||
RELEASE(zone);
|
if (zone != nil)
|
||||||
if ([localException name] != fileException)
|
RELEASE(zone);
|
||||||
[localException raise];
|
zone = nil;
|
||||||
zone = nil;
|
if ([localException name] != fileException)
|
||||||
NSLog(@"Unable to obtain time zone `%@'.", aTimeZoneName);
|
[localException raise];
|
||||||
|
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];
|
||||||
return zone;
|
return zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSTimeZoneDetail*)timeZoneDetailForDate: (NSDate*)date
|
- (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date
|
||||||
{
|
{
|
||||||
return [self subclassResponsibility: _cmd];
|
return [self subclassResponsibility: _cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)setDefaultTimeZone: (NSTimeZone*)aTimeZone
|
+ (void) setDefaultTimeZone: (NSTimeZone*)aTimeZone
|
||||||
{
|
{
|
||||||
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
|
||||||
{
|
{
|
||||||
return fake_abbrev_dict;
|
return fake_abbrev_dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSDictionary*)abbreviationMap
|
+ (NSDictionary*) abbreviationMap
|
||||||
{
|
{
|
||||||
/* Instead of creating the abbreviation dictionary when the class is
|
/* Instead of creating the abbreviation dictionary when the class is
|
||||||
initialized, we create it when we first need it, since the
|
initialized, we create it when we first need it, since the
|
||||||
|
@ -820,12 +868,12 @@ decode (const void *ptr)
|
||||||
return abbreviationDictionary;
|
return abbreviationDictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)timeZoneName
|
- (NSString*) timeZoneName
|
||||||
{
|
{
|
||||||
return [self subclassResponsibility: _cmd];
|
return [self subclassResponsibility: _cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray*)timeZoneArray
|
+ (NSArray*) timeZoneArray
|
||||||
{
|
{
|
||||||
/* We create the array only when we need it to reduce overhead. */
|
/* We create the array only when we need it to reduce overhead. */
|
||||||
|
|
||||||
|
@ -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,13 +901,13 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*)timeZoneDetailArray
|
- (NSArray*) timeZoneDetailArray
|
||||||
{
|
{
|
||||||
return [self subclassResponsibility: _cmd];
|
return [self subclassResponsibility: _cmd];
|
||||||
}
|
}
|
||||||
|
@ -869,7 +917,7 @@ decode (const void *ptr)
|
||||||
|
|
||||||
@implementation NSTimeZoneDetail
|
@implementation NSTimeZoneDetail
|
||||||
|
|
||||||
- (NSString*)description
|
- (NSString*) description
|
||||||
{
|
{
|
||||||
return [NSString
|
return [NSString
|
||||||
stringWithFormat: @"%@(%@, %s%d)",
|
stringWithFormat: @"%@(%@, %s%d)",
|
||||||
|
@ -879,18 +927,18 @@ decode (const void *ptr)
|
||||||
[self timeZoneSecondsFromGMT]];
|
[self timeZoneSecondsFromGMT]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)isDaylightSavingTimeZone
|
- (BOOL) isDaylightSavingTimeZone
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*)timeZoneAbbreviation
|
- (NSString*) timeZoneAbbreviation
|
||||||
{
|
{
|
||||||
return [self subclassResponsibility: _cmd];
|
return [self subclassResponsibility: _cmd];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)timeZoneSecondsFromGMT
|
- (int) timeZoneSecondsFromGMT
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -901,28 +949,28 @@ decode (const void *ptr)
|
||||||
|
|
||||||
@implementation NSTimeZone (Private)
|
@implementation NSTimeZone (Private)
|
||||||
|
|
||||||
+ (NSString*)getAbbreviationFile
|
+ (NSString*) getAbbreviationFile
|
||||||
{
|
{
|
||||||
return [NSBundle pathForGNUstepResource: ABBREV_DICT
|
return [NSBundle pathForGNUstepResource: ABBREV_DICT
|
||||||
ofType: @""
|
ofType: @""
|
||||||
inDirectory: TIME_ZONE_DIR];
|
inDirectory: TIME_ZONE_DIR];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString*)getRegionsFile
|
+ (NSString*) getRegionsFile
|
||||||
{
|
{
|
||||||
return [NSBundle pathForGNUstepResource: REGIONS_FILE
|
return [NSBundle pathForGNUstepResource: REGIONS_FILE
|
||||||
ofType: @""
|
ofType: @""
|
||||||
inDirectory: TIME_ZONE_DIR];
|
inDirectory: TIME_ZONE_DIR];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString*)getLocalTimeFile
|
+ (NSString*) getLocalTimeFile
|
||||||
{
|
{
|
||||||
return [NSBundle pathForGNUstepResource: LOCAL_TIME_FILE
|
return [NSBundle pathForGNUstepResource: LOCAL_TIME_FILE
|
||||||
ofType: @""
|
ofType: @""
|
||||||
inDirectory: TIME_ZONE_DIR];
|
inDirectory: TIME_ZONE_DIR];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString*)getTimeZoneFile: (NSString *)name
|
+ (NSString*) getTimeZoneFile: (NSString *)name
|
||||||
{
|
{
|
||||||
NSString *fileName = [NSString stringWithFormat: @"%@%@",
|
NSString *fileName = [NSString stringWithFormat: @"%@%@",
|
||||||
ZONES_DIR, name];
|
ZONES_DIR, name];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue