mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
Various minor thread safety fixes and fallback mechanisms for bad installations.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22524 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
1c89b5daed
commit
82a690e0bd
2 changed files with 422 additions and 122 deletions
|
@ -146,6 +146,8 @@
|
|||
/* Many systems have this file */
|
||||
#define SYSTEM_TIME_FILE @"/etc/localtime"
|
||||
|
||||
#define POSIX_TZONES @"posix/"
|
||||
|
||||
/* Possible location of system time zone files */
|
||||
static NSString *tzdir = nil;
|
||||
|
||||
|
@ -187,6 +189,7 @@ typedef struct {
|
|||
{
|
||||
@public
|
||||
NSString *timeZoneName;
|
||||
NSArray *abbreviations;
|
||||
NSData *timeZoneData;
|
||||
unsigned int n_trans;
|
||||
unsigned int n_types;
|
||||
|
@ -636,7 +639,7 @@ static NSMapTable *absolutes = 0;
|
|||
char buf[9];
|
||||
|
||||
sprintf(buf, "GMT%c%02d%02d", s, h, m);
|
||||
name = [[NSString alloc] initWithCString: buf];
|
||||
name = [[NSString alloc] initWithUTF8String: buf];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -872,22 +875,67 @@ static NSMapTable *absolutes = 0;
|
|||
*/
|
||||
+ (NSDictionary*) abbreviationDictionary
|
||||
{
|
||||
NSString *path;
|
||||
if (abbreviationDictionary != nil)
|
||||
return abbreviationDictionary;
|
||||
|
||||
path = _time_zone_path (ABBREV_DICT, @"plist");
|
||||
if (path == NULL)
|
||||
{
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone abbreviation dictionary."];
|
||||
return abbreviationDictionary;
|
||||
}
|
||||
abbreviationDictionary =
|
||||
[[NSString stringWithContentsOfFile: path] propertyList];
|
||||
abbreviationDictionary =
|
||||
[abbreviationDictionary makeImmutableCopyOnFail: NO];
|
||||
return RETAIN(abbreviationDictionary);
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex lock];
|
||||
}
|
||||
if (abbreviationDictionary == nil)
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
NSString *path;
|
||||
|
||||
path = _time_zone_path (ABBREV_DICT, @"plist");
|
||||
if (path != nil)
|
||||
{
|
||||
/*
|
||||
* Fast mechanism ... load prebuilt data from file so we don't
|
||||
* need to load in all time zones.
|
||||
*/
|
||||
abbreviationDictionary
|
||||
= RETAIN([[NSString stringWithContentsOfFile: path] propertyList]);
|
||||
}
|
||||
if (abbreviationDictionary == nil)
|
||||
{
|
||||
NSMutableDictionary *md;
|
||||
NSString *name;
|
||||
NSEnumerator *names;
|
||||
|
||||
/*
|
||||
* Slow fallback ... load all time zones and generate
|
||||
* abbreviation dictionary from them.
|
||||
*/
|
||||
md = [[NSMutableDictionary alloc] init];
|
||||
names = [[NSTimeZone knownTimeZoneNames] objectEnumerator];
|
||||
while ((name = [names nextObject]) != nil)
|
||||
{
|
||||
NSTimeZone *zone;
|
||||
|
||||
if ((zone = [NSTimeZone timeZoneWithName: name]))
|
||||
{
|
||||
NSEnumerator *details;
|
||||
NSTimeZoneDetail *detail;
|
||||
|
||||
details = [[zone timeZoneDetailArray] objectEnumerator];
|
||||
while ((detail = [details nextObject]) != nil)
|
||||
{
|
||||
[md setObject: name forKey: [detail abbreviation]];
|
||||
}
|
||||
}
|
||||
}
|
||||
[md makeImmutableCopyOnFail: NO];
|
||||
abbreviationDictionary = md;
|
||||
}
|
||||
RELEASE(pool);
|
||||
}
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex unlock];
|
||||
}
|
||||
return abbreviationDictionary;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -896,64 +944,143 @@ static NSMapTable *absolutes = 0;
|
|||
*/
|
||||
+ (NSDictionary*) abbreviationMap
|
||||
{
|
||||
FILE *file; // For the file containing the abbreviation dictionary
|
||||
char abbrev[80], name[80];
|
||||
NSString *path;
|
||||
|
||||
/* Instead of creating the abbreviation dictionary when the class is
|
||||
initialized, we create it when we first need it, since the
|
||||
dictionary can be potentially very large, considering that it's
|
||||
almost never used. */
|
||||
if (abbreviationMap != nil)
|
||||
return abbreviationMap;
|
||||
|
||||
/* Read dictionary from file. */
|
||||
abbreviationMap = [[NSMutableDictionary alloc] init];
|
||||
path = _time_zone_path (ABBREV_MAP, nil);
|
||||
#if defined(__MINGW32__)
|
||||
{
|
||||
unichar mode[3];
|
||||
mode[0] = 'r';
|
||||
mode[1] = 'b';
|
||||
mode[2] = '\0';
|
||||
file = _wfopen((const unichar*)[path fileSystemRepresentation], mode);
|
||||
}
|
||||
#else
|
||||
file = fopen([path fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone abbreviation map."];
|
||||
while (fscanf(file, "%79s %79s", abbrev, name) == 2)
|
||||
{
|
||||
id a, the_name, the_abbrev;
|
||||
|
||||
the_name = [NSString stringWithCString: name];
|
||||
the_abbrev = [NSString stringWithCString: abbrev];
|
||||
a = [abbreviationMap objectForKey: the_abbrev];
|
||||
if (a == nil)
|
||||
{
|
||||
a = AUTORELEASE([NSMutableArray new]);
|
||||
[abbreviationMap setObject: a forKey: the_abbrev];
|
||||
}
|
||||
[a addObject: the_name];
|
||||
return abbreviationMap;
|
||||
}
|
||||
fclose(file);
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex lock];
|
||||
}
|
||||
if (abbreviationMap == nil)
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
NSMutableDictionary *md;
|
||||
NSMutableArray *ma;
|
||||
NSString *the_name;
|
||||
NSString *the_abbrev;
|
||||
FILE *file;
|
||||
char abbrev[80];
|
||||
char name[80];
|
||||
NSString *path;
|
||||
|
||||
/* Special case: Add the system time zone if it doesn't exist in the map */
|
||||
{
|
||||
id array;
|
||||
id the_abbrev = [systemTimeZone abbreviation];
|
||||
array = [abbreviationMap objectForKey: the_abbrev];
|
||||
if (array == nil)
|
||||
{
|
||||
array = AUTORELEASE([NSMutableArray new]);
|
||||
[abbreviationMap setObject: array forKey: the_abbrev];
|
||||
}
|
||||
if ([array containsObject: [systemTimeZone timeZoneName]] == NO)
|
||||
[array addObject: [systemTimeZone timeZoneName]];
|
||||
}
|
||||
/*
|
||||
* Read dictionary from file... fast mechanism because we don't have
|
||||
* to create all timezoneas and parse all their data files.
|
||||
*/
|
||||
md = [NSMutableDictionary dictionaryWithCapacity: 100];
|
||||
path = _time_zone_path (ABBREV_MAP, nil);
|
||||
if (path != nil)
|
||||
{
|
||||
#if defined(__MINGW32__)
|
||||
unichar mode[3];
|
||||
|
||||
mode[0] = 'r';
|
||||
mode[1] = 'b';
|
||||
mode[2] = '\0';
|
||||
|
||||
file = _wfopen((const unichar*)[path fileSystemRepresentation], mode);
|
||||
#else
|
||||
file = fopen([path fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
{
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex unlock];
|
||||
}
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone abbreviation map."];
|
||||
}
|
||||
while (fscanf(file, "%79s %79s", abbrev, name) == 2)
|
||||
{
|
||||
the_name = [[NSString alloc] initWithUTF8String: name];
|
||||
the_abbrev = [[NSString alloc] initWithUTF8String: abbrev];
|
||||
ma = [md objectForKey: the_abbrev];
|
||||
if (ma == nil)
|
||||
{
|
||||
ma = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
[md setObject: ma forKey: the_abbrev];
|
||||
RELEASE(ma);
|
||||
}
|
||||
RELEASE(the_abbrev);
|
||||
[ma addObject: the_name];
|
||||
RELEASE(the_name);
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSArray *names;
|
||||
NSString *name;
|
||||
NSEnumerator *e;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Slow fallback mechanism ... go through all time names
|
||||
* so we load all the time zone data and generate the info
|
||||
* we need from it.
|
||||
*/
|
||||
names = [NSTimeZone knownTimeZoneNames];
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
e = [[names objectAtIndex: i] objectEnumerator];
|
||||
while ((name = [e nextObject]) != nil)
|
||||
{
|
||||
NSTimeZone *zone;
|
||||
|
||||
if ((zone = [NSTimeZone timeZoneWithName: name]))
|
||||
{
|
||||
NSEnumerator *details;
|
||||
NSTimeZoneDetail *detail;
|
||||
|
||||
details = [[zone timeZoneDetailArray] objectEnumerator];
|
||||
while ((detail = [details nextObject]) != nil)
|
||||
{
|
||||
the_abbrev = [detail abbreviation];
|
||||
ma = [md objectForKey: the_abbrev];
|
||||
if (ma == nil)
|
||||
{
|
||||
ma = [[NSMutableArray alloc] initWithCapacity: 1];
|
||||
[md setObject: ma forKey: the_abbrev];
|
||||
RELEASE(ma);
|
||||
}
|
||||
[ma addObject: name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Special case: Add the system time zone if
|
||||
* it doesn't exist in the map */
|
||||
the_abbrev = [systemTimeZone abbreviation];
|
||||
ma = [md objectForKey: the_abbrev];
|
||||
if (ma == nil)
|
||||
{
|
||||
ma = [NSMutableArray new];
|
||||
[md setObject: ma forKey: the_abbrev];
|
||||
RELEASE(ma);
|
||||
}
|
||||
the_name = [systemTimeZone timeZoneName];
|
||||
if ([ma containsObject: the_name] == NO)
|
||||
{
|
||||
[ma addObject: the_name];
|
||||
}
|
||||
|
||||
[md makeImmutableCopyOnFail: NO];
|
||||
abbreviationMap = RETAIN(md);
|
||||
RELEASE(pool);
|
||||
}
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex unlock];
|
||||
}
|
||||
|
||||
return abbreviationMap;
|
||||
}
|
||||
|
@ -964,24 +1091,40 @@ static NSMapTable *absolutes = 0;
|
|||
+ (NSArray*) knownTimeZoneNames
|
||||
{
|
||||
static NSArray *namesArray = nil;
|
||||
int i;
|
||||
id temp_array;
|
||||
NSArray *regionsArray, *array;
|
||||
|
||||
/* We create the array only when we need it to reduce overhead. */
|
||||
if (namesArray != nil)
|
||||
return namesArray;
|
||||
|
||||
temp_array = [NSMutableArray array];
|
||||
regionsArray = [self timeZoneArray];
|
||||
|
||||
for (i = 0; i < [regionsArray count]; i++)
|
||||
{
|
||||
array = [regionsArray objectAtIndex: i];
|
||||
[temp_array addObjectsFromArray: array];
|
||||
return namesArray;
|
||||
}
|
||||
|
||||
namesArray = [[NSArray alloc] initWithArray: temp_array];
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex lock];
|
||||
}
|
||||
if (namesArray == nil)
|
||||
{
|
||||
unsigned i;
|
||||
NSMutableArray *ma;
|
||||
NSArray *regionsArray;
|
||||
|
||||
ma = [NSMutableArray new];
|
||||
regionsArray = [self timeZoneArray];
|
||||
|
||||
for (i = 0; i < [regionsArray count]; i++)
|
||||
{
|
||||
NSArray *names = [regionsArray objectAtIndex: i];
|
||||
|
||||
[ma addObjectsFromArray: names];
|
||||
}
|
||||
|
||||
[ma makeImmutableCopyOnFail: NO];
|
||||
namesArray = ma;
|
||||
}
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex unlock];
|
||||
}
|
||||
return namesArray;
|
||||
}
|
||||
|
||||
|
@ -1205,8 +1348,8 @@ static NSMapTable *absolutes = 0;
|
|||
is a symlink to the time zone. Getting the actual data (which
|
||||
is easier) doesn't help, since we won't know the name itself. */
|
||||
#if defined(HAVE_TZHEAD) && defined(TZDEFAULT)
|
||||
tzdir = RETAIN([NSString stringWithCString: TZDIR]);
|
||||
localZoneString = [NSString stringWithCString: TZDEFAULT];
|
||||
tzdir = RETAIN([NSString stringWithUTF8String: TZDIR]);
|
||||
localZoneString = [NSString stringWithUTF8String: TZDEFAULT];
|
||||
localZoneString = [localZoneString stringByResolvingSymlinksInPath];
|
||||
#else
|
||||
NSFileManager *dflt = [NSFileManager defaultManager];
|
||||
|
@ -1257,7 +1400,7 @@ static NSMapTable *absolutes = 0;
|
|||
{
|
||||
tzset();
|
||||
if (tzname[0] != NULL && *tzname[0] != '\0')
|
||||
localZoneString = [NSString stringWithCString: tzname[0]];
|
||||
localZoneString = [NSString stringWithUTF8String: tzname[0]];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1291,7 +1434,7 @@ static NSMapTable *absolutes = 0;
|
|||
bufsize--;
|
||||
}
|
||||
localZoneString
|
||||
= [NSString stringWithCString: buf length: bufsize];
|
||||
= [NSString stringWithUTF8String: buf length: bufsize];
|
||||
}
|
||||
RegCloseKey(regkey);
|
||||
}
|
||||
|
@ -1332,6 +1475,18 @@ static NSMapTable *absolutes = 0;
|
|||
return zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common locations for timezone info on unix systems.
|
||||
*/
|
||||
static NSString *zoneDirs[] = {
|
||||
@"/usr/share/zoneinfo/",
|
||||
@"/usr/lib/zoneinfo/",
|
||||
@"/usr/local/share/zoneinfo/",
|
||||
@"/usr/local/lib/zoneinfo/",
|
||||
@"/etc/zoneinfo/",
|
||||
@"/usr/local/etc/zoneinfo/"
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an array of all the known regions.<br />
|
||||
* There are 24 elements, of course, one for each time zone.
|
||||
|
@ -1341,39 +1496,159 @@ static NSMapTable *absolutes = 0;
|
|||
+ (NSArray*) timeZoneArray
|
||||
{
|
||||
static NSArray *regionsArray = nil;
|
||||
int index, i;
|
||||
char name[80];
|
||||
FILE *file;
|
||||
id temp_array[24];
|
||||
NSString *fileName;
|
||||
|
||||
/* We create the array only when we need it to reduce overhead. */
|
||||
if (regionsArray != nil)
|
||||
return regionsArray;
|
||||
{
|
||||
return regionsArray;
|
||||
}
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex lock];
|
||||
}
|
||||
if (regionsArray == nil)
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
int index, i;
|
||||
char name[80];
|
||||
FILE *fp;
|
||||
NSMutableArray *temp_array[24];
|
||||
NSString *path;
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
temp_array[i] = [NSMutableArray array];
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
temp_array[i] = [NSMutableArray array];
|
||||
}
|
||||
|
||||
fileName = _time_zone_path (REGIONS_FILE, nil);
|
||||
path = _time_zone_path (REGIONS_FILE, nil);
|
||||
if (path != nil)
|
||||
{
|
||||
#if defined(__MINGW32__)
|
||||
{
|
||||
unichar mode[3];
|
||||
mode[0] = 'r';
|
||||
mode[1] = 'b';
|
||||
mode[2] = '\0';
|
||||
file = _wfopen((const unichar*)[fileName fileSystemRepresentation], mode);
|
||||
}
|
||||
unichar mode[3];
|
||||
|
||||
mode[0] = 'r';
|
||||
mode[1] = 'b';
|
||||
mode[2] = '\0';
|
||||
|
||||
fp = _wfopen((const unichar*)[path fileSystemRepresentation], mode);
|
||||
#else
|
||||
file = fopen([fileName fileSystemRepresentation], "r");
|
||||
fp = fopen([path fileSystemRepresentation], "r");
|
||||
#endif
|
||||
if (file == NULL)
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone regions array file."];
|
||||
while (fscanf(file, "%d %s", &index, name) == 2)
|
||||
[temp_array[index] addObject: [NSString stringWithCString: name]];
|
||||
fclose(file);
|
||||
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
|
||||
if (fp == NULL)
|
||||
{
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex unlock];
|
||||
}
|
||||
[NSException
|
||||
raise: NSInternalInconsistencyException
|
||||
format: @"Failed to open time zone regions array file."];
|
||||
}
|
||||
while (fscanf(fp, "%d %s", &index, name) == 2)
|
||||
{
|
||||
[temp_array[index]
|
||||
addObject: [NSString stringWithUTF8String: name]];
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
NSString *zonedir = nil;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sizeof(zoneDirs)/sizeof(zoneDirs[0]); i++)
|
||||
{
|
||||
BOOL isDir;
|
||||
|
||||
path = [zoneDirs[i] stringByAppendingString: POSIX_TZONES];
|
||||
if ([mgr fileExistsAtPath: path isDirectory: &isDir] && isDir)
|
||||
{
|
||||
zonedir = path;
|
||||
break; // use first one
|
||||
}
|
||||
}
|
||||
|
||||
if (zonedir == nil)
|
||||
{
|
||||
NSLog(@"no zone directory found!");
|
||||
}
|
||||
else
|
||||
{
|
||||
NSDirectoryEnumerator *enumerator;
|
||||
NSString *name;
|
||||
|
||||
enumerator = [mgr enumeratorAtPath: zonedir];
|
||||
while ((name = [enumerator nextObject]) != nil)
|
||||
{
|
||||
NSTimeZone *zone = nil;
|
||||
BOOL isDir;
|
||||
|
||||
// FIXME: check file validity.
|
||||
|
||||
path = [zonedir stringByAppendingString: name];
|
||||
if ([mgr fileExistsAtPath: path isDirectory: &isDir]
|
||||
&& isDir == NO)
|
||||
{
|
||||
zone = [zoneDictionary objectForKey: name];
|
||||
if (zone == nil)
|
||||
{
|
||||
NSData *data;
|
||||
|
||||
data = [NSData dataWithContentsOfFile: path];
|
||||
zone = [[self alloc] initWithName: name data: data];
|
||||
AUTORELEASE(zone);
|
||||
}
|
||||
if (zone != nil)
|
||||
{
|
||||
int offset;
|
||||
NSArray *details;
|
||||
NSTimeZoneDetail *detail;
|
||||
NSEnumerator *e;
|
||||
|
||||
details = [zone timeZoneDetailArray];
|
||||
e = [details objectEnumerator];
|
||||
|
||||
while ((detail = [e nextObject]) != nil)
|
||||
{
|
||||
if ([detail isDaylightSavingTime] == NO)
|
||||
{
|
||||
break; // Found a standard time
|
||||
}
|
||||
}
|
||||
if (detail == nil && [details count] > 0)
|
||||
{
|
||||
// If no standard time
|
||||
detail = [details objectAtIndex: 0];
|
||||
}
|
||||
|
||||
offset = [detail secondsFromGMT];
|
||||
if (offset < 0)
|
||||
{
|
||||
offset = -offset;
|
||||
offset %= (60 * 60 * 24);
|
||||
offset = -offset;
|
||||
offset += (60 * 60 * 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
offset %= (60 * 60 * 24);
|
||||
}
|
||||
offset /= (60 * 60);
|
||||
|
||||
[temp_array[offset] addObject: name];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
regionsArray = [[NSArray alloc] initWithObjects: temp_array count: 24];
|
||||
RELEASE(pool);
|
||||
}
|
||||
if (zone_mutex != nil)
|
||||
{
|
||||
[zone_mutex unlock];
|
||||
}
|
||||
return regionsArray;
|
||||
}
|
||||
|
||||
|
@ -1403,7 +1678,7 @@ static NSMapTable *absolutes = 0;
|
|||
NSTimeZone *zone;
|
||||
|
||||
zone = [self timeZoneWithName: [[self abbreviationDictionary]
|
||||
objectForKey: abbreviation] data: nil];
|
||||
objectForKey: abbreviation] data: nil];
|
||||
return zone;
|
||||
}
|
||||
|
||||
|
@ -1935,7 +2210,7 @@ int dayOfCommonEra(NSTimeInterval when);
|
|||
int a, b;
|
||||
|
||||
ASSIGN(timeZoneName,
|
||||
[NSString stringWithCString: standardName]);
|
||||
[NSString stringWithUTF8String: standardName]);
|
||||
|
||||
/* Abbr generated here is IMHO a
|
||||
* bit suspicous but I kept it */
|
||||
|
@ -1946,7 +2221,7 @@ int dayOfCommonEra(NSTimeInterval when);
|
|||
}
|
||||
standardName[b] = 0;
|
||||
ASSIGN(timeZoneNameAbbr,
|
||||
[NSString stringWithCString: standardName]);
|
||||
[NSString stringWithUTF8String: standardName]);
|
||||
}
|
||||
|
||||
/* Set the daylight savings name for the time zone. */
|
||||
|
@ -1955,7 +2230,7 @@ int dayOfCommonEra(NSTimeInterval when);
|
|||
int a, b;
|
||||
|
||||
ASSIGN(daylightZoneName,
|
||||
[NSString stringWithCString: daylightName]);
|
||||
[NSString stringWithUTF8String: daylightName]);
|
||||
|
||||
/* Abbr generated here is IMHO
|
||||
* a bit suspicous but I kept it */
|
||||
|
@ -1966,7 +2241,7 @@ int dayOfCommonEra(NSTimeInterval when);
|
|||
}
|
||||
daylightName[b] = 0;
|
||||
ASSIGN(daylightZoneNameAbbr,
|
||||
[NSString stringWithCString: daylightName]);
|
||||
[NSString stringWithUTF8String: daylightName]);
|
||||
}
|
||||
}
|
||||
RegCloseKey(regKey);
|
||||
|
@ -2228,14 +2503,9 @@ newDetailInZoneForType(GSTimeZone *zone, TypeInfo *type)
|
|||
{
|
||||
RELEASE(timeZoneName);
|
||||
RELEASE(timeZoneData);
|
||||
RELEASE(abbreviations);
|
||||
if (types != 0)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < n_types; i++)
|
||||
{
|
||||
RELEASE(types[i].abbreviation);
|
||||
}
|
||||
NSZoneFree(NSDefaultMallocZone(), types);
|
||||
}
|
||||
[super dealloc];
|
||||
|
@ -2335,7 +2605,9 @@ newDetailInZoneForType(GSTimeZone *zone, TypeInfo *type)
|
|||
}
|
||||
abbr = (unsigned char*)(bytes + pos);
|
||||
{
|
||||
id abbrevs[charcnt];
|
||||
id abbrevs[charcnt];
|
||||
unsigned count = 0;
|
||||
unsigned used = 0;
|
||||
|
||||
memset(abbrevs, '\0', sizeof(id)*charcnt);
|
||||
for (i = 0; i < n_types; i++)
|
||||
|
@ -2345,14 +2617,38 @@ newDetailInZoneForType(GSTimeZone *zone, TypeInfo *type)
|
|||
if (abbrevs[loc] == nil)
|
||||
{
|
||||
abbrevs[loc]
|
||||
= [[NSString alloc] initWithCString: (char*)abbr + loc];
|
||||
}
|
||||
else
|
||||
{
|
||||
RETAIN(abbrevs[loc]);
|
||||
= [[NSString alloc] initWithUTF8String: (char*)abbr + loc];
|
||||
count++;
|
||||
}
|
||||
types[i].abbreviation = abbrevs[loc];
|
||||
}
|
||||
/*
|
||||
* Now we have created all the abbreviations, we put them in an
|
||||
* array for easy access later and easy deallocation if/when
|
||||
* the receiver is deallocated.
|
||||
*/
|
||||
i = charcnt;
|
||||
while (i-- > count)
|
||||
{
|
||||
if (abbrevs[i] != nil)
|
||||
{
|
||||
while (abbrevs[used] != nil)
|
||||
{
|
||||
used++;
|
||||
}
|
||||
abbrevs[used] = abbrevs[i];
|
||||
abbrevs[i] = nil;
|
||||
if (++used >= count)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
abbreviations = [[NSArray alloc] initWithObjects: abbrevs count: count];
|
||||
while (count-- > 0)
|
||||
{
|
||||
RELEASE(abbrevs[count]);
|
||||
}
|
||||
}
|
||||
|
||||
if (zone_mutex != nil)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue