/* This file is (c) 2008-2012 Konstantin Isakov * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ #include "transliteration.hh" #include "utf8.hh" #include "folding.hh" #include "gddebug.hh" namespace Transliteration { using gd::wchar; BaseTransliterationDictionary::BaseTransliterationDictionary( string const & id, string const & name_, QIcon icon_, bool caseSensitive_ ): Dictionary::Class( id, vector< string >() ), name( name_ ), caseSensitive( caseSensitive_ ) { dictionaryIcon = icon_; dictionaryIconLoaded = true; } string BaseTransliterationDictionary::getName() noexcept { return name; } map< Dictionary::Property, string > BaseTransliterationDictionary::getProperties() noexcept { return map< Dictionary::Property, string >(); } unsigned long BaseTransliterationDictionary::getArticleCount() noexcept { return 0; } unsigned long BaseTransliterationDictionary::getWordCount() noexcept { return 0; } sptr< Dictionary::WordSearchRequest > BaseTransliterationDictionary::prefixMatch( wstring const &, unsigned long ) { return std::make_shared(); } sptr< Dictionary::DataRequest > BaseTransliterationDictionary::getArticle( wstring const &, vector< wstring > const &, wstring const &, bool ) { return std::make_shared( false ); } sptr< Dictionary::WordSearchRequest > BaseTransliterationDictionary::findHeadwordsForSynonym( wstring const & str ) { sptr< Dictionary::WordSearchRequestInstant > result = std::make_shared(); vector< wstring > alts = getAlternateWritings( str ); GD_DPRINTF( "alts = %u\n", (unsigned) alts.size() ); for( unsigned x = 0; x < alts.size(); ++x ) result->getMatches().push_back( alts[ x ] ); return result; } void Table::ins( char const * from, char const * to ) { wstring fr = Utf8::decode( std::string( from ) ); if ( fr.size() > maxEntrySize ) maxEntrySize = fr.size(); insert( std::pair< wstring, wstring >( fr, Utf8::decode( std::string( to ) ) ) ); } TransliterationDictionary::TransliterationDictionary( string const & id, string const & name_, QIcon icon_, Table const & table_, bool caseSensitive_ ): BaseTransliterationDictionary(id, name_, icon_, caseSensitive_), table( table_ ) { } vector< wstring > TransliterationDictionary::getAlternateWritings( wstring const & str ) noexcept { vector< wstring > results; wstring result, folded; wstring const * target; if ( caseSensitive ) { // Don't do any transform -- the transliteration is case-sensitive target = &str; } else { folded = Folding::applySimpleCaseOnly( str ); target = &folded; } wchar const * ptr = target->c_str(); size_t left = target->size(); Table::const_iterator i; while( left ) { unsigned x; for( x = table.getMaxEntrySize(); x >= 1; --x ) { if ( left >= x ) { i = table.find( wstring( ptr, x ) ); if ( i != table.end() ) { result.append( i->second ); ptr += x; left -= x; break; } } } if ( !x ) { // No matches -- add this char as it is result.push_back( *ptr++ ); --left; } } if ( result != *target ) results.push_back( result ); return results; } }