1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2011, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: ustrcase_locale.cpp
9 * encoding: US-ASCII
10 * tab size: 8 (not used)
11 * indentation:4
12 *
13 * created on: 2011may31
14 * created by: Markus W. Scherer
15 *
16 * Locale-sensitive case mapping functions (ones that call uloc_getDefault())
17 * were moved here to break dependency cycles among parts of the common library.
18 */
19
20 #include "unicode/utypes.h"
21 #include "unicode/ucasemap.h"
22 #include "unicode/uloc.h"
23 #include "unicode/ustring.h"
24 #include "ucase.h"
25 #include "ustr_imp.h"
26
27 U_CFUNC void
ustrcase_setTempCaseMapLocale(UCaseMap * csm,const char * locale)28 ustrcase_setTempCaseMapLocale(UCaseMap *csm, const char *locale) {
29 /*
30 * We could call ucasemap_setLocale(), but here we really only care about
31 * the initial language subtag, we need not return the real string via
32 * ucasemap_getLocale(), and we don't care about only getting "x" from
33 * "x-some-thing" etc.
34 *
35 * We ignore locales with a longer-than-3 initial subtag.
36 *
37 * We also do not fill in the locCache because it is rarely used,
38 * and not worth setting unless we reuse it for many case mapping operations.
39 * (That's why UCaseMap was created.)
40 */
41 int i;
42 char c;
43
44 /* the internal functions require locale!=NULL */
45 if(locale==NULL) {
46 // Do not call uprv_getDefaultLocaleID() because that does not see
47 // changes to the default locale via uloc_setDefault().
48 // It would also be inefficient if used frequently because uprv_getDefaultLocaleID()
49 // does not cache the locale ID.
50 //
51 // Unfortunately, uloc_getDefault() has many dependencies.
52 // We only care about a small set of language subtags,
53 // and we do not need the locale ID to be canonicalized.
54 //
55 // Best is to not call case mapping functions with a NULL locale ID.
56 locale=uloc_getDefault();
57 }
58 for(i=0; i<4 && (c=locale[i])!=0 && c!='-' && c!='_'; ++i) {
59 csm->locale[i]=c;
60 }
61 if(i<=3) {
62 csm->locale[i]=0; /* Up to 3 non-separator characters. */
63 } else {
64 csm->locale[0]=0; /* Longer-than-3 initial subtag: Ignore. */
65 }
66 }
67
68 /*
69 * Set parameters on an empty UCaseMap, for UCaseMap-less API functions.
70 * Do this fast because it is called with every function call.
71 */
72 static inline void
setTempCaseMap(UCaseMap * csm,const char * locale)73 setTempCaseMap(UCaseMap *csm, const char *locale) {
74 if(csm->csp==NULL) {
75 csm->csp=ucase_getSingleton();
76 }
77 if(locale!=NULL && locale[0]==0) {
78 csm->locale[0]=0;
79 } else {
80 ustrcase_setTempCaseMapLocale(csm, locale);
81 }
82 }
83
84 /* public API functions */
85
86 U_CAPI int32_t U_EXPORT2
u_strToLower(UChar * dest,int32_t destCapacity,const UChar * src,int32_t srcLength,const char * locale,UErrorCode * pErrorCode)87 u_strToLower(UChar *dest, int32_t destCapacity,
88 const UChar *src, int32_t srcLength,
89 const char *locale,
90 UErrorCode *pErrorCode) {
91 UCaseMap csm=UCASEMAP_INITIALIZER;
92 setTempCaseMap(&csm, locale);
93 return ustrcase_map(
94 &csm,
95 dest, destCapacity,
96 src, srcLength,
97 ustrcase_internalToLower, pErrorCode);
98 }
99
100 U_CAPI int32_t U_EXPORT2
u_strToUpper(UChar * dest,int32_t destCapacity,const UChar * src,int32_t srcLength,const char * locale,UErrorCode * pErrorCode)101 u_strToUpper(UChar *dest, int32_t destCapacity,
102 const UChar *src, int32_t srcLength,
103 const char *locale,
104 UErrorCode *pErrorCode) {
105 UCaseMap csm=UCASEMAP_INITIALIZER;
106 setTempCaseMap(&csm, locale);
107 return ustrcase_map(
108 &csm,
109 dest, destCapacity,
110 src, srcLength,
111 ustrcase_internalToUpper, pErrorCode);
112 }
113