00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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
00180
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
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
00200
00201
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(
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;
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
00256 FilePart translation = {tmp_offset,0};
00257 return translation;
00258 }
00259
00260
00261
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
00274 timer(TIMER_START, (gchar*)__FUNCTION__);
00275 XDXFData* data = (XDXFData*)(engine->engine_data);
00276
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
00285 return;
00286 };
00287
00288
00289 gchar* trans;
00290
00291
00292 if(data->cache != NULL) {
00293 trans = word_translation_cache(data, word);
00294
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
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
00351
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
00359
00360
00361 while(TRUE)
00362 {
00363 g_debug(":Working around in writing the tail:");
00364
00365 gnome_vfs_read(data->xdxf,
00366 read_buffer,
00367 read_size,
00368 &read_bytes_size);
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
00379
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
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,
00393 read_buffer,
00394 read_size,
00395 &read_bytes_size);
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
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
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
00446 FilePart position_part = get_adding_position(data, word);
00447 GnomeVFSFileSize position =
00448 position_part.offset;
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
00456 while(TRUE)
00457 {
00458 g_debug(":Working around in writing the tail:");
00459
00460 vfs_result = gnome_vfs_read(data->xdxf,
00461 read_buffer,
00462 read_size,
00463 &read_bytes_size);
00464 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00465
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
00472 if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break;
00473 }
00474
00475
00476
00477
00478 gchar* buffer = NULL;
00479
00480 gchar* search_pattern = g_strconcat("<k>", word, "</k>", NULL);
00481
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,
00486 read_word,
00487 position_part.length,
00488 &read_bytes_size);
00489 gchar* cmp_result = g_strrstr(read_word ,
00490 search_pattern);
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
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
00526
00527 while(TRUE)
00528 {
00529
00530
00531 vfs_result = gnome_vfs_read(swap_xdxf,
00532 read_buffer,
00533 read_size,
00534 &read_bytes_size);
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
00541 g_debug("%s", gnome_vfs_result_to_string(vfs_result));
00542
00543 if (read_bytes_size < DICT_CACHEING_BUFF_SIZE) break;
00544 }
00545
00546
00547 gnome_vfs_close(swap_xdxf);
00548 gnome_vfs_unlink("/media/mmc1/swap_xdxf.xdxf");
00549
00550
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
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
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
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
00945
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
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
01061 g_strstrip(arg);
01062
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
01069 if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) {
01070
01071 if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) {
01072 g_free(arg);
01073 new = NULL;
01074 }
01075
01076 else
01077 {
01078 new = g_path_get_dirname (arg);
01079 g_free(arg);
01080 }
01081 }
01082
01083 else {
01084
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
01094 if (!g_file_test(new, G_FILE_TEST_IS_DIR)) {
01095
01096 g_free(new);
01097 new = NULL;
01098 };
01099
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
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
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
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
01404
01405
01406
01407
01408
01409
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
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
01673 loc_data->last_word_length = 0;
01674
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
01697 static void word_list_cache(XDXFData* data, gchar* pattern, GArray* result) {
01698 gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);
01699
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')
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
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
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
01864
01865
01866
01867
01868
01869
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
01967 if(data->cache != NULL) {
01968 word_list_cache(data, pattern, result);
01969 }
01970
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 }