diff --git a/ChangeLog b/ChangeLog index 6bfc06d27..5552ddba3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-06-25 Richard Frith-Macdonald + + * Headers/Foundation/Foundation.h: add NSLocale + * Headers/Foundation/NSLocale.h: rewrite/document + * Source/GNUmakefile: add NSLocale + * Source/NSLocale.m: fixup headers and disable temporarily (so that + base will still build) + +2010-06-25 Stef Bidi + + * Headers/Foundation/NSLocale.h + * Source/NSLocale.m + Partial NSLocale implementation wrapping ICU + 2010-06-23 Richard Frith-Macdonald * Source/NSBundle.m: When looking up paths, if no extension is provided diff --git a/Headers/Foundation/Foundation.h b/Headers/Foundation/Foundation.h index baefe0be5..d2486cfb0 100644 --- a/Headers/Foundation/Foundation.h +++ b/Headers/Foundation/Foundation.h @@ -78,6 +78,7 @@ #import #import #import +#import #import #import #import diff --git a/Headers/Foundation/NSLocale.h b/Headers/Foundation/NSLocale.h new file mode 100644 index 000000000..903ed2e04 --- /dev/null +++ b/Headers/Foundation/NSLocale.h @@ -0,0 +1,225 @@ +/* NSLocale.h + + Copyright (C) 2010 Free Software Foundation, Inc. + + Written by: Stefan Bidigaray, Richard Frith-Macdonald + Date: June, 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef __NSLocale_h_GNUSTEP_BASE_INCLUDE +#define __NSLocale_h_GNUSTEP_BASE_INCLUDE + +#import + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GSAPI_LAST) + +#import + +#if defined(__cplusplus) +extern "C" { +#endif + +@class NSMutableDictionary; +@class NSString; + +typedef NSUInteger NSLocaleLanguageDirection; +enum +{ + NSLocaleLanguageDirectionUnknown = 0, + NSLocaleLanguageDirectionLeftToRight = 1, + NSLocaleLanguageDirectionRightToLeft = 2, + NSLocaleLanguageDirectionTopToBottom = 3, + NSLocaleLanguageDirectionBottomToTop = 4 +}; + +GS_EXPORT NSString * const NSCurrentLocaleDidChangeNotification; + +// +// NSLocale Component Keys +// +GS_EXPORT NSString * const NSLocaleIdentifier; +GS_EXPORT NSString * const NSLocaleLanguageCode; +GS_EXPORT NSString * const NSLocaleCountryCode; +GS_EXPORT NSString * const NSLocaleScriptCode; +GS_EXPORT NSString * const NSLocaleVariantCode; +GS_EXPORT NSString * const NSLocaleExemplarCharacterSet; +GS_EXPORT NSString * const NSLocaleCalendar; +GS_EXPORT NSString * const NSLocaleCollationIdentifier; +GS_EXPORT NSString * const NSLocaleUsesMetricSystem; +GS_EXPORT NSString * const NSLocaleMeasurementSystem; +GS_EXPORT NSString * const NSLocaleDecimalSeparator; +GS_EXPORT NSString * const NSLocaleGroupingSeparator; +GS_EXPORT NSString * const NSLocaleCurrencySymbol; +GS_EXPORT NSString * const NSLocaleCurrencyCode; +GS_EXPORT NSString * const NSLocaleCollatorIdentifier; +GS_EXPORT NSString * const NSLocaleQuotationBeginDelimiterKey; +GS_EXPORT NSString * const NSLocaleAlternateQuotationBeginDelimiterKey; +GS_EXPORT NSString * const NSLocaleAlternateQuotationEndDelimiterKey; + +// +// NSLocale Calendar Keys +// +GS_EXPORT NSString * const NSGregorianCalendar; +GS_EXPORT NSString * const NSBuddhistCalendar; +GS_EXPORT NSString * const NSChineseCalendar; +GS_EXPORT NSString * const NSHebrewCalendar; +GS_EXPORT NSString * const NSIslamicCalendar; +GS_EXPORT NSString * const NSIslamicCivilCalendar; +GS_EXPORT NSString * const NSJapaneseCalendar; +GS_EXPORT NSString * const NSRepublicOfChinaCalendar; +GS_EXPORT NSString * const NSPersianCalendar; +GS_EXPORT NSString * const NSIndianCalendar; +GS_EXPORT NSString * const NSISO8601Calendar; + +/** + * Provides information describing language, date and time, and currency + * information. + */ +@interface NSLocale : NSObject +{ +#if GS_EXPOSE(NSUserDefaults) +@private + NSString *_localeId; + NSMutableDictionary *_components; +#endif +#if !GS_NONFRAGILE + void *_unused; +#endif +} + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GSAPI_LAST) +/** Returns a version of the current locale which automatically updates + * when locale settngs are changed. + */ ++ (id) autoupdatingCurrentLocale; +#endif + +/** Returns an array of NSStrings with all the available locale identifiers. + */ ++ (NSArray *) availableLocaleIdentifiers; + +/** Returns the caoninical identifier for a language represented by + * the supplied string. + */ ++ (NSString *) canonicalLanguageIdentifierFromString: (NSString *)string; + +/** Returns the canonical identifier for a locale represented by the + * supplied string. + */ ++ (NSString *) canonicalLocaleIdentifierFromString: (NSString *)string; + +/** Returns the direction in which the language is written. + */ ++ (NSLocaleLanguageDirection) characterDirectionForLanguage: + (NSString *)isoLangCode; + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GSAPI_LAST) +/** Returns a list of available ISO currency code strings. + */ ++ (NSArray *) commonISOCurrencyCodes; +#endif + +/** Parses the supplied locale identifier and returns a dictionary containing + * its components.
+ * Components are NSLocaleLanguageCode, NSLocaleCountryCode, NSLocaleCalendar. + */ ++ (NSDictionary *) componentsFromLocaleIdentifier: (NSString *)string; + +/** Returns the current locale information. + */ ++ (id) currentLocale; + +/** Returns an array of NSString representing all known country codes. + */ ++ (NSArray *) ISOCountryCodes; + +/** Returns an array of NSString representing all known currency codes. + */ ++ (NSArray *) ISOCurrencyCodes; + +/** Returns an array of NSString representing all known language codes. + */ ++ (NSArray *) ISOLanguageCodes; + +/** Returns the direction in which lines of text in the specified + * language are written. + */ ++ (NSLocaleLanguageDirection) lineDirectionForLanguage: (NSString*)isoLangCode; + +/** Builds and returns a locale idntifier from the individual components + * supplied in dict.
+ * Components are NSLocaleLanguageCode, NSLocaleCountryCode, NSLocaleCalendar. + */ ++ (NSString *) localeIdentifierFromComponents: (NSDictionary*)dict; + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GSAPI_LAST) +/** Returns the standard locale identifier for the windows locale code. + */ ++ (NSString *) localeIdentifierFromWindowsLocaleCode: (uint32_t)lcid; +#endif + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_5, GSAPI_LAST) +/** Returns an array of preferred languages. Sorted from most preferred to + * leave preferred. + */ ++ (NSArray *) preferredLanguages; +#endif + +/** Returns the the system locale. + */ ++ (id) systemLocale; + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GSAPI_LAST) +/** Returns the windows locale code corresponding to the staqndard locale + * identifier. + */ ++ (uint32_t) windowsLocaleCodeFromLocaleIdentifier: + (NSString *)localeIdentifier; +#endif + +/** Returns the localised representation of the supplied value converted + * on the basis that it represents information whose type is specified by + * the key. + */ +- (NSString *) displayNameForKey: (id)key value: (id)value; + +/** Initialises the receiver to be the locale specified by the identifier. + * This may result in replacement of the receiver by an existing locale. + */ +- (id) initWithLocaleIdentifier: (NSString *)string; + +/** Returns the canonical identifier for the receiver (which + * may differ from the identifgier used to create the receiver + * since different identifiers may map to the same locale). + */ +- (NSString *) localeIdentifier; + +/** Returns the named object from the receiver locale. + */ +- (id) objectForKey: (id)key; + +@end + +#if defined(__cplusplus) +} +#endif + +#endif /* OS_API_VERSION(MAC_OS_X_VERSION_10_4, GSAPI_LAST) */ + +#endif /* __NSLocale_h_GNUSTEPBASE_INCLUDE */ diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 7dbcc5219..18d2e5d53 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -209,6 +209,7 @@ NSKeyedArchiver.m \ NSKeyedUnarchiver.m \ NSKeyValueCoding.m \ NSKeyValueObserving.m \ +NSLocale.m \ NSLock.m \ NSLog.m \ NSMapTable.m \ @@ -359,6 +360,7 @@ NSInvocation.h \ NSKeyedArchiver.h \ NSKeyValueCoding.h \ NSKeyValueObserving.h \ +NSLocale.h \ NSLock.h \ NSMapTable.h \ NSMethodSignature.h \ diff --git a/Source/NSLocale.m b/Source/NSLocale.m new file mode 100644 index 000000000..6d39bb617 --- /dev/null +++ b/Source/NSLocale.m @@ -0,0 +1,505 @@ +/* NSLocale.m + + Copyright (C) 2010 Free Software Foundation, Inc. + + Written by: Stefan Bidigaray + Date: June, 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; see the file COPYING.LIB. + If not, see or write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#import "common.h" +#import "Foundation/NSLocale.h" +#import "Foundation/NSArray.h" +#import "Foundation/NSDictionary.h" +#import "Foundation/NSLock.h" +#import "Foundation/NSUserDefaults.h" +#import "Foundation/NSString.h" +#import "GNUstepBase/GSLock.h" + +// +// NSLocale Component Keys +// +NSString * const NSLocaleIdentifier = @"NSLocaleIdentifier"; +NSString * const NSLocaleLanguageCode = @"NSLocaleLanguageCode"; +NSString * const NSLocaleCountryCode = @"NSLocaleCountryCode"; +NSString * const NSLocaleScriptCode = @"NSLocaleScriptCode"; +NSString * const NSLocaleVariantCode = @"NSLocaleVariantCode"; +NSString * const NSLocaleExemplarCharacterSet = @"NSLocaleExemplarCharacterSet"; +NSString * const NSLocaleCalendar = @"NSLocaleCalendar"; +NSString * const NSLocaleCollationIdentifier = @"NSLocaleCollationIdentifier"; +NSString * const NSLocaleUsesMetricSystem = @"NSLocaleUsesMetricSystem"; +NSString * const NSLocaleMeasurementSystem = @"NSLocaleMeasurementSystem"; +NSString * const NSLocaleDecimalSeparator = @"NSLocaleDecimalSeparator"; +NSString * const NSLocaleGroupingSeparator = @"NSLocaleGroupingSeparator"; +NSString * const NSLocaleCurrencySymbol = @"NSLocaleCurrencySymbol"; +NSString * const NSLocaleCurrencyCode = @"NSLocaleCurrencyCode"; +NSString * const NSLocaleCollatorIdentifier = @"NSLocaleCollatorIdentifier"; +NSString * const NSLocaleQuotationBeginDelimiterKey = + @"NSLocaleQuotationBeginDelimiterKey"; +NSString * const NSLocaleAlternateQuotationBeginDelimiterKey = + @"NSLocaleAlternateQuotationBeginDelimiterKey"; +NSString * const NSLocaleAlternateQuotationEndDelimiterKey = + @"NSLocaleAlternateQuotationEndDelimiterKey"; + +// +// NSLocale Calendar Keys +// +NSString * const NSGregorianCalendar = @"NSGregorianCalendar"; +NSString * const NSBuddhistCalendar = @"NSBuddhistCalendar"; +NSString * const NSChineseCalendar = @"NSChineseCalendar"; +NSString * const NSHebrewCalendar = @"NSHebrewCalendar"; +NSString * const NSIslamicCalendar = @"NSIslamicCalendar"; +NSString * const NSIslamicCivilCalendar = @"NSIslamicCivilCalendar"; +NSString * const NSJapaneseCalendar = @"NSJapaneseCalendar"; +NSString * const NSRepublicOfChinaCalendar = @"NSRepublicOfChinaCalendar"; +NSString * const NSPersianCalendar = @"NSPersianCalendar"; +NSString * const NSIndianCalendar = @"NSIndianCalendar"; +NSString * const NSISO8601Calendar = @"NSISO8601Calendar"; + +#if HAVE_ICU + +#include +#include +#include + +// +// ICU Component Keywords +// +static const char * ICUCalendarKeyword = "calendar"; +static const char * ICUCollationKeyword = "collation"; + +static NSLocaleLanguageDirection _ICUToNSLocaleOrientation (ULayoutType layout) +{ + switch (layout) + { + case ULOC_LAYOUT_LTR: + return NSLocaleLanguageDirectionLeftToRight; + case ULOC_LAYOUT_RTL: + return NSLocaleLanguageDirectionRightToLeft; + case ULOC_LAYOUT_TTB: + return NSLocaleLanguageDirectionTopToBottom; + case ULOC_LAYOUT_BTT: + return NSLocaleLanguageDirectionBottomToTop; + default: + return NSLocaleLanguageDirectionUnknown; + } +} + +static NSArray *_currencyCodesWithType (uint32_t currType) +{ + NSArray *result; + NSMutableArray *currencies = [[NSMutableArray alloc] initWithCapacity: 10]; + UErrorCode error = U_ZERO_ERROR; + UErrorCode status = U_ZERO_ERROR; + char *currCode; + UEnumeration *codes = ucurr_openISOCurrencies (currType, &error); + if (U_FAILURE(error)) + return nil; + + do + { + int32_t strLength; + currCode = uenum_next (codes, &strLength, &status); + if (U_FAILURE(status)) + { + uenum_close (codes); + return nil; + } + [currencies addObject: [NSString stringWithCString: currCode + length: strLength]]; + } while (NULL != currCode); + + uenum_close (codes); + result = [NSArray arrayWithArray: currencies]; + RELEASE (currencies); + return result; +} + + +static NSLocale *autoupdatingLocale = nil; +static NSLocale *currentLocale = nil; +static NSLocale *systemLocale = nil; +static NSMutableDictionary *allLocales = nil; +static NSRecursiveLock *classLock = nil; + +@implementation NSLocale + ++ (void) initialize +{ + if (self == [NSLocale class]) + { + classLock = [GSLazyRecursiveLock new]; + } +} + ++ (id) autoupdatingCurrentLocale +{ + // FIXME + NSLocale *result; + + [classLock lock]; + if (nil == autoupdatingLocale) + { + } + + result = RETAIN(autoupdatingLocale); + [classLock unlock]; + return AUTORELEASE(result); +} + ++ (NSArray *) availableLocaleIdentifiers +{ + NSArray *result; + NSMutableArray *available = [[NSMutableArray alloc] initWithCapacity: 10]; + int32_t i; + int32_t count = uloc_countAvailable (); + + for (i = 1 ; i <= count ; ++i) + { + const char *localeID = uloc_getAvailable (i); + [available addObject: [NSString stringWithCString: localeID]]; + } + + result = [NSArray arrayWithArray: available]; + RELEASE(available); + return result; +} + ++ (NSString *) canonicalLanguageIdentifierFromString: (NSString *) string +{ + // FIXME + return nil; +} + ++ (NSString *) canonicalLocaleIdentifierFromString: (NSString *) string +{ + // FIXME + return nil; +} + ++ (NSLocaleLanguageDirection) characterDirectionForLanguage: + (NSString *)isoLangCode +{ + ULayoutType result; + UErrorCode status = U_ZERO_ERROR; + + result = uloc_getCharacterOrientation ([isoLangCode cString], &status); + if (U_FAILURE(status) || ULOC_LAYOUT_UNKNOWN == result) + return NSLocaleLanguageDirectionUnknown; + + return _ICUToNSLocaleOrientation (result); +} + ++ (NSDictionary *) componentsFromLocaleIdentifier: (NSString *) string +{ + char buffer[ULOC_LANG_CAPACITY]; + int32_t strLength; + UErrorCode error = U_ZERO_ERROR; + NSDictionary *result; + NSMutableDictionary *tmpDict = + [[NSMutableDictionary alloc] initWithCapacity: 5]; + + strLength = + uloc_getLanguage ([string cString], buffer, ULOC_LANG_CAPACITY, &error); + if (U_SUCCESS(error)) + { + [tmpDict setObject: [NSString stringWithCString: buffer length: strLength] + forKey: NSLocaleLanguageCode]; + } + error = U_ZERO_ERROR; + + strLength = + uloc_getCountry ([string cString], buffer, ULOC_COUNTRY_CAPACITY, &error); + if (U_SUCCESS(error)) + { + [tmpDict setObject: [NSString stringWithCString: buffer length: strLength] + forKey: NSLocaleCountryCode]; + } + error = U_ZERO_ERROR; + + strLength = + uloc_getScript ([string cString], buffer, ULOC_SCRIPT_CAPACITY, &error); + if (U_SUCCESS(error)) + { + [tmpDict setObject: [NSString stringWithCString: buffer length: strLength] + forKey: NSLocaleScriptCode]; + } + error = U_ZERO_ERROR; + + strLength = + uloc_getVariant ([string cString], buffer, ULOC_LANG_CAPACITY, &error); + if (U_SUCCESS(error)) + { + [tmpDict setObject: [NSString stringWithCString: buffer length: strLength] + forKey: NSLocaleVariantCode]; + } + error = U_ZERO_ERROR; + + result = [NSDictionary dictionaryWithDictionary: tmpDict]; + RELEASE(tmpDict); + return result; +} + ++ (id) currentLocale +{ + NSLocale *result; + + [classLock lock]; + if (nil == currentLocale) + { + const char *cLocaleId = uloc_getDefault (); + NSString *localeId = [NSString stringWithCString: cLocaleId]; + currentLocale = [[NSLocale alloc] initWithLocaleIdentifier: localeId]; + } + + result = RETAIN(currentLocale); + [classLock unlock]; + return AUTORELEASE(result); + +} + ++ (NSArray *) commonISOCurrencyCodes +{ + return _currencyCodesWithType (UCURR_COMMON | UCURR_NON_DEPRECATED); +} + ++ (NSArray *) ISOCurrencyCodes +{ + return _currencyCodesWithType (UCURR_ALL); +} + ++ (NSArray *) ISOCountryCodes +{ + NSArray *result; + NSMutableArray *countries = [[NSMutableArray alloc] initWithCapacity: 10]; + const char *const *codes = uloc_getISOCountries (); + while (codes != NULL) + { + [countries addObject: [NSString stringWithCString: *codes]]; + ++codes; + } + result = [NSArray arrayWithArray: countries]; + RELEASE(countries); + return result; +} + ++ (NSArray *) ISOLanguageCodes +{ + NSArray *result; + NSMutableArray *languages = [[NSMutableArray alloc] initWithCapacity: 10]; + const char *const *codes = uloc_getISOCountries (); + while (codes != NULL) + { + [languages addObject: [NSString stringWithCString: *codes]]; + ++codes; + } + result = [NSArray arrayWithArray: languages]; + RELEASE(languages); + return result; +} + ++ (NSLocaleLanguageDirection) lineDirectionForLanguage: (NSString *) isoLangCode +{ + ULayoutType result; + UErrorCode status = U_ZERO_ERROR; + + result = uloc_getLineOrientation ([isoLangCode cString], &status); + if (U_FAILURE(status) || ULOC_LAYOUT_UNKNOWN == result) + return NSLocaleLanguageDirectionUnknown; + + return _ICUToNSLocaleOrientation (result); +} + ++ (NSArray *) preferredLanguages +{ + // FIXME + return [NSUserDefaults userLanguages]; +} + ++ (id) systemLocale +{ + // FIXME + NSLocale *result; + + [classLock lock]; + if (nil == systemLocale) + { + } + + result = RETAIN(systemLocale); + [classLock unlock]; + return AUTORELEASE(result); +} + ++ (NSString *) localeIdentifierFromComponents: (NSDictionary *) dict +{ + char buffer[ULOC_FULLNAME_CAPACITY]; + UErrorCode status = U_ZERO_ERROR; + const char *language = [[dict objectForKey: NSLocaleLanguageCode] cString]; + const char *script = [[dict objectForKey: NSLocaleScriptCode] cString]; + const char *country = [[dict objectForKey: NSLocaleCountryCode] cString]; + const char *variant = [[dict objectForKey: NSLocaleVariantCode] cString]; + const char *calendar = [[dict objectForKey: NSLocaleCalendar] cString]; + const char *collation = [[dict objectForKey: NSLocaleCollationIdentifier] cString]; + +#define __TEST_CODE(x) (x ? "_" : ""), (x ? x : "") + snprintf (buffer, ULOC_FULLNAME_CAPACITY, "%s%s%s%s%s%s%s", + (language ? language : ""), __TEST_CODE(script), + __TEST_CODE(country), __TEST_CODE(variant)); +#undef __TEST_CODE + + if (calendar) + { + uloc_setKeywordValue (ICUCalendarKeyword, calendar, buffer, + ULOC_FULLNAME_CAPACITY, &status); + } + if (collation) + { + uloc_setKeywordValue (ICUCollationKeyword, collation, buffer, + ULOC_FULLNAME_CAPACITY, &status); + } + + return [NSString stringWithCString: buffer]; +} + ++ (NSString *) localeIdentifierFromWindowsLocaleCode: (uint32_t) lcid +{ + char buffer[ULOC_FULLNAME_CAPACITY]; + UErrorCode status = U_ZERO_ERROR; + + int32_t length = + uloc_getLocaleForLCID (lcid, buffer, ULOC_FULLNAME_CAPACITY, &status); + if (U_FAILURE(status)) + return nil; + + return [NSString stringWithCString: buffer length: (NSUInteger)length]; +} + ++ (uint32_t) windowsLocaleCodeFromLocaleIdentifier: (NSString *)localeIdentifier +{ + return uloc_getLCID ([localeIdentifier cString]); +} + +- (NSString *) displayNameForKey: (id) key value: (id) value +{ + int32_t length; + unichar buffer[ULOC_FULLNAME_CAPACITY]; + UErrorCode status; + const char *locale = [[self localeIdentifier] cString]; + + length = uloc_getDisplayKeywordValue (locale, [key cString], + [value cString], (UChar *)buffer, sizeof(buffer)/sizeof(unichar), + &status); + if (U_FAILURE(status)) + return nil; + + return [NSString stringWithCharacters: buffer length: (NSUInteger)length]; +} + +- (id) initWithLocaleIdentifier: (NSString *) string +{ + NSLocale *newLocale; + NSString *localeId; + int32_t length; + char cLocaleId[ULOC_FULLNAME_CAPACITY]; + UErrorCode error = U_ZERO_ERROR; + + length = uloc_canonicalize ([string cString], cLocaleId, + ULOC_FULLNAME_CAPACITY, &error); + if (U_FAILURE(error)) + return nil; + localeId = [[NSString alloc] initWithCString: cLocaleId length: length]; + + if (nil == allLocales) + { + newLocale = [allLocales objectForKey: localeId]; + if (newLocale) + { + RELEASE(self); + return newLocale; + } + } + else + { + allLocales = [[NSMutableDictionary alloc] initWithCapacity: 0]; + } + + _localeId = localeId; + _components = [[NSMutableDictionary alloc] initWithCapacity: 0]; + [allLocales setObject: self forKey: localeId]; + + return self; +} + +- (NSString *) localeIdentifier +{ + return _localeId; +} + +- (id) objectForKey: (id) key +{ + // FIXME: this is really messy... + id result; + + if (key == NSLocaleIdentifier) + return _localeId; + + if ((result = [_components objectForKey: key])) + return result; + + [_components addEntriesFromDictionary: + [NSLocale componentsFromLocaleIdentifier: [self localeIdentifier]]]; + if ((result = [_components objectForKey: key])) + return result; + + // FIXME: look up other keywords with uloc_getKeywordValue(). + return nil; +} + +- (void) dealloc +{ + RELEASE(_localeId); + RELEASE(_components); + + [super dealloc]; +} + +// +// NSCoding +// +- (void) encodeWithCoder: (NSCoder *) encoder +{ +} + +- (id) initWithCoder: (NSCoder *) decoder +{ + return nil; +} + +// +// NSCopying +// +- (id) copyWithZone: (NSZone *) zone +{ + return RETAIN(self); +} + +@end + +#else +#endif