~ubuntu-branches/ubuntu/saucy/ibus-pinyin/saucy-proposed

« back to all changes in this revision

Viewing changes to src/SimpTradConverter.cc

  • Committer: Bazaar Package Importer
  • Author(s): LI Daobing, Asias He
  • Date: 2010-09-08 21:38:54 UTC
  • mfrom: (1.2.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100908213854-q4wlx8zlcyqxvelz
Tags: 1.3.11-1
[ Asias He ]
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* vim:set et ts=4 sts=4:
2
 
 *
3
 
 * ibus-pinyin - The Chinese PinYin engine for IBus
4
 
 *
5
 
 * Copyright (c) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
6
 
 * Copyright (c) 2010 BYVoid <byvoid1@gmail.com>
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or modify
9
 
 * it under the terms of the GNU General Public License as published by
10
 
 * the Free Software Foundation; either version 2, or (at your option)
11
 
 * any later version.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
 * GNU General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program; if not, write to the Free Software
20
 
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
 */
22
 
#ifdef HAVE_CONFIG_H
23
 
#  include "config.h"
24
 
#endif
25
 
 
26
 
#include "SimpTradConverter.h"
27
 
 
28
 
#ifdef HAVE_OPENCC
29
 
#  include <opencc.h>
30
 
#else
31
 
#  include <cstring>
32
 
#  include <cstdlib>
33
 
#endif
34
 
 
35
 
#include "Types.h"
36
 
#include "String.h"
37
 
 
38
 
namespace PY {
39
 
 
40
 
#ifdef HAVE_OPENCC
41
 
 
42
 
class opencc {
43
 
    static const int BUFFER_SIZE = 64;
44
 
public:
45
 
    opencc (void)
46
 
    {
47
 
        m_od = opencc_open (OPENCC_DEFAULT_CONFIG_SIMP_TO_TRAD);
48
 
        g_assert (m_od != NULL);
49
 
    }
50
 
 
51
 
    ~opencc (void)
52
 
    {
53
 
        opencc_close(m_od);
54
 
    }
55
 
 
56
 
    void convert (const gchar *in, String &out)
57
 
    {
58
 
        glong n_char;
59
 
        gunichar *in_ucs4 = g_utf8_to_ucs4_fast (in, -1, &n_char);
60
 
 
61
 
        ucs4_t *pinbuf = (ucs4_t *)in_ucs4;
62
 
        size_t inbuf_left = n_char;
63
 
        while (inbuf_left != 0) {
64
 
            ucs4_t *poutbuf = (ucs4_t *)m_buffer;
65
 
            size_t outbuf_left = BUFFER_SIZE;
66
 
            size_t retval = opencc_convert(m_od, &pinbuf, &inbuf_left, &poutbuf, &outbuf_left);
67
 
            if (retval == (size_t) -1) {
68
 
                /* append left chars in pinbuf */
69
 
                g_warning ("opencc_convert return failed");
70
 
                out << (gunichar *) pinbuf;
71
 
                break;
72
 
            }
73
 
            *poutbuf = L'\0';
74
 
            out << m_buffer;
75
 
        }
76
 
        g_free (in_ucs4);
77
 
    }
78
 
private:
79
 
    opencc_t m_od;
80
 
    gunichar m_buffer[BUFFER_SIZE + 1];
81
 
};
82
 
 
83
 
void
84
 
SimpTradConverter::simpToTrad (const gchar *in, String &out)
85
 
{
86
 
    static opencc opencc;
87
 
    opencc.convert (in, out);
88
 
}
89
 
 
90
 
#else
91
 
 
92
 
static gint _xcmp (const gchar *p1, const gchar *p2, const gchar *str)
93
 
{
94
 
    for (;;) {
95
 
        // both reach end
96
 
        if (p1 == p2 && *str == '\0')
97
 
            return 0;
98
 
        // p1 reaches end
99
 
        if (p1 == p2)
100
 
            return -1;
101
 
        // str reaches end
102
 
        if (*str == '\0')
103
 
            return 1;
104
 
 
105
 
        if (*p1 < *str)
106
 
            return -1;
107
 
        if (*p1 > *str)
108
 
            return 1;
109
 
 
110
 
        p1 ++; str ++;
111
 
    };
112
 
}
113
 
 
114
 
static gint _cmp (gconstpointer p1, gconstpointer p2)
115
 
{
116
 
    const gchar **pp = (const gchar **) p1;
117
 
    const gchar **s2 = (const gchar **) p2;
118
 
 
119
 
    return _xcmp (pp[0], pp[1], s2[0]);
120
 
}
121
 
 
122
 
#include "SimpTradConverterTable.h"
123
 
 
124
 
void
125
 
SimpTradConverter::simpToTrad (const gchar *in, String &out)
126
 
{
127
 
    const gchar *pend;
128
 
    const gchar *pp[2];
129
 
    glong len;
130
 
    glong begin;
131
 
 
132
 
    if (!g_utf8_validate (in, -1 , NULL)) {
133
 
        g_warning ("\%s\" is not an utf8 string!", in);
134
 
        g_assert_not_reached ();
135
 
    }
136
 
 
137
 
    begin = 0;
138
 
    pend = in + std::strlen (in);
139
 
    len = g_utf8_strlen (in, -1);   // length in charactoers
140
 
    pp[0] = in;
141
 
 
142
 
    while (pp[0] != pend) {
143
 
        glong slen  = std::min (len - begin, (glong) SIMP_TO_TRAD_MAX_LEN); // the length of sub string in character
144
 
        pp[1] = g_utf8_offset_to_pointer (pp[0], slen);    // the end of sub string
145
 
 
146
 
        for (;;) {
147
 
            const gchar **result;
148
 
            result = (const gchar **) std::bsearch (pp, simp_to_trad,
149
 
                                            G_N_ELEMENTS (simp_to_trad), sizeof (simp_to_trad[0]),
150
 
                                            _cmp);
151
 
 
152
 
            if (result != NULL) {
153
 
                // found item in table,
154
 
                // append the trad to out and adjust pointers
155
 
                out << result[1];
156
 
                pp[0] = pp[1];
157
 
                begin += slen;
158
 
                break;
159
 
            }
160
 
 
161
 
            if (slen == 1) {
162
 
                // if only one character left,
163
 
                // append origin character to out and adjust pointers
164
 
                out.append (pp[0], pp[1] - pp[0]);
165
 
                pp[0] = pp[1];
166
 
                begin += 1;
167
 
                break;
168
 
            }
169
 
 
170
 
            // if more than on characters left,
171
 
            // adjust pp[1] to previous character
172
 
            pp[1] = g_utf8_prev_char (pp[1]);
173
 
            slen--;
174
 
        }
175
 
    }
176
 
}
177
 
#endif
178
 
 
179
 
}