1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
3f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius * Copyright (C) 2001-2014, International Business Machines Corporation and    *
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved.                                                *
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/resbund.h"
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uresimp.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "servloc.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "ustrfmt.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uhash.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "charstr.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h"
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define UNDERSCORE_CHAR ((UChar)0x005f)
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define AT_SIGN_CHAR    ((UChar)64)
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define PERIOD_CHAR     ((UChar)46)
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey*
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       const UnicodeString* canonicalFallbackID,
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       UErrorCode& status)
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LocaleKey::createWithCanonicalFallback(primaryID, canonicalFallbackID, KIND_ANY, status);
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey*
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::createWithCanonicalFallback(const UnicodeString* primaryID,
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       const UnicodeString* canonicalFallbackID,
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       int32_t kind,
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       UErrorCode& status)
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (primaryID == NULL || U_FAILURE(status)) {
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString canonicalPrimaryID;
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LocaleUtility::canonicalLocaleString(primaryID, canonicalPrimaryID);
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return new LocaleKey(*primaryID, canonicalPrimaryID, canonicalFallbackID, kind);
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::LocaleKey(const UnicodeString& primaryID,
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     const UnicodeString& canonicalPrimaryID,
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     const UnicodeString* canonicalFallbackID,
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     int32_t kind)
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  : ICUServiceKey(primaryID)
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  , _kind(kind)
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  , _primaryID(canonicalPrimaryID)
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  , _fallbackID()
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  , _currentID()
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _fallbackID.setToBogus();
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (_primaryID.length() != 0) {
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (canonicalFallbackID != NULL && _primaryID != *canonicalFallbackID) {
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _fallbackID = *canonicalFallbackID;
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _currentID = _primaryID;
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::~LocaleKey() {}
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::prefix(UnicodeString& result) const {
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (_kind != KIND_ANY) {
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UChar buffer[64];
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_itou(buffer, 64, _kind, 10, 0);
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UnicodeString temp(buffer);
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        result.append(temp);
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::kind() const {
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return _kind;
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::canonicalID(UnicodeString& result) const {
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result.append(_primaryID);
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::currentID(UnicodeString& result) const {
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!_currentID.isBogus()) {
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        result.append(_currentID);
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::currentDescriptor(UnicodeString& result) const {
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!_currentID.isBogus()) {
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        prefix(result).append(PREFIX_DELIMITER).append(_currentID);
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        result.setToBogus();
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocale&
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::canonicalLocale(Locale& result) const {
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LocaleUtility::initLocaleFromName(_primaryID, result);
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocale&
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::currentLocale(Locale& result) const {
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return LocaleUtility::initLocaleFromName(_currentID, result);
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::fallback() {
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!_currentID.isBogus()) {
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int x = _currentID.lastIndexOf(UNDERSCORE_CHAR);
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (x != -1) {
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _currentID.remove(x); // truncate current or fallback, whichever we're pointing to
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return TRUE;
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!_fallbackID.isBogus()) {
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _currentID = _fallbackID;
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _fallbackID.setToBogus();
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return TRUE;
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (_currentID.length() > 0) {
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            _currentID.remove(0); // completely truncate
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return TRUE;
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        _currentID.setToBogus();
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::isFallbackOf(const UnicodeString& id) const {
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString temp(id);
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    parseSuffix(temp);
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return temp.indexOf(_primaryID) == 0 &&
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        (temp.length() == _primaryID.length() ||
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        temp.charAt(_primaryID.length()) == UNDERSCORE_CHAR);
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef SERVICE_DEBUG
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::debug(UnicodeString& result) const
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ICUServiceKey::debug(result);
1611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    result.append((UnicodeString)" kind: ");
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result.append(_kind);
1631b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    result.append((UnicodeString)" primaryID: ");
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result.append(_primaryID);
1651b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    result.append((UnicodeString)" fallbackID: ");
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result.append(_fallbackID);
1671b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    result.append((UnicodeString)" currentID: ");
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result.append(_currentID);
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString&
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocaleKey::debugClass(UnicodeString& result) const
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
1751b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    return result.append((UnicodeString)"LocaleKey ");
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(LocaleKey)
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* !UCONFIG_NO_SERVICE */
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
187