* - XDXF engine code review
[mdictionary] / src / plugins / xdxf / include / engine_xdxf.h
1 /*******************************************************************************
2 This file is part of mdictionary.
3
4 mdictionary is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 mdictionary is distributed in the hope that it will be useful, 
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License 
15 along with mdictionary; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18 Copyright 2006-2008 ComArch S.A.
19 *******************************************************************************/
20 /** \defgroup XDXFEngine Dictionary Engine - XDXF format
21  * \brief XDXF-based dictionary engine.
22  *
23  * This is library with dictionary engine supporting XDXF dictionaries. XDXF is
24  * based on XML language. For more information, please go to:
25  * \li http://xdxf.sourceforge.net/
26  *
27  * TODO: currently XDXF engine does not support all function from engine API!
28  * It need implementation of API version 0.2 function, like getting icon path
29  * etc.
30  */
31 /*@{*/
32 /** \file engine_xdxf.h
33  * \brief Header for XDXF-based dictionary engine.
34  */
35
36 #ifndef _DICTIONARY_ENGINE_XDXF
37 #define _DICTIONARY_ENGINE_XDXF
38
39 #ifdef __cplusplus
40         extern "C" {
41 #endif
42
43 /* headers with unix types/functions - onl for timers */
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 #include <sys/time.h>
47 #include <fcntl.h>
48 #include <unistd.h>
49
50 #include <glib.h> /* header with GLIB definitions/functions/types */
51 #include <libgnomevfs/gnome-vfs.h> /* header with gnome-vfs - recommended I/O
52                                     * API for maemo */
53 #include <expat.h> /* header with expat - XML Parser API */
54 #include <string.h> /* manipulating strings */
55 #include <dictionary_engine.h> /* header wit engine API */
56
57
58 /** \name Timers */
59 /*@{*/
60 /** \brief Flags telling that we want to start timer. */
61 #define TIMER_START     TRUE
62 /** \brief Flags telling that we want to stop timer. */
63 #define TIMER_STOP      FALSE
64
65 /** \brief Start/stop timers.
66  *
67  * \param start do we want start new timer or end the last one
68  * \param message string which shoul be printed by function while debbuging
69  * \return -1.0 if we start or seconds passed from start if we want to 
70  * stop timer
71  */
72 /* in final releases timer capapilities should be removed for increase
73  * performance */
74 /* static double timer(gboolean start, gchar* message); */
75
76 /*@}*/
77
78
79 /** \brief Version of XDXF engine. */
80 #define DIC_ENG_VERSION "0.1b"
81
82 /** \brief Short description of format supported by the current engine. */
83 #define DIC_ENG_FORMAT  "XDXF"
84
85 /** \brief Buffer's length used while generating cache for dictionary. */
86 #define DICT_CACHEING_BUFF_SIZE                 16*1024
87
88 /** \brief Buffer's length used while searching for words list. */
89 #define DICT_SEARCHING_WORD_LIST_BUFF_SIZE      16*1024
90
91 /** \brief Buffer's length used while searching for translation. */
92 #define DICT_SEARCHING_WORD_TRAN_BUFF_SIZE      16*1024
93
94 /** \brief Maximum length of word in dictionary.
95  *
96  * Engine use this value while searching in cache file. If this would be too
97  * low value engine would work incorrectly, but too big value will decrease
98  * performance of searching. 512 is optimal in most cases.
99  */
100 #define DICT_MAX_WORD_LENGTH   512
101
102 /** \brief Translate boolean value into string. */
103 #define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" )
104
105
106 /** \brief Structure used while dict_eng_module_check() is working.
107  */
108 struct _XDXFCheckingData {
109         gboolean further;
110         /**< \brief do we need to continue checking */
111         gboolean good;
112         /**< \brief returned value telling if given file was proper XDXF
113          * dictionary */
114         guint    deep;
115         /**< \brief keep depth of XDXF structure while parsing file */
116 };
117 typedef struct _XDXFCheckingData XDXFCheckingData;
118
119 /** \brief Structure to help parse xdxf file for searching words list.
120  */
121 struct _XDXFWordsListData {
122         gchar*   last_word;
123         /**< \brief last found word */
124         gchar*   pattern;
125         /**< \brief pattern for words to search */
126         guint    pattern_len;
127         /**< \brief length of pattern */
128         guint    last_word_length;
129         /**< \brief length of last found word */
130         GArray*  result;
131         /**< \brief result of searching - GArray with words matching pattern */
132         guint    one_word;
133         /**< \brief 1 while engine is parsing whole particular word (k tag), 0 
134          * otherwise */
135         gboolean cont;
136         /**< \brief do we need to continue searching */
137 };
138 typedef struct _XDXFWordsListData       XDXFWordsListData;
139
140 /** \brief Structure to help parse xdxf file for searching word's translation.
141  */
142 struct _XDXFWordsTransData {
143         gchar*          last_word;
144         /**< \brief last found word in dictionary */
145         gchar*          word;
146         /**< \brief word to search translation for */
147         guint           word_len;
148         /**< \brief length of word */
149         guint           last_word_length;
150         /**< \brief length of last found word */
151         gchar*          translation;
152         /**< \brief found translation or NULL if such was not found */
153         guint           one_word;
154         /**< \brief 1 while engine is parsing whole particular word (k tag), 0
155          * otherwise */
156         gboolean        cont;
157         /**< \brief do we need to continue searching */
158         gulong          last_start;
159         /**< \brief keeps offset in file of last found article 
160          * (word plus translation) */
161         XML_Parser*     parser;
162         /**< \brief pointer to expat XML parser */
163         gboolean        found;
164         /**< \brief telling if translation was found */
165         GnomeVFSHandle* xdxf;
166         /**< \brief pointer to dictionary file */
167 };
168 typedef struct _XDXFWordsTransData      XDXFWordsTransData;
169
170 /** \brief Structure to help make optimization possible
171  */
172 struct _XDXFCacheData {
173         gchar*          buffer;
174         /**< \brief buffer with output part of cache file */
175         long            last_start;
176         /**< \brief keeps offset in file of the beggining of last found article
177          */
178         long            last_stop;
179         /**< \brief keeps offset in file of the end of last found article */
180         long            last_length;
181         /**< \brief keeps length of last found article */
182         GnomeVFSHandle* cache;
183         /**< \brief pointer to cache file */
184         XML_Parser      parser;
185         /**< \brief pointer to expat XML parser */
186         int             state;
187         /**< \brief 1 if parser is parsing article key (word), 2 if parser is
188          * parsing article value (translation), 0 otherwise. */
189         long            buffer_length;
190         /**< \brief buffer's length */
191 };
192 typedef struct _XDXFCacheData           XDXFCacheData;
193
194 /** \brief Internal data structure for representing part of file.
195  */
196 struct _FilePart {
197         guint offset;
198         /**< \brief offset in file of file part */
199         guint length;
200         /**< \brief length of file part */
201 };
202 typedef struct _FilePart        FilePart;
203
204 /** \brief Internal data structure of XDXF Engine.
205  */
206 struct _XDXFData {
207         GnomeVFSHandle*         xdxf;
208         /**< \brief pointer to *.xdxf file */
209         GnomeVFSHandle*         cache;
210         /**< \brief pointer to cache file */
211         gchar*                  dict_path;
212         /**< \brief path to dictionary */
213         EngineStatus            last_error;
214         /**< \brief status of last taken action */
215         gboolean                auto_free;
216         /**< \brief auto free mechanism status: FALSE - off, TRUE - on */
217
218         cb_progress             cb_progress_caching;
219         /**< \brief pointer to callback function called while informing about 
220          * caching progress */
221         gpointer                cb_progress_caching_data;
222         /**< \brief pointer to data passed to callback function called while
223          * informing about caching progress */
224         gdouble                 cb_progress_caching_seed;
225         /**< \brief how often progress callback should be called. 0.01 mean 
226          * that after each 1% of work callback shoul be called */
227
228         cb_progress             cb_progress_word_list;
229         /**< \brief pointer to callback function called while informing about
230          * words list searching progress */
231         gpointer                cb_progress_word_list_data;
232         /**< \brief pointer to data passed to callback function called while
233          * informing about words list searching progress */
234         gdouble                 cb_progress_word_list_seed;
235         /**< \brief how often progress callback should be called. 0.01 mean
236          * that after each 1% of work callback shoul be called */
237
238         cb_progress             cb_progress_word_trans;
239         /**< \brief pointer to callback function called while informing about
240          * word's translation searching progress */
241         gpointer                cb_progress_word_trans_data;
242         /**< \brief pointer to data passed to callback function called while
243          * informing about word's translation searching progress */
244         gdouble                 cb_progress_word_trans_seed;
245         /**< \brief how often progress callback should be called. 0.01 mean
246          * that after each 1% of work callback shoul be called */
247
248         cb_word_list            cb_search_word_list;
249         /**< \brief pointer to callback function called after words list is
250          * found */
251         gpointer                cb_search_word_list_data;
252         /**< \brief pointer to data passed to callback function called after
253          * words list is found */
254
255         cb_word_translation     cb_search_word_trans;
256         /**< \brief pointer to callback function called after word's translation
257          * is found */
258         gpointer                cb_search_word_trans_data;
259         /**< \brief pointer to data passed to callback function called after
260          * word's translation is found */
261 };
262 typedef struct _XDXFData        XDXFData;
263
264
265 /** \name Parsing Expat's callbacks */
266 /*@{*/
267
268 /** \brief Checking XML file is proper XDXF file - tag starts.
269  *
270  * See Expat documentation for more information about parser callbacks.
271  */
272 static void     is_xdxf_file_start(void *data,
273                                    const char *el,
274                                    const char **attr);
275
276 /** \brief Checking XML file is proper XDXF file - tag ends.
277  *
278  * See Expat documentation for more information about parser callbacks.
279  */
280 static void     is_xdxf_file_end(void *data,  const char *el);
281
282 /** \brief Searching for words list - tag start.
283  *
284  * See Expat documentation for more information about parser callbacks.
285  */
286 static void     search_word_list_start(void *data,
287                                        const char *el,
288                                        const char **attr);
289 /** \brief Searching for words list - tag ends.
290  *
291  * See Expat documentation for more information about parser callbacks.
292  */
293 static void     search_word_list_end(void *data, const char *el);
294
295 /** \brief Searching for words list - text node.
296  *
297  * See Expat documentation for more information about parser callbacks.
298  */
299 static void     search_word_list_text(void *data, const XML_Char *txt, int len);
300
301 /** \brief Searching for word's translation - tag start.
302  *
303  * See Expat documentation for more information about parser callbacks.
304  */
305 static void     search_word_trans_start(void *data,
306                                         const char *el,
307                                         const char **attr);
308
309 /** \brief Searching for word's translation - tag ends.
310  *
311  * See Expat documentation for more information about parser callbacks.
312  */
313 static void     search_word_trans_end(void *data, const char *el);
314
315 /** \brief Searching for word's translation - text node.
316  *
317  * See Expat documentation for more information about parser callbacks.
318  */
319 static void     search_word_trans_text(void *data,
320                                        const XML_Char *txt,
321                                        int len);
322 /*@}*/
323
324
325 /** \brief Return particular part of file. */
326 static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file);
327
328 /** \brief Convert string to proper path name. */
329 static gchar*           string_to_path(gchar** string);
330
331 /** \brief Tells if file is in XDXF format (file should exist). */
332 static gboolean         is_xdxf_file(gchar* file);
333
334 /** \brief Get file's lenght. */
335 static guint64          get_file_size(GnomeVFSHandle* file);
336
337 /** \brief Return how many records (from cache file) are in the current buffer.
338  */
339 static guint            get_max_length(gchar* a, guint length);
340
341 /** \brief Searching for word's translation in cache file. */
342 static gchar* word_translation_cache(XDXFData* data, gchar* word);
343
344 /** \brief Searching for word's translation in XDXF file. */
345 static gchar* word_translation_xdxf(XDXFData* data, gchar* word);
346
347 /** \brief Searching for words list in cache file. */
348 static void word_list_cache(XDXFData* data,
349                             gchar* pattern,
350                             GArray* result,
351                             gpointer cb_data);
352
353 /** \brief Searching for words list in XDXF file. */
354 static void word_list_xdxf(XDXFData* data,
355                            gchar* pattern,
356                            GArray* result,
357                            gpointer cb_data);
358
359 /** \name Module functions */
360 /*@{*/
361
362 /** \brief dict_eng_module_check() function implementation. */
363 gboolean        xdxf_engine_check(gchar* location);
364
365 /** \brief dict_eng_module_get_description() function implementation. */
366 gchar*          xdxf_engine_description();
367
368 /** \brief dict_eng_module_get_format() function implementation. */
369 gchar*          xdxf_engine_format();
370
371 /** \brief dict_eng_module_get_version() function implementation. */
372 gchar*          xdxf_engine_version();
373
374 /** \brief dict_eng_module_create() function implementation. */
375 Engine*         xdxf_engine_create(gchar* location, 
376                               EngineOptimizationFlag flags,
377                               cb_progress progress_handler,
378                               gpointer progress_data,
379                               gdouble seed);
380 /*@}*/
381
382
383 /** \name Particular dictionary function */
384 /*@{*/
385
386 /** \brief dict_eng_destroy() function implementation. */
387 void            xdxf_engine_close(Engine* engine);
388
389 /** \brief dict_eng_get_location() function implementation. */
390 gchar*          xdxf_engine_location(Engine* engine);
391
392 /** \brief dict_eng_optimize() function implementation. */
393 void            xdxf_engine_optimize(Engine* engine);
394
395 /** \brief dict_eng_is_optimized() function implementation. */
396 gboolean        xdxf_engine_is_optimized(Engine* engine);
397
398 /** \brief dict_eng_set_auto_free() function implementation. */
399 void            xdxf_engine_set_auto_free(Engine* engine, gboolean state);
400
401 /** \brief dict_eng_set_callback() function implementation. */
402 gpointer        xdxf_engine_set_callbacks(Engine* engine,
403                                      gchar* event,
404                                      gpointer c_handler,
405                                      gpointer user_data);
406
407 /** \brief dict_eng_set_progress_seed() function implementation. */
408 void            xdxf_engine_set_progress_seed(Engine* engine,
409                                          gchar* signal,
410                                          gdouble seed);
411
412 /** \brief dict_eng_search_word_list() function implementation. */
413 void            xdxf_engine_search_word_list(Engine* engine,
414                                              gchar* pattern,
415                                              gpointer data);
416
417 /** \brief dict_eng_search_word_translation() function implementation. */
418 void            xdxf_engine_search_word_translation(Engine* engine,
419                                                     gchar* word,
420                                                     gpointer data);
421
422 /*** \brief dict_eng_search_word_translation_extended() function implementation.
423  */
424 /* this function was removed from engine API */
425 /*void            xdxf_engine_search_word_translation_extended(Engine* engine,
426                                                         gchar* word);
427 */
428
429 /** \brief dict_eng_get_last_status() function implementation. */
430 EngineStatus    xdxf_engine_error(Engine* engine);
431
432 /** \brief dict_eng_status_message() function implementation. */
433 gchar*          xdxf_engine_error_message(EngineStatus error);
434
435 /** \brief dict_eng_add_word() function implementation. */
436 gboolean        xdxf_engine_add_word(Engine* engine,
437                                      gchar*  word,
438                                      gchar*  translation);
439
440 /** \brief dict_eng_remove_word() function implementation. */
441 gboolean        xdxf_engine_remove_word(Engine* engine, gchar*  word);
442 /*@}*/
443
444 /** \brief implementation of engine_global_functions(void) function. */
445 EngineModule    engine_global_functions();
446
447 #ifdef __cplusplus
448 }
449 #endif
450 #endif
451
452 /*@}*/