From 5350ab5fdc7b2938463d553cb343f3bf5c8977ac Mon Sep 17 00:00:00 2001 From: stranger Date: Fri, 4 Jan 2008 15:39:24 +0000 Subject: [PATCH] * - XDXF engine code review git-svn-id: file:///svnroot/mdictionary/trunk@227 5bde0345-f819-0410-ac75-e5045f9217cc --- src/plugins/xdxf/include/engine_xdxf.h | 502 +++--- src/plugins/xdxf/src/engine_xdxf.c | 2788 +++++++++++++++++--------------- 2 files changed, 1750 insertions(+), 1540 deletions(-) diff --git a/src/plugins/xdxf/include/engine_xdxf.h b/src/plugins/xdxf/include/engine_xdxf.h index c4270e4..4b6fd6e 100644 --- a/src/plugins/xdxf/include/engine_xdxf.h +++ b/src/plugins/xdxf/include/engine_xdxf.h @@ -15,8 +15,24 @@ You should have received a copy of the GNU General Public License along with mdictionary; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Copyright 2006 ComArch S.A. +Copyright 2006-2008 ComArch S.A. *******************************************************************************/ +/** \defgroup XDXFEngine Dictionary Engine - XDXF format + * \brief XDXF-based dictionary engine. + * + * This is library with dictionary engine supporting XDXF dictionaries. XDXF is + * based on XML language. For more information, please go to: + * \li http://xdxf.sourceforge.net/ + * + * TODO: currently XDXF engine does not support all function from engine API! + * It need implementation of API version 0.2 function, like getting icon path + * etc. + */ +/*@{*/ +/** \file engine_xdxf.h + * \brief Header for XDXF-based dictionary engine. + */ + #ifndef _DICTIONARY_ENGINE_XDXF #define _DICTIONARY_ENGINE_XDXF @@ -24,311 +40,413 @@ Copyright 2006 ComArch S.A. extern "C" { #endif -//______________________________________________________________________________ -// ***************************************************************************** -//************************************************************* HEADERS SECTION: -//------------------------------------------------------------------------------ -// headers with unix types/functions - onl for timers +/* headers with unix types/functions - onl for timers */ #include #include #include -#include -#include -//------------------------------------------------------------------------------ -// header with GLIB definitions/functions/types -#include -//------------------------------------------------------------------------------ -// header with gnome-vfs - recommended I/O API for maemo -#include -//------------------------------------------------------------------------------ -// header with expat - XML Parser API -#include -//------------------------------------------------------------------------------ -// header wit engine API -#include "dictionary_engine.h" -//------------------------------------------------------------------------------ - - -//______________________________________________________________________________ -// ***************************************************************************** -//********************************************************* DEFINITIONS SECTION: -//------------------------------------------------------------------------------ -// definitions for timer function - flag telling if we want to start or stop -// timing +#include +#include + +#include /* header with GLIB definitions/functions/types */ +#include /* header with gnome-vfs - recommended I/O + * API for maemo */ +#include /* header with expat - XML Parser API */ +#include /* manipulating strings */ +#include /* header wit engine API */ + + +/** \name Timers */ +/*@{*/ +/** \brief Flags telling that we want to start timer. */ #define TIMER_START TRUE +/** \brief Flags telling that we want to stop timer. */ #define TIMER_STOP FALSE -//------------------------------------------------------------------------------ -// definitions of version and format which engine handles + +/** \brief Start/stop timers. + * + * \param start do we want start new timer or end the last one + * \param message string which shoul be printed by function while debbuging + * \return -1.0 if we start or seconds passed from start if we want to + * stop timer + */ +/* in final releases timer capapilities should be removed for increase + * performance */ +/* static double timer(gboolean start, gchar* message); */ + +/*@}*/ + + +/** \brief Version of XDXF engine. */ #define DIC_ENG_VERSION "0.1b" + +/** \brief Short description of format supported by the current engine. */ #define DIC_ENG_FORMAT "XDXF" -//------------------------------------------------------------------------------ -// defines lenght of buffers for particular functions in engine which needs -// big buffers + +/** \brief Buffer's length used while generating cache for dictionary. */ #define DICT_CACHEING_BUFF_SIZE 16*1024 + +/** \brief Buffer's length used while searching for words list. */ #define DICT_SEARCHING_WORD_LIST_BUFF_SIZE 16*1024 + +/** \brief Buffer's length used while searching for translation. */ #define DICT_SEARCHING_WORD_TRAN_BUFF_SIZE 16*1024 -//------------------------------------------------------------------------------ -// maximum length of word possible to find in any dictionary + +/** \brief Maximum length of word in dictionary. + * + * Engine use this value while searching in cache file. If this would be too + * low value engine would work incorrectly, but too big value will decrease + * performance of searching. 512 is optimal in most cases. + */ #define DICT_MAX_WORD_LENGTH 512 -//------------------------------------------------------------------------------ -// macro for "printing" gboolean statement - "TRUE" or "FALSE" + +/** \brief Translate boolean value into string. */ #define PRINT_STATE(state) ( (state) ? "TRUE" : "FALSE" ) -//------------------------------------------------------------------------------ -//______________________________________________________________________________ -// ***************************************************************************** -//****************************************** DATA STRUCTURE DEFINITIONS SECTION: -//------------------------------------------------------------------------------ /** \brief Structure used while dict_eng_module_check() is working. */ struct _XDXFCheckingData { - gboolean further; - gboolean good; - guint deep; + gboolean further; + /**< \brief do we need to continue checking */ + gboolean good; + /**< \brief returned value telling if given file was proper XDXF + * dictionary */ + guint deep; + /**< \brief keep depth of XDXF structure while parsing file */ }; -typedef struct _XDXFCheckingData XDXFCheckingData; -//------------------------------------------------------------------------------ +typedef struct _XDXFCheckingData XDXFCheckingData; + /** \brief Structure to help parse xdxf file for searching words list. */ struct _XDXFWordsListData { - gchar* last_word; - gchar* pattern; - guint pattern_len; - guint last_word_length; - GArray* result; - guint one_word; - gboolean cont; + gchar* last_word; + /**< \brief last found word */ + gchar* pattern; + /**< \brief pattern for words to search */ + guint pattern_len; + /**< \brief length of pattern */ + guint last_word_length; + /**< \brief length of last found word */ + GArray* result; + /**< \brief result of searching - GArray with words matching pattern */ + guint one_word; + /**< \brief 1 while engine is parsing whole particular word (k tag), 0 + * otherwise */ + gboolean cont; + /**< \brief do we need to continue searching */ }; typedef struct _XDXFWordsListData XDXFWordsListData; -//------------------------------------------------------------------------------ + /** \brief Structure to help parse xdxf file for searching word's translation. */ struct _XDXFWordsTransData { - gchar* last_word; - gchar* word; - guint word_len; - guint last_word_length; - gchar* translation; - guint one_word; - gboolean cont; - gulong last_start; - XML_Parser* parser; - gboolean found; - GnomeVFSHandle* xdxf; + gchar* last_word; + /**< \brief last found word in dictionary */ + gchar* word; + /**< \brief word to search translation for */ + guint word_len; + /**< \brief length of word */ + guint last_word_length; + /**< \brief length of last found word */ + gchar* translation; + /**< \brief found translation or NULL if such was not found */ + guint one_word; + /**< \brief 1 while engine is parsing whole particular word (k tag), 0 + * otherwise */ + gboolean cont; + /**< \brief do we need to continue searching */ + gulong last_start; + /**< \brief keeps offset in file of last found article + * (word plus translation) */ + XML_Parser* parser; + /**< \brief pointer to expat XML parser */ + gboolean found; + /**< \brief telling if translation was found */ + GnomeVFSHandle* xdxf; + /**< \brief pointer to dictionary file */ }; typedef struct _XDXFWordsTransData XDXFWordsTransData; -//------------------------------------------------------------------------------ + /** \brief Structure to help make optimization possible */ struct _XDXFCacheData { - gchar* buffer; - long last_start; - long last_stop; - long last_length; - GnomeVFSHandle* cache; - XML_Parser parser; - int state; - long buffer_length; + gchar* buffer; + /**< \brief buffer with output part of cache file */ + long last_start; + /**< \brief keeps offset in file of the beggining of last found article + */ + long last_stop; + /**< \brief keeps offset in file of the end of last found article */ + long last_length; + /**< \brief keeps length of last found article */ + GnomeVFSHandle* cache; + /**< \brief pointer to cache file */ + XML_Parser parser; + /**< \brief pointer to expat XML parser */ + int state; + /**< \brief 1 if parser is parsing article key (word), 2 if parser is + * parsing article value (translation), 0 otherwise. */ + long buffer_length; + /**< \brief buffer's length */ }; typedef struct _XDXFCacheData XDXFCacheData; -//------------------------------------------------------------------------------ + /** \brief Internal data structure for representing part of file. */ struct _FilePart { - guint offset; - guint length; + guint offset; + /**< \brief offset in file of file part */ + guint length; + /**< \brief length of file part */ }; typedef struct _FilePart FilePart; -//------------------------------------------------------------------------------ + /** \brief Internal data structure of XDXF Engine. */ struct _XDXFData { - GnomeVFSHandle* xdxf; - GnomeVFSHandle* cache; - gchar* dict_path; - EngineStatus last_error; - gboolean auto_free; + GnomeVFSHandle* xdxf; + /**< \brief pointer to *.xdxf file */ + GnomeVFSHandle* cache; + /**< \brief pointer to cache file */ + gchar* dict_path; + /**< \brief path to dictionary */ + EngineStatus last_error; + /**< \brief status of last taken action */ + gboolean auto_free; + /**< \brief auto free mechanism status: FALSE - off, TRUE - on */ - cb_progress cb_progress_caching; - gpointer cb_progress_caching_data; - gdouble cb_progress_caching_seed; + cb_progress cb_progress_caching; + /**< \brief pointer to callback function called while informing about + * caching progress */ + gpointer cb_progress_caching_data; + /**< \brief pointer to data passed to callback function called while + * informing about caching progress */ + gdouble cb_progress_caching_seed; + /**< \brief how often progress callback should be called. 0.01 mean + * that after each 1% of work callback shoul be called */ - cb_progress cb_progress_word_list; - gpointer cb_progress_word_list_data; - gdouble cb_progress_word_list_seed; + cb_progress cb_progress_word_list; + /**< \brief pointer to callback function called while informing about + * words list searching progress */ + gpointer cb_progress_word_list_data; + /**< \brief pointer to data passed to callback function called while + * informing about words list searching progress */ + gdouble cb_progress_word_list_seed; + /**< \brief how often progress callback should be called. 0.01 mean + * that after each 1% of work callback shoul be called */ - cb_progress cb_progress_word_trans; - gpointer cb_progress_word_trans_data; - gdouble cb_progress_word_trans_seed; + cb_progress cb_progress_word_trans; + /**< \brief pointer to callback function called while informing about + * word's translation searching progress */ + gpointer cb_progress_word_trans_data; + /**< \brief pointer to data passed to callback function called while + * informing about word's translation searching progress */ + gdouble cb_progress_word_trans_seed; + /**< \brief how often progress callback should be called. 0.01 mean + * that after each 1% of work callback shoul be called */ - cb_word_list cb_search_word_list; - gpointer cb_search_word_list_data; + cb_word_list cb_search_word_list; + /**< \brief pointer to callback function called after words list is + * found */ + gpointer cb_search_word_list_data; + /**< \brief pointer to data passed to callback function called after + * words list is found */ - cb_word_translation cb_search_word_trans; - gpointer cb_search_word_trans_data; + cb_word_translation cb_search_word_trans; + /**< \brief pointer to callback function called after word's translation + * is found */ + gpointer cb_search_word_trans_data; + /**< \brief pointer to data passed to callback function called after + * word's translation is found */ }; typedef struct _XDXFData XDXFData; -//------------------------------------------------------------------------------ -//______________________________________________________________________________ -// ***************************************************************************** -//*************************************************** PARSING FUNCTIONS SECTION: -//------------------------------------------------------------------------------ -// while is_xdxf_file() is working +/** \name Parsing Expat's callbacks */ +/*@{*/ + +/** \brief Checking XML file is proper XDXF file - tag starts. + * + * See Expat documentation for more information about parser callbacks. + */ static void is_xdxf_file_start(void *data, const char *el, const char **attr); + +/** \brief Checking XML file is proper XDXF file - tag ends. + * + * See Expat documentation for more information about parser callbacks. + */ static void is_xdxf_file_end(void *data, const char *el); -//------------------------------------------------------------------------------ -// while dict_eng_search_word_list() is working + +/** \brief Searching for words list - tag start. + * + * See Expat documentation for more information about parser callbacks. + */ static void search_word_list_start(void *data, const char *el, - const char **attr); + const char **attr); +/** \brief Searching for words list - tag ends. + * + * See Expat documentation for more information about parser callbacks. + */ static void search_word_list_end(void *data, const char *el); + +/** \brief Searching for words list - text node. + * + * See Expat documentation for more information about parser callbacks. + */ static void search_word_list_text(void *data, const XML_Char *txt, int len); -//------------------------------------------------------------------------------ -// // while dict_eng_search_word_translation() is working + +/** \brief Searching for word's translation - tag start. + * + * See Expat documentation for more information about parser callbacks. + */ static void search_word_trans_start(void *data, const char *el, const char **attr); -static void search_word_trans_end(void *data, const char *el); + +/** \brief Searching for word's translation - tag ends. + * + * See Expat documentation for more information about parser callbacks. + */ +static void search_word_trans_end(void *data, const char *el); + +/** \brief Searching for word's translation - text node. + * + * See Expat documentation for more information about parser callbacks. + */ static void search_word_trans_text(void *data, const XML_Char *txt, int len); -//------------------------------------------------------------------------------ - - -//______________________________________________________________________________ -// ***************************************************************************** -//************************************************ ADDITIONAL FUNCTIONS SECTION: -//------------------------------------------------------------------------------ -// returning concrete part of file -static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); -//------------------------------------------------------------------------------ -// convert string to proper path name (no filename, no "/" at the ned, file -// exist) +/*@}*/ + + +/** \brief Return particular part of file. */ +static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file); + +/** \brief Convert string to proper path name. */ static gchar* string_to_path(gchar** string); -//------------------------------------------------------------------------------ -// tells if file is in XDXF format (file should exist) -static gboolean is_xdxf_file(gchar* file); -//------------------------------------------------------------------------------ -// start/stop timers - returnet -1.0 if we start or seconds passed from start -// if we want to stop timer -//static double timer(gboolean start, gchar* message); -//------------------------------------------------------------------------------ -// return size of files + +/** \brief Tells if file is in XDXF format (file should exist). */ +static gboolean is_xdxf_file(gchar* file); + +/** \brief Get file's lenght. */ static guint64 get_file_size(GnomeVFSHandle* file); -//------------------------------------------------------------------------------ -// return how many records (from cache file) are in current buffer a with length -// length. + +/** \brief Return how many records (from cache file) are in the current buffer. + */ static guint get_max_length(gchar* a, guint length); -//------------------------------------------------------------------------------ -// return translation of word using cache file + +/** \brief Searching for word's translation in cache file. */ static gchar* word_translation_cache(XDXFData* data, gchar* word); -//------------------------------------------------------------------------------ -// return translation of word but using only xdxf dictionary file + +/** \brief Searching for word's translation in XDXF file. */ static gchar* word_translation_xdxf(XDXFData* data, gchar* word); -//------------------------------------------------------------------------------ -// return translation of word using cache file + +/** \brief Searching for words list in cache file. */ static void word_list_cache(XDXFData* data, gchar* pattern, GArray* result, gpointer cb_data); -//------------------------------------------------------------------------------ -// return translation of word but using only xdxf dictionary file + +/** \brief Searching for words list in XDXF file. */ static void word_list_xdxf(XDXFData* data, gchar* pattern, GArray* result, gpointer cb_data); -//------------------------------------------------------------------------------ - +/** \name Module functions */ +/*@{*/ -//______________________________________________________________________________ -// ***************************************************************************** -//****************************************************** MAIN FUNCTIONS SECTION: -//------------------------------------------------------------------------------ -// implementation of dict_eng_module_check(module,location) function +/** \brief dict_eng_module_check() function implementation. */ gboolean xdxf_engine_check(gchar* location); -//------------------------------------------------------------------------------ -// implementation of dict_eng_module_get_description(module) function + +/** \brief dict_eng_module_get_description() function implementation. */ gchar* xdxf_engine_description(); -//------------------------------------------------------------------------------ -// implementation of dict_eng_module_get_format(module) function + +/** \brief dict_eng_module_get_format() function implementation. */ gchar* xdxf_engine_format(); -//------------------------------------------------------------------------------ -// implementation of dict_eng_module_get_version(module) function + +/** \brief dict_eng_module_get_version() function implementation. */ gchar* xdxf_engine_version(); -//------------------------------------------------------------------------------ -// implementation of dict_eng_module_create(module,location,flags) and -// dict_eng_module_create_ext(module,location,flags) functions + +/** \brief dict_eng_module_create() function implementation. */ Engine* xdxf_engine_create(gchar* location, EngineOptimizationFlag flags, cb_progress progress_handler, gpointer progress_data, gdouble seed); -//------------------------------------------------------------------------------ -// implementation of dict_eng_destroy(engine) function +/*@}*/ + + +/** \name Particular dictionary function */ +/*@{*/ + +/** \brief dict_eng_destroy() function implementation. */ void xdxf_engine_close(Engine* engine); -//------------------------------------------------------------------------------ -// implementation of dict_eng_get_location(engine) function + +/** \brief dict_eng_get_location() function implementation. */ gchar* xdxf_engine_location(Engine* engine); -//------------------------------------------------------------------------------ -// implementation of dict_eng_optimize(engine) function + +/** \brief dict_eng_optimize() function implementation. */ void xdxf_engine_optimize(Engine* engine); -//------------------------------------------------------------------------------ -// implementation of dict_eng_is_optimized( engine ) function + +/** \brief dict_eng_is_optimized() function implementation. */ gboolean xdxf_engine_is_optimized(Engine* engine); -//------------------------------------------------------------------------------ -// implementation of dict_eng_set_auto_free(engine, state) function + +/** \brief dict_eng_set_auto_free() function implementation. */ void xdxf_engine_set_auto_free(Engine* engine, gboolean state); -//------------------------------------------------------------------------------ -// implementation of dict_eng_set_callback(engine,signal,c_handler,data) -// function + +/** \brief dict_eng_set_callback() function implementation. */ gpointer xdxf_engine_set_callbacks(Engine* engine, gchar* event, gpointer c_handler, gpointer user_data); -//------------------------------------------------------------------------------ -// implementation of dict_eng_set_progress_seed(engine, signal, val) function + +/** \brief dict_eng_set_progress_seed() function implementation. */ void xdxf_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed); -//------------------------------------------------------------------------------ -// implementation ofdict_eng_search_word_list(engine,pattern) function + +/** \brief dict_eng_search_word_list() function implementation. */ void xdxf_engine_search_word_list(Engine* engine, gchar* pattern, gpointer data); -//------------------------------------------------------------------------------ -// implementation of dict_eng_search_word_translation(engine,word) function + +/** \brief dict_eng_search_word_translation() function implementation. */ void xdxf_engine_search_word_translation(Engine* engine, gchar* word, gpointer data); -//------------------------------------------------------------------------------ -// implementation of dict_eng_search_word_translation_extended(engine,word) -// function -void xdxf_engine_search_word_translation_extended(Engine* engine, + +/*** \brief dict_eng_search_word_translation_extended() function implementation. + */ +/* this function was removed from engine API */ +/*void xdxf_engine_search_word_translation_extended(Engine* engine, gchar* word); -//------------------------------------------------------------------------------ -// implementation of dict_eng_get_last_state(engine) function +*/ + +/** \brief dict_eng_get_last_status() function implementation. */ EngineStatus xdxf_engine_error(Engine* engine); -//------------------------------------------------------------------------------ -// implementation of dict_eng_state_message(error) function + +/** \brief dict_eng_status_message() function implementation. */ gchar* xdxf_engine_error_message(EngineStatus error); -//------------------------------------------------------------------------------ -// implementation of engine_global_functions(void) function -// API 2.0 -gboolean xdxf_engine_add_word(Engine* engine, - gchar* word, - gchar* translation); -gboolean xdxf_engine_remove_word(Engine* engine, gchar* word); +/** \brief dict_eng_add_word() function implementation. */ +gboolean xdxf_engine_add_word(Engine* engine, + gchar* word, + gchar* translation); +/** \brief dict_eng_remove_word() function implementation. */ +gboolean xdxf_engine_remove_word(Engine* engine, gchar* word); +/*@}*/ + +/** \brief implementation of engine_global_functions(void) function. */ EngineModule engine_global_functions(); #ifdef __cplusplus } #endif #endif + +/*@}*/ diff --git a/src/plugins/xdxf/src/engine_xdxf.c b/src/plugins/xdxf/src/engine_xdxf.c index 51d79dc..d057038 100644 --- a/src/plugins/xdxf/src/engine_xdxf.c +++ b/src/plugins/xdxf/src/engine_xdxf.c @@ -15,250 +15,250 @@ You should have received a copy of the GNU General Public License along with mdictionary; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -Copyright 2006 ComArch S.A. +Copyright 2006-2008 ComArch S.A. ******************************************************************************/ +/** \addtogroup XDXFEngine + */ +/*@{*/ +/** \file engine_xdxf.c + * \brief Code of XDXF-based dictionary engine. + */ -// header with data structure and function definition for XDXF engine. -// Also Engine API. #include -#include -//------------------------------------------------------------------------------ - -// searching word translation in cache file +/** + * \param data engine's global data + * \param word word to search translation for + * \return translation of given word or NULL + */ static gchar* word_translation_cache(XDXFData* data, gchar* word) { - gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); - gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1]; - GnomeVFSFileSize bytes_readed; - - guint word_length = strlen(word); - guint record_length = 0; - guint trans_offset = 0; - guint already = 0; - guint64 readed = 0; - gchar* buffer = NULL; - gchar* trans = NULL; - guint file_size = get_file_size(data->cache); - while(TRUE) { - gnome_vfs_read(data->cache, - b, - DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, - &bytes_readed - ); - guint max_length = (guint)get_max_length(b,bytes_readed); - readed += max_length; - buffer = b; - already = 0; + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); + gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1]; + GnomeVFSFileSize bytes_readed; + + guint word_length = strlen(word); + guint record_length = 0; + guint trans_offset = 0; + guint already = 0; + guint64 readed = 0; + gchar* buffer = NULL; + gchar* trans = NULL; + guint file_size = get_file_size(data->cache); + while(TRUE) { + gnome_vfs_read( data->cache, + b, + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, + &bytes_readed ); + guint max_length = (guint)get_max_length(b,bytes_readed); + readed += max_length; + buffer = b; + already = 0; gchar* tmp = NULL; - while(already < max_length) { - memcpy(&record_length, buffer, sizeof(guint)); - memcpy(&trans_offset, - buffer+record_length-2*sizeof(guint), - sizeof(guint) - ); - buffer[record_length-sizeof(guint)*2] = '\0'; + while(already < max_length) { + memcpy(&record_length, buffer, sizeof(guint)); + memcpy( &trans_offset, + buffer+record_length-2*sizeof(guint), + sizeof(guint) ); + buffer[record_length-sizeof(guint)*2] = '\0'; tmp = g_utf8_casefold(buffer+sizeof(guint), -1); - if(((record_length - 3*sizeof(guint)) == word_length) && - (g_utf8_collate(word,tmp) == 0)) { - FilePart translation = {0,0}; - translation.offset = trans_offset; - memcpy(&(translation.length), - buffer + record_length - sizeof(guint), - sizeof(guint) - ); - trans =read_file_part(&translation, data->xdxf); + if(((record_length - 3*sizeof(guint)) == word_length) && + (g_utf8_collate(word,tmp) == 0) ) + { + FilePart translation = {0,0}; + translation.offset = trans_offset; + memcpy( &(translation.length), + buffer + record_length - sizeof(guint), + sizeof(guint) ); + trans = read_file_part( &translation, + data->xdxf ); g_free(tmp); tmp = NULL; - break; - }; - already += record_length; - buffer += record_length; + break; + }; + already += record_length; + buffer += record_length; g_free(tmp); tmp = NULL; - }; - + }; - if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) || - ( readed > (file_size - 3) )) + if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) || + ( readed > (file_size - 3) )) { - break; + break; }; - gnome_vfs_seek(data->cache, - GNOME_VFS_SEEK_CURRENT, - ((gint)max_length) -DICT_SEARCHING_WORD_TRAN_BUFF_SIZE - ); - } - return trans; + + gnome_vfs_seek( + data->cache, + GNOME_VFS_SEEK_CURRENT, + ((gint)max_length) -DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ); + } + return trans; } -//------------------------------------------------------------------------------ -// searching word translation in xdxf dictionary -static gchar* word_translation_xdxf(XDXFData* data, gchar* word) { + +/** + * \param data engine's global data + * \param word word to search translation for + * \return translation of given word or NULL + */ +static gchar* word_translation_xdxf(XDXFData* data, gchar* word) +{ gchar* casefold_word = g_utf8_casefold(word, -1); guint word_length = strlen(casefold_word); - gchar* trans = NULL; - gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); - GnomeVFSResult vfs_result; - GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_TRAN_BUFF_SIZE; - gchar buffer[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE+1]; - guint64 file_size = get_file_size(data->xdxf); - - - XML_Parser parser = XML_ParserCreate(NULL); - if (!parser) { - g_warning("XDXF/%s->%s() Could not open initialize " - "XML parser.\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - return NULL; - }; + gchar* trans = NULL; + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); + GnomeVFSResult vfs_result; + GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_TRAN_BUFF_SIZE; + gchar buffer[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE+1]; + guint64 file_size = get_file_size(data->xdxf); + + + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) { + g_warning("XDXF/%s->%s() Could not open initialize " + "XML parser.\n", + __FILE__, + __FUNCTION__ ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + return NULL; + }; + + gchar tmp[DICT_MAX_WORD_LENGTH]; + XDXFWordsTransData search_data = { + tmp, + casefold_word, + word_length, + 0, + NULL, + FALSE, + TRUE, + 0, + &parser, + FALSE, + data->xdxf + }; + XML_SetElementHandler( parser, + search_word_trans_start, + search_word_trans_end ); + XML_SetCharacterDataHandler(parser, search_word_trans_text); + XML_SetUserData(parser, &search_data); + + gdouble last_prog = 0.0; + while(TRUE) { + vfs_result = gnome_vfs_read( data->xdxf, + buffer, + DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, + &bytes_readed ); + XML_Parse( parser, + buffer, + bytes_readed, + bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ); + + last_prog = 0.0; + if(data->cb_progress_word_trans != NULL) { + GnomeVFSFileSize act_pos; + gnome_vfs_tell(data->xdxf, &act_pos); + gdouble progress = + ((gdouble)act_pos)/((gdouble)file_size); + if((( (progress - last_prog)/ + (data->cb_progress_word_trans_seed) ) > 1.0) || + (progress >= 1.0)) + { + data-> + cb_progress_word_trans(progress, + data->cb_progress_word_trans_data, + ENGINE_NO_ERROR ); + last_prog = progress; + }; + } - gchar tmp[DICT_MAX_WORD_LENGTH]; - XDXFWordsTransData search_data = {tmp, - casefold_word, - word_length, - 0, - NULL, - FALSE, - TRUE, - 0, - &parser, - FALSE, - data->xdxf - }; - XML_SetElementHandler(parser, - search_word_trans_start, - search_word_trans_end - ); - XML_SetCharacterDataHandler(parser, search_word_trans_text); - - XML_SetUserData(parser, &search_data); - - //gdouble last_prog = 0; - while(TRUE) { - vfs_result = gnome_vfs_read(data->xdxf, - buffer, - DICT_SEARCHING_WORD_TRAN_BUFF_SIZE, - &bytes_readed - ); - XML_Parse(parser, - buffer, - bytes_readed, - bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE - ); - - gdouble last_prog = 0.0; - if(data->cb_progress_word_trans != NULL) { - GnomeVFSFileSize act_pos; - gnome_vfs_tell(data->xdxf, &act_pos); - gdouble progress = - ((gdouble)act_pos)/((gdouble)file_size); - if((( (progress - last_prog)/ - (data->cb_progress_word_trans_seed) ) > 1.0) || - (progress >= 1.0)) { - data-> - cb_progress_word_trans(progress, - data->cb_progress_word_trans_data, - ENGINE_NO_ERROR - ); - last_prog = progress; - }; - } - if(bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE) { - break; - } - if(search_data.cont == FALSE) { - break; - } - } - XML_ParserFree(parser); - trans = search_data.translation; + if(bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE) + { + break; + }; + if(search_data.cont == FALSE) + { + break; + }; + } + XML_ParserFree(parser); + trans = search_data.translation; g_free(casefold_word); casefold_word = NULL; - return trans; + return trans; } -//------------------------------------------------------------------------------ -// searching word by concrete engine + +/** \sa dict_eng_search_word_translation */ void xdxf_engine_search_word_translation(Engine* engine, gchar* word, gpointer user_data) { - g_debug("XDXF/%s->%s() called.\n" - "-->PARAM:engine at adress=%p\n" - "-->PARAM:word=\'%s\'\n", - __FILE__, - __FUNCTION__, - engine, - word); - g_assert(engine != NULL); - g_assert(word != NULL); - // start timer for this function - //timer(TIMER_START, (gchar*)__FUNCTION__); - XDXFData* data = (XDXFData*)(engine->engine_data); - // if callback is not set, we do not have to search word - if(data->cb_search_word_trans == NULL) { - g_warning("XDXF/%s->%s() callback for Word Translation not set." - " Searching aborted.\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - // do not send any signal, just exit - return; - }; - - //guint word_length = strlen(word); - gchar* trans; + g_debug( "XDXF/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:word=\'%s\'\n", + __FILE__, + __FUNCTION__, + engine, + word ); + g_assert(engine != NULL); + g_assert(word != NULL); + + /* timer(TIMER_START, (gchar*)__FUNCTION__); */ + XDXFData* data = (XDXFData*)(engine->engine_data); + /* if callback is not set, we do not have to search word */ + if(data->cb_search_word_trans == NULL) { + g_warning("XDXF/%s->%s() callback for Word Translation not set." + " Searching aborted.\n", + __FILE__, + __FUNCTION__ ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + /* do not call any callback, just exit */ + return; + }; + + + gchar* trans; gchar* casefold_word = g_utf8_casefold(word, -1); - // dictionary is optimized - if(data->cache != NULL) { - trans = word_translation_cache(data, casefold_word); - } + /* is dictionary optimized */ + if(data->cache != NULL) { + trans = word_translation_cache(data, casefold_word); + } else - // dictionary is not optimized right now - { - trans = word_translation_xdxf(data, casefold_word); - }; + { + trans = word_translation_xdxf(data, casefold_word); + }; g_free(casefold_word); casefold_word = NULL; - g_debug("XDXF/%s->%s() found for word \'%s\' translation:\n\'%s\'\n", - __FILE__, - __FUNCTION__, - word, - trans - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - //timer(TIMER_START,"callback for returning word's translation START"); - // calling callback for word translation + g_debug("XDXF/%s->%s() found for word \'%s\' translation:\n\'%s\'\n", + __FILE__, + __FUNCTION__, + word, + trans + ); + /*timer(TIMER_STOP,(gchar*)__FUNCTION__); + timer(TIMER_START,"callback for returning word's translation START"); */ + + /* calling callback for word translation */ gpointer tmp = user_data; if (NULL == tmp) { tmp = data->cb_search_word_trans_data; } - data->cb_search_word_trans(trans, - word, - tmp, - ENGINE_NO_ERROR - ); - //timer(TIMER_STOP,"callback for returning word's translation END"); - /*if(data->auto_free) { - g_debug("XDXF/%s->%s() deleting all dynamic data because " - "AUTO_FREE=TRUE\n", - __FILE__, - __FUNCTION__ - ); - g_free(trans); - trans = NULL; - }*/ - if (trans != NULL) - { + data->cb_search_word_trans( trans, + word, + tmp, + ENGINE_NO_ERROR ); + /*timer(TIMER_STOP,"callback for returning word's translation END"); */ + + /* free memmory if needed */ + if (data->auto_free && (NULL != trans) ) + { g_free(trans); - trans = NULL; + trans = NULL; } return; } -//------------------------------------------------------------------------------ + +/** \sa dict_eng_remove_word */ gboolean xdxf_engine_remove_word(Engine* engine, gchar* word) { @@ -267,6 +267,7 @@ gboolean xdxf_engine_remove_word(Engine* engine, return FALSE; } +/** \sa dict_eng_add_word */ gboolean xdxf_engine_add_word(Engine* engine, gchar* word, gchar* translation) @@ -278,380 +279,406 @@ gboolean xdxf_engine_add_word(Engine* engine, static void search_word_trans_start(void *data, const char *el, - const char **attr - ) + const char **attr ) { - XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; - if( (NULL != loc_data->translation) || !(loc_data->cont) ) + XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; + if( (NULL != loc_data->translation) || !(loc_data->cont) ) { - //g_debug("STOP SEARCHING! -> _start\n"); - return; - }; + return; + }; - if( ('k' == el[0]) && ('\0' == el[1]) ) + if( ('k' == el[0]) && ('\0' == el[1]) ) { - loc_data->one_word = 1; - loc_data->last_word_length = 0; + /* beggining of article key */ + loc_data->one_word = 1; + loc_data->last_word_length = 0; loc_data->last_word[0] = '\0'; - } + } else if( ('a' == el[0]) && ('r' == el[1]) && ('\0' == el[2]) ) { - loc_data->last_start = - XML_GetCurrentByteIndex(*(loc_data->parser)); - } + /* begining of article */ + loc_data->last_start = + XML_GetCurrentByteIndex(*(loc_data->parser)); + } } -//------------------------------------------------------------------------------ + static void search_word_trans_end(void *data, const char *el) { - XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; - if( (NULL != loc_data->translation) || (FALSE == loc_data->cont) ) { - //g_debug("STOP SEARCHING! -> _end\n"); - return; - }; + XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; + if( (NULL != loc_data->translation) || (FALSE == loc_data->cont) ) + { + return; + }; - if( ('k' == el[0]) && ('\0' == el[1]) ) { - loc_data->one_word = 0; + if( ('k' == el[0]) && ('\0' == el[1]) ) + { + /* end of article key */ + loc_data->one_word = 0; gchar* tmp = g_utf8_casefold(loc_data->last_word, -1); - gint com = g_utf8_collate(tmp, loc_data->word); + gint com = g_utf8_collate(tmp, loc_data->word); g_free(tmp); tmp = NULL; - if(com != 0) + if(com != 0) { - //loc_data->cont = FALSE; - // dictionaries are not alway properly sorted, so for - // searching we should lookd in whole file! - return; - } - else if((loc_data->last_word_length == loc_data->word_len) && - (0 == com)) + /* loc_data->cont = FALSE; */ + /* dictionaries are not alway properly sorted, so for + searching we should lookd in whole file! */ + return; + } + else if( (loc_data->last_word_length == loc_data->word_len) && + (0 == com) ) { - loc_data->found = TRUE; - }; - // "clearing" buffer for next word - loc_data->last_word_length = 0; - //loc_data->last_word[0] = '\0'; - } - else if( (TRUE == loc_data->found) && (0 == g_utf8_collate(el,"ar")) ) + loc_data->found = TRUE; + }; + + /* "clearing" buffer for next word - article key */ + loc_data->last_word_length = 0; + } + else if( (TRUE == loc_data->found) && (0 == g_utf8_collate(el,"ar")) ) { - loc_data->found = FALSE; - loc_data->cont = FALSE; - gulong last_stop = - (gulong)XML_GetCurrentByteIndex(*(loc_data->parser)); - last_stop += strlen(""); - FilePart fp = {loc_data->last_start, - (last_stop - (loc_data->last_start)) - }; - loc_data->translation = read_file_part(&fp, loc_data->xdxf); - //g_debug("File part returned from file is: %s\n",loc_data->translation); - } + loc_data->found = FALSE; + loc_data->cont = FALSE; + gulong last_stop = + (gulong)XML_GetCurrentByteIndex(*(loc_data->parser)); + last_stop += strlen(""); + FilePart fp = { loc_data->last_start, + (last_stop - (loc_data->last_start)) }; + loc_data->translation = read_file_part(&fp, loc_data->xdxf); + } } -//------------------------------------------------------------------------------ + static void search_word_trans_text(void *data, const XML_Char *txt, int len) { - XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; - if( (NULL != loc_data->translation ) || (FALSE == loc_data->cont) ) { - //g_debug("STOP SEARCHING! -> _text\n"); + XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data; + if( (NULL != loc_data->translation ) || (FALSE == loc_data->cont) ) + { + return; - }; + }; - if(1 == loc_data->one_word) { - memcpy(&(loc_data->last_word[loc_data->last_word_length]), - (gchar*)txt, - len - ); - loc_data->last_word_length += (guint)len; - loc_data->last_word[loc_data->last_word_length] = '\0'; - }; + if(1 == loc_data->one_word) + { + memcpy( &(loc_data->last_word[loc_data->last_word_length]), + (gchar*)txt, + len ); + loc_data->last_word_length += (guint)len; + loc_data->last_word[loc_data->last_word_length] = '\0'; + }; } -//------------------------------------------------------------------------------ -void xdxf_engine_search_word_translation_extended(Engine* engine, gchar* word) + +/** + * \param engine pointer to the engine + * \param signal signal identifier + * \param seed how often progress callback should be called (0.01 = 1% of work) + */ +void xdxf_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); -} -//------------------------------------------------------------------------------ -void xdxf_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - XDXFData* data = (XDXFData*)(engine->engine_data); - if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { - data->cb_progress_caching_seed = seed; - g_debug("XDXF/%s->%s() sets new seed=%0.2f for for signal " - "\"%s\".\n", - __FILE__, - __FUNCTION__, - seed, - signal - ); - } - else { - g_warning("XDXF/%s->%s() unsupported signal" - "for progress: %s.\n", - __FILE__, - __FUNCTION__, - signal - ); - }; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) + { + data->cb_progress_caching_seed = seed; + g_debug( "XDXF/%s->%s() sets new seed=%0.2f for for signal " + "\"%s\".\n", + __FILE__, + __FUNCTION__, + seed, + signal ); + } + else + { + g_warning("XDXF/%s->%s() unsupported signal " + "for progress: %s.\n", + __FILE__, + __FUNCTION__, + signal ); + }; } -//------------------------------------------------------------------------------ + +/** + * \param engine pointer to the engine + * \param signal signal identifier to which we want to set callback + * \param c_handler callback to be called on signal + * \param user_data pointer to data which will be passed to the callback + * \return previously set callback for selected signal + */ gpointer xdxf_engine_set_callbacks(Engine* engine, gchar* signal, gpointer c_handler, gpointer user_data) { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - g_assert(engine != NULL); - g_assert(signal != NULL); - g_assert(c_handler != NULL); - XDXFData* data = (XDXFData*)(engine->engine_data); - if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { - gpointer result = data->cb_progress_caching; - data->cb_progress_caching = c_handler; - data->cb_progress_caching_data = user_data; - g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n", - __FILE__, - __FUNCTION__, - signal - ); - g_debug("XDXF/%s->%s() Function at adress = %d.\n", - __FILE__, - __FUNCTION__, - (guint)c_handler - ); - g_debug("XDXF/%s->%s() Data at adress = %d.\n", - __FILE__, - __FUNCTION__, - (guint)user_data - ); - return result; - } - else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) { - gpointer result = data->cb_search_word_list; - data->cb_search_word_list = c_handler; - data->cb_search_word_list_data = user_data; - g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n", - __FILE__, - __FUNCTION__, - signal - ); - g_debug("XDXF/%s->%s() Function at adress = %d.\n", - __FILE__, - __FUNCTION__, - (guint)c_handler - ); - g_debug("XDXF/%s->%s() Data at adress = %d.\n", - __FILE__, - __FUNCTION__, - (guint)user_data - ); - return result; - } - else if(g_ascii_strcasecmp(signal, - ENGINE_WORD_TRANSLATION_SIGNAL) == 0) { - gpointer result = data->cb_search_word_trans; - data->cb_search_word_trans = c_handler; - data->cb_search_word_trans_data = user_data; - g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n", - __FILE__, - __FUNCTION__, - signal - ); - g_debug("XDXF/%s->%s() Function at adress = %d.\n", - __FILE__, - __FUNCTION__, - (guint)c_handler - ); - g_debug("XDXF/%s->%s() Data at adress = %d.\n", - __FILE__, - __FUNCTION__, - (guint)user_data - ); - return result; - } - else { - g_warning("XDXF/%s->%s() unsupported signal: %s.\n", - __FILE__, - __FUNCTION__, - signal - ); - return NULL; - } + g_debug("XDXF/%s->%s() called.\n", __FILE__, __FUNCTION__); + g_assert(engine != NULL); + g_assert(signal != NULL); + g_assert(c_handler != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + + if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) { + gpointer result = data->cb_progress_caching; + data->cb_progress_caching = c_handler; + data->cb_progress_caching_data = user_data; + g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n", + __FILE__, + __FUNCTION__, + signal ); + g_debug("XDXF/%s->%s() Function at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)c_handler ); + g_debug("XDXF/%s->%s() Data at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)user_data ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) + { + gpointer result = data->cb_search_word_list; + data->cb_search_word_list = c_handler; + data->cb_search_word_list_data = user_data; + g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n", + __FILE__, + __FUNCTION__, + signal ); + g_debug("XDXF/%s->%s() Function at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)c_handler ); + g_debug("XDXF/%s->%s() Data at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)user_data ); + return result; + } + else if(g_ascii_strcasecmp(signal, ENGINE_WORD_TRANSLATION_SIGNAL) == 0) + { + gpointer result = data->cb_search_word_trans; + data->cb_search_word_trans = c_handler; + data->cb_search_word_trans_data = user_data; + g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n", + __FILE__, + __FUNCTION__, + signal ); + g_debug("XDXF/%s->%s() Function at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)c_handler ); + g_debug("XDXF/%s->%s() Data at adress = %d.\n", + __FILE__, + __FUNCTION__, + (guint)user_data ); + return result; + } + else { + g_warning("XDXF/%s->%s() unsupported signal: %s.\n", + __FILE__, + __FUNCTION__, + signal ); + return NULL; + } } -//------------------------------------------------------------------------------ + +/** + * \param engine pointer to the engine do destroy + */ void xdxf_engine_close(Engine* engine) { - g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n", - __FILE__, - __FUNCTION__, - engine); - if(engine == NULL) { - g_warning("XDXF/%s->%s() Trying delete not existed engine.\n", - __FILE__, - __FUNCTION__ - ); - return; - } - XDXFData* data = (XDXFData*)(engine->engine_data); - if(data->cache != NULL) { - gnome_vfs_close(data->cache); - }; - if(data->xdxf != NULL) { - gnome_vfs_close(data->xdxf); - }; + g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine ); + + if(engine == NULL) + { + g_warning("XDXF/%s->%s() Trying delete not existed engine.\n", + __FILE__, + __FUNCTION__ ); + return; + } + + XDXFData* data = (XDXFData*)(engine->engine_data); + if(data->cache != NULL) + { + gnome_vfs_close(data->cache); + }; + if(data->xdxf != NULL) + { + gnome_vfs_close(data->xdxf); + }; + + g_free(data->dict_path); + g_free(data); + g_free(engine); - g_free(data->dict_path); - g_free(data); - g_free(engine); - //gnome_vfs_shutdown(); - g_debug("XDXF/%s->%s() engine at adress=%p is deleted.\n", - __FILE__, - __FUNCTION__, - engine); + g_debug("XDXF/%s->%s() engine at adress=%p is deleted.\n", + __FILE__, + __FUNCTION__, + engine ); } -//------------------------------------------------------------------------------ + +/** + * \param error status to translate into meaningful message + */ gchar* xdxf_engine_error_message(EngineStatus error) { g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); return "Error - not yet implemented."; } -//------------------------------------------------------------------------------ -Engine* xdxf_engine_create(gchar* location, - EngineOptimizationFlag auto_cache, - cb_progress progress_handler, - gpointer progress_data, - gdouble seed) -{ - g_debug("XDXF/%s->%s() called.\n" - "-->PARAM:location=\'%s\'\n" - "-->PARAM:auto_cache=%d\n", - __FILE__, - __FUNCTION__, - location, - (guint)auto_cache - ); - //timer(TIMER_START,(gchar*)__FUNCTION__); - GnomeVFSResult open_result; - - if(!gnome_vfs_initialized ()) { - gnome_vfs_init (); - }; - gchar* tmp = g_strdup(location); - string_to_path(&tmp); - - Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); - result->engine_location = xdxf_engine_location; - result->engine_is_optimized = xdxf_engine_is_optimized; - result->engine_optimize = xdxf_engine_optimize; - result->engine_search_word_list = xdxf_engine_search_word_list; - result->engine_search_word_translation = - xdxf_engine_search_word_translation; - - result->engine_close = xdxf_engine_close; - result->engine_status = xdxf_engine_error; - result->engine_status_message = xdxf_engine_error_message; - result->engine_set_callback = xdxf_engine_set_callbacks; - result->engine_set_progress_seed = xdxf_engine_set_progress_seed; - result->engine_set_auto_free = xdxf_engine_set_auto_free; - // API 0.2 +/** + * \param location path to the dictionary file directory + * \param auto_cache flag deciding if we want to use optimization for engine + * \param progress_handler optional progress handler for chaching proccess + * \param progress_data data for progress_handler + * \param seed how often caching progress callback will be called + */ +Engine* xdxf_engine_create( gchar* location, + EngineOptimizationFlag auto_cache, + cb_progress progress_handler, + gpointer progress_data, + gdouble seed) +{ + g_debug("XDXF/%s->%s() called.\n" + "-->PARAM:location=\'%s\'\n" + "-->PARAM:auto_cache=%d\n", + __FILE__, + __FUNCTION__, + location, + (guint)auto_cache ); + + /* timer(TIMER_START,(gchar*)__FUNCTION__); */ + GnomeVFSResult open_result; + + if(!gnome_vfs_initialized ()) { + gnome_vfs_init (); + }; + + gchar* tmp = g_strdup(location); + string_to_path(&tmp); + + Engine* result = (Engine*)g_try_malloc(sizeof(Engine)); + result->engine_location = xdxf_engine_location; + result->engine_is_optimized = xdxf_engine_is_optimized; + result->engine_optimize = xdxf_engine_optimize; + result->engine_search_word_list = xdxf_engine_search_word_list; + result->engine_search_word_translation = + xdxf_engine_search_word_translation; + + result->engine_close = xdxf_engine_close; + result->engine_status = xdxf_engine_error; + result->engine_status_message = xdxf_engine_error_message; + result->engine_set_callback = xdxf_engine_set_callbacks; + result->engine_set_progress_seed = xdxf_engine_set_progress_seed; + result->engine_set_auto_free = xdxf_engine_set_auto_free; + /* API 0.2 functions: */ result->engine_add_word = xdxf_engine_add_word; - result->engine_remove_word = xdxf_engine_remove_word; - - XDXFData* data = (XDXFData*)g_try_malloc(sizeof(XDXFData)); - result->engine_data = (gpointer)data; - - g_debug("XDXF/%s->%s() opening file...\'%s\'.\n", - __FILE__, - __FUNCTION__, - location - ); - gchar* tmp2 = g_strconcat(tmp,"/dict.xdxf",NULL); - open_result = - gnome_vfs_open (&(data->xdxf), tmp2, GNOME_VFS_OPEN_READ); - g_free(tmp2); tmp2 = NULL; - - if(open_result != GNOME_VFS_OK) { - g_warning("XDXF/%s->%s() opening dictionary file failed" - " due to reason: %s.\n", - __FILE__, - __FUNCTION__, - gnome_vfs_result_to_string(open_result) - ); - result->engine_data = NULL; - g_free(data); - g_free(result); - result = NULL; - } - else { - g_debug("XDXF/%s->%s() opening dictionary file successed.\n", - __FILE__, - __FUNCTION__ - ); - data->dict_path = g_strdup(tmp); - data->cache = NULL; - data->cb_progress_caching = progress_handler; - data->cb_progress_caching_data = progress_data; - data->cb_progress_caching_seed = seed; - data->cb_progress_word_list = NULL; - data->cb_progress_word_list_data = NULL; - data->cb_progress_word_list_seed = 0.01; - data->cb_progress_word_trans = NULL; - data->cb_progress_word_trans_data = NULL; - data->cb_progress_word_trans_seed = 0.01; - - data->cb_search_word_list = NULL; - data->cb_search_word_list_data = NULL; - - data->cb_search_word_trans = NULL; - data->cb_search_word_trans_data = NULL; - - data->auto_free = FALSE; - if(auto_cache != ENGINE_NO) { - if(auto_cache == ENGINE_REFRESH) { - xdxf_engine_optimize(result); - } - else if(auto_cache == ENGINE_CREATE) { - gchar* cache_path = g_strconcat(data->dict_path, - "/dict.cache", - NULL); - open_result = - gnome_vfs_open (&(data->cache), - cache_path, - GNOME_VFS_OPEN_READ - ); - if(open_result != GNOME_VFS_OK) { - xdxf_engine_optimize(result); - }; - g_free(cache_path); cache_path = NULL; - } - }; - } - g_free(tmp); tmp = NULL; - - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - g_debug("XDXF/%s->%s() returned Engine at adress=%p\n", - __FILE__, - __FUNCTION__, - result - ); - return result; + result->engine_remove_word = xdxf_engine_remove_word; + + XDXFData* data = (XDXFData*)g_try_malloc(sizeof(XDXFData)); + result->engine_data = (gpointer)data; + + g_debug("XDXF/%s->%s() opening file...\'%s\'.\n", + __FILE__, + __FUNCTION__, + location ); + gchar* tmp2 = g_strconcat(tmp,"/dict.xdxf",NULL); + open_result = + gnome_vfs_open (&(data->xdxf), tmp2, GNOME_VFS_OPEN_READ); + g_free(tmp2); tmp2 = NULL; + + if(open_result != GNOME_VFS_OK) + { + g_warning("XDXF/%s->%s() opening dictionary file failed" + " due to reason: %s.\n", + __FILE__, + __FUNCTION__, + gnome_vfs_result_to_string(open_result) ); + result->engine_data = NULL; + g_free(data); + g_free(result); + result = NULL; + } + else + { + g_debug("XDXF/%s->%s() opening dictionary file successed.\n", + __FILE__, + __FUNCTION__ ); + + data->dict_path = g_strdup(tmp); + data->cache = NULL; + data->cb_progress_caching = progress_handler; + data->cb_progress_caching_data = progress_data; + data->cb_progress_caching_seed = seed; + data->cb_progress_word_list = NULL; + data->cb_progress_word_list_data = NULL; + data->cb_progress_word_list_seed = 0.01; + data->cb_progress_word_trans = NULL; + data->cb_progress_word_trans_data = NULL; + data->cb_progress_word_trans_seed = 0.01; + + data->cb_search_word_list = NULL; + data->cb_search_word_list_data = NULL; + + data->cb_search_word_trans = NULL; + data->cb_search_word_trans_data = NULL; + + data->auto_free = FALSE; + if(auto_cache != ENGINE_NO) + { + if(auto_cache == ENGINE_REFRESH) + { + xdxf_engine_optimize(result); + } + else if(auto_cache == ENGINE_CREATE) + { + gchar* cache_path = g_strconcat(data->dict_path, + "/dict.cache", + NULL ); + open_result = + gnome_vfs_open( &(data->cache), + cache_path, + GNOME_VFS_OPEN_READ ); + if(open_result != GNOME_VFS_OK) { + xdxf_engine_optimize(result); + }; + g_free(cache_path); + cache_path = NULL; + } + }; + } + g_free(tmp); tmp = NULL; + + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + g_debug("XDXF/%s->%s() returned Engine at adress=%p\n", + __FILE__, + __FUNCTION__, + result ); + return result; } -//------------------------------------------------------------------------------ + +/** + * \return EngineModule structure for XDXF engine + */ EngineModule engine_global_functions() { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - EngineModule result; - result.engine_check = xdxf_engine_check; - result.engine_description = xdxf_engine_description; - result.engine_format = xdxf_engine_format; - result.engine_version = xdxf_engine_version; - result.engine_create = xdxf_engine_create; - g_debug("XDXF/%s->%s() returned EngineModule at adress=%p.\n", - __FILE__, - __FUNCTION__, - &result - ); - return result; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + + EngineModule result; + result.engine_check = xdxf_engine_check; + result.engine_description = xdxf_engine_description; + result.engine_format = xdxf_engine_format; + result.engine_version = xdxf_engine_version; + result.engine_create = xdxf_engine_create; + + g_debug("XDXF/%s->%s() returned EngineModule at adress=%p.\n", + __FILE__, + __FUNCTION__, + &result ); + return result; } -//------------------------------------------------------------------------------ -/*static double timer(gboolean start, gchar* message) + +/* we remove for this moment timers capabilities - but it could be easily + move back again in the future for time consuption measurement. +static double timer(gboolean start, gchar* message) { static GArray* stack = NULL; static gboolean first_run = TRUE; @@ -712,973 +739,1038 @@ EngineModule engine_global_functions() } } return seconds; -}*/ -//------------------------------------------------------------------------------ +} +*/ + +/** + * \param part strucutre defining what part of file we want to read + * \param file pointer to file from which we want to read + * \return readed file part or NULL if read did not successed + */ static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file) { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - //timer(TIMER_START,(gchar*)__FUNCTION__); - gchar* result = NULL; - GnomeVFSResult f_result; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + /* timer(TIMER_START,(gchar*)__FUNCTION__); */ + gchar* result = NULL; + GnomeVFSResult f_result; GnomeVFSFileSize bytes_read; - f_result = gnome_vfs_seek(file, GNOME_VFS_SEEK_START, part->offset); - if(f_result != GNOME_VFS_OK) { - g_warning("XDXF/%s->%s() failed. Not possible to seek " - "through file!\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - return result; - }; - result = g_try_malloc((part->length + 1) * sizeof(gchar)); - if(result == NULL) { - g_warning("XDXF/%s->%s() failed. Not possible to allocate " - "so big memmory chunk!\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - return result; - }; - f_result = gnome_vfs_read (file, result, part->length, &bytes_read); - if((f_result != GNOME_VFS_OK) || - (((gulong)bytes_read) != part->length)) { - g_debug("XDXF/%s->%s() failed. Not possible to read from " - "file!\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - g_free(result); result = NULL; - return result; - }; - result[part->length] = '\0'; - - g_debug("XDXF/%s->%s() returned string=\n\'%s\'.\n", - __FILE__, - __FUNCTION__, - result - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - return result; + f_result = gnome_vfs_seek(file, GNOME_VFS_SEEK_START, part->offset); + if(f_result != GNOME_VFS_OK) + { + g_warning("XDXF/%s->%s() failed. Not possible to seek " + "through file!\n", + __FILE__, + __FUNCTION__ ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + return result; + }; + + result = g_try_malloc((part->length + 1) * sizeof(gchar)); + if(result == NULL) { + g_warning("XDXF/%s->%s() failed. Not possible to allocate " + "so big memmory chunk!\n", + __FILE__, + __FUNCTION__ ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + return result; + }; + + f_result = gnome_vfs_read (file, result, part->length, &bytes_read); + if((f_result != GNOME_VFS_OK) || + (((gulong)bytes_read) != part->length)) { + g_debug("XDXF/%s->%s() failed. Not possible to read from " + "file!\n", + __FILE__, + __FUNCTION__ ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + g_free(result); result = NULL; + return result; + }; + result[part->length] = '\0'; + + g_debug("XDXF/%s->%s() returned string=\n\'%s\'.\n", + __FILE__, + __FUNCTION__, + result ); + + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + return result; } -//------------------------------------------------------------------------------ -/** Translate given string to proper full file path. Function works "in-situ". -* It means that string is translated and replaced by proper full file path if + +/** +* Translate given string to proper full file path. Function works "in-situ". +* It means that string is translated and replaced by proper full file path if * this file path exists, or this string is cleared and setted to NULL, if string * was representing wrong path. This function is static - to use only * within this module. * -* @param string :: gchar** - pointer to pointer to string +* @param string pointer to to string * representing file path - it will be replaced by a proper filepath. * It should be path to directory or file, ended with "/" or not, absolute * or not -* @return gchar* - pointer to new full file path, it is the same -* as string[0] in fact and it is returned only for abillity of nesting of +* @return pointer to new full file path, it is the same +* as string[0] in fact and it is returned only for abillity of nesting of * functions by pointer to string identyfying full file path */ static gchar* string_to_path(gchar** string) { - g_debug("XDXF/%s->%s() called.\n\ - -->PARAM:string=\'%s\'\n", - __FILE__, - __FUNCTION__, - string[0] - ); - gchar* arg = string[0]; - gchar* new = NULL; - // cleaning from leading and trailing whitespaces - g_strstrip(arg); - // add current directory if this is not absolute directory - if (!g_path_is_absolute(arg)) { - gchar* tmp = g_get_current_dir(); - new = g_strconcat(tmp,"/",arg,NULL); - g_free(arg); arg = new; new = NULL; - }; - // this is not a directory - if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) { - // if this is wrong filepath, string was wrong - if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) { - g_free(arg); - new = NULL; - } - //if this is a file, remove filename - else - { - new = g_path_get_dirname (arg); - g_free(arg); - } - } - // this is a directory - else { - // remove suffix "/" if neded... - if (g_str_has_suffix(arg,"/") ) { - new = g_path_get_dirname (arg); - g_free(arg); - } - else { - new = arg; - } - }; - // now in new should be proper filepath, if not, string was wrong - if (!g_file_test(new, G_FILE_TEST_IS_DIR)) { - // if that directory does not exist, passed string wasn't proper - g_free(new); - new = NULL; - }; - // replace string under passed address - string[0] = new; - g_debug("XDXF/%s->%s() returned string=\'%s\'\n", - __FILE__, - __FUNCTION__, - string[0] - ); - return new; + g_debug("XDXF/%s->%s() called.\n" + "-->PARAM:string=\'%s\'\n", + __FILE__, + __FUNCTION__, + string[0] ); + gchar* arg = string[0]; + gchar* new = NULL; + + /* cleaning from leading and trailing whitespaces */ + g_strstrip(arg); + + /* add current directory if this is not absolute directory */ + if (!g_path_is_absolute(arg)) + { + gchar* tmp = g_get_current_dir(); + new = g_strconcat(tmp,"/",arg,NULL); + g_free(arg); arg = new; new = NULL; + }; + + /* this is not a directory */ + if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) + { + /* if this is wrong filepath, string was wrong */ + if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) + { + g_free(arg); + new = NULL; + } + else + { + /* if this is a file, remove filename */ + new = g_path_get_dirname (arg); + g_free(arg); + } + } + else + { + /* this is a directory ... */ + /* remove suffix "/" if neded... */ + if (g_str_has_suffix(arg,"/") ) + { + new = g_path_get_dirname (arg); + g_free(arg); + } + else + { + new = arg; + } + }; + + /* now in new should be proper filepath, if not, string was wrong */ + if (!g_file_test(new, G_FILE_TEST_IS_DIR)) + { + /* if that directory does not exist, passed string wasn't proper + */ + g_free(new); + new = NULL; + }; + + /* replace string under passed address */ + string[0] = new; + g_debug("XDXF/%s->%s() returned string=\'%s\'\n", + __FILE__, + __FUNCTION__, + string[0] ); + return new; } -//------------------------------------------------------------------------------ -static gboolean is_xdxf_file(gchar* file) { - g_debug("XDXF/%s->%s() called.\n\ - -->PARAM:file=\'%s\'\n", - __FILE__, - __FUNCTION__, - file - ); - gboolean result = TRUE; - GnomeVFSHandle* fd = NULL; - GnomeVFSResult file_result; - GnomeVFSFileSize bytes_read; - - if(!gnome_vfs_initialized ()) { - gnome_vfs_init (); - }; - file_result = gnome_vfs_open (&fd, file, GNOME_VFS_OPEN_READ); - if(file_result != GNOME_VFS_OK) { - g_warning("XDXF/%s->%s() Could not open the file.\n", - __FILE__, - __FUNCTION__ - ); - return FALSE; - }; +/** + * \param file path to file which we want to test + * \return TRUE if file was XDXF format, FALSE otherwise + */ +static gboolean is_xdxf_file(gchar* file) { + g_debug("XDXF/%s->%s() called.\n" + "-->PARAM:file=\'%s\'\n", + __FILE__, + __FUNCTION__, + file ); + + gboolean result = TRUE; + GnomeVFSHandle* fd = NULL; + GnomeVFSResult file_result; + GnomeVFSFileSize bytes_read; + + if(!gnome_vfs_initialized ()) + { + gnome_vfs_init (); + }; - XML_Parser p = XML_ParserCreate(NULL); - if (!p) { - g_warning("XDXF/%s->%s() Could not open initialize " - "XML parser.\n", - __FILE__, - __FUNCTION__ - ); - gnome_vfs_close(fd); - return FALSE; - }; - XML_SetElementHandler(p, is_xdxf_file_start, is_xdxf_file_end); - XDXFCheckingData user_data = {TRUE, FALSE, 0}; - XML_SetUserData(p, &user_data); - gchar buffer[DICT_CACHEING_BUFF_SIZE]; - - guint loop_count = 0; - while(TRUE) { - file_result = gnome_vfs_read (fd, - buffer, - DICT_CACHEING_BUFF_SIZE, - &bytes_read - ); - if (file_result != GNOME_VFS_OK) { - result = FALSE; - g_warning("XDXF/%s->%s() Could not read enought from" - " file.\n", - __FILE__, - __FUNCTION__ - ); - break; - }; - if (! XML_Parse(p, - buffer, - (gulong)bytes_read, - ((gulong)bytes_read) < DICT_CACHEING_BUFF_SIZE - ) ) { - result = FALSE; - g_warning("XDXF/%s->%s() Could not parse file.\n", - __FILE__, - __FUNCTION__ - ); - break; - }; - if (user_data.further == FALSE) { - result = user_data.good; - g_debug("XDXF/%s->%s() statement: location is " - "compatible with this module, is %s\n", - __FILE__, - __FUNCTION__, - PRINT_STATE(result) - ); - break; - }; - if (loop_count > 1) { - result = FALSE; - g_debug("XDXF/%s->%s() Wrong file format.\n", - __FILE__, - __FUNCTION__ - ); - break; - }; - loop_count++; - } + file_result = gnome_vfs_open (&fd, file, GNOME_VFS_OPEN_READ); + if(file_result != GNOME_VFS_OK) + { + g_warning("XDXF/%s->%s() Could not open the file.\n", + __FILE__, + __FUNCTION__ ); + return FALSE; + }; + + XML_Parser p = XML_ParserCreate(NULL); + if (!p) + { + g_warning("XDXF/%s->%s() Could not open initialize " + "XML parser.\n", + __FILE__, + __FUNCTION__ ); + gnome_vfs_close(fd); + return FALSE; + }; + + XML_SetElementHandler(p, is_xdxf_file_start, is_xdxf_file_end); + XDXFCheckingData user_data = {TRUE, FALSE, 0}; + XML_SetUserData(p, &user_data); + gchar buffer[DICT_CACHEING_BUFF_SIZE]; + + guint loop_count = 0; + while(TRUE) + { + file_result = gnome_vfs_read( fd, + buffer, + DICT_CACHEING_BUFF_SIZE, + &bytes_read ); + if (file_result != GNOME_VFS_OK) + { + result = FALSE; + g_warning("XDXF/%s->%s() Could not read enought from" + " file.\n", + __FILE__, + __FUNCTION__ ); + break; + }; + if (! XML_Parse( p, + buffer, + (gulong)bytes_read, + ((gulong)bytes_read) < DICT_CACHEING_BUFF_SIZE + )) + { + result = FALSE; + g_warning("XDXF/%s->%s() Could not parse file.\n", + __FILE__, + __FUNCTION__ ); + break; + }; + if (user_data.further == FALSE) + { + result = user_data.good; + g_debug("XDXF/%s->%s() statement: location is " + "compatible with this module, is %s\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) ); + break; + }; + if (loop_count > 1) + { + result = FALSE; + g_debug("XDXF/%s->%s() Wrong file format.\n", + __FILE__, + __FUNCTION__ ); + break; + }; + loop_count++; + } - gnome_vfs_close(fd); - XML_ParserFree(p); - g_debug("XDXF/%s->%s() returned bool statement=%s.\n", - __FILE__, - __FUNCTION__, - PRINT_STATE(result) - ); - return result; + gnome_vfs_close(fd); + XML_ParserFree(p); + g_debug("XDXF/%s->%s() returned bool statement=%s.\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result)); + return result; } -//------------------------------------------------------------------------------ + static void is_xdxf_file_start(void *data, const char *el, const char **attr) { - XDXFCheckingData* user_data = (XDXFCheckingData*)data; - if (user_data->deep == 0) { - if (g_utf8_collate (el,"xdxf") != 0) { - user_data->good = FALSE; - } - else { - user_data->good = TRUE; - } - user_data->further = FALSE; - } - user_data->deep++; -} -//------------------------------------------------------------------------------ -static void is_xdxf_file_end(void *data, const char *el) -{ - // clear as far as in this callback is nothing to do + XDXFCheckingData* user_data = (XDXFCheckingData*)data; + if (user_data->deep == 0) { + if (g_utf8_collate (el,"xdxf") != 0) { + user_data->good = FALSE; + } + else { + user_data->good = TRUE; + } + user_data->further = FALSE; + } + user_data->deep++; } -//------------------------------------------------------------------------------ +static void is_xdxf_file_end(void *data, const char *el) +{ /* clear as far as in this callback is nothing to do */ } + +/** + * \param engine pointer to the engine + * \return status of last taken action + */ EngineStatus xdxf_engine_error(Engine* engine) { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - XDXFData* data = (XDXFData*)(engine->engine_data); - g_debug("XDXF/%s->%s() returned error code: %d\n", - __FILE__, - __FUNCTION__, - (gint)(data->last_error) - ); - return data->last_error; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + XDXFData* data = (XDXFData*)(engine->engine_data); + g_debug("XDXF/%s->%s() returned error code: %d\n", + __FILE__, + __FUNCTION__, + (gint)(data->last_error) ); + return data->last_error; } -//------------------------------------------------------------------------------ + static void caching_expat_start(void *data, const char *el, const char **attr) { - XDXFCacheData* loc_data = (XDXFCacheData*)data; - if(g_utf8_collate(el,"ar") == 0) { - loc_data->last_start = - XML_GetCurrentByteIndex(loc_data->parser); - } - else if(g_utf8_collate(el,"k") == 0) { - loc_data->state = 1; - } - else { - //loc_data->state = 0; - } + XDXFCacheData* loc_data = (XDXFCacheData*)data; + if(g_utf8_collate(el,"ar") == 0) + { + loc_data->last_start = + XML_GetCurrentByteIndex(loc_data->parser); + } + else if(g_utf8_collate(el,"k") == 0) + { + loc_data->state = 1; + } } -//------------------------------------------------------------------------------ + static void caching_expat_end(void *data, const char *el) { - XDXFCacheData* loc_data = (XDXFCacheData*)data; - loc_data->last_stop = XML_GetCurrentByteIndex(loc_data->parser); + XDXFCacheData* loc_data = (XDXFCacheData*)data; + loc_data->last_stop = XML_GetCurrentByteIndex(loc_data->parser); - static guint record_length; - static guint start; - static guint length; - static guint buffer_length; + static guint record_length; + static guint start; + static guint length; + static guint buffer_length; - if((g_utf8_collate("k",el) == 0) && - (loc_data->state == 1)) { - loc_data->state = 2; - } - else if((g_utf8_collate("ar",el) == 0) && - (loc_data->state == 2)) { - buffer_length = loc_data->buffer_length; - record_length = sizeof(guint)*3 + loc_data->buffer_length; - start = loc_data->last_start; - length = loc_data->last_stop + strlen("") - - loc_data->last_start; - - gboolean error_writting = FALSE; - GnomeVFSFileSize bytes_written; - GnomeVFSResult vfs_result; - vfs_result = gnome_vfs_write(loc_data->cache, - &record_length, - sizeof(guint), - &bytes_written - ); - if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; - vfs_result = gnome_vfs_write(loc_data->cache, - loc_data->buffer, - loc_data->buffer_length, - &bytes_written - ); - if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; - vfs_result = gnome_vfs_write(loc_data->cache, - &start, - sizeof(guint), - &bytes_written - ); - if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; - vfs_result = gnome_vfs_write(loc_data->cache, - &length, - sizeof(guint), - &bytes_written - ); - if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; - - loc_data->buffer[0] = '\0'; - loc_data->buffer_length = 0; - loc_data->state = 0; - }; + if((g_utf8_collate("k",el) == 0) && + (loc_data->state == 1)) + { + loc_data->state = 2; + } + else if((g_utf8_collate("ar",el) == 0) && + (loc_data->state == 2)) + { + buffer_length = loc_data->buffer_length; + record_length = sizeof(guint)*3 + loc_data->buffer_length; + start = loc_data->last_start; + length = loc_data->last_stop + strlen("") - + loc_data->last_start; + + gboolean error_writting = FALSE; + GnomeVFSFileSize bytes_written; + GnomeVFSResult vfs_result; + + vfs_result = gnome_vfs_write(loc_data->cache, + &record_length, + sizeof(guint), + &bytes_written ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + + vfs_result = gnome_vfs_write(loc_data->cache, + loc_data->buffer, + loc_data->buffer_length, + &bytes_written ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + + vfs_result = gnome_vfs_write(loc_data->cache, + &start, + sizeof(guint), + &bytes_written ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + + vfs_result = gnome_vfs_write(loc_data->cache, + &length, + sizeof(guint), + &bytes_written ); + if(vfs_result != GNOME_VFS_OK) error_writting = TRUE; + + loc_data->buffer[0] = '\0'; + loc_data->buffer_length = 0; + loc_data->state = 0; + }; } -//------------------------------------------------------------------------------ + static void caching_expat_text(void *data, const XML_Char *txt, int len) { - XDXFCacheData* loc_data = (XDXFCacheData*)data; - - if(loc_data->state == 1) { - memcpy(&(loc_data->buffer[loc_data->buffer_length]), - (gchar*)txt, - len - ); - loc_data->buffer_length += (long)len; - loc_data->buffer[loc_data->buffer_length] = '\0'; - }; + XDXFCacheData* loc_data = (XDXFCacheData*)data; + + if(loc_data->state == 1) + { + memcpy( &(loc_data->buffer[loc_data->buffer_length]), + (gchar*)txt, + len ); + loc_data->buffer_length += (long)len; + loc_data->buffer[loc_data->buffer_length] = '\0'; + }; } -//------------------------------------------------------------------------------ + +/** + * \param file pointer to file + * \return size of given file + */ static guint64 get_file_size(GnomeVFSHandle* file) { - guint64 result = 0; - guint64 old_pos = 0; - gnome_vfs_tell(file, &old_pos); + guint64 result = 0; + guint64 old_pos = 0; + gnome_vfs_tell(file, &old_pos); - if( gnome_vfs_seek(file, GNOME_VFS_SEEK_END, 0) != GNOME_VFS_OK) { - return 0; - } + if( gnome_vfs_seek(file, GNOME_VFS_SEEK_END, 0) != GNOME_VFS_OK) + { + return 0; + } - if( gnome_vfs_tell(file, &result) != GNOME_VFS_OK) { - result = 0; - } + if( gnome_vfs_tell(file, &result) != GNOME_VFS_OK) + { + result = 0; + } - gnome_vfs_seek(file, GNOME_VFS_SEEK_START, old_pos); - return result; + gnome_vfs_seek(file, GNOME_VFS_SEEK_START, old_pos); + return result; } -//------------------------------------------------------------------------------ + +/** + * \param engine pointer to the engine + */ void xdxf_engine_optimize(Engine* engine) { - g_debug("XDXF/%s->%s() called for engine at adress=%p\n", - __FILE__, - __FUNCTION__, - engine - ); - //timer(TIMER_START,(gchar*)__FUNCTION__); - - GnomeVFSResult vfs_result; - XDXFData* data = (XDXFData*)(engine->engine_data); - gchar* cache_path = g_strconcat(data->dict_path,"/dict.cache",NULL); - vfs_result = gnome_vfs_create(&(data->cache), - cache_path, - GNOME_VFS_OPEN_WRITE, - FALSE, - 0666 - ); - if(vfs_result != GNOME_VFS_OK) { - data->cache = NULL; - g_warning("XDXF/%s->%s().Could not create new cache file: %s.\n", - __FILE__, - __FUNCTION__, - cache_path - ); - } - else { - XDXFCacheData* c_data = - (XDXFCacheData*)g_try_malloc(sizeof(XDXFCacheData)); - c_data->parser = XML_ParserCreate(NULL); - c_data->cache = data->cache; - c_data->buffer = - (gchar*)g_try_malloc(sizeof(gchar)*DICT_CACHEING_BUFF_SIZE); - c_data->buffer_length = 0; - c_data->last_start = 0; - c_data->last_stop = 0; - c_data->last_length = 0; - - guint64 file_size = get_file_size(data->xdxf); - /*g_debug("XDXF/%s->%s(): caching dictionaries size is %.2f kB " - "[%d bytes = %.2f MB].\n", - __FILE__, - __FUNCTION__, - ((gdouble)file_size)/1024.0, - file_size, - ((gdouble)file_size)/(1024.0*1024.0) - );*/ - - XML_SetUserData(c_data->parser, (gpointer)c_data); - XML_SetElementHandler(c_data->parser, - caching_expat_start, - caching_expat_end - ); - XML_SetCharacterDataHandler(c_data->parser, caching_expat_text); - - GnomeVFSFileSize bytes_readed = DICT_CACHEING_BUFF_SIZE; - gchar b[DICT_CACHEING_BUFF_SIZE + 1]; - gdouble last_prog = 0; - while(TRUE) { - vfs_result = gnome_vfs_read(data->xdxf, - b, - DICT_CACHEING_BUFF_SIZE, - &bytes_readed - ); - XML_Parse(c_data->parser, - b, - bytes_readed, - bytes_readed < DICT_CACHEING_BUFF_SIZE - ); - - if(data->cb_progress_caching != NULL) { - GnomeVFSFileSize act_pos; - gnome_vfs_tell(data->xdxf, &act_pos); - gdouble progress = ((gdouble)act_pos)/ - ((gdouble)file_size); - if((( (progress - last_prog) / - (data->cb_progress_caching_seed) ) > 1.0) || - (progress >= 1.0)) { - data->cb_progress_caching( - progress, - data->cb_progress_caching_data, - ENGINE_NO_ERROR - ); - last_prog = progress; - }; - } - if(bytes_readed < DICT_CACHEING_BUFF_SIZE) break; - } + g_debug("XDXF/%s->%s() called for engine at adress=%p\n", + __FILE__, + __FUNCTION__, + engine ); + /* timer(TIMER_START,(gchar*)__FUNCTION__); */ + + GnomeVFSResult vfs_result; + XDXFData* data = (XDXFData*)(engine->engine_data); + gchar* cache_path = g_strconcat(data->dict_path,"/dict.cache",NULL); + vfs_result = gnome_vfs_create(&(data->cache), + cache_path, + GNOME_VFS_OPEN_WRITE, + FALSE, + 0666 ); + + if(vfs_result != GNOME_VFS_OK) + { + data->cache = NULL; + g_warning("XDXF/%s->%s().Could not create new " + "cache file: %s.\n", + __FILE__, + __FUNCTION__, + cache_path ); + } + else + { + XDXFCacheData* c_data = + (XDXFCacheData*)g_try_malloc(sizeof(XDXFCacheData)); + c_data->parser = XML_ParserCreate(NULL); + c_data->cache = data->cache; + c_data->buffer = + (gchar*)g_try_malloc(sizeof(gchar)*DICT_CACHEING_BUFF_SIZE); + c_data->buffer_length = 0; + c_data->last_start = 0; + c_data->last_stop = 0; + c_data->last_length = 0; + + guint64 file_size = get_file_size(data->xdxf); + + XML_SetUserData(c_data->parser, (gpointer)c_data); + XML_SetElementHandler(c_data->parser, + caching_expat_start, + caching_expat_end ); + XML_SetCharacterDataHandler(c_data->parser, caching_expat_text); + + GnomeVFSFileSize bytes_readed = DICT_CACHEING_BUFF_SIZE; + gchar b[DICT_CACHEING_BUFF_SIZE + 1]; + gdouble last_prog = 0; + while(TRUE) + { + vfs_result = gnome_vfs_read( data->xdxf, + b, + DICT_CACHEING_BUFF_SIZE, + &bytes_readed ); + XML_Parse(c_data->parser, + b, + bytes_readed, + bytes_readed < DICT_CACHEING_BUFF_SIZE ); + + if(data->cb_progress_caching != NULL) + { + GnomeVFSFileSize act_pos; + gnome_vfs_tell(data->xdxf, &act_pos); + gdouble progress = ((gdouble)act_pos)/ + ((gdouble)file_size); + if((( (progress - last_prog) / + (data->cb_progress_caching_seed) ) > 1.0) || + (progress >= 1.0)) + { + data->cb_progress_caching( + progress, + data->cb_progress_caching_data, + ENGINE_NO_ERROR ); + last_prog = progress; + }; + } + if(bytes_readed < DICT_CACHEING_BUFF_SIZE) + { + break; + } + } - g_free(c_data->buffer); - g_free(c_data); - } + g_free(c_data->buffer); + g_free(c_data); + } - vfs_result = gnome_vfs_close(data->cache); - vfs_result = gnome_vfs_open(&(data->cache), - cache_path, - GNOME_VFS_OPEN_READ - ); - g_free(cache_path); cache_path = NULL; - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - g_debug("XDXF/%s->%s()'s work finished.\n",__FILE__,__FUNCTION__); + vfs_result = gnome_vfs_close(data->cache); + vfs_result = gnome_vfs_open( &(data->cache), + cache_path, + GNOME_VFS_OPEN_READ ); + g_free(cache_path); cache_path = NULL; + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + g_debug("XDXF/%s->%s()'s work finished.\n",__FILE__,__FUNCTION__); } -//------------------------------------------------------------------------------ + +/** + * \param location path to file to check + * \return + */ gboolean xdxf_engine_check(gchar* location) { - g_debug("XDXF/%s->%s() called.\n-->PARAM:location=\'%s\'\n", - __FILE__, - __FUNCTION__, - location - ); - //timer(TIMER_START,(gchar*)__FUNCTION__); - gboolean result = TRUE; - gchar* filepath = g_strdup(location); - gchar* tmp = NULL; - - string_to_path(&filepath); - if (filepath == NULL) { - result = FALSE; - g_warning("XDXF/%s->%s() location \'%s\' is not a proper " - "path!\n", - __FILE__, - __FUNCTION__, - location - ); - } - else { - tmp = g_strconcat(filepath,"/dict.xdxf",NULL); - g_free(filepath); - filepath = tmp; - tmp = NULL; - - g_debug("XDXF/%s->%s() finnal file to check is: %s\n", - __FILE__, - __FUNCTION__, - filepath - ); - if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) { - g_warning("XDXF/%s->%s() file \'%s\' does not " - "exists!\n", - __FILE__, - __FUNCTION__, - filepath - ); - result = FALSE; - }; - }; - if (result != FALSE) { - result = is_xdxf_file(filepath); - }; - - g_free(filepath); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - g_debug("XDXF/%s->%s() returned bool statement=%s.\n", - __FILE__, - __FUNCTION__, - PRINT_STATE(result) - ); - return result; + g_debug("XDXF/%s->%s() called.\n-->PARAM:location=\'%s\'\n", + __FILE__, + __FUNCTION__, + location ); + /* timer(TIMER_START,(gchar*)__FUNCTION__); */ + gboolean result = TRUE; + gchar* filepath = g_strdup(location); + gchar* tmp = NULL; + + string_to_path(&filepath); + if (filepath == NULL) + { + result = FALSE; + g_warning("XDXF/%s->%s() location \'%s\' is not a proper " + "path!\n", + __FILE__, + __FUNCTION__, + location + ); + } + else + { + tmp = g_strconcat(filepath,"/dict.xdxf",NULL); + g_free(filepath); + filepath = tmp; + tmp = NULL; + + g_debug("XDXF/%s->%s() finnal file to check is: %s\n", + __FILE__, + __FUNCTION__, + filepath + ); + if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) + { + g_warning("XDXF/%s->%s() file \'%s\' does not " + "exists!\n", + __FILE__, + __FUNCTION__, + filepath + ); + result = FALSE; + }; + }; + if (result != FALSE) { + result = is_xdxf_file(filepath); + }; + + g_free(filepath); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + g_debug("XDXF/%s->%s() returned bool statement=%s.\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) + ); + return result; } -//------------------------------------------------------------------------------ + +/** + * \param a pointer to buffer + * \param length length of buffer + * \return number of words in buffer + */ static guint get_max_length(gchar* a, guint length) { - gchar* b = a; - guint len = 0; - guint n = 0; - memcpy(&n,b,sizeof(guint)); - while((len + n) <= length) { - len += n; - b = b + n; + gchar* b = a; + guint len = 0; + guint n = 0; + memcpy(&n,b,sizeof(guint)); + while((len + n) <= length) { + len += n; + b = b + n; if(len >= (length-sizeof(guint))) break; - memcpy(&n,b,sizeof(guint)); - } - return len; + memcpy(&n,b,sizeof(guint)); + } + return len; } -//------------------------------------------------------------------------------ // finished functions: + +/** + * \param engine pointer to the engine + * \param state do auto free mechanism should be enabled? + */ void xdxf_engine_set_auto_free(Engine* engine, gboolean state) { - g_debug("XDXF/%s->%s() called.\n" - "-->PARAM:engine at adress=%p\n" - "-->PARAM:state=%s\n", - __FILE__, - __FUNCTION__, - engine, - PRINT_STATE(state) - ); - g_assert(engine != NULL); - XDXFData* data = (XDXFData*)(engine->engine_data); - data->auto_free = state; - g_debug("XDXF/%s->%s() Current auto_free is %s\n", - __FILE__, - __FUNCTION__, - PRINT_STATE(data->auto_free) - ); + g_debug( "XDXF/%s->%s() called.\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:state=%s\n", + __FILE__, + __FUNCTION__, + engine, + PRINT_STATE(state) ); + g_assert(engine != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + data->auto_free = state; + g_debug( "XDXF/%s->%s() Current auto_free is %s\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(data->auto_free) ); } -//------------------------------------------------------------------------------ + +/** + * \return string with engine version + */ gchar* xdxf_engine_version() { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - gchar* result = g_strdup(DIC_ENG_VERSION); - g_debug("XDXF/%s->%s() return string=%s\n", - __FILE__, - __FUNCTION__, - result - ); - return result; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_VERSION); + g_debug( "XDXF/%s->%s() return string=%s\n", + __FILE__, + __FUNCTION__, + result ); + return result; } -//------------------------------------------------------------------------------ + +/** + * \return string with engine supported format - XDXF + */ gchar* xdxf_engine_format() { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - gchar* result = g_strdup(DIC_ENG_FORMAT); - g_debug("XDXF/%s->%s() return string=%s\n", - __FILE__, - __FUNCTION__, - result - ); - return result; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + gchar* result = g_strdup(DIC_ENG_FORMAT); + g_debug("XDXF/%s->%s() return string=%s\n", + __FILE__, + __FUNCTION__, + result + ); + return result; } -//------------------------------------------------------------------------------ + +/** + * \return string with short description of engine + */ gchar* xdxf_engine_description() { - g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); - gchar* result = g_strdup("This module operates on " - DIC_ENG_FORMAT - " dictionaries. Version " - DIC_ENG_VERSION - "." - ); - g_debug("XDXF/%s->%s() return string=%s\n", - __FILE__, - __FUNCTION__, - result - ); - return result; + g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__); + gchar* result = g_strdup("This module operates on " + DIC_ENG_FORMAT + " dictionaries. Version " + DIC_ENG_VERSION + "." ); + g_debug("XDXF/%s->%s() return string=%s\n", + __FILE__, + __FUNCTION__, + result ); + return result; } -//------------------------------------------------------------------------------ + +/** + * \param engine pointer to the engine + * \return TRUE if particular dictionary is optimized + */ gboolean xdxf_engine_is_optimized(Engine* engine) { - g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n", - __FILE__, - __FUNCTION__, - engine - ); - g_assert(engine != NULL); - XDXFData* data = (XDXFData*)(engine->engine_data); - gboolean result = (data->cache != NULL); - g_debug("XDXF/%s->%s() returned bool statement=%s.\n", - __FILE__, - __FUNCTION__, - PRINT_STATE(result) - ); - return result; + g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine ); + + g_assert(engine != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + gboolean result = (data->cache != NULL); + g_debug("XDXF/%s->%s() returned bool statement=%s.\n", + __FILE__, + __FUNCTION__, + PRINT_STATE(result) ); + return result; } -//------------------------------------------------------------------------------ + +/** + * \param engine pointer to the engine + * \return string with path to the dictionary file + */ gchar* xdxf_engine_location(Engine* engine) { - g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n", - __FILE__, - __FUNCTION__, - engine - ); - g_assert(engine != NULL); - XDXFData* data = (XDXFData*)(engine->engine_data); - gchar* result; - if(data->auto_free) { - result = data->dict_path; - } - else { - result = g_strdup(data->dict_path); - } + g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n", + __FILE__, + __FUNCTION__, + engine ); + g_assert(engine != NULL); + XDXFData* data = (XDXFData*)(engine->engine_data); + gchar* result; + if(data->auto_free) + { + result = data->dict_path; + } + else + { + result = g_strdup(data->dict_path); + } - g_debug("XDXF/%s->%s() returned string=%s\n", - __FILE__, - __FUNCTION__, - result - ); - return result; + g_debug("XDXF/%s->%s() returned string=%s\n", + __FILE__, + __FUNCTION__, + result ); + return result; } -//------------------------------------------------------------------------------ + static void search_word_list_start(void *data, const char *el, - const char **attr - ) + const char **attr ) { - XDXFWordsListData* loc_data = (XDXFWordsListData*)data; - if( ('k' == el[0]) && ('\0' == el[1]) ) { - loc_data->one_word = 1; - }; + XDXFWordsListData* loc_data = (XDXFWordsListData*)data; + if( ('k' == el[0]) && ('\0' == el[1]) ) { + loc_data->one_word = 1; + }; } -//------------------------------------------------------------------------------ + static void search_word_list_end(void *data, const char *el) { - static gboolean matched = FALSE; + static gboolean matched = FALSE; static gchar* tmp = NULL; - XDXFWordsListData* loc_data = (XDXFWordsListData*)data; - GPatternSpec* regex; - regex = g_pattern_spec_new (loc_data->pattern); + XDXFWordsListData* loc_data = (XDXFWordsListData*)data; + GPatternSpec* regex; + regex = g_pattern_spec_new (loc_data->pattern); if( ('k' == el[0]) && ('\0' == el[1]) ) { - loc_data->one_word = 0; - } - else + loc_data->one_word = 0; + } + else { - return; - } + return; + } gchar *tmp1 = g_strconcat (loc_data->last_word, " ", NULL); tmp = g_utf8_casefold(tmp1, -1); g_free (tmp1); tmp1 = g_utf8_casefold(loc_data->last_word, -1); - -/* if(loc_data->last_word_length > loc_data->pattern_len) - { - tmp[loc_data->pattern_len] = '\0'; - };*/ - -// if ( loc_data->last_word_length >= loc_data->pattern_len ) - if (( g_pattern_match_string (regex, tmp) == TRUE ) || + + if (( g_pattern_match_string (regex, tmp) == TRUE ) || ( g_pattern_match_string (regex, tmp1) == TRUE ) ) { - matched = TRUE; - gchar* new = g_strdup(loc_data->last_word); - g_array_append_val((loc_data->result), new); - g_debug("New Word for pattern \"%s\" found: %s\n", - loc_data->pattern, - new - ); - } - else { + matched = TRUE; + gchar* new = g_strdup(loc_data->last_word); + g_array_append_val((loc_data->result), new); + g_debug("New Word for pattern \"%s\" found: %s\n", + loc_data->pattern, + new ); + } + else + { matched = FALSE; } - // "clearing" buffer for next word - loc_data->last_word_length = 0; - // if we passed words matching -> ends - if( (loc_data->result->len > 0) && (!matched) ) { - loc_data->cont = FALSE; - }; + + /* "clearing" buffer for next word */ + loc_data->last_word_length = 0; + /* if we passed words matching -> ends */ + if( (loc_data->result->len > 0) && (!matched) ) + { + loc_data->cont = FALSE; + }; + g_free(tmp); tmp = NULL; g_free(tmp1); g_pattern_spec_free (regex); } -//------------------------------------------------------------------------------ + static void search_word_list_text(void *data, const XML_Char *txt, int len) { - XDXFWordsListData* loc_data = (XDXFWordsListData*)data; - - if(1 == loc_data->one_word) { - memcpy(&(loc_data->last_word[loc_data->last_word_length]), - (gchar*)txt, - len - ); - loc_data->last_word_length += (guint)len; - loc_data->last_word[loc_data->last_word_length] = '\0'; - }; + XDXFWordsListData* loc_data = (XDXFWordsListData*)data; + + if(1 == loc_data->one_word) + { + memcpy( &(loc_data->last_word[loc_data->last_word_length]), + (gchar*)txt, + len ); + loc_data->last_word_length += (guint)len; + loc_data->last_word[loc_data->last_word_length] = '\0'; + }; } -//------------------------------------------------------------------------------ -// return translation of word using cache file + +/** + * \param data engine global data + * \param pattern pattern for words list + * \param result GArray for output words list + * \param cb_data optional data for words list callback + */ static void word_list_cache(XDXFData* data, gchar* pattern, GArray* result, - gpointer cb_data) { - gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); - //GnomeVFSResult vfs_result; - GnomeVFSFileSize bytes_readed; - guint record_length = 0; - gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE]; - gchar* buf; - guint already = 0; - guint max_length = 0; - guint64 file_size = get_file_size(data->cache); + gpointer cb_data) +{ + gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0); + + GnomeVFSFileSize bytes_readed; + guint record_length = 0; + gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE]; + gchar* buf; + guint already = 0; + guint max_length = 0; + guint64 file_size = get_file_size(data->cache); gchar* casefold_pattern = g_utf8_casefold(pattern, -1); -// gchar* casefold_word = NULL; -// guint pattern_len = strlen(pattern); + GPatternSpec* regex; regex = g_pattern_spec_new (casefold_pattern); guint i = 0; - while(TRUE) + while(TRUE) { - gnome_vfs_read(data->cache, - buffer, - DICT_SEARCHING_WORD_LIST_BUFF_SIZE, - &bytes_readed - ); - - max_length = get_max_length(buffer, (guint)bytes_readed); - already += max_length; - buf = buffer; - - guint how_far = 0; - while(how_far < max_length) { + gnome_vfs_read( data->cache, + buffer, + DICT_SEARCHING_WORD_LIST_BUFF_SIZE, + &bytes_readed ); + + max_length = get_max_length(buffer, (guint)bytes_readed); + already += max_length; + buf = buffer; + + guint how_far = 0; + while(how_far < max_length) + { ++i; - memcpy(&record_length, buf, sizeof(guint)); - buf[record_length-sizeof(guint)*2] = '\0'; + memcpy(&record_length, buf, sizeof(guint)); + buf[record_length-sizeof(guint)*2] = '\0'; - gchar *tmp1 = g_strconcat (buf + sizeof(guint), " ", NULL); + gchar *tmp1 = g_strconcat( buf + sizeof(guint), + " ", + NULL ); gchar* tmp = g_utf8_casefold(tmp1, -1); g_free (tmp1); - -// if (record_length - 3*sizeof(guint)) >= pattern_len) - - if ( g_pattern_match_string (regex, tmp) == TRUE ) { - gchar* new = g_strndup(buf + sizeof(guint), - record_length - - 3*sizeof(guint)); - g_array_append_val(result, new); - g_debug("New Word for pattern \"%s\" found: " - "%s (pos:%d)\n", - pattern, - new, - i - ); - }; - how_far += record_length; - buf = buf + record_length; + + if ( g_pattern_match_string (regex, tmp) == TRUE ) + { + gchar* new = g_strndup(buf + sizeof(guint), + record_length - + 3*sizeof(guint) ); + g_array_append_val(result, new); + g_debug("New Word for pattern \"%s\" found: " + "%s (pos:%d)\n", + pattern, + new, + i ); + }; + how_far += record_length; + buf = buf + record_length; g_free(tmp); tmp = NULL; - } - if( (bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) || - (already > (file_size -3)) ) + } + if( (bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) || + (already > (file_size -3)) ) { break; } - gnome_vfs_seek(data->cache, - GNOME_VFS_SEEK_CURRENT, - (gint)max_length - - DICT_SEARCHING_WORD_LIST_BUFF_SIZE - ); - } - - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - //timer(TIMER_START,"callback for returning words list START"); - data->cb_search_word_list(result, - pattern, - cb_data, - ENGINE_NO_ERROR - ); - g_free(casefold_pattern); casefold_pattern = NULL; - //timer(TIMER_STOP,"callback for returning words list END"); + gnome_vfs_seek( data->cache, + GNOME_VFS_SEEK_CURRENT, + (gint)max_length - + DICT_SEARCHING_WORD_LIST_BUFF_SIZE ); + } + + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + /* timer(TIMER_START,"callback for returning words list START"); */ + data->cb_search_word_list( result, + pattern, + cb_data, + ENGINE_NO_ERROR ); + g_free(casefold_pattern); + casefold_pattern = NULL; + /* timer(TIMER_STOP,"callback for returning words list END"); */ } -//------------------------------------------------------------------------------ -// return translation of word but using only xdxf dictionary file + +/** + * \param data engine global data + * \param pattern pattern for words list + * \param result GArray for output words list + * \param cb_data optional data for words list callback + */ static void word_list_xdxf(XDXFData* data, gchar* pattern, GArray* result, gpointer cb_data) { - gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); - GnomeVFSResult vfs_result; - GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_LIST_BUFF_SIZE; - gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE+1]; - guint64 file_size = get_file_size(data->xdxf); + gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0); + GnomeVFSResult vfs_result; + GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_LIST_BUFF_SIZE; + gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE+1]; + guint64 file_size = get_file_size(data->xdxf); gchar* casefold_pattern = g_utf8_casefold(pattern, -1); - guint pattern_len = strlen(casefold_pattern); + guint pattern_len = strlen(casefold_pattern); - XML_Parser parser = XML_ParserCreate(NULL); - if (!parser) { - g_warning("XDXF/%s->%s() Could not open initialize XML " - "parser.\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - return; - }; - - gchar tmp[DICT_MAX_WORD_LENGTH]; - XML_SetElementHandler(parser, - search_word_list_start, - search_word_list_end - ); - XML_SetCharacterDataHandler(parser, search_word_list_text); - - // buffer for single word - // pattern to search - // length of pattern - // actal length of readed word - // array to append words - // continuation of the same word - // continue of searching? - XDXFWordsListData search_data = {tmp, - casefold_pattern, - pattern_len, - 0, - result, - 0, - TRUE - }; - XML_SetUserData(parser, &search_data); - - gdouble last_prog = 0; - while(TRUE) { - vfs_result = gnome_vfs_read(data->xdxf, - buffer, - DICT_SEARCHING_WORD_LIST_BUFF_SIZE, - &bytes_readed - ); - XML_Parse(parser, - buffer, - bytes_readed, - bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE - ); - - if(NULL != data->cb_progress_word_list) + XML_Parser parser = XML_ParserCreate(NULL); + if (!parser) + { + g_warning("XDXF/%s->%s() Could not open initialize XML " + "parser.\n", + __FILE__, + __FUNCTION__ + ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + return; + }; + + gchar tmp[DICT_MAX_WORD_LENGTH]; + XML_SetElementHandler( parser, + search_word_list_start, + search_word_list_end ); + XML_SetCharacterDataHandler(parser, search_word_list_text); + + /* + buffer for single word + pattern to search + length of pattern + actal length of readed word + array to append words + continuation of the same word + continue of searching? + */ + XDXFWordsListData search_data = { tmp, + casefold_pattern, + pattern_len, + 0, + result, + 0, + TRUE + }; + XML_SetUserData(parser, &search_data); + + gdouble last_prog = 0; + while(TRUE) { + vfs_result = gnome_vfs_read( data->xdxf, + buffer, + DICT_SEARCHING_WORD_LIST_BUFF_SIZE, + &bytes_readed ); + XML_Parse( parser, + buffer, + bytes_readed, + bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE ); + + if(NULL != data->cb_progress_word_list) { - GnomeVFSFileSize act_pos; - gnome_vfs_tell(data->xdxf, &act_pos); - gdouble progress = ((gdouble)act_pos)/ - ((gdouble)file_size); - if((((progress - last_prog)/ - (data->cb_progress_word_list_seed)) > 1.0) || - (progress >= 1.0)) { - data->cb_progress_word_list( - progress, - data->cb_progress_word_list_data, - ENGINE_NO_ERROR - ); - last_prog = progress; - }; - }; - - if(bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) + GnomeVFSFileSize act_pos; + gnome_vfs_tell(data->xdxf, &act_pos); + gdouble progress = ((gdouble)act_pos)/ + ((gdouble)file_size); + if((((progress - last_prog)/ + (data->cb_progress_word_list_seed)) > 1.0) || + (progress >= 1.0)) + { + data->cb_progress_word_list( + progress, + data->cb_progress_word_list_data, + ENGINE_NO_ERROR ); + last_prog = progress; + }; + }; + + if(bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) { - break; - }; + break; + }; - if(FALSE == search_data.cont) + if(FALSE == search_data.cont) { - g_debug("XDXF/%s->%s() We found every words matching " - "pattern \"%s\". Abort further searching.\n", - __FILE__, - __FUNCTION__, - pattern - ); - break; - }; - } - XML_ParserFree(parser); + g_debug("XDXF/%s->%s() We found every words matching " + "pattern \"%s\". Abort further searching.\n", + __FILE__, + __FUNCTION__, + pattern + ); + break; + }; + } + XML_ParserFree(parser); g_free(casefold_pattern); casefold_pattern = NULL; - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - //timer(TIMER_START,"callback for returning words list START"); - data->cb_search_word_list(result, - pattern, - cb_data, - ENGINE_NO_ERROR - ); - //timer(TIMER_STOP,"callback for returning words list END"); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + /* timer(TIMER_START,"callback for returning words list START"); */ + data->cb_search_word_list( result, + pattern, + cb_data, + ENGINE_NO_ERROR ); + /* timer(TIMER_STOP,"callback for returning words list END"); */ } -//------------------------------------------------------------------------------ + +/** + * \param data engine global data + * \param pattern pattern for words list + * \param user_data optional data for translation callback + */ void xdxf_engine_search_word_list(Engine* engine, gchar* pattern, gpointer user_data) { - g_debug("XDXF/%s->%s() called. Searching words list\n" - "-->PARAM:engine at adress=%p\n" - "-->PARAM:pattern=\"%s\"\n", - __FILE__, - __FUNCTION__, - engine, - pattern - ); - g_assert(engine != NULL); - g_assert(pattern != NULL); - - //timer(TIMER_START,(gchar*)__FUNCTION__); - XDXFData* data = (XDXFData*)(engine->engine_data); - if(data->cb_search_word_list == NULL) + g_debug("XDXF/%s->%s() called. Searching words list\n" + "-->PARAM:engine at adress=%p\n" + "-->PARAM:pattern=\"%s\"\n", + __FILE__, + __FUNCTION__, + engine, + pattern ); + + g_assert(engine != NULL); + g_assert(pattern != NULL); + + /* timer(TIMER_START,(gchar*)__FUNCTION__); */ + XDXFData* data = (XDXFData*)(engine->engine_data); + if(data->cb_search_word_list == NULL) { - g_warning("XDXF/%s->%s() callback for Word List not set. " - "Searching aborted.\n", - __FILE__, - __FUNCTION__ - ); - //timer(TIMER_STOP,(gchar*)__FUNCTION__); - return; - }; + g_warning( "XDXF/%s->%s() callback for Word List not set. " + "Searching aborted.\n", + __FILE__, + __FUNCTION__ ); + /* timer(TIMER_STOP,(gchar*)__FUNCTION__); */ + return; + }; gpointer cb_data = user_data; if ( NULL == cb_data ) { cb_data = data->cb_search_word_list_data; } - GArray* result = g_array_new(TRUE,FALSE,sizeof(gchar*)); - // dictionary is optimized so search in cache file - if(data->cache != NULL) + + GArray* result = g_array_new(TRUE,FALSE,sizeof(gchar*)); + /* dictionary is optimized so search in cache file */ + if(data->cache != NULL) { - word_list_cache(data, pattern, result, cb_data); - } - // dictionary is not optimized so search directly fom XDXF file - else + word_list_cache(data, pattern, result, cb_data); + } + else { - word_list_xdxf(data, pattern, result, cb_data); - }; - guint i = 0; + /* dictionary is not optimized-search directly fom XDXF file */ + word_list_xdxf(data, pattern, result, cb_data); + }; + guint i = 0; if (result!=NULL){ - for (i=0; ilen; i++) + for (i = 0; i < result->len; i++) { g_free(g_array_index(result, gchar*, i)); } g_array_free(result, TRUE); result = NULL; } - g_debug("XDXF/%s->%s() finished definately its work.\n", - __FILE__, - __FUNCTION__ - ); + + g_debug("XDXF/%s->%s() finished definately its work.\n", + __FILE__, + __FUNCTION__ + ); return; } + +/*@}*/ -- 1.7.9.5