Allow libpinyin to build in cross compile mode.
[platform/upstream/libpinyin.git] / src / storage / table_info.cpp
1 /* 
2  *  libpinyin
3  *  Library to deal with pinyin.
4  *  
5  *  Copyright (C) 2013 Peng Wu <alexepico@gmail.com>
6  *  
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  * 
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  *  GNU General Public License for more details.
16  *  
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20  */
21
22 #include "table_info.h"
23 #include <stdio.h>
24 #include <assert.h>
25 #include <string.h>
26 #include <locale.h>
27
28 using namespace pinyin;
29
30
31 static const pinyin_table_info_t reserved_tables[] = {
32     {RESERVED, NULL, NULL, NULL, NOT_USED},
33     {GB_DICTIONARY, "gb_char.table", "gb_char.bin", "gb_char.dbin", SYSTEM_FILE},
34     {GBK_DICTIONARY, "gbk_char.table", "gbk_char.bin", "gbk_char.dbin", SYSTEM_FILE},
35
36     {MERGED_DICTIONARY, "merged.table", "merged.bin", "merged.dbin", SYSTEM_FILE},
37
38     {USER_DICTIONARY, NULL, NULL, "user.bin", USER_FILE}
39 };
40
41
42 SystemTableInfo::SystemTableInfo() {
43     m_binary_format_version = 0;
44     m_model_data_version = 0;
45     m_lambda = 0.;
46
47     size_t i;
48     for (i = 0; i < PHRASE_INDEX_LIBRARY_COUNT; ++i) {
49         pinyin_table_info_t * table_info = &m_table_info[i];
50
51         table_info->m_dict_index = i;
52         table_info->m_table_filename = NULL;
53         table_info->m_system_filename = NULL;
54         table_info->m_user_filename = NULL;
55         table_info->m_file_type = NOT_USED;
56     }
57 }
58
59 SystemTableInfo::~SystemTableInfo() {
60     reset();
61 }
62
63 void SystemTableInfo::reset() {
64     m_binary_format_version = 0;
65     m_model_data_version = 0;
66     m_lambda = 0.;
67
68     size_t i;
69     for (i = 0; i < PHRASE_INDEX_LIBRARY_COUNT; ++i) {
70         pinyin_table_info_t * table_info = &m_table_info[i];
71
72         g_free((gchar *)table_info->m_table_filename);
73         table_info->m_table_filename = NULL;
74         g_free((gchar *)table_info->m_system_filename);
75         table_info->m_system_filename = NULL;
76         g_free((gchar *)table_info->m_user_filename);
77         table_info->m_user_filename = NULL;
78
79         table_info->m_file_type = NOT_USED;
80     }
81 }
82
83 void SystemTableInfo::postfix_tables() {
84     size_t i;
85     for (i = 0; i < G_N_ELEMENTS(reserved_tables); ++i) {
86         const pinyin_table_info_t * postfix = &reserved_tables[i];
87
88         guint8 index = postfix->m_dict_index;
89         pinyin_table_info_t * table_info = &m_table_info[index];
90         assert(table_info->m_dict_index == index);
91
92         table_info->m_table_filename = g_strdup(postfix->m_table_filename);
93         table_info->m_system_filename = g_strdup(postfix->m_system_filename);
94         table_info->m_user_filename = g_strdup(postfix->m_user_filename);
95         table_info->m_file_type = postfix->m_file_type;
96     }
97 }
98
99 static gchar * to_string(const char * str) {
100     if (0 == strcmp(str, "NULL"))
101         return NULL;
102
103     return g_strdup(str);
104 }
105
106 static PHRASE_FILE_TYPE to_file_type(const char * str) {
107 #define HANDLE(x) {                             \
108         if (0 == strcmp(str, #x))               \
109             return x;                           \
110     }
111
112     HANDLE(NOT_USED);
113     HANDLE(SYSTEM_FILE);
114     HANDLE(DICTIONARY);
115     HANDLE(USER_FILE);
116
117     assert(false);
118
119 #undef HANDLE
120 }
121
122 bool SystemTableInfo::load(const char * filename) {
123     reset();
124
125     char * locale = setlocale(LC_NUMERIC, "C");
126
127     FILE * input = fopen(filename, "r");
128     if (NULL == input) {
129         fprintf(stderr, "open %s failed.\n", filename);
130         return false;
131     }
132
133     int binver = 0, modelver = 0;
134     gfloat lambda = 0.;
135
136     int num = fscanf(input, "binary format version:%d\n", &binver);
137     if (1 != num) {
138         fclose(input);
139         return false;
140     }
141
142     num = fscanf(input, "model data version:%d\n", &modelver);
143     if (1 != num) {
144         fclose(input);
145         return false;
146     }
147
148     num = fscanf(input, "lambda parameter:%f\n", &lambda);
149     if (1 != num) {
150         fclose(input);
151         return false;
152     }
153
154 #if 0
155     printf("binver:%d modelver:%d lambda:%f\n", binver, modelver, lambda);
156 #endif
157
158     m_binary_format_version = binver;
159     m_model_data_version = modelver;
160     m_lambda = lambda;
161
162     int index = 0;
163     char tablefile[256], sysfile[256], userfile[256], filetype[256];
164     while (!feof(input)) {
165         num = fscanf(input, "%d %s %s %s %s\n",
166                      &index, tablefile, sysfile, userfile, filetype);
167
168         if (5 != num)
169             continue;
170
171         if (!(0 <= index && index < PHRASE_INDEX_LIBRARY_COUNT))
172             continue;
173
174         /* save into m_table_info. */
175         pinyin_table_info_t * table_info = &m_table_info[index];
176         assert(index == table_info->m_dict_index);
177
178         table_info->m_table_filename = to_string(tablefile);
179         table_info->m_system_filename = to_string(sysfile);
180         table_info->m_user_filename = to_string(userfile);
181
182         table_info->m_file_type = to_file_type(filetype);
183     }
184
185     fclose(input);
186
187     /* postfix reserved tables. */
188     postfix_tables();
189
190     setlocale(LC_NUMERIC, locale);
191
192     return true;
193 }
194
195 const pinyin_table_info_t * SystemTableInfo::get_table_info() {
196     return m_table_info;
197 }
198
199 gfloat SystemTableInfo::get_lambda() {
200     return m_lambda;
201 }
202
203
204 UserTableInfo::UserTableInfo() {
205     m_binary_format_version = 0;
206     m_model_data_version = 0;
207 }
208
209 void UserTableInfo::reset() {
210     m_binary_format_version = 0;
211     m_model_data_version = 0;
212 }
213
214 bool UserTableInfo::load(const char * filename) {
215     reset();
216
217     char * locale = setlocale(LC_NUMERIC, "C");
218
219     FILE * input = fopen(filename, "r");
220     if (NULL == input) {
221         fprintf(stderr, "open %s failed.", filename);
222         return false;
223     }
224
225     int binver = 0, modelver = 0;
226
227     int num = fscanf(input, "binary format version:%d\n", &binver);
228     if (1 != num) {
229         fclose(input);
230         return false;
231     }
232
233     num = fscanf(input, "model data version:%d\n", &modelver);
234     if (1 != num) {
235         fclose(input);
236         return false;
237     }
238
239 #if 0
240     printf("binver:%d modelver:%d\n", binver, modelver);
241 #endif
242
243     m_binary_format_version = binver;
244     m_model_data_version = modelver;
245
246     fclose(input);
247
248     setlocale(LC_NUMERIC, locale);
249
250     return true;
251 }
252
253 bool UserTableInfo::save(const char * filename) {
254     char * locale = setlocale(LC_NUMERIC, "C");
255
256     FILE * output = fopen(filename, "w");
257     if (NULL == output) {
258         fprintf(stderr, "write %s failed.\n", filename);
259         return false;
260     }
261
262     fprintf(output, "binary format version:%d\n", m_binary_format_version);
263     fprintf(output, "model data version:%d\n", m_model_data_version);
264
265     fclose(output);
266
267     setlocale(LC_NUMERIC, locale);
268
269     return true;
270 }
271
272 bool UserTableInfo::is_conform(const SystemTableInfo * sysinfo) {
273     if (sysinfo->m_binary_format_version != m_binary_format_version)
274         return false;
275
276     if (sysinfo->m_model_data_version != m_model_data_version)
277         return false;
278
279     return true;
280 }
281
282 bool UserTableInfo::make_conform(const SystemTableInfo * sysinfo) {
283     m_binary_format_version = sysinfo->m_binary_format_version;
284     m_model_data_version = sysinfo->m_model_data_version;
285     return true;
286 }