1 /* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
2  * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
3 
4 #include "transliteration.hh"
5 #include "utf8.hh"
6 #include "folding.hh"
7 #include "gddebug.hh"
8 
9 namespace Transliteration {
10 
11 using gd::wchar;
12 
BaseTransliterationDictionary(string const & id,string const & name_,QIcon icon_,bool caseSensitive_)13 BaseTransliterationDictionary::BaseTransliterationDictionary( string const & id,
14                                                               string const & name_,
15                                                               QIcon icon_,
16                                                               bool caseSensitive_ ):
17   Dictionary::Class( id, vector< string >() ),
18   name( name_ ),
19   caseSensitive( caseSensitive_ )
20 {
21   dictionaryIcon = dictionaryNativeIcon = icon_;
22   dictionaryIconLoaded = true;
23 }
24 
getName()25 string BaseTransliterationDictionary::getName() throw()
26 { return name; }
27 
getProperties()28 map< Dictionary::Property, string > BaseTransliterationDictionary::getProperties() throw()
29 { return map< Dictionary::Property, string >(); }
30 
getArticleCount()31 unsigned long BaseTransliterationDictionary::getArticleCount() throw()
32 { return 0; }
33 
getWordCount()34 unsigned long BaseTransliterationDictionary::getWordCount() throw()
35 { return 0; }
36 
prefixMatch(wstring const &,unsigned long)37 sptr< Dictionary::WordSearchRequest > BaseTransliterationDictionary::prefixMatch( wstring const &,
38                                                                                   unsigned long ) THROW_SPEC( std::exception )
39 { return new Dictionary::WordSearchRequestInstant(); }
40 
getArticle(wstring const &,vector<wstring> const &,wstring const &,bool)41 sptr< Dictionary::DataRequest > BaseTransliterationDictionary::getArticle( wstring const &,
42                                                                            vector< wstring > const &,
43                                                                            wstring const &, bool )
44   THROW_SPEC( std::exception )
45 { return new Dictionary::DataRequestInstant( false ); }
46 
findHeadwordsForSynonym(wstring const & str)47 sptr< Dictionary::WordSearchRequest > BaseTransliterationDictionary::findHeadwordsForSynonym( wstring const & str )
48   THROW_SPEC( std::exception )
49 {
50   sptr< Dictionary::WordSearchRequestInstant > result = new Dictionary::WordSearchRequestInstant();
51 
52   vector< wstring > alts = getAlternateWritings( str );
53 
54   GD_DPRINTF( "alts = %u\n", (unsigned) alts.size() );
55 
56   for( unsigned x = 0; x < alts.size(); ++x )
57     result->getMatches().push_back( alts[ x ] );
58 
59   return result;
60 }
61 
62 
ins(char const * from,char const * to)63 void Table::ins( char const * from, char const * to )
64 {
65   wstring fr = Utf8::decode( std::string( from ) );
66 
67   if ( fr.size() > maxEntrySize )
68     maxEntrySize = fr.size();
69 
70   insert( std::pair< wstring, wstring >( fr,
71                                          Utf8::decode( std::string( to ) ) ) );
72 }
73 
74 
TransliterationDictionary(string const & id,string const & name_,QIcon icon_,Table const & table_,bool caseSensitive_)75 TransliterationDictionary::TransliterationDictionary( string const & id,
76                                                       string const & name_,
77                                                       QIcon icon_,
78                                                       Table const & table_,
79                                                       bool caseSensitive_ ):
80   BaseTransliterationDictionary(id, name_, icon_, caseSensitive_),
81   table( table_ )
82 {
83 }
84 
getAlternateWritings(wstring const & str)85 vector< wstring > TransliterationDictionary::getAlternateWritings( wstring const & str )
86   throw()
87 {
88   vector< wstring > results;
89 
90   wstring result, folded;
91   wstring const * target;
92 
93   if ( caseSensitive )
94   {
95     // Don't do any transform -- the transliteration is case-sensitive
96     target = &str;
97   }
98   else
99   {
100     folded = Folding::applySimpleCaseOnly( str );
101     target = &folded;
102   }
103 
104   wchar const * ptr = target->c_str();
105   size_t left = target->size();
106 
107   Table::const_iterator i;
108 
109   while( left )
110   {
111     unsigned x;
112 
113     for( x = table.getMaxEntrySize(); x >= 1; --x )
114     {
115       if ( left >= x )
116       {
117         i = table.find( wstring( ptr, x ) );
118 
119         if ( i != table.end() )
120         {
121           result.append( i->second );
122           ptr += x;
123           left -= x;
124           break;
125         }
126       }
127     }
128 
129     if ( !x )
130     {
131       // No matches -- add this char as it is
132       result.push_back( *ptr++ );
133       --left;
134     }
135   }
136 
137   if ( result != *target )
138     results.push_back( result );
139 
140   return results;
141 }
142 
143 }
144