write table info
[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
26 using namespace pinyin;
27
28
29 static const pinyin_table_info_t reserved_tables[] = {
30     {RESERVED, NULL, NULL, NULL, NOT_USED},
31     {GB_DICTIONARY, "gb_char.table", "gb_char.bin", "gb_char.dbin", SYSTEM_FILE},
32     {GBK_DICTIONARY, "gbk_char.table", "gbk_char.bin", "gbk_char.dbin", SYSTEM_FILE},
33
34     {MERGED_DICTIONARY, "merged.table", "merged.bin", "merged.dbin", SYSTEM_FILE},
35
36     {USER_DICTIONARY, NULL, NULL, "user.bin", USER_FILE}
37 };
38
39
40 SystemTableInfo::SystemTableInfo() {
41     m_binary_format_version = 0;
42     m_model_data_version = 0;
43     m_lambda = 0.;
44
45     size_t i;
46     for (i = 0; i < PHRASE_INDEX_LIBRARY_COUNT; ++i) {
47         pinyin_table_info_t * tableinfo = &m_table_info[i];
48
49         tableinfo->m_dict_index = i;
50         tableinfo->m_table_filename = NULL;
51         tableinfo->m_system_filename = NULL;
52         tableinfo->m_user_filename = NULL;
53         tableinfo->m_file_type = NOT_USED;
54     }
55 }
56
57 SystemTableInfo::~SystemTableInfo() {
58     reset();
59 }
60
61 void SystemTableInfo::reset() {
62     m_binary_format_version = 0;
63     m_model_data_version = 0;
64     m_lambda = 0.;
65
66     size_t i;
67     for (i = 0; i < PHRASE_INDEX_LIBRARY_COUNT; ++i) {
68         pinyin_table_info_t * tableinfo = &m_table_info[i];
69
70         g_free(tableinfo->m_table_filename);
71         tableinfo->m_table_filename = NULL;
72         g_free(tableinfo->m_system_filename);
73         tableinfo->m_system_filename = NULL;
74         g_free(tableinfo->m_user_filename);
75         tableinfo->m_user_filename = NULL;
76         tableinfo->m_file_type = NOT_USED;
77     }
78 }
79
80 void SystemTableInfo::postfix_tables() {
81     size_t i;
82     for (i = 0; i < G_N_ELEMENTS(reserved_tables); ++i) {
83         pinyin_table_info_t * postfix = &reserved_tables[i];
84
85         guint8 index = postfix->m_dict_index;
86         pinyin_table_info_t * tableinfo = &m_table_info[index];
87         assert(tableinfo->m_dict_index == index);
88
89         tableinfo->m_table_filename = g_strdup(postfix->m_table_filename);
90         tableinfo->m_system_filename = g_strdup(postfix->m_system_filename);
91         tableinfo->m_user_filename = g_strdup(postfix->m_user_filename);
92         tableinfo->m_file_type = postfix->m_file_type;
93     }
94 }
95
96 static gchar * to_string(const char * str) {
97     if (0 == strcmp(str, "NULL"))
98         return NULL;
99
100     return g_strdup(str);
101 }
102
103 static PHRASE_FILE_TYPE to_file_type(const char * str) {
104 #define HANDLE(x) {                             \
105         if (0 == strcmp(str, #x))               \
106             return x;                           \
107     }
108
109     HANDLE(NOT_USED);
110     HANDLE(SYSTEM_FILE);
111     HANDLE(DICTIONARY);
112     HANDLE(USER_FILE);
113
114     assert(false);
115
116 #undef HANDLE
117 }
118
119 bool SystemTableInfo::load(const char * filename) {
120     reset();
121
122     FILE * input = fopen(filename, "r");
123     if (NULL == input) {
124         fprintf(stderr, "open %s failed.\n", filename);
125         return false;
126     }
127
128     int binver = 0, modelver = 0;
129     gfloat lambda = 0.;
130
131     int num = fscanf(input, "binary format version:%d", &binver);
132     if (1 != num)
133         return false;
134
135     num = fscanf(input, "model data version:%d", &modelver);
136     if (1 != num)
137         return false;
138
139     num = fscanf(input, "lambda parameter:%f", &lambda);
140     if (1 != num)
141         return false;
142
143 #if 0
144     printf("binver:%d modelver:%d lambda:%f\n", binver, modelver, lambda);
145 #endif
146
147     m_binary_format_version = binver;
148     m_model_data_version = modelver;
149     m_lambda = lambda;
150
151     int index = 0;
152     char tablefile[256], sysfile[256], userfile[256], filetype[256];
153     while (!feof(infile)){
154         num = fscanf("%d %s %s %s %s",
155                      &index, tablefile, sysfile, userfile, filetype);
156
157         if (5 != num)
158             continue;
159
160         if (!(0 <= index && index < PHRASE_INDEX_LIBRARY_COUNT))
161             continue;
162
163         /* save into m_table_info. */
164         pinyin_table_info_t * tableinfo = &m_table_info[index];
165         assert(index == tableinfo->m_dict_index);
166
167         table_info->m_table_filename = to_string(tablefile);
168         table_info->m_system_filename = to_string(sysfile);
169         table_info->m_user_filename = to_string(userfile);
170
171         table_info->m_file_type = to_file_type(filetype);
172     }
173
174     fclose(input);
175
176     /* postfix reserved tables. */
177     postfix_tables();
178     return true;
179 }
180
181 const pinyin_table_info_t * SystemTableInfo::get_table_info() {
182     return m_table_info;
183 }
184
185 gfloat SystemTableInfo::get_lambda() {
186     return m_lambda;
187 }
188
189
190 UserTableInfo::UserTableInfo() {
191     m_binary_format_version = 0;
192     m_model_data_version = 0;
193 }
194
195 void UserTableInfo::reset() {
196     m_binary_format_version = 0;
197     m_model_data_version = 0;
198 }
199
200 bool UserTableInfo::load(cosnt char * filename) {
201     reset();
202
203     FILE * input = fopen(filename, "r");
204     if (NULL == input) {
205         fprintf(stderr, "open %s failed.", filename);
206         return false;
207     }
208
209     int binver = 0, modelver = 0;
210
211     int num = fscanf(input, "binary format version:%d", &binver);
212     if (1 != num)
213         return false;
214
215     num = fscanf(input, "model data version:%d", &modelver);
216     if (1 != num)
217         return false;
218
219 #if 0
220     printf("binver:%d modelver:%d\n", binver, modelver);
221 #endif
222
223     m_binary_format_version = binver;
224     m_model_data_version = modelver;
225
226     fclose(input);
227
228     return true;
229 }
230
231 bool UserTableInfo::save(const char * filename) {
232     FILE * output = fopen(filename, "w");
233     if (NULL == output) {
234         fprintf(stderr, "write %s failed.\n", output);
235         return false;
236     }
237
238     fprintf(output, "binary format version:%d\n", m_binary_format_version);
239     fprintf(output, "model data version:%d\n", m_model_data_version);
240
241     fclose(output);
242
243     return true;
244 }
245
246 bool UserTableInfo::is_conform(const SystemTableInfo * sysinfo) {
247     if (sysinfo->m_binary_format_version != m_binary_format_version)
248         return false;
249
250     if (sysinfo->m_model_data_version != m_model_data_version)
251         return false;
252
253     return true;
254 }
255
256 bool UserTableInfo::make_conform(const SystemTableInfo * sysinfo) {
257     m_binary_format_version = sysinfo->m_binary_format_version;
258     m_model_data_version = sysinfo->m_model_data_version;
259     return true;
260 }