~ubuntu-branches/ubuntu/raring/sunpinyin/raring

« back to all changes in this revision

Viewing changes to src/ime-core/userdict.cpp

  • Committer: Package Import Robot
  • Author(s): YunQiang Su
  • Date: 2012-03-30 15:31:55 UTC
  • mfrom: (1.1.3) (1.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20120330153155-qgls77sogzgtg9zp
Tags: 2.0.3+git20120222-1
* Team upload: git snapshot 20120222.
   - fix breaks if LDFLAGS in environment contains
       multiple words (Closese #646001).
   - rm patches merged to upstream:
       append-os-environ-toenv.patch
       fix-ftbfs-on-sh.patch
       remove-10-candidate-words-limitation.patch
   - refresh disable-lm-dict-compile.patch.
* Bump stardard version to 3.9.3: no modify needed.
* add libsunpinyin3-dbg and python-sunpinyin packages.
* debian/compat to 9, multiarch it.
* rewrite debian/rules with dh 7 format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 
 * 
 
3
 *
4
4
 * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
5
 
 * 
 
5
 *
6
6
 * The contents of this file are subject to the terms of either the GNU Lesser
7
7
 * General Public License Version 2.1 only ("LGPL") or the Common Development and
8
8
 * Distribution License ("CDDL")(collectively, the "License"). You may not use this
9
9
 * file except in compliance with the License. You can obtain a copy of the CDDL at
10
10
 * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
11
 
 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the 
 
11
 * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
12
12
 * specific language governing permissions and limitations under the License. When
13
13
 * distributing the software, include this License Header Notice in each file and
14
14
 * include the full text of the License in the License file as well as the
15
15
 * following notice:
16
 
 * 
 
16
 *
17
17
 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
18
18
 * (CDDL)
19
19
 * For Covered Software in this distribution, this License shall be governed by the
21
21
 * Any litigation relating to this License shall be subject to the jurisdiction of
22
22
 * the Federal Courts of the Northern District of California and the state courts
23
23
 * of the State of California, with venue lying in Santa Clara County, California.
24
 
 * 
 
24
 *
25
25
 * Contributor(s):
26
 
 * 
 
26
 *
27
27
 * If you wish your version of this file to be governed by only the CDDL or only
28
28
 * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
29
29
 * include this software in this distribution under the [CDDL or LGPL Version 2.1]
32
32
 * Version 2.1, or to extend the choice of license to its licensees as provided
33
33
 * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
34
34
 * Version 2 license, then the option applies only if the new code is made subject
35
 
 * to such option by the copyright holder. 
 
35
 * to such option by the copyright holder.
36
36
 */
37
37
 
38
38
#include <assert.h>
 
39
#include <stdlib.h>
39
40
#include "userdict.h"
40
41
 
41
42
 
42
 
bool CUserDict::load(const char  *fname)
43
 
{       
44
 
    int rc = sqlite3_open(fname, &m_db);
 
43
bool
 
44
CUserDict::load(const char  *fname)
 
45
{
 
46
    int rc = sqlite3_open(":memory:", &m_db);
45
47
 
46
48
    if (rc != SQLITE_OK) {
47
49
        sqlite3_close(m_db);
48
50
        return false;
49
51
    }
50
52
 
 
53
    m_fname = strdup(fname);
 
54
    rc = _copyDb(Load);
 
55
 
51
56
    return _createTable() && _createIndexes();
52
57
}
53
58
 
54
59
 
55
 
void CUserDict::free()
 
60
void
 
61
CUserDict::free()
56
62
{
 
63
    if (m_fname) {
 
64
        _copyDb(Save);
 
65
        ::free(m_fname);
 
66
        m_fname = NULL;
 
67
    }
 
68
 
57
69
    if (m_db) {
58
70
        sqlite3_close(m_db);
59
71
        m_db = NULL;
60
 
    }   
 
72
    }
61
73
}
62
74
 
63
75
 
64
 
unsigned CUserDict::addWord (CSyllables &syllables, const wstring& word) 
 
76
unsigned
 
77
CUserDict::addWord(CSyllables &syllables, const wstring& word)
65
78
{
66
79
    assert(m_db != NULL);
67
 
    assert (syllables.size() >= 2 && syllables.size() <= MAX_USRDEF_WORD_LEN);
 
80
    assert(syllables.size() >= 2 && syllables.size() <= MAX_USRDEF_WORD_LEN);
68
81
 
69
82
    sqlite3_stmt *stmt;
70
 
    const char *sql_str = 
 
83
    const char *sql_str =
71
84
        "INSERT INTO dict (len, i0, f0, t0, i1, f1, t1, i2, f2, t2, i3, f3, t3, i4, f4, t4, i5, f5, t5, utf8str) \
72
85
         VALUES           (?,   ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?,  ?);";
73
86
    const char *tail;
74
87
 
75
 
    sqlite3_prepare (m_db, sql_str, strlen(sql_str), &stmt, &tail);
 
88
    sqlite3_prepare(m_db, sql_str, strlen(sql_str), &stmt, &tail);
76
89
 
77
90
    int i = 1;
78
 
    sqlite3_bind_int (stmt, i++, syllables.size());
 
91
    sqlite3_bind_int(stmt, i++, syllables.size());
79
92
 
80
 
    CSyllables::iterator it  = syllables.begin();
 
93
    CSyllables::iterator it = syllables.begin();
81
94
    CSyllables::iterator ite = syllables.end();
82
95
    for (; it != ite; ++it) {
83
 
        sqlite3_bind_int (stmt, i++, it->initial);
84
 
        sqlite3_bind_int (stmt, i++, it->final);
85
 
        sqlite3_bind_int (stmt, i++, it->tone);
 
96
        sqlite3_bind_int(stmt, i++, it->initial);
 
97
        sqlite3_bind_int(stmt, i++, it->final);
 
98
        sqlite3_bind_int(stmt, i++, it->tone);
86
99
    }
87
100
 
88
 
    while (i <= MAX_USRDEF_WORD_LEN*3 + 1)
89
 
        sqlite3_bind_int (stmt, i++, 0);
 
101
    while (i <= MAX_USRDEF_WORD_LEN * 3 + 1)
 
102
        sqlite3_bind_int(stmt, i++, 0);
90
103
 
91
 
    char buf[MAX_USRDEF_WORD_LEN*6+1];
 
104
    char buf[MAX_USRDEF_WORD_LEN * 6 + 1];
92
105
    WCSTOMBS(buf, word.c_str(), sizeof(buf) - 1);
93
 
    sqlite3_bind_text (stmt, i, (const char *)buf, strlen(buf), NULL);
 
106
    sqlite3_bind_text(stmt, i, (const char*)buf, strlen(buf), NULL);
94
107
 
95
 
    unsigned ret = (SQLITE_DONE == sqlite3_step (stmt))? 
96
 
                   INI_USRDEF_WID + sqlite3_last_insert_rowid (m_db):
 
108
    unsigned ret = (SQLITE_DONE == sqlite3_step(stmt)) ?
 
109
                   INI_USRDEF_WID + sqlite3_last_insert_rowid(m_db) :
97
110
                   0;
98
111
 
99
 
    sqlite3_finalize (stmt);
 
112
    sqlite3_finalize(stmt);
100
113
    return ret;
101
114
}
102
115
 
103
116
 
104
 
void CUserDict::removeWord (unsigned wid)
 
117
void
 
118
CUserDict::removeWord(unsigned wid)
105
119
{
106
 
    assert (m_db != NULL);
 
120
    assert(m_db != NULL);
107
121
    char    *zErr = NULL;
108
122
    char sql[256] = "DELETE FROM dict WHERE id=";
109
 
    
 
123
 
110
124
    if (wid > INI_USRDEF_WID) {
111
125
        sprintf(sql, "%s%d;", sql, (wid - INI_USRDEF_WID));
112
126
        sqlite3_exec(m_db, sql, NULL, NULL, &zErr);
113
127
 
114
 
        m_dict.erase (m_dict.find(wid - INI_USRDEF_WID));
 
128
        m_dict.erase(m_dict.find(wid - INI_USRDEF_WID));
115
129
    }
116
130
}
117
131
 
118
132
 
119
 
void CUserDict::getWords (CSyllables &syllables,
120
 
                          std::vector<CPinyinTrie::TWordIdInfo> &result) 
 
133
void
 
134
CUserDict::getWords(CSyllables &syllables,
 
135
                    std::vector<CPinyinTrie::TWordIdInfo> &result)
121
136
{
122
 
    assert (m_db != NULL);
 
137
    assert(m_db != NULL);
123
138
 
124
139
    char *sql_str;
125
140
    const char *tail;
131
146
 
132
147
    if (length > MAX_USRDEF_WORD_LEN)
133
148
        return;
134
 
    
135
 
    for (int i=0; i<length; i++) {
136
 
        sprintf (buf, " and i%d=%d", i, syllables[i].initial);
 
149
 
 
150
    for (int i = 0; i < length; i++) {
 
151
        sprintf(buf, " and i%d=%d", i, syllables[i].initial);
137
152
        i_conditions += buf;
138
153
 
139
154
        if (!syllables[i].final)
140
155
            continue;
141
156
 
142
 
        sprintf (buf, " and f%i=%i", i, syllables[i].final);
 
157
        sprintf(buf, " and f%i=%i", i, syllables[i].final);
143
158
        f_conditions += buf;
144
159
 
145
160
        if (!syllables[i].tone)
146
161
            continue;
147
162
 
148
 
        sprintf (buf, " and t%i=%i", i, syllables[i].tone);
 
163
        sprintf(buf, " and t%i=%i", i, syllables[i].tone);
149
164
        t_conditions += buf;
150
 
    }    
151
 
 
152
 
    sql_str = sqlite3_mprintf("SELECT id, utf8str FROM dict WHERE len=%i%q%q%q;",
153
 
                               length, i_conditions.c_str(), f_conditions.c_str(), t_conditions.c_str());
154
 
 
155
 
    rc = sqlite3_prepare(m_db, sql_str, strlen (sql_str), &stmt, &tail);
156
 
    if(rc != SQLITE_OK) {
 
165
    }
 
166
 
 
167
    sql_str = sqlite3_mprintf(
 
168
        "SELECT id, utf8str FROM dict WHERE len=%i%q%q%q;",
 
169
        length,
 
170
        i_conditions.c_str(),
 
171
        f_conditions.c_str(),
 
172
        t_conditions.c_str());
 
173
 
 
174
    rc = sqlite3_prepare(m_db, sql_str, strlen(sql_str), &stmt, &tail);
 
175
    if (rc != SQLITE_OK) {
157
176
        sqlite3_free(sql_str);
158
177
        fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(m_db));
159
178
        return;
164
183
    const unsigned char     *utf8str = NULL;
165
184
    CPinyinTrie::TWordIdInfo word;
166
185
 
167
 
    while(SQLITE_ROW == sqlite3_step(stmt)) {
168
 
        id      = sqlite3_column_int  (stmt, 0);
169
 
        utf8str = sqlite3_column_text (stmt, 1);
 
186
    while (SQLITE_ROW == sqlite3_step(stmt)) {
 
187
        id = sqlite3_column_int(stmt, 0);
 
188
        utf8str = sqlite3_column_text(stmt, 1);
170
189
 
171
190
        if (id >= MAX_USRDEF_WID - INI_USRDEF_WID)
172
191
            continue;
176
195
 
177
196
        word.m_id = id + INI_USRDEF_WID;
178
197
        word.m_bSeen = 1;
179
 
        result.push_back (word);
 
198
        result.push_back(word);
180
199
 
181
 
        m_dict.insert (std::make_pair (id, wstring(cwstr)));
 
200
        m_dict.insert(std::make_pair(id, wstring(cwstr)));
182
201
    }
183
202
 
184
203
    sqlite3_free(sql_str);
186
205
}
187
206
 
188
207
 
189
 
const TWCHAR* CUserDict::operator [] (unsigned wid)
 
208
const TWCHAR*
 
209
CUserDict::operator [](unsigned wid)
190
210
{
191
 
    assert (m_db != NULL);
 
211
    assert(m_db != NULL);
192
212
 
193
 
    sqlite3_stmt *stmt=NULL;
 
213
    sqlite3_stmt *stmt = NULL;
194
214
    int rc = SQLITE_OK;
195
215
    const char *tail;
196
216
    char sql_str[256];
201
221
    wid -= INI_USRDEF_WID;
202
222
 
203
223
    std::map<unsigned, wstring>::const_iterator it = m_dict.find(wid);
204
 
    if (it != m_dict.end ())
205
 
        return it->second.c_str ();
 
224
    if (it != m_dict.end())
 
225
        return it->second.c_str();
206
226
 
207
 
    sprintf (sql_str, "SELECT utf8str FROM dict WHERE id=%d;", wid);
 
227
    sprintf(sql_str, "SELECT utf8str FROM dict WHERE id=%d;", wid);
208
228
 
209
229
    rc = sqlite3_prepare(m_db, sql_str, strlen(sql_str), &stmt, &tail);
210
 
    if(rc != SQLITE_OK) {
 
230
    if (rc != SQLITE_OK) {
211
231
        fprintf(stderr, "SQL error: %s\n", sqlite3_errmsg(m_db));
212
232
        return NULL;
213
233
    }
219
239
        utf8str = sqlite3_column_text(stmt, 0);
220
240
        MBSTOWCS(cwstr, (const char*)utf8str, MAX_USRDEF_WORD_LEN);
221
241
        wstring wstr(cwstr);
222
 
        m_dict.insert (std::make_pair (wid, wstr));
 
242
        m_dict.insert(std::make_pair(wid, wstr));
223
243
        ret = wstr.c_str();
224
244
    }
225
245
 
226
 
    sqlite3_finalize (stmt);
 
246
    sqlite3_finalize(stmt);
227
247
    return ret;
228
248
}
229
249
 
230
 
 
231
 
bool CUserDict::_createTable()
 
250
int
 
251
CUserDict::_copyDb(DBCopyDirection direction)
 
252
{
 
253
    sqlite3 *disk_db;
 
254
    int rc = sqlite3_open(m_fname, &disk_db);
 
255
 
 
256
    if (rc == SQLITE_OK) {
 
257
        sqlite3 *dst = direction == Load ? m_db : disk_db;
 
258
        sqlite3 *src = direction == Save ? m_db : disk_db;
 
259
        sqlite3_backup *backup = sqlite3_backup_init(dst, "main", src, "main");
 
260
        if (backup) {
 
261
            sqlite3_backup_step(backup, -1);
 
262
            sqlite3_backup_finish(backup);
 
263
        }
 
264
        rc = sqlite3_errcode(dst);
 
265
    }
 
266
 
 
267
    sqlite3_close(disk_db);
 
268
    return rc;
 
269
}
 
270
 
 
271
bool
 
272
CUserDict::_createTable()
232
273
{
233
274
    assert(m_db != NULL);
234
275
 
235
276
    char *zErr = NULL;
236
 
    int  rc = SQLITE_OK;
237
 
    const char *sql_str = 
 
277
    int rc = SQLITE_OK;
 
278
    const char *sql_str =
238
279
        "CREATE TABLE IF NOT EXISTS dict( \
239
280
         id INTEGER PRIMARY KEY, len INTEGER, \
240
281
         i0 INTEGER, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER, i5 INTEGER, \
243
284
         utf8str TEXT, UNIQUE (i0, i1, i2, i3, i4, i5, utf8str));";
244
285
 
245
286
    rc = sqlite3_exec(m_db, sql_str, NULL, NULL, &zErr);
246
 
    if(rc != SQLITE_OK) {
 
287
    if (rc != SQLITE_OK) {
247
288
        if (zErr != NULL) {
248
289
            fprintf(stderr, "SQL error: %s\n", zErr);
249
290
            sqlite3_free(zErr);
252
293
    }
253
294
 
254
295
    return true;
255
 
}       
 
296
}
256
297
 
257
 
bool CUserDict::_createIndexes()
 
298
bool
 
299
CUserDict::_createIndexes()
258
300
{
259
 
    assert(m_db!=NULL);
 
301
    assert(m_db != NULL);
260
302
 
261
303
    char *zErr = NULL;
262
 
    int  rc = SQLITE_OK;
263
 
    const char * sql_str = 
 
304
    int rc = SQLITE_OK;
 
305
    const char * sql_str =
264
306
        "CREATE INDEX IF NOT EXISTS index_0 ON dict (len, i0, i1, i2, i3, i4, i5);";
265
307
 
266
308
    rc = sqlite3_exec(m_db, sql_str, NULL, NULL, &zErr);
267
 
    if(rc != SQLITE_OK) {
 
309
    if (rc != SQLITE_OK) {
268
310
        if (zErr != NULL) {
269
311
            fprintf(stderr, "SQL error: %s\n", zErr);
270
312
            sqlite3_free(zErr);