00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include <map> 00014 00015 #include "zypp/Locale.h" 00016 #include "zypp/ZConfig.h" 00017 00018 using std::endl; 00019 00021 namespace zypp 00022 { 00023 00024 typedef std::map<std::string, std::string> OtherDefaultLanguage; 00025 static OtherDefaultLanguage otherDefaultLanguage; 00026 00028 // 00029 // CLASS NAME : Locale::Impl 00030 // 00032 struct Locale::Impl 00033 { 00034 Impl() 00035 {} 00036 00037 Impl( const std::string & code_r ) 00038 { 00039 std::string t; 00040 std::string::size_type sep = code_r.find_first_of( "@." ); 00041 if ( sep == std::string::npos ) { 00042 t = code_r; 00043 } else { 00044 t = code_r.substr( 0, sep ); 00045 } 00046 00047 sep = t.find( '_' ); 00048 if ( sep == std::string::npos ) { 00049 _language = LanguageCode( t ); 00050 } else { 00051 _language = LanguageCode( t.substr( 0, sep ) ); 00052 _country = CountryCode( t.substr( sep+1 ) ); 00053 } 00054 } 00055 00056 Impl( const LanguageCode & language_r, 00057 const CountryCode & country_r ) 00058 : _language( language_r ) 00059 , _country( country_r ) 00060 {} 00061 00062 const LanguageCode & language() const 00063 { return _language; } 00064 00065 const CountryCode & country() const 00066 { return _country; } 00067 00068 std::string code() const 00069 { 00070 std::string ret( _language.code() ); 00071 if ( _country.hasCode() ) 00072 ret += "_" + _country.code(); 00073 return ret; 00074 } 00075 00076 std::string name() const 00077 { 00078 std::string ret( _language.name() ); 00079 if ( _country.hasCode() ) 00080 ret += " (" + _country.name() + ")"; 00081 return ret; 00082 } 00083 00084 Locale fallback() const 00085 { 00086 if (otherDefaultLanguage.size() == 0) { 00087 // initial inserting map 00088 otherDefaultLanguage["pt_BR"] = "en"; 00089 } 00090 00091 if (otherDefaultLanguage.find(code()) != otherDefaultLanguage.end()) 00092 return LanguageCode(otherDefaultLanguage[code()]); 00093 00094 if ( _country.hasCode() ) 00095 return _language; 00096 00097 if ( _language.hasCode() && _language != LanguageCode("en") ) 00098 return LanguageCode("en"); 00099 00100 return Locale(); 00101 } 00102 00103 private: 00104 00105 LanguageCode _language; 00106 CountryCode _country; 00107 00108 public: 00110 static shared_ptr<Impl> nullimpl() 00111 { 00112 static shared_ptr<Impl> _nullimpl( new Impl ); 00113 return _nullimpl; 00114 } 00115 }; 00117 00119 inline std::ostream & operator<<( std::ostream & str, const Locale::Impl & obj ) 00120 { 00121 return str << "Locale::Impl"; 00122 } 00123 00125 // 00126 // CLASS NAME : Locale 00127 // 00129 00130 const Locale Locale::noCode; 00131 00133 // 00134 // METHOD NAME : Locale::Locale 00135 // METHOD TYPE : Ctor 00136 // 00137 Locale::Locale() 00138 : _pimpl( Impl::nullimpl() ) 00139 {} 00140 00142 // 00143 // METHOD NAME : Locale::Locale 00144 // METHOD TYPE : Ctor 00145 // 00146 Locale::Locale( IdString code_r ) 00147 : _pimpl( new Impl( code_r.asString() ) ) 00148 {} 00149 00151 // 00152 // METHOD NAME : Locale::Locale 00153 // METHOD TYPE : Ctor 00154 // 00155 Locale::Locale( const std::string & code_r ) 00156 : _pimpl( new Impl( code_r ) ) 00157 {} 00158 00160 // 00161 // METHOD NAME : Locale::Locale 00162 // METHOD TYPE : Ctor 00163 // 00164 Locale::Locale( const char * code_r ) 00165 : _pimpl( new Impl( C_Str(code_r).c_str() ) ) 00166 {} 00167 00169 // 00170 // METHOD NAME : Locale::Locale 00171 // METHOD TYPE : Ctor 00172 // 00173 Locale::Locale( const LanguageCode & language_r, 00174 const CountryCode & country_r ) 00175 : _pimpl( new Impl( language_r, country_r ) ) 00176 {} 00177 00179 // 00180 // METHOD NAME : Locale::~Locale 00181 // METHOD TYPE : Dtor 00182 // 00183 Locale::~Locale() 00184 {} 00185 00187 // 00188 // METHOD NAME : Locale:: 00189 // METHOD TYPE : 00190 // 00191 const LanguageCode & Locale::language() const 00192 { return _pimpl->language(); } 00193 00195 // 00196 // METHOD NAME : Locale:: 00197 // METHOD TYPE : 00198 // 00199 const CountryCode & Locale::country() const 00200 { return _pimpl->country(); } 00201 00203 // 00204 // METHOD NAME : Locale:: 00205 // METHOD TYPE : 00206 // 00207 std::string Locale::code() const 00208 { return _pimpl->code(); } 00209 00211 // 00212 // METHOD NAME : Locale:: 00213 // METHOD TYPE : 00214 // 00215 std::string Locale::name() const 00216 { return _pimpl->name(); } 00217 00219 // 00220 // METHOD NAME : Locale:: 00221 // METHOD TYPE : 00222 // 00223 Locale Locale::fallback() const 00224 { return _pimpl->fallback(); } 00225 00226 00228 00229 Locale Locale::bestMatch( const LocaleSet & avLocales_r, const Locale & requested_r ) 00230 { 00231 if ( ! avLocales_r.empty() ) 00232 { 00233 for ( Locale check( requested_r == noCode ? ZConfig::instance().textLocale() : requested_r ); 00234 check != noCode; check = check.fallback() ) 00235 { 00236 if ( avLocales_r.find( check ) != avLocales_r.end() ) 00237 return check; 00238 } 00239 } 00240 return noCode; 00241 } 00242 00243 00245 } // namespace zypp