src/bookmarks/xdxf/src/engine_bookmark.c

00001 /******************************************************************************
00002 This file is part of mdictionary.
00003 
00004 mdictionary is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 mdictionary is distributed in the hope that it will be useful, 
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License 
00015 along with mdictionary; if not, write to the Free Software
00016 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00017 
00018 Copyright 2006 ComArch S.A.
00019 ******************************************************************************/
00020 
00021 // header with data structure and function definition for XDXF engine.
00022 // Also Engine API. 
00023 #include <engine_bookmark.h>
00024 #include <string.h>
00025 //------------------------------------------------------------------------------
00026 #define LOGS g_debug
00027 #define g_strlen(string) ( NULL == (string) ? 0 : strlen(string) )
00028 // searching word translation in cache file
00029 static void caching_expat_start(void *data, const char *el, const char **attr);
00030 static void caching_expat_end(void *data, const char *el);
00031 static void caching_expat_text(void *data, const XML_Char *txt, int len);
00032 static gchar* word_translation_cache(XDXFData* data, gchar* word)
00033 {
00034         gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);
00035         gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1];
00036         GnomeVFSFileSize bytes_readed;
00037 
00038         guint word_length = g_strlen(word);
00039         guint record_length = 0;
00040         guint trans_offset = 0;
00041         guint already = 0;
00042         guint64 readed = 0;
00043         gchar* buffer = NULL;
00044         gchar* trans = NULL;
00045         guint file_size = get_file_size(data->cache);
00046         if (file_size > 0){
00047         while(TRUE) {
00048                 gnome_vfs_read(data->cache,
00049                                b,
00050                                DICT_SEARCHING_WORD_TRAN_BUFF_SIZE,
00051                                &bytes_readed
00052                               );
00053                 guint max_length = (guint)get_max_length(b,bytes_readed);
00054                 readed += max_length;
00055                 buffer = b;
00056                 already = 0;
00057                 while(already < max_length) {
00058                         memcpy(&record_length, buffer, sizeof(guint));
00059                         memcpy(&trans_offset,
00060                                 buffer+record_length-2*sizeof(guint),
00061                                 sizeof(guint)
00062                               );
00063                         buffer[record_length-sizeof(guint)*2] = '\0';
00064                         if(((record_length - 3*sizeof(guint)) == word_length) &&
00065                            (g_utf8_collate(word,buffer+sizeof(guint)) == 0)) {
00066                                 FilePart translation = {0,0};
00067                                 translation.offset = trans_offset;
00068                                 memcpy(&(translation.length),
00069                                         buffer + record_length - sizeof(guint),
00070                                         sizeof(guint)
00071                                       );
00072                                 trans =read_file_part(&translation, data->xdxf);
00073                                 break;
00074                         };
00075                         already += record_length;
00076                         buffer += record_length;
00077                 };
00078 
00079                 if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) || 
00080                       ( readed > (file_size - 3) )) {
00081                         break;
00082                       };
00083                       gnome_vfs_seek(data->cache,
00084                                      GNOME_VFS_SEEK_CURRENT,
00085                                      ((gint)max_length) - 
00086                                           DICT_SEARCHING_WORD_TRAN_BUFF_SIZE
00087                                     );
00088         }
00089         }
00090         return trans;
00091 }
00092 //------------------------------------------------------------------------------
00093 // searching word translation in xdxf dictionary
00094 static gchar* word_translation_xdxf(XDXFData* data, gchar* word) {
00095         guint word_length = strlen(word);
00096         gchar* trans = NULL;
00097         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0);
00098         GnomeVFSResult vfs_result;
00099         GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_TRAN_BUFF_SIZE;                
00100         gchar buffer[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE+1];                
00101         guint64 file_size = get_file_size(data->xdxf);
00102                 //guint word_len = strlen(word); added by me
00103                 
00104         XML_Parser parser = XML_ParserCreate(NULL);        
00105         if (!parser) {
00106                 g_warning("%s->%s() Could not open initialize "
00107                           "XML parser.\n",
00108                           __FILE__,
00109                           __FUNCTION__
00110                          );
00111                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
00112                 return NULL;
00113         };
00114 
00115         gchar tmp[DICT_MAX_WORD_LENGTH];
00116         XDXFWordsTransData search_data = {tmp,
00117                                           word,
00118                                           word_length,
00119                                           0,
00120                                           NULL,
00121                                           FALSE,
00122                                           TRUE,
00123                                           0,
00124                                           &parser,
00125                                           FALSE,
00126                                           data->xdxf
00127                                          };
00128         XML_SetElementHandler(parser,
00129                               search_word_trans_start,
00130                               search_word_trans_end
00131                              );
00132         XML_SetCharacterDataHandler(parser, search_word_trans_text);
00133                 
00134         XML_SetUserData(parser, &search_data);
00135 
00136         //gdouble last_prog = 0;
00137         while(TRUE) {
00138                 vfs_result = gnome_vfs_read(data->xdxf,
00139                                             buffer,
00140                                             DICT_SEARCHING_WORD_TRAN_BUFF_SIZE,
00141                                             &bytes_readed
00142                                            );
00143                 XML_Parse(parser,
00144                           buffer,
00145                           bytes_readed,
00146                           bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE
00147                          );
00148                         
00149                 gdouble last_prog = 0.0;
00150                 if(data->cb_progress_word_trans != NULL) {
00151                         GnomeVFSFileSize act_pos;
00152                         gnome_vfs_tell(data->xdxf, &act_pos);
00153                         gdouble progress = 
00154                                 ((gdouble)act_pos)/((gdouble)file_size);
00155                         if((( (progress - last_prog)/
00156                               (data->cb_progress_word_trans_seed) ) > 1.0) ||
00157                             (progress >= 1.0)) {
00158                                 data->
00159                                 cb_progress_word_trans(progress,
00160                                               data->cb_progress_word_trans_data,
00161                                               ENGINE_NO_ERROR
00162                                                       );
00163                                 last_prog = progress;
00164                         };
00165                 }
00166                 if(bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE) {
00167                         break;
00168                 }
00169                 if(search_data.cont == FALSE) {
00170                         break;
00171                 }
00172         }
00173         XML_ParserFree(parser);
00174         trans = search_data.translation; 
00175         return trans;        
00176 }
00177 
00178 //------------------------------------------------------------------------------
00179 // get position of a word in order to add this word to bookmarks
00180 /*GnomeVFSFileSize*/
00181 static FilePart get_adding_position(XDXFData* data, 
00182                         gchar* word)
00183 {
00184         
00185         
00186         g_debug("%s<->", __FUNCTION__);
00187         gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);
00188         gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1];
00189         GnomeVFSFileSize bytes_readed;
00190 
00191         //guint word_length = g_strlen(word);
00192         guint record_length = 0;
00193         guint trans_offset = 0;
00194         guint already = 0;
00195         guint64 readed = 0;
00196         gchar* buffer = NULL;
00197         gchar* trans = NULL;
00198         
00199 //      g_printf ("\n\ncache: %p\n", data->cache);
00200         
00201 //      return 0;
00202         gchar* down_word = g_utf8_strdown(word, -1);
00203         guint file_size = get_file_size(data->cache);
00204         if (file_size > 0){
00205         while(TRUE) {
00206                 gnome_vfs_read(data->cache,
00207                                b,
00208                                DICT_SEARCHING_WORD_TRAN_BUFF_SIZE,
00209                                &bytes_readed
00210                               );
00211                 guint max_length = (guint)get_max_length(b,bytes_readed);
00212                 readed += max_length;
00213                 buffer = b;
00214                 already = 0;
00215                 while(already < max_length) {
00216                         memcpy(&record_length, buffer, sizeof(guint));
00217                         memcpy(&trans_offset,
00218                                 buffer+record_length-2*sizeof(guint),
00219                                 sizeof(guint)
00220                               );
00221                         buffer[record_length-sizeof(guint)*2] = '\0';
00222                         gboolean test = 
00223                                 g_utf8_collate(buffer+sizeof(guint), down_word);
00224                         g_debug("And here is the buffer content: %s\nCompare result of word %d which is %s", 
00225                                 buffer+sizeof(guint), test, down_word);
00226                         if(/*((record_length - 3*sizeof(guint)) == word_length) &&*/
00227                            test >= 0)
00228                         {
00229                                 FilePart translation = {0,0};
00230                                 translation.offset = trans_offset;
00231                                 memcpy(&(translation.length),
00232                                         buffer + record_length - sizeof(guint),
00233                                         sizeof(guint)
00234                                       );
00235                                 trans =read_file_part(&translation, data->xdxf);
00236                                 return translation/*translation.offset + translation.length*/;  
00237        
00238                         };
00239                         already += record_length;
00240                         buffer += record_length;
00241                 };
00242 
00243                 if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) || 
00244                       ( readed > (file_size - 3) )) {
00245                         break;
00246                       };
00247                       gnome_vfs_seek(data->cache,
00248                                      GNOME_VFS_SEEK_CURRENT,
00249                                      ((gint)max_length) - 
00250                                           DICT_SEARCHING_WORD_TRAN_BUFF_SIZE
00251                                     );
00252         }
00253         }
00254         guint64 tmp_offset = get_file_size(data->xdxf) - g_strlen("</xdxf>");
00255         //g_debug("TMP_OFFSET: %ld", tmp_offset);
00256         FilePart translation = {tmp_offset,0};
00257         return /*trans_offset*/translation;
00258 }
00259 
00260 //------------------------------------------------------------------------------
00261 // searching word by concrete engine
00262 void bm_engine_search_word_translation(Engine* engine, gchar* word)
00263 {
00264         g_debug("%s->%s() called.\n"
00265                 "-->PARAM:engine at adress=%p\n"
00266                 "-->PARAM:word=\'%s\'\n",
00267                  __FILE__,
00268                  __FUNCTION__,
00269                  engine,
00270                  word);
00271         g_assert(engine != NULL);
00272         g_assert(word != NULL);
00273         // start timer for this function
00274         timer(TIMER_START, (gchar*)__FUNCTION__);
00275         XDXFData* data = (XDXFData*)(engine->engine_data);
00276         // if callback is not set, we do not have to search word
00277         if(data->cb_search_word_trans == NULL) {
00278                 g_warning("%s->%s() callback for Word Translation not set."
00279                           " Searching aborted.\n",
00280                           __FILE__,
00281                           __FUNCTION__
00282                          );
00283                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
00284                 // do not send any signal, just exit
00285                 return;                
00286         };
00287         
00288         //guint word_length = strlen(word);
00289         gchar* trans;
00290 
00291         // dictionary is optimized
00292         if(data->cache != NULL) {
00293                 trans = word_translation_cache(data, word);
00294         // dictionary is not optimized right now
00295         } else 
00296         {        
00297                 trans = word_translation_xdxf(data, word);                
00298         };
00299 
00300         g_debug("%s->%s() found for word \'%s\' translation:\n\'%s\'\n",
00301                 __FILE__,
00302                 __FUNCTION__,
00303                 word,
00304                 trans
00305                );
00306         timer(TIMER_STOP,(gchar*)__FUNCTION__);
00307         timer(TIMER_START,"callback for returning word's translation START");
00308         // calling callback for word translation
00309         data->cb_search_word_trans(trans,
00310                                    word,
00311                                    data->cb_search_word_trans_data,
00312                                    ENGINE_NO_ERROR
00313                                   );
00314         timer(TIMER_STOP,"callback for returning word's translation END");
00315         if(data->auto_free) {
00316                 g_debug("%s->%s() deleting all dynamic data because "
00317                         "AUTO_FREE=TRUE\n",
00318                         __FILE__,
00319                         __FUNCTION__
00320                        );
00321                 g_free(trans);
00322         }
00323         trans = NULL;
00324         return;
00325 }
00326 //------------------------------------------------------------------------------
00327 gboolean bm_engine_remove_word(Engine* engine,
00328                              gchar*  word)
00329 {
00330         g_debug("%s <-> %s()", __FILE__, __FUNCTION__);
00331         GnomeVFSResult vfs_result;
00332         XDXFData* data = (XDXFData*)(engine->engine_data);
00333         GnomeVFSHandle* swap_xdxf;
00334         vfs_result = 
00335                 gnome_vfs_create(&(swap_xdxf), "/media/mmc1/swap_xdxf.xdxf", 
00336                         GNOME_VFS_OPEN_WRITE | 
00337                         GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM, 
00338                         FALSE, 0666);   
00339         if(vfs_result != GNOME_VFS_OK)  {
00340                 g_warning("%s->%s() opening dictionary file failed"
00341                                 " due to reason: %s.\n",
00342                                 __FILE__,
00343                                 __FUNCTION__,
00344                                 gnome_vfs_result_to_string(vfs_result)
00345                                 );
00346                 return FALSE;
00347         }
00348         
00349         FilePart position_part = get_adding_position (data, word);
00350         //GnomeVFSFileSize position = position_part.offset /*+ position_part.length*/;
00351         //guint64 file_size = get_file_size(data->cache);
00352         gchar read_buffer[DICT_CACHEING_BUFF_SIZE + 1];
00353         GnomeVFSFileSize read_size = DICT_CACHEING_BUFF_SIZE;
00354         GnomeVFSFileSize read_bytes_size = DICT_CACHEING_BUFF_SIZE;
00355         GnomeVFSFileSize bytes_written;
00356         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 
00357                                 position_part.offset + position_part.length);
00358         /*Write form position to the end of the file*/
00359 //      GnomeVFSFileSize position = position_part.offset
00360         
00361         while(TRUE)
00362         {
00363                 g_debug(":Working around in writing the tail:");
00364                 
00365                 gnome_vfs_read(data->xdxf/*GnomeVFSHandle */,
00366                                 read_buffer/*buffer*/,
00367                                 read_size/*GnomeVFSFileSize*/,
00368                                 &read_bytes_size/*GnomeVFSFileSize*/);
00369                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00370                 vfs_result = gnome_vfs_write(swap_xdxf,
00371                                 read_buffer,
00372                                 read_bytes_size,
00373                                 &bytes_written);
00374                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00375                 if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break;
00376         }
00377         
00378         //g_printf (">>> %s %d %s<<<\n", word, position, data->dict_path);
00379         //gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, position_part.offset);
00380         
00381         gnome_vfs_truncate_handle(data->xdxf, position_part.offset);
00382         
00383         read_bytes_size = DICT_CACHEING_BUFF_SIZE;
00384         read_size = DICT_CACHEING_BUFF_SIZE + 1 ;
00385         //bytes_written = DICT_CACHEING_BUFF_SIZE;
00386         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, position_part.offset);
00387         gnome_vfs_seek(swap_xdxf, GNOME_VFS_SEEK_START, 0);
00388         while(TRUE)
00389         {
00390                 g_debug(":Working around in writing back the tail:");
00391                 
00392                 gnome_vfs_read(swap_xdxf/*GnomeVFSHandle */,
00393                                 read_buffer/*buffer*/,
00394                                 read_size/*GnomeVFSFileSize*/,
00395                                 &read_bytes_size/*GnomeVFSFileSize*/);
00396                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00397                 vfs_result = gnome_vfs_write(data->xdxf,
00398                                 read_buffer,
00399                                 read_bytes_size,
00400                                 &bytes_written);
00401                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00402 //              g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE);
00403                 if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break;
00404         }
00405         gnome_vfs_close(swap_xdxf); 
00406         gnome_vfs_unlink("/media/mmc1/swap_xdxf.xdxf");
00407         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 
00408                         0);
00409         gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 
00410                         0);
00411         gnome_vfs_close(data->cache); 
00412         gchar* cache_path = g_strconcat(data->dict_path, "/ws_bookmarks.cache", NULL);
00413         gnome_vfs_unlink(cache_path);
00414         bm_engine_optimize(engine);
00415         g_free(cache_path);
00416         return TRUE;
00417 }
00418 
00419 gboolean bm_engine_add_word(Engine* engine,
00420                          gchar*  word,
00421                          gchar*  translation) 
00422 {
00423         g_debug("%s -> %s()", __FILE__, __FUNCTION__);
00424         
00425         //guint word_length = strlen(word);
00426         XDXFData* data = (XDXFData*)(engine->engine_data);
00427         GnomeVFSResult vfs_result;
00428         GnomeVFSHandle* swap_xdxf;
00429         vfs_result = 
00430                 gnome_vfs_create(&(swap_xdxf), "/media/mmc1/swap_xdxf.xdxf", 
00431                         GNOME_VFS_OPEN_WRITE | 
00432                         GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM, 
00433                         FALSE, 0666);   
00434         if(vfs_result != GNOME_VFS_OK)  {
00435                 g_warning("%s->%s() opening dictionary file failed"
00436                                 " due to reason: %s.\n",
00437                                 __FILE__,
00438                                 __FUNCTION__,
00439                                 gnome_vfs_result_to_string(vfs_result)
00440                                 );
00441                 return FALSE;
00442         }
00443         
00444         
00445 //      guint64 file_size = get_file_size(data->xdxf);
00446         FilePart position_part = get_adding_position(data, word);
00447         GnomeVFSFileSize position = 
00448                         position_part.offset/* + position_part.length*/;
00449         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 
00450                                 position);
00451         gchar read_buffer[DICT_CACHEING_BUFF_SIZE + 1];
00452         GnomeVFSFileSize read_size = DICT_CACHEING_BUFF_SIZE + 1 ;
00453         GnomeVFSFileSize read_bytes_size = DICT_CACHEING_BUFF_SIZE;
00454         GnomeVFSFileSize bytes_written;
00455         /*Write form position to the end of the file*/
00456         while(TRUE)
00457         {
00458                 g_debug(":Working around in writing the tail:");
00459                 
00460                 vfs_result = gnome_vfs_read(data->xdxf/*GnomeVFSHandle */,
00461                                 read_buffer/*buffer*/,
00462                                 read_size/*GnomeVFSFileSize*/,
00463                                 &read_bytes_size/*GnomeVFSFileSize*/);
00464                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00465                 //g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE);
00466                 vfs_result = gnome_vfs_write(swap_xdxf,
00467                                 read_buffer,
00468                                 read_bytes_size,
00469                                 &bytes_written);
00470                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00471                 //g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE);
00472                 if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break;
00473         }
00474         /*End write*/
00475         /*Write new entry*/
00476         /*gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 
00477                         position);*/
00478         gchar* buffer = NULL;
00479         /*Testing if the adding word is in bookmark file*/
00480         gchar* search_pattern = g_strconcat("<k>", word, "</k>", NULL);
00481         //gint search_pattern_len = g_strlen(search_pattern);
00482         gchar read_word[position_part.length + 1];
00483         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 
00484                                 position_part.offset);
00485         gnome_vfs_read(data->xdxf/*GnomeVFSHandle */,
00486                         read_word/*buffer*/,
00487                         position_part.length/*GnomeVFSFileSize*/,
00488                         &read_bytes_size/*GnomeVFSFileSize*/);
00489         gchar* cmp_result = g_strrstr(read_word /*haystack*/,
00490                                         search_pattern/*needle*/);
00491         if (cmp_result != NULL)
00492         {
00493                 
00494                 gchar** tmp = g_strsplit(translation,
00495                                         "</k>",
00496                                         2);
00497                 gchar* tmp2 = g_strndup(tmp[1], 
00498                                 g_strlen(tmp[1]) - g_strlen("</ar>"));
00499                 gchar* tmp3 = g_strndup(read_word, 
00500                                 g_strlen(read_word) - g_strlen("</ar>"));
00501                 buffer = g_strconcat(tmp3, tmp2, "</ar>", NULL);
00502                 g_strfreev(tmp);
00503                 g_free(tmp2);
00504                 g_free(tmp3);
00505                 gnome_vfs_seek(swap_xdxf, GNOME_VFS_SEEK_START, 
00506                         position_part.length);
00507         }else
00508         {
00509                 buffer = g_strdup(translation); 
00510                 gnome_vfs_seek(swap_xdxf, GNOME_VFS_SEEK_START, 0);
00511         }
00512         /*End of testing*/
00513         gnome_vfs_truncate_handle(data->xdxf, position_part.offset);
00514         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_END, 0);
00515         GnomeVFSFileSize buffer_size = g_strlen(buffer);
00516                         
00517         gnome_vfs_write(data->xdxf,
00518                         buffer,
00519                         buffer_size,
00520                         &bytes_written
00521                         );
00522         
00523         read_bytes_size = DICT_CACHEING_BUFF_SIZE;
00524         read_size = DICT_CACHEING_BUFF_SIZE + 1 ;
00525         //bytes_written = DICT_CACHEING_BUFF_SIZE;
00526         //gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0);
00527         while(TRUE)
00528         {
00529                 
00530                 
00531                 vfs_result = gnome_vfs_read(swap_xdxf/*GnomeVFSHandle */,
00532                                 read_buffer/*buffer*/,
00533                                 read_size/*GnomeVFSFileSize*/,
00534                                 &read_bytes_size/*GnomeVFSFileSize*/);
00535                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00536                 vfs_result = gnome_vfs_write(data->xdxf,
00537                                 read_buffer,
00538                                 read_bytes_size,
00539                                 &bytes_written);
00540                 //g_return_val_if_fail(vfs_result != GNOME_VFS_OK, FALSE);
00541                 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00542                 //g_debug("%d", bytes_written);
00543                 if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break;
00544         }       
00545         /*End write back*/
00546         
00547         gnome_vfs_close(swap_xdxf); 
00548         gnome_vfs_unlink("/media/mmc1/swap_xdxf.xdxf");
00549 //      gnome_vfs_close(data->xdxf);
00550 //      gnome_vfs_open(data->xdxf, data->dict_path, GNOME_VFS_OPEN_READ);
00551         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 
00552                         0);
00553         gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 
00554                         0);
00555         gnome_vfs_close(data->cache); 
00556         gchar* cache_path = g_strconcat(data->dict_path, "/ws_bookmarks.cache", NULL);
00557         //gnome_vfs_unlink(cache_path);
00558         bm_engine_optimize(engine);
00559         g_free(cache_path);
00560         return TRUE;
00561 }
00562 
00563 static void search_word_trans_start(void *data,
00564                                     const char *el,
00565                                     const char **attr
00566                                    )
00567 {
00568         XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data;
00569         if((loc_data->translation != NULL) || !(loc_data->cont)) {
00570                 return;
00571         };
00572 
00573         if(g_utf8_collate(el,"k") == 0) {
00574                 loc_data->one_word = 1;
00575         } else if(g_utf8_collate(el,"ar") == 0) {
00576                 loc_data->last_start = 
00577                                 XML_GetCurrentByteIndex(*(loc_data->parser));
00578         }
00579 }
00580 //------------------------------------------------------------------------------
00581 static void search_word_trans_end(void *data, const char *el)
00582 {
00583         XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data;
00584         if((loc_data->translation != NULL) || !(loc_data->cont)) {
00585                 return;
00586         };
00587 
00588         if(g_utf8_collate(el,"k") == 0) {
00589                 loc_data->one_word = 0;
00590 
00591                 gint com = g_utf8_collate(loc_data->last_word, loc_data->word);
00592                 if(com > 0) {
00593                         loc_data->cont = FALSE;
00594                         return;
00595                 } else if((loc_data->last_word_length == loc_data->word_len) &&
00596                           ( com == 0 )
00597                          )  {
00598                         loc_data->found = TRUE;
00599                 };       
00600                 // "clearing" buffer for next word        
00601                 loc_data->last_word_length = 0;
00602         } 
00603         else if((g_utf8_collate(el,"ar") == 0) && (loc_data->found)) {
00604                 loc_data->found = FALSE;
00605                 loc_data->cont = FALSE;
00606                 gulong last_stop = 
00607                        (gulong)XML_GetCurrentByteIndex(*(loc_data->parser));
00608                 last_stop += strlen("</ar>");
00609                 FilePart fp = {loc_data->last_start,
00610                                (last_stop - (loc_data->last_start))
00611                               };
00612                 loc_data->translation = read_file_part(&fp, loc_data->xdxf);
00613         }
00614 }
00615 //------------------------------------------------------------------------------
00616 static void search_word_trans_text(void *data, const XML_Char *txt, int len)
00617 {
00618         XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data;
00619         if((loc_data->translation != NULL) || !(loc_data->cont))  {
00620                 return;
00621         };
00622 
00623         if(loc_data->one_word == 1) {
00624                 memcpy(&(loc_data->last_word[loc_data->last_word_length]),
00625                        (gchar*)txt,
00626                        len
00627                       );
00628                 loc_data->last_word_length += (guint)len;
00629                 loc_data->last_word[loc_data->last_word_length] = '\0';
00630         };
00631 }
00632 //------------------------------------------------------------------------------
00633 void bm_engine_search_word_translation_extended(Engine* engine, gchar* word)
00634 {
00635         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
00636 }
00637 //------------------------------------------------------------------------------
00638 void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) {
00639         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
00640         XDXFData* data = (XDXFData*)(engine->engine_data);
00641         if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0)  {
00642                 data->cb_progress_caching_seed = seed;
00643                 g_debug("%s->%s() sets new seed=%0.2f for for signal "
00644                         "\"%s\".\n",
00645                         __FILE__,
00646                         __FUNCTION__,
00647                         seed,
00648                         signal
00649                        );        
00650         } 
00651         else {
00652                 g_warning("%s->%s() unsupported signal"
00653                           "for progress: %s.\n",
00654                           __FILE__,
00655                           __FUNCTION__,
00656                           signal
00657                          );
00658         };
00659 }
00660 //------------------------------------------------------------------------------
00661 gpointer bm_engine_set_callbacks(Engine* engine,
00662                              gchar* signal,
00663                              gpointer c_handler,
00664                              gpointer user_data)
00665 {
00666         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
00667         g_assert(engine != NULL);
00668         g_assert(signal != NULL);
00669         g_assert(c_handler != NULL);
00670         XDXFData* data = (XDXFData*)(engine->engine_data);
00671         if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0)  {
00672                 gpointer result = data->cb_progress_caching;
00673                 data->cb_progress_caching = c_handler;
00674                 data->cb_progress_caching_data = user_data;
00675                 g_debug("%s->%s() sets handler for signal \"%s\".\n",
00676                         __FILE__,
00677                         __FUNCTION__,
00678                         signal
00679                        );
00680                 g_debug("%s->%s() Function at adress =  %d.\n",
00681                         __FILE__,
00682                         __FUNCTION__,
00683                         (guint)c_handler
00684                        );
00685                 g_debug("%s->%s()     Data at adress =  %d.\n",
00686                         __FILE__,
00687                         __FUNCTION__,
00688                         (guint)user_data
00689                        );
00690                 return result;                
00691         }
00692         else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) {
00693                 gpointer result = data->cb_search_word_list;
00694                 data->cb_search_word_list = c_handler;
00695                 data->cb_search_word_list_data = user_data;
00696                 g_debug("%s->%s() sets handler for signal \"%s\".\n",
00697                         __FILE__,
00698                         __FUNCTION__,
00699                         signal
00700                        );
00701                 g_debug("%s->%s() Function at adress =  %d.\n",
00702                         __FILE__,
00703                         __FUNCTION__,
00704                         (guint)c_handler
00705                        );
00706                 g_debug("%s->%s()     Data at adress =  %d.\n",
00707                         __FILE__,
00708                         __FUNCTION__,
00709                         (guint)user_data
00710                        );
00711                 return result;                        
00712         }
00713         else if(g_ascii_strcasecmp(signal,
00714                                    ENGINE_WORD_TRANSLATION_SIGNAL) == 0)  {
00715                 gpointer result = data->cb_search_word_trans;
00716                 data->cb_search_word_trans = c_handler;
00717                 data->cb_search_word_trans_data = user_data;
00718                 g_debug("%s->%s() sets handler for signal \"%s\".\n",
00719                         __FILE__,
00720                         __FUNCTION__,
00721                         signal
00722                        );
00723                 g_debug("%s->%s() Function at adress =  %d.\n",
00724                         __FILE__,
00725                         __FUNCTION__,
00726                         (guint)c_handler
00727                        );
00728                 g_debug("%s->%s()     Data at adress =  %d.\n",
00729                         __FILE__,
00730                         __FUNCTION__,
00731                         (guint)user_data
00732                        );
00733                 return result;                        
00734         }
00735         else {
00736                 g_warning("%s->%s() unsupported signal: %s.\n",
00737                           __FILE__,
00738                           __FUNCTION__,
00739                           signal
00740                          );
00741                 return NULL;
00742         }
00743 }
00744 //------------------------------------------------------------------------------
00745 void bm_engine_close(Engine* engine)
00746 {
00747         g_debug("%s->%s() called.\n-->PARAM: engine adress=%p\n",
00748                 __FILE__,
00749                 __FUNCTION__,
00750                 engine);
00751         if(engine == NULL) {
00752                 g_warning("%s->%s() Trying delete not existed engine.\n",
00753                            __FILE__,
00754                            __FUNCTION__
00755                           );
00756                 return;        
00757         }
00758         XDXFData* data = (XDXFData*)(engine->engine_data);
00759         if(data->cache != NULL) {
00760                 gnome_vfs_close(data->cache);
00761         };
00762         if(data->xdxf != NULL) {
00763                 gnome_vfs_close(data->xdxf);
00764         };
00765         
00766         g_free(data->dict_path);
00767         g_free(data);
00768         g_free(engine);
00769         g_debug("%s->%s() engine at adress=%p is deleted.\n",
00770                 __FILE__,
00771                 __FUNCTION__,
00772                 engine);
00773 }
00774 //------------------------------------------------------------------------------
00775 gchar* bm_engine_error_message(EngineStatus error) 
00776 {
00777         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
00778         return "Error - not yet implemented.";
00779 }
00780 //------------------------------------------------------------------------------
00781 Engine* bm_engine_create(gchar* location,
00782                       EngineOptimizationFlag auto_cache,
00783                       cb_progress progress_handler,
00784                       gpointer progress_data,
00785                       gdouble seed)
00786 {
00787         g_debug("%s->%s() called.\n"
00788                 "-->PARAM:location=\'%s\'\n"
00789                 "-->PARAM:auto_cache=%d\n",
00790                 __FILE__,
00791                 __FUNCTION__,
00792                 location,
00793                 (guint)auto_cache
00794                );
00795         timer(TIMER_START,(gchar*)__FUNCTION__);        
00796         GnomeVFSResult    open_result;
00797 
00798         if(!gnome_vfs_initialized ()) {
00799                 gnome_vfs_init ();                       
00800         };
00801 
00802         gchar* tmp = g_strdup(location);
00803         string_to_path(&tmp);
00804 
00805         Engine* result = (Engine*)g_try_malloc(sizeof(Engine));
00806         result->engine_location = bm_engine_location;
00807         result->engine_is_optimized = bm_engine_is_optimized;
00808         result->engine_optimize = bm_engine_optimize;
00809         result->engine_search_word_list = bm_engine_search_word_list;
00810         result->engine_search_word_translation = 
00811                         bm_engine_search_word_translation;
00812 
00813         result->engine_close = bm_engine_close;
00814         result->engine_status = bm_engine_error;
00815         result->engine_error_message = bm_engine_error_message;
00816         result->engine_set_callback = bm_engine_set_callbacks;
00817         result->engine_set_progress_seed = bm_engine_set_progress_seed;
00818         result->engine_set_auto_free = bm_engine_set_auto_free;
00819         // API 0.2
00820         result->engine_add_word = bm_engine_add_word;
00821         result->engine_remove_word = bm_engine_remove_word;
00822         
00823         XDXFData* data = (XDXFData*)g_try_malloc(sizeof(XDXFData));
00824         result->engine_data = (gpointer)data;
00825         
00826         
00827         g_debug("%s->%s() opening file...\'%s\'.\n",
00828                 __FILE__,
00829                 __FUNCTION__,
00830                 location
00831                 );
00832         gchar* tmp2 = g_strconcat(tmp,"/ws_bookmarks.xdxf",NULL);
00833         open_result = 
00834                 gnome_vfs_open (&(data->xdxf), tmp2, GNOME_VFS_OPEN_READ | 
00835                         GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM);
00836         g_free(tmp2); tmp2 = NULL;
00837         
00838         if(open_result != GNOME_VFS_OK)  {
00839                 g_warning("%s->%s() opening dictionary file failed"
00840                                 " due to reason: %s.\n",
00841                                 __FILE__,
00842                                 __FUNCTION__,
00843                                 gnome_vfs_result_to_string(open_result)
00844                                 );
00845                 result->engine_data = NULL;
00846                 g_free(data);
00847                 g_free(result);
00848                 result = NULL;
00849         }
00850         else {
00851                 g_debug("%s->%s() opening dictionary file successed.\n",
00852                         __FILE__,
00853                         __FUNCTION__
00854                        );
00855                 data->dict_path = g_strdup(tmp);
00856                 data->cache = NULL;
00857                 data->cb_progress_caching = progress_handler;
00858                 data->cb_progress_caching_data = progress_data;        
00859                 data->cb_progress_caching_seed = seed;        
00860                 data->cb_progress_word_list = NULL;
00861                 data->cb_progress_word_list_data = NULL;
00862                 data->cb_progress_word_list_seed = 0.01;
00863                 data->cb_progress_word_trans = NULL;
00864                 data->cb_progress_word_trans_data = NULL;
00865                 data->cb_progress_word_trans_seed = 0.01;
00866 
00867                 data->cb_search_word_list = NULL;
00868                 data->cb_search_word_list_data = NULL;
00869 
00870                 data->cb_search_word_trans = NULL;
00871                 data->cb_search_word_trans_data = NULL;
00872 
00873                 data->auto_free = FALSE;
00874                 if(auto_cache != ENGINE_NO) {
00875                         if(auto_cache == ENGINE_REFRESH) {
00876                                 bm_engine_optimize(result);
00877                         }
00878                         else if(auto_cache == ENGINE_CREATE) {
00879                                 gchar* cache_path = g_strconcat(data->dict_path,
00880                                                                 "/ws_bookmarks.cache",
00881                                                                 NULL);
00882                                 open_result = 
00883                                         gnome_vfs_open (&(data->cache),
00884                                                         cache_path,
00885                                                         GNOME_VFS_OPEN_READ
00886                                                        );
00887                                 if(open_result != GNOME_VFS_OK) {
00888                                         bm_engine_optimize(result);
00889                                 };
00890                                 g_free(cache_path); cache_path = NULL;
00891                         }
00892                 };
00893         }
00894         g_free(tmp); tmp = NULL;
00895         
00896         timer(TIMER_STOP,(gchar*)__FUNCTION__);
00897         g_debug("%s->%s() returned Engine at adress=%p\n TO NAPEWNO TEN PLIK",
00898                 __FILE__,
00899                 __FUNCTION__,
00900                 result
00901                );
00902         return result;
00903 }
00904 //------------------------------------------------------------------------------
00905 EngineModule engine_global_functions()
00906 {
00907         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
00908         EngineModule* result = g_try_new(EngineModule, 1);        
00909                 result->engine_check             = bm_engine_check;
00910                 result->engine_description       = bm_engine_description;
00911                 result->engine_format            = bm_engine_format;
00912                 result->engine_version           = bm_engine_version;
00913                 result->engine_create            = bm_engine_create;
00914         g_debug("%s->%s() returned EngineModule at adress=%p.\n",
00915                 __FILE__,
00916                 __FUNCTION__,
00917                 result
00918                );
00919         return *result;
00920 }
00921 //------------------------------------------------------------------------------
00922 static double timer(gboolean start, gchar* message)
00923 {
00924         static GArray* stack = NULL;
00925         static gboolean first_run = TRUE;
00926         static struct timeval actual_time;
00927         static struct timeval last_time;
00928         static struct timeval result;
00929         static double seconds = 0.0;
00930         if(first_run) {
00931                 first_run = FALSE;
00932                 stack = g_array_new(TRUE, TRUE, sizeof(struct timeval));
00933         };        
00934 
00935         if (start) {
00936                 g_debug("XDXF->%s() start counting time for function '%s()'.\n",
00937                         __FUNCTION__,
00938                         message
00939                        );
00940                 g_array_prepend_val(stack, actual_time);
00941                 gettimeofday(&g_array_index(stack, struct timeval, 0),NULL);
00942                 return -1.0;
00943         }
00944         // we just want to end some timer - print some information about 
00945         // working time;
00946         else {          
00947                 gettimeofday(&actual_time,NULL);
00948                 last_time = g_array_index(stack, struct timeval, 0);
00949                 g_array_remove_index(stack, 0);
00950 
00951                 if (actual_time.tv_usec < last_time.tv_usec) {
00952                         int nsec = (last_time.tv_usec - actual_time.tv_usec) / 
00953                                                                   (1000000 + 1);
00954                         last_time.tv_usec -= 1000000 * nsec;
00955                         last_time.tv_sec += nsec;
00956                 }
00957                 if (actual_time.tv_usec - last_time.tv_usec > 1000000) {
00958                         int nsec = (last_time.tv_usec - actual_time.tv_usec) / 
00959                                                                         1000000;
00960                         last_time.tv_usec += 1000000 * nsec;
00961                         last_time.tv_sec -= nsec;
00962                 }
00963                 result.tv_sec = actual_time.tv_sec - last_time.tv_sec;
00964                 result.tv_usec = actual_time.tv_usec - last_time.tv_usec;
00965                 seconds = (((double)(result.tv_usec)) / 1e6) +
00966                                                       ((double)(result.tv_sec));
00967 
00968                 g_debug("XDXF->%s() function \'%s()\' was working for: %g [s] "
00969                         "or %ld [us].\n",
00970                         __FUNCTION__,
00971                         message,
00972                         seconds,
00973                         ((long)(result.tv_sec*1e6)+(result.tv_usec))
00974                        );
00975                 // stack is empty so we delete everything
00976                 if(stack->len == 0)   
00977                 {
00978                         g_array_free(stack, TRUE);
00979                         first_run = TRUE;
00980                 }
00981         }
00982         return seconds;
00983 }
00984 //------------------------------------------------------------------------------
00985 static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file) 
00986 {
00987         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
00988         timer(TIMER_START,(gchar*)__FUNCTION__);
00989         gchar* result = NULL;
00990         GnomeVFSResult    f_result;
00991         GnomeVFSFileSize  bytes_read;
00992         
00993         f_result = gnome_vfs_seek(file, GNOME_VFS_SEEK_START, part->offset);        
00994         if(f_result != GNOME_VFS_OK) {
00995                 g_warning("%s->%s() failed. Not possible to seek "
00996                           "through file!\n",
00997                           __FILE__,
00998                           __FUNCTION__
00999                          );
01000                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
01001                 return result;
01002                 
01003         };
01004         result = g_try_malloc((part->length + 1) * sizeof(gchar));
01005         if(result == NULL) {
01006                 g_warning("%s->%s() failed. Not possible to allocate "
01007                           "so big memmory chunk!\n",
01008                           __FILE__,
01009                           __FUNCTION__
01010                          );
01011                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
01012                 return result;
01013         };
01014         f_result = gnome_vfs_read (file, result, part->length, &bytes_read);
01015         if((f_result != GNOME_VFS_OK) ||
01016                 (((gulong)bytes_read) != part->length)) {
01017                 g_debug("%s->%s() failed. Not possible to read from "
01018                         "file!\n",
01019                         __FILE__,
01020                         __FUNCTION__
01021                        );
01022                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
01023                 g_free(result); result = NULL;
01024                 return result;                
01025         };
01026         result[part->length] = '\0';
01027 
01028         g_debug("%s->%s() returned string=\n\'%s\'.\n",
01029                 __FILE__,
01030                 __FUNCTION__,
01031                 result
01032                );
01033         timer(TIMER_STOP,(gchar*)__FUNCTION__);
01034         return result;
01035 }
01036 //------------------------------------------------------------------------------
01051 static gchar* string_to_path(gchar** string) {
01052         g_debug("%s->%s() called.\n\
01053                  -->PARAM:string=\'%s\'\n",
01054                  __FILE__,
01055                  __FUNCTION__,
01056                  string[0]
01057                );
01058         gchar* arg = string[0];
01059         gchar* new = NULL;
01060         // cleaning from leading and trailing whitespaces
01061         g_strstrip(arg);        
01062          // add current directory if this is not absolute directory
01063         if (!g_path_is_absolute(arg)) {
01064                 gchar* tmp = g_get_current_dir();
01065                 new = g_strconcat(tmp,"/",arg,NULL);
01066                 g_free(arg); arg = new; new = NULL;
01067         };
01068         // this is not a directory
01069         if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) {        
01070                 // if this is wrong filepath, string was wrong
01071                 if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) {        
01072                         g_free(arg);
01073                         new = NULL;
01074                 }
01075                 //if this is a file, remove filename
01076                 else
01077                 {   
01078                         new = g_path_get_dirname (arg);
01079                         g_free(arg);
01080                 }
01081         }
01082         // this is a directory
01083         else {   
01084                 // remove suffix "/" if neded...     
01085                 if (g_str_has_suffix(arg,"/") ) {        
01086                         new = g_path_get_dirname (arg);
01087                         g_free(arg);
01088                 }
01089                 else {
01090                         new = arg;
01091                 }
01092         };
01093         // now in new should be proper filepath, if not, string was wrong
01094         if (!g_file_test(new, G_FILE_TEST_IS_DIR))  {        
01095                 // if that directory does not exist, passed string wasn't proper       
01096                 g_free(new);
01097                 new = NULL;
01098         };
01099         // replace string under passed address
01100         string[0] = new;
01101         g_debug("%s->%s() returned string=\'%s\'\n",
01102                 __FILE__,
01103                 __FUNCTION__,
01104                 string[0]
01105                );
01106         return new;
01107 }
01108 //------------------------------------------------------------------------------
01109 static gboolean is_bm_file(gchar* file) {
01110          g_debug("%s->%s() called.\n\
01111                  -->PARAM:file=\'%s\'\n",
01112                  __FILE__,
01113                  __FUNCTION__,
01114                  file
01115                );
01116         gboolean                result = TRUE;
01117         GnomeVFSHandle*         fd = NULL;
01118         GnomeVFSResult          file_result;
01119         GnomeVFSFileSize        bytes_read;
01120 
01121         if(!gnome_vfs_initialized ()) {
01122                 gnome_vfs_init ();                       
01123         };
01124 
01125         file_result = gnome_vfs_open (&fd, file, GNOME_VFS_OPEN_READ);
01126         if(file_result != GNOME_VFS_OK) {
01127                 g_warning("%s->%s() Could not open the file.\n",
01128                           __FILE__,
01129                           __FUNCTION__
01130                          );
01131                 return FALSE;
01132         };
01133 
01134         XML_Parser p = XML_ParserCreate(NULL);        
01135         if (!p) {
01136                 g_warning("%s->%s() Could not open initialize "
01137                           "XML parser.\n",
01138                           __FILE__,
01139                           __FUNCTION__
01140                          );
01141                 gnome_vfs_close(fd);
01142                 return FALSE;
01143         };
01144         XML_SetElementHandler(p, is_bm_file_start, is_bm_file_end);
01145         XDXFCheckingData user_data = {TRUE, FALSE, 0};
01146         XML_SetUserData(p, &user_data);
01147         gchar buffer[DICT_CACHEING_BUFF_SIZE];        
01148 
01149         guint loop_count = 0;
01150         while(TRUE) {
01151                 file_result = gnome_vfs_read (fd,
01152                                               buffer,
01153                                               DICT_CACHEING_BUFF_SIZE,
01154                                               &bytes_read
01155                                              );
01156                 if  (file_result != GNOME_VFS_OK) {
01157                         result = FALSE;
01158                         g_warning("%s->%s() Could not read enought from"
01159                                   " file.\n",
01160                                   __FILE__,
01161                                   __FUNCTION__
01162                                  );
01163                         break;
01164                 };               
01165                 if (! XML_Parse(p,
01166                                 buffer,
01167                                 (gulong)bytes_read,
01168                                 ((gulong)bytes_read) < DICT_CACHEING_BUFF_SIZE
01169                                ) ) {
01170                         result = FALSE;
01171                         g_warning("%s->%s() Could not parse file.\n",
01172                                   __FILE__,
01173                                   __FUNCTION__
01174                                  );
01175                         break;
01176                 };
01177                 if (user_data.further == FALSE) {
01178                         result = user_data.good;
01179                         g_debug("%s->%s() statement: location is "
01180                                 "compatible with this module, is %s\n",
01181                                 __FILE__,
01182                                 __FUNCTION__,
01183                                 PRINT_STATE(result)
01184                                );
01185                         break;
01186                 };
01187                 if (loop_count > 1) {
01188                         result = FALSE;
01189                         g_debug("%s->%s() Wrong file format.\n",
01190                                 __FILE__,
01191                                 __FUNCTION__
01192                                );
01193                         break;
01194                 };
01195                 loop_count++;
01196         }
01197 
01198         gnome_vfs_close(fd);
01199         XML_ParserFree(p);
01200         g_debug("%s->%s() returned bool statement=%s.\n",
01201                 __FILE__,
01202                 __FUNCTION__,
01203                 PRINT_STATE(result)
01204                );
01205         return result;
01206 }
01207 //------------------------------------------------------------------------------
01208 static void is_bm_file_start(void *data, const char *el, const char **attr) 
01209 {
01210          XDXFCheckingData* user_data = (XDXFCheckingData*)data;
01211         if (user_data->deep == 0) {
01212                 if (g_utf8_collate (el,"xdxf") != 0) {
01213                         user_data->good = FALSE;                
01214                 }
01215                 else {
01216                         user_data->good = TRUE;
01217                 }
01218                 user_data->further = FALSE;        
01219         }
01220         user_data->deep++;
01221 }
01222 //------------------------------------------------------------------------------
01223 static void is_bm_file_end(void *data, const char *el) 
01224 {
01225         // clear as far as in this callback is nothing to do
01226 }
01227 //------------------------------------------------------------------------------
01228 EngineStatus bm_engine_error(Engine* engine) 
01229 {
01230         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
01231         XDXFData* data = (XDXFData*)(engine->engine_data);
01232         g_debug("%s->%s() returned error code: %d\n",
01233                 __FILE__,
01234                 __FUNCTION__,
01235                 (gint)(data->last_error)
01236                );        
01237         return data->last_error;
01238 }
01239 //------------------------------------------------------------------------------
01240 static void caching_expat_start(void *data, const char *el, const char **attr) {
01241         XDXFCacheData* loc_data = (XDXFCacheData*)data;
01242         if(g_utf8_collate(el,"ar") == 0)  {
01243                 loc_data->last_start = 
01244                                      XML_GetCurrentByteIndex(loc_data->parser);
01245         }
01246         else if(g_utf8_collate(el,"k") == 0) {
01247                 loc_data->state = 1;
01248         }
01249         else {
01250                 loc_data->state = 0;
01251         }
01252 }
01253 //------------------------------------------------------------------------------
01254 static void caching_expat_end(void *data, const char *el) {
01255         XDXFCacheData* loc_data = (XDXFCacheData*)data;
01256         loc_data->last_stop = XML_GetCurrentByteIndex(loc_data->parser);
01257         
01258         static guint record_length;
01259         static guint start;
01260         static guint length;
01261         static guint buffer_length;
01262 
01263         if((g_utf8_collate("k",el) == 0) &&
01264                 (loc_data->state == 1))  {
01265                 loc_data->state = 2;
01266         }
01267         else if((g_utf8_collate("ar",el) == 0) &&
01268                         (loc_data->state == 2)) {
01269                 buffer_length = loc_data->buffer_length;
01270                 record_length = sizeof(guint)*3 + loc_data->buffer_length;
01271                 start = loc_data->last_start;
01272                 length = loc_data->last_stop + strlen("</ar>") - 
01273                          loc_data->last_start;
01274                 
01275                 gboolean error_writting = FALSE;
01276                 GnomeVFSFileSize bytes_written;
01277                 GnomeVFSResult vfs_result;
01278                 vfs_result = gnome_vfs_write(loc_data->cache,
01279                                              &record_length,
01280                                              sizeof(guint),
01281                                              &bytes_written
01282                                             );
01283                         if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01284                 vfs_result = gnome_vfs_write(loc_data->cache,
01285                                              loc_data->buffer,
01286                                              loc_data->buffer_length,
01287                                              &bytes_written
01288                                             );
01289                         if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01290                 vfs_result = gnome_vfs_write(loc_data->cache,
01291                                              &start,
01292                                              sizeof(guint),
01293                                              &bytes_written
01294                                             );
01295                         if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01296                 vfs_result = gnome_vfs_write(loc_data->cache,
01297                                              &length,
01298                                              sizeof(guint),
01299                                              &bytes_written
01300                                             );
01301                         if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01302                 
01303                 loc_data->buffer[0] = '\0';
01304                 loc_data->buffer_length = 0;
01305                 loc_data->state = 0;
01306         };
01307 }
01308 //------------------------------------------------------------------------------
01309 static void caching_expat_text(void *data, const XML_Char *txt, int len) {
01310         XDXFCacheData* loc_data = (XDXFCacheData*)data;
01311 
01312         if(loc_data->state == 1) {
01313                 memcpy(&(loc_data->buffer[loc_data->buffer_length]),
01314                        (gchar*)txt,
01315                        len
01316                       );
01317                 loc_data->buffer_length += (long)len;
01318                 loc_data->buffer[loc_data->buffer_length] = '\0';
01319         };
01320 }
01321 //------------------------------------------------------------------------------
01322 static guint64 get_file_size(GnomeVFSHandle* file)
01323 {
01324         guint64 result = 0;
01325         guint64 old_pos = 0;
01326         gnome_vfs_tell(file, &old_pos);
01327 
01328         if( gnome_vfs_seek(file, GNOME_VFS_SEEK_END, 0) != GNOME_VFS_OK) {
01329                 return 0;
01330         }
01331 
01332         if( gnome_vfs_tell(file, &result) != GNOME_VFS_OK) {
01333                 result = 0;
01334         }
01335         
01336         gnome_vfs_seek(file, GNOME_VFS_SEEK_START, old_pos);
01337         return result;
01338 }
01339 //------------------------------------------------------------------------------
01340 /*
01341 static gboolean is_Bookmark_file(gchar* file) {
01342         LOGS("Bookmark/%s->%s() called.\n\
01343                  -->PARAM:file=\'%s\'\n",
01344                  (gchar*)__FILE__,
01345                  (gchar*)__FUNCTION__,
01346                  file
01347                );
01348         
01349         GnomeVFSHandle *handle;
01350         
01351         GnomeVFSResult result = gnome_vfs_open (&handle, file, GNOME_VFS_OPEN_READ);
01352                         
01353         if(result != GNOME_VFS_OK) {
01354                 LOGS("File Access Error.\n");
01355                 return FALSE;
01356         }
01357 
01358         if( g_strrstr (file, "ws_bookmarks") == NULL) {
01359                 LOGS("Wrong file! Not a bookmarks' database.\n");
01360                 return FALSE;
01361         }
01362         return TRUE;
01363 }*/
01364 
01365 void bm_engine_optimize(Engine* engine)
01366 {
01367         g_debug("%s->%s() called for engine at adress=%p\n",
01368                 __FILE__,
01369                 __FUNCTION__,
01370                 engine
01371                );
01372         timer(TIMER_START,(gchar*)__FUNCTION__);   
01373         GnomeVFSResult vfs_result;
01374         XDXFData* data = (XDXFData*)(engine->engine_data);
01375         g_debug("data->dict_path %s", data->dict_path);
01376         gchar* cache_path = g_strconcat(data->dict_path,"/ws_bookmarks.cache",NULL);
01377         vfs_result = gnome_vfs_create(&(data->cache),
01378                                       cache_path,
01379                                       GNOME_VFS_OPEN_WRITE,
01380                                       FALSE,
01381                                       0666
01382                                      );
01383         if(vfs_result != GNOME_VFS_OK)  {
01384                data->cache = NULL;
01385                g_warning("%s->%s().Could not create new cache file: %s.\n",
01386                           __FILE__,
01387                           __FUNCTION__,
01388                           cache_path
01389                          );
01390         }
01391         else {
01392                 XDXFCacheData* c_data = 
01393                             (XDXFCacheData*)g_try_malloc(sizeof(XDXFCacheData));
01394                 c_data->parser = XML_ParserCreate(NULL);
01395                 c_data->cache = data->cache;
01396                 c_data->buffer = 
01397                     (gchar*)g_try_malloc(sizeof(gchar)*DICT_CACHEING_BUFF_SIZE);
01398                 c_data->buffer_length = 0;
01399                 c_data->last_start = 0;
01400                 c_data->last_stop = 0;
01401                 c_data->last_length = 0;
01402                 guint64 file_size = get_file_size(data->xdxf);
01403 //                 g_debug("%s->%s(): caching dictionaries size is %.2f kB "
01404 //                         "[%d bytes = %.2f MB].\n",
01405 //                         __FILE__,
01406 //                         __FUNCTION__,
01407 //                         ((gdouble)file_size)/1024.0,
01408 //                         file_size,
01409 //                         ((gdouble)file_size)/(1024.0*1024.0)
01410 //                        );
01411 
01412                 XML_SetUserData(c_data->parser, (gpointer)c_data);
01413                 XML_SetElementHandler(c_data->parser,
01414                                       caching_expat_start,
01415                                       caching_expat_end
01416                                      );
01417                 XML_SetCharacterDataHandler(c_data->parser, caching_expat_text);
01418                 GnomeVFSFileSize bytes_readed = DICT_CACHEING_BUFF_SIZE;
01419                 gchar b[DICT_CACHEING_BUFF_SIZE + 1];
01420                 gdouble last_prog = 0;
01421                 while(TRUE) {
01422                         vfs_result = gnome_vfs_read(data->xdxf,
01423                                                     b,
01424                                                     DICT_CACHEING_BUFF_SIZE,
01425                                                     &bytes_readed
01426                                                    );
01427                         XML_Parse(c_data->parser,
01428                                   b,
01429                                   bytes_readed,
01430                                   bytes_readed < DICT_CACHEING_BUFF_SIZE
01431                                  );
01432                         if(data->cb_progress_caching != NULL) {
01433                                 GnomeVFSFileSize act_pos;
01434                                 gnome_vfs_tell(data->xdxf, &act_pos);
01435                                 gdouble progress = ((gdouble)act_pos)/
01436                                                            ((gdouble)file_size);
01437                                 if((( (progress - last_prog) /
01438                                     (data->cb_progress_caching_seed) ) > 1.0) ||
01439                                    (progress >= 1.0)) {
01440                                         data->cb_progress_caching(
01441                                                  progress,
01442                                                  data->cb_progress_caching_data,
01443                                                  ENGINE_NO_ERROR
01444                                                                  );
01445                                         last_prog = progress;
01446                                 };
01447                         }
01448                         if(bytes_readed < DICT_CACHEING_BUFF_SIZE) break;
01449                 }
01450                 g_free(c_data->buffer);
01451                 g_free(c_data);
01452         }
01453 
01454         vfs_result = gnome_vfs_close(data->cache);
01455         vfs_result = gnome_vfs_open(&(data->cache),
01456                                     cache_path,
01457                                     GNOME_VFS_OPEN_READ
01458                                    );
01459         g_free(cache_path); cache_path = NULL;
01460         timer(TIMER_STOP,(gchar*)__FUNCTION__);
01461         g_debug("%s->%s()'s work finished.\n",__FILE__,__FUNCTION__);
01462 }
01463 //------------------------------------------------------------------------------
01464 gboolean bm_engine_check(gchar* location) 
01465 {        
01466         g_debug("%s->%s() called.\n-->PARAM:location=\'%s\'\n",
01467                 __FILE__,
01468                 __FUNCTION__,
01469                 location
01470                );
01471         timer(TIMER_START,(gchar*)__FUNCTION__);
01472         gboolean result = TRUE;        
01473         gchar* filepath = g_strdup(location);
01474         gchar* tmp = NULL;
01475         
01476         string_to_path(&filepath);
01477         if (filepath == NULL) {
01478                 result = FALSE;
01479                 g_warning("%s->%s() location \'%s\' is not a proper "
01480                           "path!\n",
01481                           __FILE__,
01482                           __FUNCTION__,
01483                           location
01484                          );
01485         }
01486         else {
01487                 tmp = g_strconcat(filepath,"/ws_bookmarks.xdxf",NULL);
01488                 g_free(filepath);
01489                 filepath = tmp;
01490                 tmp = NULL;
01491 
01492                 g_debug("%s->%s() finnal file to check is: %s\n",
01493                         __FILE__,
01494                         __FUNCTION__,
01495                         filepath
01496                        );
01497                 if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR)) {
01498                         g_warning("%s->%s() file \'%s\' does not "
01499                                   "exists!\n",
01500                                   __FILE__,
01501                                   __FUNCTION__,
01502                                   filepath
01503                                  );
01504                         result = FALSE;
01505                 };
01506         };
01507         if (result != FALSE) {
01508                 result = is_bm_file(filepath);
01509         };
01510 
01511         g_free(filepath);
01512         timer(TIMER_STOP,(gchar*)__FUNCTION__);
01513         g_debug("%s->%s() returned bool statement=%s.\n",
01514                 __FILE__,
01515                 __FUNCTION__,
01516                 PRINT_STATE(result)
01517                );
01518         return result;
01519 }
01520 
01521 
01522 //------------------------------------------------------------------------------
01523 static guint get_max_length(gchar* a, guint length) 
01524 {
01525         gchar* b = a;
01526         guint len = 0;
01527         guint n = 0;
01528         memcpy(&n,b,sizeof(guint));
01529         while((len + n) <= (length - 4)) {
01530                 len += n;
01531                 b = b + n;
01532                 memcpy(&n,b,sizeof(guint));
01533         }
01534         return len;
01535 }
01536 //------------------------------------------------------------------------------                                                                                     // finished functions:
01537 void bm_engine_set_auto_free(Engine* engine, gboolean state) 
01538 {
01539         g_debug("%s->%s() called.\n"
01540                 "-->PARAM:engine at adress=%p\n"
01541                 "-->PARAM:state=%s\n",
01542                 __FILE__,
01543                 __FUNCTION__,
01544                 engine,
01545                 PRINT_STATE(state)
01546                );
01547         g_assert(engine != NULL);
01548         XDXFData* data = (XDXFData*)(engine->engine_data);
01549         data->auto_free = state;
01550         g_debug("%s->%s() Current auto_free is %s\n",
01551                 __FILE__,
01552                 __FUNCTION__,
01553                 PRINT_STATE(data->auto_free)
01554                );
01555 }
01556 //------------------------------------------------------------------------------
01557 gchar* bm_engine_version() 
01558 {
01559         g_debug("%s->%s() called.\n",__FILE__,__FUNCTION__);
01560         gchar* result = g_strdup(DIC_ENG_VERSION);
01561         g_debug("%s->%s() return string=%s\n",
01562                 __FILE__,
01563                 __FUNCTION__,
01564                 result
01565                );
01566         return result;
01567 }
01568 //------------------------------------------------------------------------------
01569 gchar* bm_engine_format() 
01570 {
01571         LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01572         gchar* result = g_strdup(DIC_ENG_FORMAT);
01573         LOGS("Bookmark/%s->%s() return string=%s\n",
01574              (gchar*)__FILE__,
01575              (gchar*)__FUNCTION__,
01576              result
01577             );
01578         return result;
01579 }
01580 //------------------------------------------------------------------------------
01581 gchar* bm_engine_description() 
01582 {
01583         LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01584         gchar* result = g_strdup(DIC_ENG_DESCRIPTION);
01585         LOGS("Bookmark/%s->%s() return string=%s\n",
01586              (gchar*)__FILE__,
01587              (gchar*)__FUNCTION__,
01588              result
01589             );
01590         return result;
01591 }
01592 //------------------------------------------------------------------------------
01593 gboolean bm_engine_is_optimized(Engine* engine) 
01594 {
01595         g_debug("%s->%s() called.\n-->PARAM: engine adress=%p\n",
01596                 __FILE__,
01597                 __FUNCTION__,
01598                 engine
01599                );
01600         g_assert(engine != NULL);                
01601         XDXFData* data = (XDXFData*)(engine->engine_data);
01602         gboolean result = (data->cache != NULL);
01603         g_debug("%s->%s() returned bool statement=%s.\n",
01604                 __FILE__,
01605                 __FUNCTION__,
01606                 PRINT_STATE(result)
01607                );
01608         return result;
01609 }
01610 //------------------------------------------------------------------------------
01611 gchar* bm_engine_location(Engine* engine)
01612 {
01613         g_debug("%s->%s() called.\n-->PARAM: engine adress=%p\n",
01614                 __FILE__,
01615                 __FUNCTION__,
01616                 engine
01617                );
01618         g_assert(engine != NULL);
01619         XDXFData* data = (XDXFData*)(engine->engine_data);
01620         gchar* result;
01621         if(data->auto_free) {
01622                 result = data->dict_path;
01623         }
01624         else {
01625                 result = g_strdup(data->dict_path);
01626         }
01627 
01628         g_debug("%s->%s() returned string=%s\n",
01629                 __FILE__,
01630                 __FUNCTION__,
01631                 result
01632                );
01633         return result;
01634 }
01635 //------------------------------------------------------------------------------
01636 static void search_word_list_start(void *data,
01637                                    const char *el,
01638                                    const char **attr
01639                                   )
01640 {
01641         XDXFWordsListData* loc_data = (XDXFWordsListData*)data;
01642         if(g_utf8_collate(el,"k") == 0) {
01643                 loc_data->one_word = 1;
01644         };
01645 }
01646 //------------------------------------------------------------------------------
01647 static void search_word_list_end(void *data, const char *el)
01648 {
01649         XDXFWordsListData* loc_data = (XDXFWordsListData*)data;
01650         if(g_utf8_collate(el,"k") == 0) {
01651                 loc_data->one_word = 0;
01652         }
01653         else {
01654                 return;
01655         }
01656         static  gboolean any_found = FALSE;
01657                         gboolean matched   = FALSE;
01658 
01659         if(( loc_data->last_word_length >= loc_data->pattern_len ) &&
01660            (g_ascii_strncasecmp(loc_data->last_word,
01661                                 loc_data->pattern,
01662                                 loc_data->pattern_len) == 0)) {
01663                 matched = TRUE;
01664                 any_found = TRUE;
01665                 gchar* new = g_strdup(loc_data->last_word);
01666                 g_array_append_val((loc_data->result), new);
01667                 g_debug("New Word for pattern \"%s\" found: %s\n",
01668                         loc_data->pattern,
01669                         new
01670                        );
01671         };
01672         // "clearing" buffer for next word        
01673         loc_data->last_word_length = 0;
01674         // if we passed words matching -> ends
01675         if(any_found && !matched) {
01676                 loc_data->cont = FALSE;
01677         };
01678         matched = FALSE;
01679         any_found = FALSE;
01680 }
01681 //------------------------------------------------------------------------------
01682 static void search_word_list_text(void *data, const XML_Char *txt, int len) 
01683 {
01684         XDXFWordsListData* loc_data = (XDXFWordsListData*)data;
01685 
01686         if(loc_data->one_word == 1) {
01687                 memcpy(&(loc_data->last_word[loc_data->last_word_length]),
01688                        (gchar*)txt,
01689                        len
01690                       );
01691                 loc_data->last_word_length += (guint)len;
01692                 loc_data->last_word[loc_data->last_word_length] = '\0';
01693         };
01694 }
01695 //------------------------------------------------------------------------------
01696 // return translation of word using cache file
01697 static void word_list_cache(XDXFData* data, gchar* pattern, GArray* result) {
01698         gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);        
01699 //        GnomeVFSResult vfs_result;
01700         GnomeVFSFileSize bytes_readed;
01701         guint64 file_size = get_file_size(data->cache);
01702         if (file_size > 0){
01703         guint pattern_len;
01704         gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE];
01705         gchar* buf;
01706         guint record_length = 0;
01707         guint already = 0;
01708         guint max_length = 0;
01709         pattern_len = g_strlen(pattern);
01710         g_strstrip(pattern);
01711         if ((int)(pattern[0]) == 42 && pattern[1] == '\0') //asterix?
01712         {
01713                 gchar pattern_copy[2] = "A\0";
01714         
01715                 pattern_len = g_strlen(pattern_copy);
01716                 while (TRUE)
01717                 {
01718                 
01719                         record_length = 0;
01720                         already = 0;
01721                         max_length = 0;
01722         //gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);        
01723         //
01724                         while(TRUE)  {
01725                                 gnome_vfs_read(data->cache,
01726                                         buffer,
01727                                         DICT_SEARCHING_WORD_LIST_BUFF_SIZE,
01728                                         &bytes_readed
01729                                         );
01730                         
01731                         max_length = get_max_length(buffer, (guint)bytes_readed);
01732                         already += max_length;
01733                         buf = buffer;
01734 
01735                         guint how_far = 0;
01736                         while(how_far < max_length) {
01737                                 memcpy(&record_length, buf, sizeof(guint));
01738                                 if(
01739                                 ((record_length - 3*sizeof(guint)) >= pattern_len) &&
01740                                 (g_ascii_strncasecmp(buf + sizeof(guint),
01741                                                  pattern_copy,
01742                                                  pattern_len
01743                                                 ) == 0 ) ) {
01744                                         gchar* new = 
01745                                                 g_strndup(buf + sizeof(guint),
01746                                                        record_length - 
01747                                                                3*sizeof(guint));
01748                                         g_array_append_val(result, new);
01749                                         g_debug(
01750                                         "New Word for pattern \"%s\" found: "
01751                                         "%s\n",
01752                                         pattern_copy,
01753                                         new
01754                                        );
01755                                 };
01756                                 how_far += record_length;
01757                                 buf = buf + record_length;
01758                         }
01759                         if((bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE)|| 
01760                                 (already > (file_size -3))) {
01761                                 break;
01762                         }
01763                                 gnome_vfs_seek(data->cache, 
01764                                         GNOME_VFS_SEEK_CURRENT,
01765                                         ((gint)max_length) - 
01766                                              DICT_SEARCHING_WORD_LIST_BUFF_SIZE
01767                                    );
01768                         }
01769                         pattern_copy[0] = (gchar)((gint) pattern_copy[0] + 1);
01770                         
01771                         g_debug("now this is pattern %d ", (gint) pattern_copy[0]);
01772                         if ((gint) pattern_copy[0] > 90) break;
01773                         gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);
01774                 }
01775         }else
01776         {
01777                 while(TRUE)  {
01778                         gnome_vfs_read(data->cache,
01779                                         buffer,
01780                                         DICT_SEARCHING_WORD_LIST_BUFF_SIZE,
01781                                         &bytes_readed
01782                                         );
01783                         
01784                         max_length = get_max_length(buffer, (guint)bytes_readed);
01785                         already += max_length;
01786                         buf = buffer;
01787 
01788                         guint how_far = 0;
01789                         while(how_far < max_length) {
01790                                 memcpy(&record_length, buf, sizeof(guint));
01791                                 if(
01792                                 ((record_length - 3*sizeof(guint)) >= pattern_len) &&
01793                                 (g_ascii_strncasecmp(buf + sizeof(guint),
01794                                                  pattern,
01795                                                  pattern_len
01796                                                 ) == 0 ) ) {
01797                                         gchar* new = 
01798                                                 g_strndup(buf + sizeof(guint),
01799                                                        record_length - 
01800                                                                3*sizeof(guint));
01801                                         g_array_append_val(result, new);
01802                                         g_debug(
01803                                         "New Word for pattern \"%s\" found: "
01804                                         "%s\n",
01805                                         pattern,
01806                                         new
01807                                        );
01808                                 };
01809                                 how_far += record_length;
01810                                 buf = buf + record_length;
01811                         }
01812                         if((bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE)|| 
01813                                 (already > (file_size -3)) ) {
01814                 
01815                                 break;
01816                         }
01817                                 gnome_vfs_seek(data->cache, 
01818                                         GNOME_VFS_SEEK_CURRENT,
01819                                         ((gint)max_length) - 
01820                                              DICT_SEARCHING_WORD_LIST_BUFF_SIZE
01821                                    );
01822                 }       
01823         }
01824         }
01825         timer(TIMER_STOP,(gchar*)__FUNCTION__);
01826         timer(TIMER_START,"callback for returning words list START");                
01827         data->cb_search_word_list(result,
01828                                   pattern,
01829                                   data->cb_search_word_list_data,
01830                                   ENGINE_NO_ERROR
01831                                  );
01832         timer(TIMER_STOP,"callback for returning words list END");        
01833 }
01834 //------------------------------------------------------------------------------
01835 // return translation of word but using only xdxf dictionary file
01836 static void word_list_xdxf(XDXFData* data, gchar* pattern, GArray* result) {
01837         gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0);
01838         GnomeVFSResult vfs_result;
01839         GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_LIST_BUFF_SIZE;                
01840         gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE+1];                
01841         guint64 file_size = get_file_size(data->xdxf);
01842         guint pattern_len;
01843                
01844         XML_Parser parser = XML_ParserCreate(NULL);        
01845         if (!parser) {
01846                 g_warning("%s->%s() Could not open initialize XML "
01847                           "parser.\n",
01848                           __FILE__,
01849                           __FUNCTION__
01850                          );
01851                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
01852                 return;
01853         };
01854         
01855         
01856         gchar tmp[DICT_MAX_WORD_LENGTH];
01857         XML_SetElementHandler(parser,
01858                               search_word_list_start,
01859                               search_word_list_end
01860                              );
01861         XML_SetCharacterDataHandler(parser, search_word_list_text);
01862         
01863         // buffer for single word 
01864         // pattern to search 
01865         // length of pattern 
01866         // actal length of readed word 
01867         // array to append words 
01868         // continuation of the same word 
01869         // continue of searching?
01870         XDXFWordsListData search_data = {tmp,
01871                                          pattern,
01872                                          pattern_len,
01873                                          0,
01874                                          result,
01875                                          0,
01876                                          TRUE
01877                                         }; 
01878         XML_SetUserData(parser, &search_data);
01879 
01880         gdouble last_prog = 0;
01881        
01882         while(TRUE) {
01883                 vfs_result = gnome_vfs_read(data->xdxf,
01884                                             buffer,
01885                                             DICT_SEARCHING_WORD_LIST_BUFF_SIZE,
01886                                             &bytes_readed
01887                                            );
01888                 XML_Parse(parser,
01889                           buffer,
01890                           bytes_readed,
01891                           bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE
01892                          );
01893                         
01894                 if(data->cb_progress_word_list != NULL) {
01895                         GnomeVFSFileSize act_pos;
01896                         gnome_vfs_tell(data->xdxf, &act_pos);
01897                         gdouble progress = ((gdouble)act_pos)/
01898                                                            ((gdouble)file_size);
01899                         if((((progress - last_prog)/
01900                             (data->cb_progress_word_list_seed)) > 1.0) ||
01901                             (progress >= 1.0)) {
01902                                 data->cb_progress_word_list(
01903                                                progress,
01904                                                data->cb_progress_word_list_data,
01905                                                ENGINE_NO_ERROR
01906                                                            );
01907                                 last_prog = progress;
01908                         };
01909                 }
01910                 if(bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) {
01911                         break;
01912                 }
01913                 if((search_data.cont) == FALSE) {
01914                         g_debug("%s->%s() We found every words matching "
01915                                 "pattern \"%s\". Abort further searching.\n",
01916                                 __FILE__,
01917                                 __FUNCTION__,
01918                                 pattern
01919                                );
01920                         break;
01921                 }
01922         }
01923          
01924         
01925         
01926         
01927         XML_ParserFree(parser);
01928         
01929         timer(TIMER_STOP,(gchar*)__FUNCTION__);
01930         timer(TIMER_START,"callback for returning words list START");
01931         data->cb_search_word_list(result,
01932                                   pattern,
01933                                   data->cb_search_word_list_data,
01934                                   ENGINE_NO_ERROR
01935                                  );
01936         timer(TIMER_STOP,"callback for returning words list END");        
01937 }
01938 //------------------------------------------------------------------------------
01939 void bm_engine_search_word_list(Engine* engine, gchar* pattern)
01940 {
01941         g_debug("%s->%s() called. Searching words list\n"
01942                 "-->PARAM:engine at adress=%p\n"
01943                 "-->PARAM:pattern=\"%s\"\n",
01944                 __FILE__,
01945                 __FUNCTION__,
01946                 engine,
01947                 pattern
01948                );
01949         g_assert(engine != NULL);
01950         g_assert(pattern != NULL);
01951 
01952         timer(TIMER_START,(gchar*)__FUNCTION__);
01953         XDXFData* data = (XDXFData*)(engine->engine_data);
01954         if(data->cb_search_word_list == NULL) {
01955                 g_warning("%s->%s() callback for Word List not set. "
01956                           "Searching aborted.\n",
01957                           __FILE__,
01958                           __FUNCTION__
01959                          );
01960                 timer(TIMER_STOP,(gchar*)__FUNCTION__);
01961                 return;
01962         };
01963         
01964         
01965         GArray* result = g_array_new(TRUE,FALSE,sizeof(gchar*));
01966         // dictionary is optimized so search in cache file
01967         if(data->cache != NULL) {        
01968                 word_list_cache(data, pattern, result);
01969         }
01970         // dictionary is not optimized so search directly fom XDXF file
01971         else {          
01972                 word_list_xdxf(data, pattern, result);
01973         };
01974         
01975         if(data->auto_free == TRUE)  {
01976                 g_debug("%s->%s() deleting all dynamic data because "
01977                         "AUTO_FREE=TRUE\n",
01978                         __FILE__,
01979                         __FUNCTION__
01980                        );
01981                 gchar* tmp;
01982                 guint i = 0;
01983                 while((tmp = g_array_index(result, gchar*, i)) != NULL) 
01984                 {
01985                         g_free(tmp); tmp = NULL;
01986                         i++;
01987                 }
01988                 g_array_free(result, TRUE);
01989         };
01990         g_debug("%s->%s() finished definately its work.\n",
01991                 __FILE__,
01992                 __FUNCTION__
01993                );
01994         return;
01995 }

Generated on Wed Jan 2 09:19:42 2008 for WhiteStork Project by  doxygen 1.5.1