Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / Locale.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/Locale.cc
10  *
11 */
12 #include <iostream>
13 #include <map>
14
15 #include "zypp/Locale.h"
16 #include "zypp/ZConfig.h"
17
18 using std::endl;
19
20 ///////////////////////////////////////////////////////////////////
21 namespace zypp
22 { /////////////////////////////////////////////////////////////////
23
24   typedef std::map<std::string, std::string> OtherDefaultLanguage;
25   static OtherDefaultLanguage otherDefaultLanguage;
26
27   ///////////////////////////////////////////////////////////////////
28   //
29   //    CLASS NAME : Locale::Impl
30   //
31   /** Locale implementation. */
32   struct Locale::Impl
33   {
34     Impl()
35     {}
36
37     Impl( const std::string & code_r )
38     {
39       std::string t;
40       std::string::size_type sep = code_r.find_first_of( "@." );
41       if ( sep == std::string::npos ) {
42         t = code_r;
43       } else {
44         t = code_r.substr( 0, sep );
45       }
46
47       sep = t.find( '_' );
48       if ( sep == std::string::npos ) {
49         _language = LanguageCode( t );
50       } else {
51         _language = LanguageCode( t.substr( 0, sep ) );
52         _country = CountryCode( t.substr( sep+1 ) );
53       }
54     }
55
56     Impl( const LanguageCode & language_r,
57           const CountryCode & country_r )
58     : _language( language_r )
59     , _country( country_r )
60     {}
61
62     const LanguageCode & language() const
63     { return _language; }
64
65     const CountryCode & country() const
66     { return _country; }
67
68     std::string code() const
69     {
70       std::string ret( _language.code() );
71       if ( _country.hasCode() )
72         ret += "_" + _country.code();
73       return ret;
74     }
75
76     std::string name() const
77     {
78       std::string ret( _language.name() );
79       if ( _country.hasCode() )
80         ret += " (" + _country.name() + ")";
81       return ret;
82     }
83
84     Locale fallback() const
85     {
86       if (otherDefaultLanguage.size() == 0) {
87           // initial inserting map
88           otherDefaultLanguage["pt_BR"] = "en";
89       }
90
91       if (otherDefaultLanguage.find(code()) != otherDefaultLanguage.end())
92           return LanguageCode(otherDefaultLanguage[code()]);
93
94       if ( _country.hasCode() )
95         return _language;
96
97       if ( _language.hasCode() && _language != LanguageCode("en") )
98         return LanguageCode("en");
99
100       return Locale();
101     }
102
103   private:
104
105     LanguageCode _language;
106     CountryCode _country;
107
108   public:
109     /** Offer default Impl. */
110     static shared_ptr<Impl> nullimpl()
111     {
112       static shared_ptr<Impl> _nullimpl( new Impl );
113       return _nullimpl;
114     }
115   };
116   ///////////////////////////////////////////////////////////////////
117
118   /** \relates Locale::Impl Stream output */
119   inline std::ostream & operator<<( std::ostream & str, const Locale::Impl & obj )
120   {
121     return str << "Locale::Impl";
122   }
123
124   ///////////////////////////////////////////////////////////////////
125   //
126   //    CLASS NAME : Locale
127   //
128   ///////////////////////////////////////////////////////////////////
129
130   const Locale Locale::noCode;
131
132   ///////////////////////////////////////////////////////////////////
133   //
134   //    METHOD NAME : Locale::Locale
135   //    METHOD TYPE : Ctor
136   //
137   Locale::Locale()
138   : _pimpl( Impl::nullimpl() )
139   {}
140
141   ///////////////////////////////////////////////////////////////////
142   //
143   //    METHOD NAME : Locale::Locale
144   //    METHOD TYPE : Ctor
145   //
146   Locale::Locale( IdString code_r )
147   : _pimpl( new Impl( code_r.asString() ) )
148   {}
149
150   ///////////////////////////////////////////////////////////////////
151   //
152   //    METHOD NAME : Locale::Locale
153   //    METHOD TYPE : Ctor
154   //
155   Locale::Locale( const std::string & code_r )
156   : _pimpl( new Impl( code_r ) )
157   {}
158
159   ///////////////////////////////////////////////////////////////////
160   //
161   //    METHOD NAME : Locale::Locale
162   //    METHOD TYPE : Ctor
163   //
164   Locale::Locale( const char * code_r )
165   : _pimpl( new Impl( C_Str(code_r).c_str() ) )
166   {}
167
168   ///////////////////////////////////////////////////////////////////
169   //
170   //    METHOD NAME : Locale::Locale
171   //    METHOD TYPE : Ctor
172   //
173   Locale::Locale( const LanguageCode & language_r,
174                   const CountryCode & country_r )
175   : _pimpl( new Impl( language_r, country_r ) )
176   {}
177
178   ///////////////////////////////////////////////////////////////////
179   //
180   //    METHOD NAME : Locale::~Locale
181   //    METHOD TYPE : Dtor
182   //
183   Locale::~Locale()
184   {}
185
186   ///////////////////////////////////////////////////////////////////
187   //
188   //    METHOD NAME : Locale::
189   //    METHOD TYPE :
190   //
191   const LanguageCode & Locale::language() const
192   { return _pimpl->language(); }
193
194   ///////////////////////////////////////////////////////////////////
195   //
196   //    METHOD NAME : Locale::
197   //    METHOD TYPE :
198   //
199   const CountryCode & Locale::country() const
200   { return _pimpl->country(); }
201
202   ///////////////////////////////////////////////////////////////////
203   //
204   //    METHOD NAME : Locale::
205   //    METHOD TYPE :
206   //
207   std::string Locale::code() const
208   { return _pimpl->code(); }
209
210   ///////////////////////////////////////////////////////////////////
211   //
212   //    METHOD NAME : Locale::
213   //    METHOD TYPE :
214   //
215   std::string Locale::name() const
216   { return _pimpl->name(); }
217
218   ///////////////////////////////////////////////////////////////////
219   //
220   //    METHOD NAME : Locale::
221   //    METHOD TYPE :
222   //
223   Locale Locale::fallback() const
224   { return _pimpl->fallback(); }
225
226
227   ///////////////////////////////////////////////////////////////////
228
229   Locale Locale::bestMatch( const LocaleSet & avLocales_r, const Locale & requested_r )
230   {
231     if ( ! avLocales_r.empty() )
232     {
233       for ( Locale check( requested_r == noCode ? ZConfig::instance().textLocale() : requested_r );
234             check != noCode; check = check.fallback() )
235       {
236         if ( avLocales_r.find( check ) != avLocales_r.end() )
237           return check;
238       }
239     }
240     return noCode;
241   }
242
243
244   /////////////////////////////////////////////////////////////////
245 } // namespace zypp
246 ///////////////////////////////////////////////////////////////////