Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Locale.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6#include <set>
7
9#include "Stroika/Foundation/Execution/Exceptions.h"
10#include "Stroika/Foundation/Execution/Throw.h"
11
12#include "Locale.h"
13
14using namespace Stroika::Foundation;
16using namespace Stroika::Foundation::Common;
17
18// Comment this in to turn on aggressive noisy DbgTrace in this module
19//#define USE_NOISY_TRACE_IN_THIS_MODULE_ 1
20
21/*
22 ********************************************************************************
23 ********************* Common::LocaleNotFoundException **************************
24 ********************************************************************************
25 */
26LocaleNotFoundException::LocaleNotFoundException (const optional<String>& iso2LetterLanguageCode, const optional<String>& iso2LetterTerritoryCode)
27 : RuntimeErrorException{(iso2LetterLanguageCode.has_value () or iso2LetterTerritoryCode.has_value ())
28 ? "Locale ({}-{}) not found"_f(iso2LetterLanguageCode.value_or (""sv), iso2LetterTerritoryCode.value_or (""sv))
29 : "Locale not found"_k}
30{
31}
32
33/*
34 ********************************************************************************
35 *************** Common::UsePlatformDefaultLocaleAsDefaultLocale ****************
36 ********************************************************************************
37 */
42
43/*
44 ********************************************************************************
45 ************************* Common::GetAvailableLocales **************************
46 ********************************************************************************
47 */
48#if 0
49EnumSystemLocales(EnumLocalesProc, LCID_INSTALLED);
50// the enumeration callback function
51BOOL CALLBACK EnumLocalesProc(LPTSTR lpLocaleString)
52{
53 LCID uiCurLocale;
54 TCHAR szCurNam[STR_LEN];
55 if (!lpLocaleString)
56 return FALSE;
57// This enumeration returns the LCID as a character string while
58// we will be using numbers in other NLS calls.
59 uiCurLocale = uiConvertStrToInt(lpLocaleString);
60// Get the language name associated with this locale ID.
61 GetLocaleInfo(uiCurLocale, LOCALE_SLANGUAGE, szCurName, STR_LEN);
62 return TRUE;
63}
64#endif
65vector<Characters::String> Common::GetAvailableLocales ()
66{
67 // @todo
68 // horrible!!!! - see TOOD
69 vector<Characters::String> result;
70 result.reserve (10);
71 IgnoreExceptionsForCall (result.push_back (FindLocaleName ("en"sv, "us"sv)));
72 return result;
73}
74
75/*
76 ********************************************************************************
77 **************************** Common::FindLocaleName ****************************
78 ********************************************************************************
79 */
80Characters::String Common::FindLocaleName (const Characters::String& iso2LetterLanguageCode, const Characters::String& iso2LetterTerritoryCode)
81{
82 if (auto r = FindLocaleNameQuietly (iso2LetterLanguageCode, iso2LetterTerritoryCode)) {
83 return *r;
84 }
85 Execution::Throw (LocaleNotFoundException{iso2LetterLanguageCode, iso2LetterTerritoryCode});
86}
87
88optional<Characters::String> Common::FindLocaleNameQuietly (const Characters::String& iso2LetterLanguageCode, const Characters::String& iso2LetterTerritoryCode)
89{
90 using namespace Characters;
91 Require (iso2LetterLanguageCode.length () == 2);
92 Require (iso2LetterTerritoryCode.length () == 2); // may lift this in the future and make it optional
93
94#if USE_NOISY_TRACE_IN_THIS_MODULE_
95 Debug::TraceContextBumper ctx{"Common::FindLocaleName", "{},{}"_f, iso2LetterLanguageCode, iso2LetterTerritoryCode};
96#endif
97
98 // This is a HORRIBLE way - but I know of no better (especially no better portable way).
99 // See todo for planned fixes
100 // --LGP 2013-03-02
101 //
102 // Could make less heinous with memoizing, but not currently used much, and I plan todo much better impl...
103 set<String> part1{
104 iso2LetterLanguageCode,
105 iso2LetterLanguageCode.ToLowerCase (),
106 iso2LetterLanguageCode.ToUpperCase (),
107 };
108 static const set<String> part2{
109 "-"sv,
110 "_"sv,
111 "."sv,
112 " "sv,
113 };
114 set<String> part3{
115 iso2LetterTerritoryCode,
116 iso2LetterTerritoryCode.ToLowerCase (),
117 iso2LetterTerritoryCode.ToUpperCase (),
118 };
119 static const set<String> part4{
120 String{},
121 ".utf8"sv,
122 };
123 for (const auto& i1 : part1) {
124 for (const auto& i2 : part2) {
125 for (const auto& i3 : part3) {
126 for (const auto& i4 : part4) {
127#if USE_NOISY_TRACE_IN_THIS_MODULE_
128 DbgTrace ("***trying locale (i1 + i2 + i3 + i4)={}"_f, i1 + i2 + i3 + i4);
129#endif
130 IgnoreExceptionsForCall (return String::FromNarrowSDKString (locale{(i1 + i2 + i3 + i4).AsNarrowSDKString ().c_str ()}.name ()));
131 }
132 }
133 }
134 }
135 return nullopt;
136}
137
138/*
139 ********************************************************************************
140 ******************************* Common::FindNamedLocale ************************
141 ********************************************************************************
142 */
143locale Common::FindNamedLocale (const Characters::String& iso2LetterLanguageCode, const Characters::String& iso2LetterTerritoryCode)
144{
145 return locale{FindLocaleName (iso2LetterLanguageCode, iso2LetterTerritoryCode).AsNarrowSDKString ().c_str ()};
146}
147
148/*
149 ********************************************************************************
150 ********************** Common::FindNamedLocaleQuietly **************************
151 ********************************************************************************
152 */
153optional<locale> Common::FindNamedLocaleQuietly (const Characters::String& iso2LetterLanguageCode, const Characters::String& iso2LetterTerritoryCode)
154{
155 if (auto o = FindLocaleNameQuietly (iso2LetterLanguageCode, iso2LetterTerritoryCode)) {
156 return locale{o->AsNarrowSDKString ().c_str ()};
157 }
158 return nullopt;
159}
#define DbgTrace
Definition Trace.h:309
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual size_t length() const noexcept
Definition String.inl:1045
nonvirtual String ToUpperCase() const
Definition String.cpp:1744
nonvirtual string AsNarrowSDKString() const
Definition String.inl:830
nonvirtual String ToLowerCase() const
Definition String.cpp:1706
Characters::String FindLocaleName(const Characters::String &iso2LetterLanguageCode, const Characters::String &iso2LetterTerritoryCode)
Not all systems appear to follow the same naming conventions for locales, so help lookup.
Definition Locale.cpp:80
optional< Characters::String > FindLocaleNameQuietly(const Characters::String &iso2LetterLanguageCode, const Characters::String &iso2LetterTerritoryCode)
Not all systems appear to follow the same naming conventions for locales, so help lookup.
Definition Locale.cpp:88
vector< Characters::String > GetAvailableLocales()
List all installed locale names (names which can be passed to std::locale::CTOR)
Definition Locale.cpp:65
locale GetPlatformDefaultLocale()
Definition Locale.inl:13
locale FindNamedLocale(const Characters::String &iso2LetterLanguageCode, const Characters::String &iso2LetterTerritoryCode)
Find the locale matching these properties (for exception trying)
Definition Locale.cpp:143
void UsePlatformDefaultLocaleAsDefaultLocale()
Set the operating system locale into the current C++ locale used by locale functions (and most locale...
Definition Locale.cpp:38
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43