File: chinese.cc

package info (click to toggle)
goldendict 1.5.0~rc2%2Bgit20221126%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 17,376 kB
  • sloc: cpp: 60,569; ansic: 11,511; xml: 529; makefile: 74; sh: 42
file content (151 lines) | stat: -rw-r--r-- 5,057 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* This file is (c) 2015 Zhe Wang <0x1997@gmail.com>
 * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */

#include "chinese.hh"
#include <stdexcept>
#include <QCoreApplication>
#ifdef Q_OS_MAC
#include <opencc/opencc.h>
#endif
#include <opencc/Export.hpp>
#include <opencc/SimpleConverter.hpp>
#include "folding.hh"
#include "gddebug.hh"
#include "transliteration.hh"
#include "utf8.hh"

namespace Chinese {

class CharacterConversionDictionary: public Transliteration::BaseTransliterationDictionary
{
#ifdef Q_OS_MAC
  opencc_t converter;
#else
  opencc::SimpleConverter* converter;
#endif

public:

  CharacterConversionDictionary( std::string const & id, std::string const & name,
                                 QIcon icon, QString const & openccConfig);
  ~CharacterConversionDictionary();

  std::vector< gd::wstring > getAlternateWritings( gd::wstring const & )
    throw();
};

CharacterConversionDictionary::CharacterConversionDictionary( std::string const & id,
                                                              std::string const & name_,
                                                              QIcon icon_,
                                                              QString const & openccConfig):
  Transliteration::BaseTransliterationDictionary( id, name_, icon_, false ),
  converter( NULL )
{
  try {
#ifdef Q_OS_MAC
    converter = opencc_open( openccConfig.toLocal8Bit().constData() );
    if( converter == reinterpret_cast< opencc_t >( -1 ) )
    {
      gdWarning( "CharacterConversionDictionary: failed to initialize OpenCC from config %s: %s\n",
                 openccConfig.toLocal8Bit().constData(), opencc_error() );
    }
#else
    converter = new opencc::SimpleConverter( openccConfig.toLocal8Bit().constData() );
#endif
  } catch ( std::runtime_error& e ) {
    gdWarning( "CharacterConversionDictionary: failed to initialize OpenCC from config %s: %s\n",
               openccConfig.toLocal8Bit().constData(), e.what() );
  }
}

CharacterConversionDictionary::~CharacterConversionDictionary()
{
#ifdef Q_OS_MAC
  if ( converter != NULL && converter != reinterpret_cast< opencc_t >( -1 ) )
    opencc_close( converter );
#else
  if ( converter != NULL )
    delete converter;
#endif
}

std::vector< gd::wstring > CharacterConversionDictionary::getAlternateWritings( gd::wstring const & str )
  throw()
{
  std::vector< gd::wstring > results;

  if ( converter != NULL ) {
    gd::wstring folded = Folding::applySimpleCaseOnly( str );
    std::string input = Utf8::encode( folded );
    std::string output;
    gd::wstring result;

    try {
#ifdef Q_OS_MAC
      if ( converter != NULL && converter != reinterpret_cast< opencc_t >( -1 ) )
      {
        char * tmp = opencc_convert_utf8( converter, input.c_str(), input.length() );
        if( tmp )
        {
          output = std::string( tmp );
          opencc_convert_utf8_free( tmp );
        }
        else
          gdWarning( "OpenCC: conversion failed %s\n", opencc_error() );
      }
#else
      output = converter->Convert( input );
#endif
      result = Utf8::decode( output );
    } catch ( std::exception& ex ) {
      gdWarning( "OpenCC: conversion failed %s\n", ex.what() );
    }

    if ( !result.empty() && result != folded )
      results.push_back( result );
  }

  return results;
}

std::vector< sptr< Dictionary::Class > > makeDictionaries( Config::Chinese const & cfg )
  THROW_SPEC( std::exception )
{
  std::vector< sptr< Dictionary::Class > > result;

#ifdef Q_OS_LINUX
  QString configDir = "";
#else
  QString configDir = Config::getOpenCCDir();
  if( !configDir.isEmpty() )
    configDir += "/";
#endif

  if ( cfg.enable )
  {
    if ( cfg.enableSCToTWConversion )
    {
      result.push_back( new CharacterConversionDictionary( "bf1c33a59cbacea8f39b5b5475787cfd",
                                                           QCoreApplication::translate( "ChineseConversion", "Simplified to traditional Chinese (Taiwan variant) conversion" ).toUtf8().data(),
                                                           QIcon( ":/flags/tw.png" ), configDir + "s2tw.json" ) );
    }

    if ( cfg.enableSCToHKConversion )
    {
      result.push_back( new CharacterConversionDictionary( "9e0681fb9e1c0b6c90e6fb46111d96b5",
                                                           QCoreApplication::translate( "ChineseConversion", "Simplified to traditional Chinese (Hong Kong variant) conversion" ).toUtf8().data(),
                                                           QIcon( ":/flags/hk.png" ), configDir + "s2hk.json" ) );
    }

    if ( cfg.enableTCToSCConversion )
    {
      result.push_back( new CharacterConversionDictionary( "0db536ce0bdc52ea30d11a82c5db4a27",
                                                           QCoreApplication::translate( "ChineseConversion", "Traditional to simplified Chinese conversion" ).toUtf8().data(),
                                                           QIcon( ":/flags/cn.png" ), configDir + "t2s.json" ) );
    }
  }

  return result;
}

}