Imported Upstream version 16.3.2
[platform/upstream/libzypp.git] / zypp / LanguageCode.cc
index a10550e..851875d 100644 (file)
  *
 */
 #include <iostream>
-#include <map>
 
 #include "zypp/base/Logger.h"
 #include "zypp/base/String.h"
 #include "zypp/base/Gettext.h"
+#include "zypp/base/Hash.h"
 
 #include "zypp/LanguageCode.h"
 
@@ -22,207 +22,130 @@ using std::endl;
 
 ///////////////////////////////////////////////////////////////////
 namespace zypp
-{ /////////////////////////////////////////////////////////////////
-
+{
   ///////////////////////////////////////////////////////////////////
   namespace
-  { /////////////////////////////////////////////////////////////////
-
+  {
     /** Wrap static codemap data. */
-    struct CodeMaps // singleton
+    struct CodeMaps
     {
-      typedef std::map<std::string,std::string> CodeMap;
-      typedef CodeMap::const_iterator Index;
+      /** The singleton */
+      static CodeMaps & instance()
+      {
+       static CodeMaps _instance;
+       return _instance;
+      }
 
-      /** Return the CodeMap Index for \a code_r. */
-      static Index getIndex( const std::string & code_r )
+      /** Lookup (translated) name for \a index_r.*/
+      std::string name( IdString index_r )
       {
-        static CodeMaps _maps; // the singleton instance
-        return _maps.lookup( code_r );
+       Link link( getIndex( index_r ) );
+
+       std::string ret;
+       if ( link->second )
+       { ret = _(link->second); }
+       else
+       {
+         ret = _("Unknown language: ");
+         ret += "'";
+         ret += index_r.c_str();
+         ret += "'";
+       }
+       return ret;
       }
 
     private:
+      typedef std::unordered_map<std::string,const char *> CodeMap;
+      typedef CodeMap::const_iterator Link;
+
+      typedef std::unordered_map<IdString,Link> IndexMap;
+
       /** Ctor initializes the code maps.
        * http://www.loc.gov/standards/iso639-2/ISO-639-2_values_8bits.txt
       */
       CodeMaps();
 
-      /** Make shure the code is in the code maps and return it's index. */
-      inline Index lookup( const std::string & code_r );
-
-      /** Return index of \a code_r, if it's in the code maps. */
-      inline Index lookupCode( const std::string & code_r );
-
-    private:
-      /** Two letter codes. */
-      CodeMap iso639_1;
-      /** Three letter codes. */
-      CodeMap iso639_2;
-      /** All the stuff the application injects. */
-      CodeMap others;
-    };
-
-    inline CodeMaps::Index CodeMaps::lookupCode( const std::string & code_r )
-    {
-      switch ( code_r.size() )
-        {
-        case 2:
-          {
-            Index it = iso639_1.find( code_r );
-            if ( it != iso639_1.end() )
-              return it;
-          }
-          break;
-
-        case 3:
-          {
-            Index it = iso639_2.find( code_r );
-            if ( it != iso639_2.end() )
-              return it;
-          }
-          break;
-        }
-      // not found: check others
-      // !!! not found at all returns others.end()
-      return others.find( code_r );
-    }
-
-    inline CodeMaps::Index CodeMaps::lookup( const std::string & code_r )
-    {
-      Index it = lookupCode( code_r );
-      if ( it != others.end() )
-        return it;
+      /** Return \ref Link for \a index_r, creating it if necessary. */
+      Link getIndex( IdString index_r )
+      {
+       auto it = _indexMap.find( index_r );
+       return( it != _indexMap.end()
+             ? it->second
+             : newIndex( index_r, index_r.asString() ) );
+      }
 
-      // not found: Remember a new code
-      CodeMap::value_type nval( code_r, std::string() );
+      /** Return the CodeMap Index for \a code_r. */
+      Link newIndex( IdString index_r, const std::string & code_r )
+      {
+       Link link = _codeMap.find( code_r );
+       if ( link != _codeMap.end() )
+         return (_indexMap[index_r] = link);
 
-      if ( code_r.size() > 3 || code_r.size() < 2 )
-        WAR << "Malformed LanguageCode '" << code_r << "' (expect 2 or 3-letter)" << endl;
+       // not found: Remember a new code
+       CodeMap::value_type nval( code_r, nullptr );
 
-      std::string lcode( str::toLower( code_r ) );
-      if ( lcode != code_r )
-        {
-          WAR << "Malformed LanguageCode '" << code_r << "' (not lower case)" << endl;
-          // but maybe we're lucky with the lower case code
-          // and find a language name.
-          it = lookupCode( lcode );
-          if ( it != others.end() )
-            nval.second = it->second;
-        }
+       if ( code_r.size() > 3 || code_r.size() < 2 )
+         WAR << "Malformed LanguageCode '" << code_r << "' (expect 2 or 3-letter)" << endl;
 
-      MIL << "Remember LanguageCode '" << code_r << "': '" << nval.second << "'" << endl;
-      return others.insert( nval ).first;
-    }
+       std::string lcode( str::toLower( code_r ) );
+       if ( lcode != code_r )
+       {
+         WAR << "Malformed LanguageCode '" << code_r << "' (not lower case)" << endl;
+         // but maybe we're lucky with the lower case code
+         // and find a language name.
+         link = _codeMap.find( lcode );
+         if ( link != _codeMap.end() )
+         {
+           nval.second = link->second;
+         }
+       }
+       MIL << "Remember LanguageCode '" << code_r << "': '" << nval.second << "'" << endl;
+       return (_indexMap[index_r] = _codeMap.insert( nval ).first);
+      }
 
-    /////////////////////////////////////////////////////////////////
+    private:
+      CodeMap _codeMap;
+      IndexMap _indexMap;
+    };
   } // namespace
   ///////////////////////////////////////////////////////////////////
 
   ///////////////////////////////////////////////////////////////////
-  //
-  //   CLASS NAME : LanguageCode::Impl
-  //
-  /** LanguageCode implementation.
-   * \note CodeMaps contain the untranslated language names.
-   * Translation is done in \ref name.
-  */
-  struct LanguageCode::Impl
-  {
-    Impl()
-    : _index( CodeMaps::getIndex( std::string() ) )
-    {}
-
-    Impl( const std::string & code_r )
-    : _index( CodeMaps::getIndex( code_r ) )
-    {}
-
-    std::string code() const
-    { return _index->first; }
-
-    std::string name() const {
-      if ( _index->second.empty() )
-        {
-          std::string ret( _("Unknown language: ") );
-          ret += "'";
-          ret += _index->first;
-          ret += "'";
-          return ret;
-        }
-      return _( _index->second.c_str() );
-    }
-
-  private:
-    /** index into code map. */
-    CodeMaps::Index _index;
-
-  public:
-    /** Offer default Impl. */
-    static shared_ptr<Impl> nullimpl()
-    {
-      static shared_ptr<Impl> _nullimpl( new Impl );
-      return _nullimpl;
-    }
-  };
-  ///////////////////////////////////////////////////////////////////
-
-  ///////////////////////////////////////////////////////////////////
-  //
-  //   CLASS NAME : LanguageCode
-  //
+  //   class LanguageCode
   ///////////////////////////////////////////////////////////////////
 
   const LanguageCode LanguageCode::noCode;
+  //const LanguageCode LanguageCode::enCode("en");     in Locale.cc as Locale::enCode depends on it
 
-  ///////////////////////////////////////////////////////////////////
-  //
-  //   METHOD NAME : LanguageCode::LanguageCode
-  //   METHOD TYPE : Ctor
-  //
   LanguageCode::LanguageCode()
-  : _pimpl( Impl::nullimpl() )
   {}
 
-  ///////////////////////////////////////////////////////////////////
-  //
-  //   METHOD NAME : LanguageCode::LanguageCode
-  //   METHOD TYPE : Ctor
-  //
-  LanguageCode::LanguageCode( const std::string & code_r )
-  : _pimpl( new Impl( code_r ) )
+  LanguageCode::LanguageCode( IdString str_r )
+  : _str( str_r )
+  {}
+
+  LanguageCode::LanguageCode( const std::string & str_r )
+  : _str( str_r )
+  {}
+
+  LanguageCode::LanguageCode( const char * str_r )
+  : _str( str_r )
   {}
 
-  ///////////////////////////////////////////////////////////////////
-  //
-  //   METHOD NAME : LanguageCode::~LanguageCode
-  //   METHOD TYPE : Dtor
-  //
   LanguageCode::~LanguageCode()
   {}
 
-  ///////////////////////////////////////////////////////////////////
-  //
-  //   METHOD NAME : LanguageCode::code
-  //   METHOD TYPE : std::string
-  //
-  std::string LanguageCode::code() const
-  { return _pimpl->code(); }
 
-  ///////////////////////////////////////////////////////////////////
-  //
-  //   METHOD NAME : LanguageCode::name
-  //   METHOD TYPE : std::string
-  //
   std::string LanguageCode::name() const
-  { return _pimpl->name(); }
+  { return CodeMaps::instance().name( _str ); }
 
   ///////////////////////////////////////////////////////////////////
   namespace
-  { /////////////////////////////////////////////////////////////////
-
+  {
     CodeMaps::CodeMaps()
     {
       // Defined LanguageCode constants
-      others[""]        = N_( "noCode" );
+      _codeMap[""]        = N_("No Code");
 
       struct LangInit
       {
@@ -233,7 +156,7 @@ namespace zypp
 
       // some languages have more than one iso639_2 code
       // so there are items with duplicate names
-      LangInit langInit[] = {
+      const LangInit langInit[] = {
          // language code: aar aa
          { "aar", "aa", N_( "Afar" ) },
          // language code: abk ab
@@ -265,7 +188,7 @@ namespace zypp
          // language code: ale
          { "ale", NULL, N_( "Aleut" ) },
          // language code: alg
-         { "alg", NULL, N_( "Algonquian languages" ) },
+         { "alg", NULL, N_( "Algonquian Languages" ) },
          // language code: alt
          { "alt", NULL, N_( "Southern Altai" ) },
          // language code: amh am
@@ -273,7 +196,7 @@ namespace zypp
          // language code: ang
          { "ang", NULL, N_( "English, Old (ca.450-1100)" ) },
          // language code: apa
-         { "apa", NULL, N_( "Apache languages" ) },
+         { "apa", NULL, N_( "Apache Languages" ) },
          // language code: ara ar
          { "ara", "ar", N_( "Arabic" ) },
          // language code: arc
@@ -297,9 +220,9 @@ namespace zypp
          // language code: ast
          { "ast", NULL, N_( "Asturian" ) },
          // language code: ath
-         { "ath", NULL, N_( "Athapascan languages" ) },
+         { "ath", NULL, N_( "Athapascan Languages" ) },
          // language code: aus
-         { "aus", NULL, N_( "Australian languages" ) },
+         { "aus", NULL, N_( "Australian Languages" ) },
          // language code: ava av
          { "ava", "av", N_( "Avaric" ) },
          // language code: ave ae
@@ -313,7 +236,7 @@ namespace zypp
          // language code: bad
          { "bad", NULL, N_( "Banda" ) },
          // language code: bai
-         { "bai", NULL, N_( "Bamileke languages" ) },
+         { "bai", NULL, N_( "Bamileke Languages" ) },
          // language code: bak ba
          { "bak", "ba", N_( "Bashkir" ) },
          // language code: bal
@@ -405,7 +328,7 @@ namespace zypp
          // language code: chm
          { "chm", NULL, N_( "Mari" ) },
          // language code: chn
-         { "chn", NULL, N_( "Chinook jargon" ) },
+         { "chn", NULL, N_( "Chinook Jargon" ) },
          // language code: cho
          { "cho", NULL, N_( "Choctaw" ) },
          // language code: chp
@@ -419,7 +342,7 @@ namespace zypp
          // language code: chy
          { "chy", NULL, N_( "Cheyenne" ) },
          // language code: cmc
-         { "cmc", NULL, N_( "Chamic languages" ) },
+         { "cmc", NULL, N_( "Chamic Languages" ) },
          // language code: cop
          { "cop", NULL, N_( "Coptic" ) },
          // language code: cor kw
@@ -427,17 +350,17 @@ namespace zypp
          // language code: cos co
          { "cos", "co", N_( "Corsican" ) },
          // language code: cpe
-         { "cpe", NULL, N_( "Creoles and pidgins, English based (Other)" ) },
+         { "cpe", NULL, N_( "Creoles and Pidgins, English-Based (Other)" ) },
          // language code: cpf
-         { "cpf", NULL, N_( "Creoles and pidgins, French-based (Other)" ) },
+         { "cpf", NULL, N_( "Creoles and Pidgins, French-Based (Other)" ) },
          // language code: cpp
-         { "cpp", NULL, N_( "Creoles and pidgins, Portuguese-based (Other)" ) },
+         { "cpp", NULL, N_( "Creoles and Pidgins, Portuguese-Based (Other)" ) },
          // language code: cre cr
          { "cre", "cr", N_( "Cree" ) },
          // language code: crh
          { "crh", NULL, N_( "Crimean Tatar" ) },
          // language code: crp
-         { "crp", NULL, N_( "Creoles and pidgins (Other)" ) },
+         { "crp", NULL, N_( "Creoles and Pidgins (Other)" ) },
          // language code: csb
          { "csb", NULL, N_( "Kashubian" ) },
          // language code: cus
@@ -649,7 +572,7 @@ namespace zypp
          // language code: ira
          { "ira", NULL, N_( "Iranian (Other)" ) },
          // language code: iro
-         { "iro", NULL, N_( "Iroquoian languages" ) },
+         { "iro", NULL, N_( "Iroquoian Languages" ) },
          // language code: ita it
          { "ita", "it", N_( "Italian" ) },
          // language code: jav jv
@@ -767,7 +690,7 @@ namespace zypp
          // language code: luo
          { "luo", NULL, N_( "Luo (Kenya and Tanzania)" ) },
          // language code: lus
-         { "lus", NULL, N_( "lushai" ) },
+         { "lus", NULL, N_( "Lushai" ) },
          // language code: mac mkd mk
          { "mac", "mk", N_( "Macedonian" ) },
          // language code: mac mkd mk
@@ -813,7 +736,7 @@ namespace zypp
          // language code: min
          { "min", NULL, N_( "Minangkabau" ) },
          // language code: mis
-         { "mis", NULL, N_( "Miscellaneous languages" ) },
+         { "mis", NULL, N_( "Miscellaneous Languages" ) },
          // language code: mkh
          { "mkh", NULL, N_( "Mon-Khmer (Other)" ) },
          // language code: mlg mg
@@ -825,7 +748,7 @@ namespace zypp
          // language code: mni
          { "mni", NULL, N_( "Manipuri" ) },
          // language code: mno
-         { "mno", NULL, N_( "Manobo languages" ) },
+         { "mno", NULL, N_( "Manobo Languages" ) },
          // language code: moh
          { "moh", NULL, N_( "Mohawk" ) },
          // language code: mol mo
@@ -835,7 +758,7 @@ namespace zypp
          // language code: mos
          { "mos", NULL, N_( "Mossi" ) },
          // language code: mul
-         { "mul", NULL, N_( "Multiple languages" ) },
+         { "mul", NULL, N_( "Multiple Languages" ) },
          // language code: mun
          { "mun", NULL, N_( "Munda languages" ) },
          // language code: mus
@@ -845,7 +768,7 @@ namespace zypp
          // language code: mwr
          { "mwr", NULL, N_( "Marwari" ) },
          // language code: myn
-         { "myn", NULL, N_( "Mayan languages" ) },
+         { "myn", NULL, N_( "Mayan Languages" ) },
          // language code: myv
          { "myv", NULL, N_( "Erzya" ) },
          // language code: nah
@@ -889,7 +812,7 @@ namespace zypp
          // language code: nso
          { "nso", NULL, N_( "Northern Sotho" ) },
          // language code: nub
-         { "nub", NULL, N_( "Nubian languages" ) },
+         { "nub", NULL, N_( "Nubian Languages" ) },
          // language code: nwc
          { "nwc", NULL, N_( "Classical Newari" ) },
          // language code: nya ny
@@ -917,7 +840,7 @@ namespace zypp
          // language code: ota
          { "ota", NULL, N_( "Turkish, Ottoman (1500-1928)" ) },
          // language code: oto
-         { "oto", NULL, N_( "Otomian languages" ) },
+         { "oto", NULL, N_( "Otomian Languages" ) },
          // language code: paa
          { "paa", NULL, N_( "Papuan (Other)" ) },
          // language code: pag
@@ -951,7 +874,7 @@ namespace zypp
          // language code: por pt
          { "por", "pt", N_( "Portuguese" ) },
          // language code: pra
-         { "pra", NULL, N_( "Prakrit languages" ) },
+         { "pra", NULL, N_( "Prakrit Languages" ) },
          // language code: pro
          { "pro", NULL, N_( "Provencal, Old (to 1500)" ) },
          // language code: pus ps
@@ -987,7 +910,7 @@ namespace zypp
          // language code: sai
          { "sai", NULL, N_( "South American Indian (Other)" ) },
          // language code: sal
-         { "sal", NULL, N_( "Salishan languages" ) },
+         { "sal", NULL, N_( "Salishan Languages" ) },
          // language code: sam
          { "sam", NULL, N_( "Samaritan Aramaic" ) },
          // language code: san sa
@@ -1023,7 +946,7 @@ namespace zypp
          // language code: sin si
          { "sin", "si", N_( "Sinhala" ) },
          // language code: sio
-         { "sio", NULL, N_( "Siouan languages" ) },
+         { "sio", NULL, N_( "Siouan Languages" ) },
          // language code: sit
          { "sit", NULL, N_( "Sino-Tibetan (Other)" ) },
          // language code: sla
@@ -1039,7 +962,7 @@ namespace zypp
          // language code: sme se
          { "sme", "se", N_( "Northern Sami" ) },
          // language code: smi
-         { "smi", NULL, N_( "Sami languages (Other)" ) },
+         { "smi", NULL, N_( "Sami Languages (Other)" ) },
          // language code: smj
          { "smj", NULL, N_( "Lule Sami" ) },
          // language code: smn
@@ -1143,7 +1066,7 @@ namespace zypp
          // language code: tum
          { "tum", NULL, N_( "Tumbuka" ) },
          // language code: tup
-         { "tup", NULL, N_( "Tupi languages" ) },
+         { "tup", NULL, N_( "Tupi Languages" ) },
          // language code: tur tr
          { "tur", "tr", N_( "Turkish" ) },
          // language code: tut
@@ -1181,7 +1104,7 @@ namespace zypp
          // language code: vot
          { "vot", NULL, N_( "Votic" ) },
          // language code: wak
-         { "wak", NULL, N_( "Wakashan languages" ) },
+         { "wak", NULL, N_( "Wakashan Languages" ) },
          // language code: wal
          { "wal", NULL, N_( "Walamo" ) },
          // language code: war
@@ -1193,7 +1116,7 @@ namespace zypp
          // language code: wel cym cy
          { "cym", NULL, N_( "Welsh" ) },
          // language code: wen
-         { "wen", NULL, N_( "Sorbian languages" ) },
+         { "wen", NULL, N_( "Sorbian Languages" ) },
          // language code: wln wa
          { "wln", "wa", N_( "Walloon" ) },
          // language code: wol wo
@@ -1211,7 +1134,7 @@ namespace zypp
          // language code: yor yo
          { "yor", "yo", N_( "Yoruba" ) },
          // language code: ypk
-         { "ypk", NULL, N_( "Yupik languages" ) },
+         { "ypk", NULL, N_( "Yupik Languages" ) },
          // language code: zap
          { "zap", NULL, N_( "Zapotec" ) },
          // language code: zen
@@ -1228,18 +1151,15 @@ namespace zypp
          { NULL, NULL, NULL }
       };
 
-      for (LangInit * i = langInit; i->iso639_2 != NULL; ++i)
+      for (const LangInit * i = langInit; i->iso639_2 != NULL; ++i)
       {
-         iso639_2[i->iso639_2] = i->name;
+         const char * name( i->name );
+         _codeMap[i->iso639_2] = name;
          if (i->iso639_1 != NULL)
-             iso639_1[i->iso639_1] = i->name;
+             _codeMap[i->iso639_1] = name;
       }
     }
-
-    /////////////////////////////////////////////////////////////////
   } // namespace
   ///////////////////////////////////////////////////////////////////
-
-  /////////////////////////////////////////////////////////////////
 } // namespace zypp
 ///////////////////////////////////////////////////////////////////