00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include <engine_xdxf.h>
00028
00029
00035 static gchar* word_translation_cache(XDXFData* data, gchar* word)
00036 {
00037 gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);
00038 gchar b[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE + 1];
00039 GnomeVFSFileSize bytes_readed;
00040
00041 guint word_length = strlen(word);
00042 guint record_length = 0;
00043 guint trans_offset = 0;
00044 guint already = 0;
00045 guint64 readed = 0;
00046 gchar* buffer = NULL;
00047 gchar* trans = NULL;
00048 guint file_size = get_file_size(data->cache);
00049 while(TRUE) {
00050 gnome_vfs_read( data->cache,
00051 b,
00052 DICT_SEARCHING_WORD_TRAN_BUFF_SIZE,
00053 &bytes_readed );
00054 guint max_length = (guint)get_max_length(b,bytes_readed);
00055 readed += max_length;
00056 buffer = b;
00057 already = 0;
00058 gchar* tmp = NULL;
00059 while(already < max_length) {
00060 memcpy(&record_length, buffer, sizeof(guint));
00061 memcpy( &trans_offset,
00062 buffer+record_length-2*sizeof(guint),
00063 sizeof(guint) );
00064 buffer[record_length-sizeof(guint)*2] = '\0';
00065 tmp = g_utf8_casefold(buffer+sizeof(guint), -1);
00066 if(((record_length - 3*sizeof(guint)) == word_length) &&
00067 (g_utf8_collate(word,tmp) == 0) )
00068 {
00069 FilePart translation = {0,0};
00070 translation.offset = trans_offset;
00071 memcpy( &(translation.length),
00072 buffer + record_length - sizeof(guint),
00073 sizeof(guint) );
00074 trans = read_file_part( &translation,
00075 data->xdxf );
00076 g_free(tmp); tmp = NULL;
00077 break;
00078 };
00079 already += record_length;
00080 buffer += record_length;
00081 g_free(tmp); tmp = NULL;
00082 };
00083
00084 if( ( bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE ) ||
00085 ( readed > (file_size - 3) ))
00086 {
00087 break;
00088 };
00089
00090 gnome_vfs_seek(
00091 data->cache,
00092 GNOME_VFS_SEEK_CURRENT,
00093 ((gint)max_length) -DICT_SEARCHING_WORD_TRAN_BUFF_SIZE );
00094 }
00095 return trans;
00096 }
00097
00103 static gchar* word_translation_xdxf(XDXFData* data, gchar* word)
00104 {
00105 gchar* casefold_word = g_utf8_casefold(word, -1);
00106 guint word_length = strlen(casefold_word);
00107 gchar* trans = NULL;
00108 gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0);
00109 GnomeVFSResult vfs_result;
00110 GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_TRAN_BUFF_SIZE;
00111 gchar buffer[DICT_SEARCHING_WORD_TRAN_BUFF_SIZE+1];
00112 guint64 file_size = get_file_size(data->xdxf);
00113
00114
00115 XML_Parser parser = XML_ParserCreate(NULL);
00116 if (!parser) {
00117 g_warning("XDXF/%s->%s() Could not open initialize "
00118 "XML parser.\n",
00119 __FILE__,
00120 __FUNCTION__ );
00121
00122 return NULL;
00123 };
00124
00125 gchar tmp[DICT_MAX_WORD_LENGTH];
00126 XDXFWordsTransData search_data = {
00127 tmp,
00128 casefold_word,
00129 word_length,
00130 0,
00131 NULL,
00132 FALSE,
00133 TRUE,
00134 0,
00135 &parser,
00136 FALSE,
00137 data->xdxf
00138 };
00139 XML_SetElementHandler( parser,
00140 search_word_trans_start,
00141 search_word_trans_end );
00142 XML_SetCharacterDataHandler(parser, search_word_trans_text);
00143 XML_SetUserData(parser, &search_data);
00144
00145 gdouble last_prog = 0.0;
00146 while(TRUE) {
00147 vfs_result = gnome_vfs_read( data->xdxf,
00148 buffer,
00149 DICT_SEARCHING_WORD_TRAN_BUFF_SIZE,
00150 &bytes_readed );
00151 XML_Parse( parser,
00152 buffer,
00153 bytes_readed,
00154 bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE );
00155
00156 last_prog = 0.0;
00157 if(data->cb_progress_word_trans != NULL) {
00158 GnomeVFSFileSize act_pos;
00159 gnome_vfs_tell(data->xdxf, &act_pos);
00160 gdouble progress =
00161 ((gdouble)act_pos)/((gdouble)file_size);
00162 if((( (progress - last_prog)/
00163 (data->cb_progress_word_trans_seed) ) > 1.0) ||
00164 (progress >= 1.0))
00165 {
00166 data->
00167 cb_progress_word_trans(progress,
00168 data->cb_progress_word_trans_data,
00169 ENGINE_NO_ERROR );
00170 last_prog = progress;
00171 };
00172 }
00173
00174 if(bytes_readed < DICT_SEARCHING_WORD_TRAN_BUFF_SIZE)
00175 {
00176 break;
00177 };
00178 if(search_data.cont == FALSE)
00179 {
00180 break;
00181 };
00182 }
00183 XML_ParserFree(parser);
00184 trans = search_data.translation;
00185 g_free(casefold_word); casefold_word = NULL;
00186 return trans;
00187 }
00188
00190 void xdxf_engine_search_word_translation(Engine* engine,
00191 gchar* word,
00192 gpointer user_data)
00193 {
00194 g_debug( "XDXF/%s->%s() called.\n"
00195 "-->PARAM:engine at adress=%p\n"
00196 "-->PARAM:word=\'%s\'\n",
00197 __FILE__,
00198 __FUNCTION__,
00199 engine,
00200 word );
00201 g_assert(engine != NULL);
00202 g_assert(word != NULL);
00203
00204
00205 XDXFData* data = (XDXFData*)(engine->engine_data);
00206
00207 if(data->cb_search_word_trans == NULL) {
00208 g_warning("XDXF/%s->%s() callback for Word Translation not set."
00209 " Searching aborted.\n",
00210 __FILE__,
00211 __FUNCTION__ );
00212
00213
00214 return;
00215 };
00216
00217
00218 gchar* trans;
00219 gchar* casefold_word = g_utf8_casefold(word, -1);
00220
00221 if(data->cache != NULL) {
00222 trans = word_translation_cache(data, casefold_word);
00223 }
00224 else
00225 {
00226 trans = word_translation_xdxf(data, casefold_word);
00227 };
00228 g_free(casefold_word); casefold_word = NULL;
00229
00230 g_debug("XDXF/%s->%s() found for word \'%s\' translation:\n\'%s\'\n",
00231 __FILE__,
00232 __FUNCTION__,
00233 word,
00234 trans
00235 );
00236
00237
00238
00239
00240 gpointer tmp = user_data;
00241 if (NULL == tmp)
00242 {
00243 tmp = data->cb_search_word_trans_data;
00244 }
00245
00246 data->cb_search_word_trans( trans,
00247 word,
00248 tmp,
00249 ENGINE_NO_ERROR );
00250
00251
00252
00253 if (data->auto_free && (NULL != trans) )
00254 {
00255 g_free(trans);
00256 trans = NULL;
00257 }
00258 return;
00259 }
00260
00262 gboolean xdxf_engine_remove_word(Engine* engine,
00263 gchar* word)
00264 {
00265 g_debug("%s -> %s()", __FILE__, __FUNCTION__);
00266 g_debug("Not implemented yet. And wont be.");
00267 return FALSE;
00268 }
00269
00271 gboolean xdxf_engine_add_word(Engine* engine,
00272 gchar* word,
00273 gchar* translation)
00274 {
00275 g_debug("%s -> %s()", __FILE__, __FUNCTION__);
00276 g_debug("Not implemented yet. And wont be.");
00277 return FALSE;
00278 }
00279
00280 static void search_word_trans_start(void *data,
00281 const char *el,
00282 const char **attr )
00283 {
00284 XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data;
00285 if( (NULL != loc_data->translation) || !(loc_data->cont) )
00286 {
00287 return;
00288 };
00289
00290 if( ('k' == el[0]) && ('\0' == el[1]) )
00291 {
00292
00293 loc_data->one_word = 1;
00294 loc_data->last_word_length = 0;
00295 loc_data->last_word[0] = '\0';
00296 }
00297 else if( ('a' == el[0]) && ('r' == el[1]) && ('\0' == el[2]) )
00298 {
00299
00300 loc_data->last_start =
00301 XML_GetCurrentByteIndex(*(loc_data->parser));
00302 }
00303 }
00304
00305 static void search_word_trans_end(void *data, const char *el)
00306 {
00307 XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data;
00308 if( (NULL != loc_data->translation) || (FALSE == loc_data->cont) )
00309 {
00310 return;
00311 };
00312
00313 if( ('k' == el[0]) && ('\0' == el[1]) )
00314 {
00315
00316 loc_data->one_word = 0;
00317 gchar* tmp = g_utf8_casefold(loc_data->last_word, -1);
00318 gint com = g_utf8_collate(tmp, loc_data->word);
00319 g_free(tmp); tmp = NULL;
00320 if(com != 0)
00321 {
00322
00323
00324
00325 return;
00326 }
00327 else if( (loc_data->last_word_length == loc_data->word_len) &&
00328 (0 == com) )
00329 {
00330 loc_data->found = TRUE;
00331 };
00332
00333
00334 loc_data->last_word_length = 0;
00335 }
00336 else if( (TRUE == loc_data->found) && (0 == g_utf8_collate(el,"ar")) )
00337 {
00338 loc_data->found = FALSE;
00339 loc_data->cont = FALSE;
00340 gulong last_stop =
00341 (gulong)XML_GetCurrentByteIndex(*(loc_data->parser));
00342 last_stop += strlen("</ar>");
00343 FilePart fp = { loc_data->last_start,
00344 (last_stop - (loc_data->last_start)) };
00345 loc_data->translation = read_file_part(&fp, loc_data->xdxf);
00346 }
00347 }
00348
00349 static void search_word_trans_text(void *data, const XML_Char *txt, int len)
00350 {
00351 XDXFWordsTransData* loc_data = (XDXFWordsTransData*)data;
00352 if( (NULL != loc_data->translation ) || (FALSE == loc_data->cont) )
00353 {
00354
00355 return;
00356 };
00357
00358 if(1 == loc_data->one_word)
00359 {
00360 memcpy( &(loc_data->last_word[loc_data->last_word_length]),
00361 (gchar*)txt,
00362 len );
00363 loc_data->last_word_length += (guint)len;
00364 loc_data->last_word[loc_data->last_word_length] = '\0';
00365 };
00366 }
00367
00373 void xdxf_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed)
00374 {
00375 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
00376 XDXFData* data = (XDXFData*)(engine->engine_data);
00377 if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0)
00378 {
00379 data->cb_progress_caching_seed = seed;
00380 g_debug( "XDXF/%s->%s() sets new seed=%0.2f for for signal "
00381 "\"%s\".\n",
00382 __FILE__,
00383 __FUNCTION__,
00384 seed,
00385 signal );
00386 }
00387 else
00388 {
00389 g_warning("XDXF/%s->%s() unsupported signal "
00390 "for progress: %s.\n",
00391 __FILE__,
00392 __FUNCTION__,
00393 signal );
00394 };
00395 }
00396
00404 gpointer xdxf_engine_set_callbacks(Engine* engine,
00405 gchar* signal,
00406 gpointer c_handler,
00407 gpointer user_data)
00408 {
00409 g_debug("XDXF/%s->%s() called.\n", __FILE__, __FUNCTION__);
00410 g_assert(engine != NULL);
00411 g_assert(signal != NULL);
00412 g_assert(c_handler != NULL);
00413 XDXFData* data = (XDXFData*)(engine->engine_data);
00414
00415 if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) {
00416 gpointer result = data->cb_progress_caching;
00417 data->cb_progress_caching = c_handler;
00418 data->cb_progress_caching_data = user_data;
00419 g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n",
00420 __FILE__,
00421 __FUNCTION__,
00422 signal );
00423 g_debug("XDXF/%s->%s() Function at adress = %d.\n",
00424 __FILE__,
00425 __FUNCTION__,
00426 (guint)c_handler );
00427 g_debug("XDXF/%s->%s() Data at adress = %d.\n",
00428 __FILE__,
00429 __FUNCTION__,
00430 (guint)user_data );
00431 return result;
00432 }
00433 else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0)
00434 {
00435 gpointer result = data->cb_search_word_list;
00436 data->cb_search_word_list = c_handler;
00437 data->cb_search_word_list_data = user_data;
00438 g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n",
00439 __FILE__,
00440 __FUNCTION__,
00441 signal );
00442 g_debug("XDXF/%s->%s() Function at adress = %d.\n",
00443 __FILE__,
00444 __FUNCTION__,
00445 (guint)c_handler );
00446 g_debug("XDXF/%s->%s() Data at adress = %d.\n",
00447 __FILE__,
00448 __FUNCTION__,
00449 (guint)user_data );
00450 return result;
00451 }
00452 else if(g_ascii_strcasecmp(signal, ENGINE_WORD_TRANSLATION_SIGNAL) == 0)
00453 {
00454 gpointer result = data->cb_search_word_trans;
00455 data->cb_search_word_trans = c_handler;
00456 data->cb_search_word_trans_data = user_data;
00457 g_debug("XDXF/%s->%s() sets handler for signal \"%s\".\n",
00458 __FILE__,
00459 __FUNCTION__,
00460 signal );
00461 g_debug("XDXF/%s->%s() Function at adress = %d.\n",
00462 __FILE__,
00463 __FUNCTION__,
00464 (guint)c_handler );
00465 g_debug("XDXF/%s->%s() Data at adress = %d.\n",
00466 __FILE__,
00467 __FUNCTION__,
00468 (guint)user_data );
00469 return result;
00470 }
00471 else {
00472 g_warning("XDXF/%s->%s() unsupported signal: %s.\n",
00473 __FILE__,
00474 __FUNCTION__,
00475 signal );
00476 return NULL;
00477 }
00478 }
00479
00483 void xdxf_engine_close(Engine* engine)
00484 {
00485 g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n",
00486 __FILE__,
00487 __FUNCTION__,
00488 engine );
00489
00490 if(engine == NULL)
00491 {
00492 g_warning("XDXF/%s->%s() Trying delete not existed engine.\n",
00493 __FILE__,
00494 __FUNCTION__ );
00495 return;
00496 }
00497
00498 XDXFData* data = (XDXFData*)(engine->engine_data);
00499 if(data->cache != NULL)
00500 {
00501 gnome_vfs_close(data->cache);
00502 };
00503 if(data->xdxf != NULL)
00504 {
00505 gnome_vfs_close(data->xdxf);
00506 };
00507
00508 g_free(data->dict_path);
00509 g_free(data);
00510 g_free(engine);
00511
00512 g_debug("XDXF/%s->%s() engine at adress=%p is deleted.\n",
00513 __FILE__,
00514 __FUNCTION__,
00515 engine );
00516 }
00517
00521 gchar* xdxf_engine_error_message(EngineStatus error)
00522 {
00523 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
00524 return "Error - not yet implemented.";
00525 }
00526
00534 Engine* xdxf_engine_create( gchar* location,
00535 EngineOptimizationFlag auto_cache,
00536 cb_progress progress_handler,
00537 gpointer progress_data,
00538 gdouble seed)
00539 {
00540 g_debug("XDXF/%s->%s() called.\n"
00541 "-->PARAM:location=\'%s\'\n"
00542 "-->PARAM:auto_cache=%d\n",
00543 __FILE__,
00544 __FUNCTION__,
00545 location,
00546 (guint)auto_cache );
00547
00548
00549 GnomeVFSResult open_result;
00550
00551 if(!gnome_vfs_initialized ()) {
00552 gnome_vfs_init ();
00553 };
00554
00555 gchar* tmp = g_strdup(location);
00556 string_to_path(&tmp);
00557
00558 Engine* result = (Engine*)g_try_malloc(sizeof(Engine));
00559 result->engine_location = xdxf_engine_location;
00560 result->engine_is_optimized = xdxf_engine_is_optimized;
00561 result->engine_optimize = xdxf_engine_optimize;
00562 result->engine_search_word_list = xdxf_engine_search_word_list;
00563 result->engine_search_word_translation =
00564 xdxf_engine_search_word_translation;
00565
00566 result->engine_close = xdxf_engine_close;
00567 result->engine_status = xdxf_engine_error;
00568 result->engine_status_message = xdxf_engine_error_message;
00569 result->engine_set_callback = xdxf_engine_set_callbacks;
00570 result->engine_set_progress_seed = xdxf_engine_set_progress_seed;
00571 result->engine_set_auto_free = xdxf_engine_set_auto_free;
00572
00573 result->engine_add_word = xdxf_engine_add_word;
00574 result->engine_remove_word = xdxf_engine_remove_word;
00575
00576 XDXFData* data = (XDXFData*)g_try_malloc(sizeof(XDXFData));
00577 result->engine_data = (gpointer)data;
00578
00579 g_debug("XDXF/%s->%s() opening file...\'%s\'.\n",
00580 __FILE__,
00581 __FUNCTION__,
00582 location );
00583 gchar* tmp2 = g_strconcat(tmp,"/dict.xdxf",NULL);
00584 open_result =
00585 gnome_vfs_open (&(data->xdxf), tmp2, GNOME_VFS_OPEN_READ);
00586 g_free(tmp2); tmp2 = NULL;
00587
00588 if(open_result != GNOME_VFS_OK)
00589 {
00590 g_warning("XDXF/%s->%s() opening dictionary file failed"
00591 " due to reason: %s.\n",
00592 __FILE__,
00593 __FUNCTION__,
00594 gnome_vfs_result_to_string(open_result) );
00595 result->engine_data = NULL;
00596 g_free(data);
00597 g_free(result);
00598 result = NULL;
00599 }
00600 else
00601 {
00602 g_debug("XDXF/%s->%s() opening dictionary file successed.\n",
00603 __FILE__,
00604 __FUNCTION__ );
00605
00606 data->dict_path = g_strdup(tmp);
00607 data->cache = NULL;
00608 data->cb_progress_caching = progress_handler;
00609 data->cb_progress_caching_data = progress_data;
00610 data->cb_progress_caching_seed = seed;
00611 data->cb_progress_word_list = NULL;
00612 data->cb_progress_word_list_data = NULL;
00613 data->cb_progress_word_list_seed = 0.01;
00614 data->cb_progress_word_trans = NULL;
00615 data->cb_progress_word_trans_data = NULL;
00616 data->cb_progress_word_trans_seed = 0.01;
00617
00618 data->cb_search_word_list = NULL;
00619 data->cb_search_word_list_data = NULL;
00620
00621 data->cb_search_word_trans = NULL;
00622 data->cb_search_word_trans_data = NULL;
00623
00624 data->auto_free = FALSE;
00625 if(auto_cache != ENGINE_NO)
00626 {
00627 if(auto_cache == ENGINE_REFRESH)
00628 {
00629 xdxf_engine_optimize(result);
00630 }
00631 else if(auto_cache == ENGINE_CREATE)
00632 {
00633 gchar* cache_path = g_strconcat(data->dict_path,
00634 "/dict.cache",
00635 NULL );
00636 open_result =
00637 gnome_vfs_open( &(data->cache),
00638 cache_path,
00639 GNOME_VFS_OPEN_READ );
00640 if(open_result != GNOME_VFS_OK) {
00641 xdxf_engine_optimize(result);
00642 };
00643 g_free(cache_path);
00644 cache_path = NULL;
00645 }
00646 };
00647 }
00648 g_free(tmp); tmp = NULL;
00649
00650
00651 g_debug("XDXF/%s->%s() returned Engine at adress=%p\n",
00652 __FILE__,
00653 __FUNCTION__,
00654 result );
00655 return result;
00656 }
00657
00661 EngineModule engine_global_functions()
00662 {
00663 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
00664
00665 EngineModule result;
00666 result.engine_check = xdxf_engine_check;
00667 result.engine_description = xdxf_engine_description;
00668 result.engine_format = xdxf_engine_format;
00669 result.engine_version = xdxf_engine_version;
00670 result.engine_create = xdxf_engine_create;
00671
00672 g_debug("XDXF/%s->%s() returned EngineModule at adress=%p.\n",
00673 __FILE__,
00674 __FUNCTION__,
00675 &result );
00676 return result;
00677 }
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00750 static gchar* read_file_part(FilePart* part, GnomeVFSHandle* file)
00751 {
00752 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
00753
00754 gchar* result = NULL;
00755 GnomeVFSResult f_result;
00756 GnomeVFSFileSize bytes_read;
00757
00758 f_result = gnome_vfs_seek(file, GNOME_VFS_SEEK_START, part->offset);
00759 if(f_result != GNOME_VFS_OK)
00760 {
00761 g_warning("XDXF/%s->%s() failed. Not possible to seek "
00762 "through file!\n",
00763 __FILE__,
00764 __FUNCTION__ );
00765
00766 return result;
00767 };
00768
00769 result = g_try_malloc((part->length + 1) * sizeof(gchar));
00770 if(result == NULL) {
00771 g_warning("XDXF/%s->%s() failed. Not possible to allocate "
00772 "so big memmory chunk!\n",
00773 __FILE__,
00774 __FUNCTION__ );
00775
00776 return result;
00777 };
00778
00779 f_result = gnome_vfs_read (file, result, part->length, &bytes_read);
00780 if((f_result != GNOME_VFS_OK) ||
00781 (((gulong)bytes_read) != part->length)) {
00782 g_debug("XDXF/%s->%s() failed. Not possible to read from "
00783 "file!\n",
00784 __FILE__,
00785 __FUNCTION__ );
00786
00787 g_free(result); result = NULL;
00788 return result;
00789 };
00790 result[part->length] = '\0';
00791
00792 g_debug("XDXF/%s->%s() returned string=\n\'%s\'.\n",
00793 __FILE__,
00794 __FUNCTION__,
00795 result );
00796
00797
00798 return result;
00799 }
00800
00816 static gchar* string_to_path(gchar** string) {
00817 g_debug("XDXF/%s->%s() called.\n"
00818 "-->PARAM:string=\'%s\'\n",
00819 __FILE__,
00820 __FUNCTION__,
00821 string[0] );
00822 gchar* arg = string[0];
00823 gchar* new = NULL;
00824
00825
00826 g_strstrip(arg);
00827
00828
00829 if (!g_path_is_absolute(arg))
00830 {
00831 gchar* tmp = g_get_current_dir();
00832 new = g_strconcat(tmp,"/",arg,NULL);
00833 g_free(arg); arg = new; new = NULL;
00834 };
00835
00836
00837 if (!g_file_test(arg, G_FILE_TEST_IS_DIR))
00838 {
00839
00840 if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR))
00841 {
00842 g_free(arg);
00843 new = NULL;
00844 }
00845 else
00846 {
00847
00848 new = g_path_get_dirname (arg);
00849 g_free(arg);
00850 }
00851 }
00852 else
00853 {
00854
00855
00856 if (g_str_has_suffix(arg,"/") )
00857 {
00858 new = g_path_get_dirname (arg);
00859 g_free(arg);
00860 }
00861 else
00862 {
00863 new = arg;
00864 }
00865 };
00866
00867
00868 if (!g_file_test(new, G_FILE_TEST_IS_DIR))
00869 {
00870
00871
00872 g_free(new);
00873 new = NULL;
00874 };
00875
00876
00877 string[0] = new;
00878 g_debug("XDXF/%s->%s() returned string=\'%s\'\n",
00879 __FILE__,
00880 __FUNCTION__,
00881 string[0] );
00882 return new;
00883 }
00884
00889 static gboolean is_xdxf_file(gchar* file) {
00890 g_debug("XDXF/%s->%s() called.\n"
00891 "-->PARAM:file=\'%s\'\n",
00892 __FILE__,
00893 __FUNCTION__,
00894 file );
00895
00896 gboolean result = TRUE;
00897 GnomeVFSHandle* fd = NULL;
00898 GnomeVFSResult file_result;
00899 GnomeVFSFileSize bytes_read;
00900
00901 if(!gnome_vfs_initialized ())
00902 {
00903 gnome_vfs_init ();
00904 };
00905
00906 file_result = gnome_vfs_open (&fd, file, GNOME_VFS_OPEN_READ);
00907 if(file_result != GNOME_VFS_OK)
00908 {
00909 g_warning("XDXF/%s->%s() Could not open the file.\n",
00910 __FILE__,
00911 __FUNCTION__ );
00912 return FALSE;
00913 };
00914
00915 XML_Parser p = XML_ParserCreate(NULL);
00916 if (!p)
00917 {
00918 g_warning("XDXF/%s->%s() Could not open initialize "
00919 "XML parser.\n",
00920 __FILE__,
00921 __FUNCTION__ );
00922 gnome_vfs_close(fd);
00923 return FALSE;
00924 };
00925
00926 XML_SetElementHandler(p, is_xdxf_file_start, is_xdxf_file_end);
00927 XDXFCheckingData user_data = {TRUE, FALSE, 0};
00928 XML_SetUserData(p, &user_data);
00929 gchar buffer[DICT_CACHEING_BUFF_SIZE];
00930
00931 guint loop_count = 0;
00932 while(TRUE)
00933 {
00934 file_result = gnome_vfs_read( fd,
00935 buffer,
00936 DICT_CACHEING_BUFF_SIZE,
00937 &bytes_read );
00938 if (file_result != GNOME_VFS_OK)
00939 {
00940 result = FALSE;
00941 g_warning("XDXF/%s->%s() Could not read enought from"
00942 " file.\n",
00943 __FILE__,
00944 __FUNCTION__ );
00945 break;
00946 };
00947 if (! XML_Parse( p,
00948 buffer,
00949 (gulong)bytes_read,
00950 ((gulong)bytes_read) < DICT_CACHEING_BUFF_SIZE
00951 ))
00952 {
00953 result = FALSE;
00954 g_warning("XDXF/%s->%s() Could not parse file.\n",
00955 __FILE__,
00956 __FUNCTION__ );
00957 break;
00958 };
00959 if (user_data.further == FALSE)
00960 {
00961 result = user_data.good;
00962 g_debug("XDXF/%s->%s() statement: location is "
00963 "compatible with this module, is %s\n",
00964 __FILE__,
00965 __FUNCTION__,
00966 PRINT_STATE(result) );
00967 break;
00968 };
00969 if (loop_count > 1)
00970 {
00971 result = FALSE;
00972 g_debug("XDXF/%s->%s() Wrong file format.\n",
00973 __FILE__,
00974 __FUNCTION__ );
00975 break;
00976 };
00977 loop_count++;
00978 }
00979
00980 gnome_vfs_close(fd);
00981 XML_ParserFree(p);
00982 g_debug("XDXF/%s->%s() returned bool statement=%s.\n",
00983 __FILE__,
00984 __FUNCTION__,
00985 PRINT_STATE(result));
00986 return result;
00987 }
00988
00989 static void is_xdxf_file_start(void *data, const char *el, const char **attr)
00990 {
00991 XDXFCheckingData* user_data = (XDXFCheckingData*)data;
00992 if (user_data->deep == 0) {
00993 if (g_utf8_collate (el,"xdxf") != 0) {
00994 user_data->good = FALSE;
00995 }
00996 else {
00997 user_data->good = TRUE;
00998 }
00999 user_data->further = FALSE;
01000 }
01001 user_data->deep++;
01002 }
01003 static void is_xdxf_file_end(void *data, const char *el)
01004 { }
01005
01010 EngineStatus xdxf_engine_error(Engine* engine)
01011 {
01012 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
01013 XDXFData* data = (XDXFData*)(engine->engine_data);
01014 g_debug("XDXF/%s->%s() returned error code: %d\n",
01015 __FILE__,
01016 __FUNCTION__,
01017 (gint)(data->last_error) );
01018 return data->last_error;
01019 }
01020
01021 static void caching_expat_start(void *data, const char *el, const char **attr) {
01022 XDXFCacheData* loc_data = (XDXFCacheData*)data;
01023 if(g_utf8_collate(el,"ar") == 0)
01024 {
01025 loc_data->last_start =
01026 XML_GetCurrentByteIndex(loc_data->parser);
01027 }
01028 else if(g_utf8_collate(el,"k") == 0)
01029 {
01030 loc_data->state = 1;
01031 }
01032 }
01033
01034 static void caching_expat_end(void *data, const char *el) {
01035 XDXFCacheData* loc_data = (XDXFCacheData*)data;
01036 loc_data->last_stop = XML_GetCurrentByteIndex(loc_data->parser);
01037
01038 static guint record_length;
01039 static guint start;
01040 static guint length;
01041 static guint buffer_length;
01042
01043 if((g_utf8_collate("k",el) == 0) &&
01044 (loc_data->state == 1))
01045 {
01046 loc_data->state = 2;
01047 }
01048 else if((g_utf8_collate("ar",el) == 0) &&
01049 (loc_data->state == 2))
01050 {
01051 buffer_length = loc_data->buffer_length;
01052 record_length = sizeof(guint)*3 + loc_data->buffer_length;
01053 start = loc_data->last_start;
01054 length = loc_data->last_stop + strlen("</ar>") -
01055 loc_data->last_start;
01056
01057 gboolean error_writting = FALSE;
01058 GnomeVFSFileSize bytes_written;
01059 GnomeVFSResult vfs_result;
01060
01061 vfs_result = gnome_vfs_write(loc_data->cache,
01062 &record_length,
01063 sizeof(guint),
01064 &bytes_written );
01065 if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01066
01067 vfs_result = gnome_vfs_write(loc_data->cache,
01068 loc_data->buffer,
01069 loc_data->buffer_length,
01070 &bytes_written );
01071 if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01072
01073 vfs_result = gnome_vfs_write(loc_data->cache,
01074 &start,
01075 sizeof(guint),
01076 &bytes_written );
01077 if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01078
01079 vfs_result = gnome_vfs_write(loc_data->cache,
01080 &length,
01081 sizeof(guint),
01082 &bytes_written );
01083 if(vfs_result != GNOME_VFS_OK) error_writting = TRUE;
01084
01085 loc_data->buffer[0] = '\0';
01086 loc_data->buffer_length = 0;
01087 loc_data->state = 0;
01088 };
01089 }
01090
01091 static void caching_expat_text(void *data, const XML_Char *txt, int len) {
01092 XDXFCacheData* loc_data = (XDXFCacheData*)data;
01093
01094 if(loc_data->state == 1)
01095 {
01096 memcpy( &(loc_data->buffer[loc_data->buffer_length]),
01097 (gchar*)txt,
01098 len );
01099 loc_data->buffer_length += (long)len;
01100 loc_data->buffer[loc_data->buffer_length] = '\0';
01101 };
01102 }
01103
01108 static guint64 get_file_size(GnomeVFSHandle* file)
01109 {
01110 guint64 result = 0;
01111 guint64 old_pos = 0;
01112 gnome_vfs_tell(file, &old_pos);
01113
01114 if( gnome_vfs_seek(file, GNOME_VFS_SEEK_END, 0) != GNOME_VFS_OK)
01115 {
01116 return 0;
01117 }
01118
01119 if( gnome_vfs_tell(file, &result) != GNOME_VFS_OK)
01120 {
01121 result = 0;
01122 }
01123
01124 gnome_vfs_seek(file, GNOME_VFS_SEEK_START, old_pos);
01125 return result;
01126 }
01127
01131 void xdxf_engine_optimize(Engine* engine)
01132 {
01133 g_debug("XDXF/%s->%s() called for engine at adress=%p\n",
01134 __FILE__,
01135 __FUNCTION__,
01136 engine );
01137
01138
01139 GnomeVFSResult vfs_result;
01140 XDXFData* data = (XDXFData*)(engine->engine_data);
01141 gchar* cache_path = g_strconcat(data->dict_path,"/dict.cache",NULL);
01142 vfs_result = gnome_vfs_create(&(data->cache),
01143 cache_path,
01144 GNOME_VFS_OPEN_WRITE,
01145 FALSE,
01146 0666 );
01147
01148 if(vfs_result != GNOME_VFS_OK)
01149 {
01150 data->cache = NULL;
01151 g_warning("XDXF/%s->%s().Could not create new "
01152 "cache file: %s.\n",
01153 __FILE__,
01154 __FUNCTION__,
01155 cache_path );
01156 }
01157 else
01158 {
01159 XDXFCacheData* c_data =
01160 (XDXFCacheData*)g_try_malloc(sizeof(XDXFCacheData));
01161 c_data->parser = XML_ParserCreate(NULL);
01162 c_data->cache = data->cache;
01163 c_data->buffer =
01164 (gchar*)g_try_malloc(sizeof(gchar)*DICT_CACHEING_BUFF_SIZE);
01165 c_data->buffer_length = 0;
01166 c_data->last_start = 0;
01167 c_data->last_stop = 0;
01168 c_data->last_length = 0;
01169
01170 guint64 file_size = get_file_size(data->xdxf);
01171
01172 XML_SetUserData(c_data->parser, (gpointer)c_data);
01173 XML_SetElementHandler(c_data->parser,
01174 caching_expat_start,
01175 caching_expat_end );
01176 XML_SetCharacterDataHandler(c_data->parser, caching_expat_text);
01177
01178 GnomeVFSFileSize bytes_readed = DICT_CACHEING_BUFF_SIZE;
01179 gchar b[DICT_CACHEING_BUFF_SIZE + 1];
01180 gdouble last_prog = 0;
01181 while(TRUE)
01182 {
01183 vfs_result = gnome_vfs_read( data->xdxf,
01184 b,
01185 DICT_CACHEING_BUFF_SIZE,
01186 &bytes_readed );
01187 XML_Parse(c_data->parser,
01188 b,
01189 bytes_readed,
01190 bytes_readed < DICT_CACHEING_BUFF_SIZE );
01191
01192 if(data->cb_progress_caching != NULL)
01193 {
01194 GnomeVFSFileSize act_pos;
01195 gnome_vfs_tell(data->xdxf, &act_pos);
01196 gdouble progress = ((gdouble)act_pos)/
01197 ((gdouble)file_size);
01198 if((( (progress - last_prog) /
01199 (data->cb_progress_caching_seed) ) > 1.0) ||
01200 (progress >= 1.0))
01201 {
01202 data->cb_progress_caching(
01203 progress,
01204 data->cb_progress_caching_data,
01205 ENGINE_NO_ERROR );
01206 last_prog = progress;
01207 };
01208 }
01209 if(bytes_readed < DICT_CACHEING_BUFF_SIZE)
01210 {
01211 break;
01212 }
01213 }
01214
01215 g_free(c_data->buffer);
01216 g_free(c_data);
01217 }
01218
01219 vfs_result = gnome_vfs_close(data->cache);
01220 vfs_result = gnome_vfs_open( &(data->cache),
01221 cache_path,
01222 GNOME_VFS_OPEN_READ );
01223 g_free(cache_path); cache_path = NULL;
01224
01225 g_debug("XDXF/%s->%s()'s work finished.\n",__FILE__,__FUNCTION__);
01226 }
01227
01232 gboolean xdxf_engine_check(gchar* location)
01233 {
01234 g_debug("XDXF/%s->%s() called.\n-->PARAM:location=\'%s\'\n",
01235 __FILE__,
01236 __FUNCTION__,
01237 location );
01238
01239 gboolean result = TRUE;
01240 gchar* filepath = g_strdup(location);
01241 gchar* tmp = NULL;
01242
01243 string_to_path(&filepath);
01244 if (filepath == NULL)
01245 {
01246 result = FALSE;
01247 g_warning("XDXF/%s->%s() location \'%s\' is not a proper "
01248 "path!\n",
01249 __FILE__,
01250 __FUNCTION__,
01251 location
01252 );
01253 }
01254 else
01255 {
01256 tmp = g_strconcat(filepath,"/dict.xdxf",NULL);
01257 g_free(filepath);
01258 filepath = tmp;
01259 tmp = NULL;
01260
01261 g_debug("XDXF/%s->%s() finnal file to check is: %s\n",
01262 __FILE__,
01263 __FUNCTION__,
01264 filepath
01265 );
01266 if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR))
01267 {
01268 g_warning("XDXF/%s->%s() file \'%s\' does not "
01269 "exists!\n",
01270 __FILE__,
01271 __FUNCTION__,
01272 filepath
01273 );
01274 result = FALSE;
01275 };
01276 };
01277 if (result != FALSE) {
01278 result = is_xdxf_file(filepath);
01279 };
01280
01281 g_free(filepath);
01282
01283 g_debug("XDXF/%s->%s() returned bool statement=%s.\n",
01284 __FILE__,
01285 __FUNCTION__,
01286 PRINT_STATE(result)
01287 );
01288 return result;
01289 }
01290
01296 static guint get_max_length(gchar* a, guint length)
01297 {
01298 gchar* b = a;
01299 guint len = 0;
01300 guint n = 0;
01301 memcpy(&n,b,sizeof(guint));
01302 while((len + n) <= length) {
01303 len += n;
01304 b = b + n;
01305 if(len >= (length-sizeof(guint))) break;
01306 memcpy(&n,b,sizeof(guint));
01307 }
01308 return len;
01309 }
01310
01315 void xdxf_engine_set_auto_free(Engine* engine, gboolean state)
01316 {
01317 g_debug( "XDXF/%s->%s() called.\n"
01318 "-->PARAM:engine at adress=%p\n"
01319 "-->PARAM:state=%s\n",
01320 __FILE__,
01321 __FUNCTION__,
01322 engine,
01323 PRINT_STATE(state) );
01324 g_assert(engine != NULL);
01325 XDXFData* data = (XDXFData*)(engine->engine_data);
01326 data->auto_free = state;
01327 g_debug( "XDXF/%s->%s() Current auto_free is %s\n",
01328 __FILE__,
01329 __FUNCTION__,
01330 PRINT_STATE(data->auto_free) );
01331 }
01332
01336 gchar* xdxf_engine_version()
01337 {
01338 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
01339 gchar* result = g_strdup(DIC_ENG_VERSION);
01340 g_debug( "XDXF/%s->%s() return string=%s\n",
01341 __FILE__,
01342 __FUNCTION__,
01343 result );
01344 return result;
01345 }
01346
01350 gchar* xdxf_engine_format()
01351 {
01352 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
01353 gchar* result = g_strdup(DIC_ENG_FORMAT);
01354 g_debug("XDXF/%s->%s() return string=%s\n",
01355 __FILE__,
01356 __FUNCTION__,
01357 result
01358 );
01359 return result;
01360 }
01361
01365 gchar* xdxf_engine_description()
01366 {
01367 g_debug("XDXF/%s->%s() called.\n",__FILE__,__FUNCTION__);
01368 gchar* result = g_strdup("This module operates on "
01369 DIC_ENG_FORMAT
01370 " dictionaries. Version "
01371 DIC_ENG_VERSION
01372 "." );
01373 g_debug("XDXF/%s->%s() return string=%s\n",
01374 __FILE__,
01375 __FUNCTION__,
01376 result );
01377 return result;
01378 }
01379
01384 gboolean xdxf_engine_is_optimized(Engine* engine)
01385 {
01386 g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n",
01387 __FILE__,
01388 __FUNCTION__,
01389 engine );
01390
01391 g_assert(engine != NULL);
01392 XDXFData* data = (XDXFData*)(engine->engine_data);
01393 gboolean result = (data->cache != NULL);
01394 g_debug("XDXF/%s->%s() returned bool statement=%s.\n",
01395 __FILE__,
01396 __FUNCTION__,
01397 PRINT_STATE(result) );
01398 return result;
01399 }
01400
01405 gchar* xdxf_engine_location(Engine* engine)
01406 {
01407 g_debug("XDXF/%s->%s() called.\n-->PARAM: engine adress=%p\n",
01408 __FILE__,
01409 __FUNCTION__,
01410 engine );
01411 g_assert(engine != NULL);
01412 XDXFData* data = (XDXFData*)(engine->engine_data);
01413 gchar* result;
01414 if(data->auto_free)
01415 {
01416 result = data->dict_path;
01417 }
01418 else
01419 {
01420 result = g_strdup(data->dict_path);
01421 }
01422
01423 g_debug("XDXF/%s->%s() returned string=%s\n",
01424 __FILE__,
01425 __FUNCTION__,
01426 result );
01427 return result;
01428 }
01429
01430 static void search_word_list_start(void *data,
01431 const char *el,
01432 const char **attr )
01433 {
01434 XDXFWordsListData* loc_data = (XDXFWordsListData*)data;
01435 if( ('k' == el[0]) && ('\0' == el[1]) ) {
01436 loc_data->one_word = 1;
01437 };
01438 }
01439
01440 static void search_word_list_end(void *data, const char *el)
01441 {
01442 static gboolean matched = FALSE;
01443 static gchar* tmp = NULL;
01444
01445 XDXFWordsListData* loc_data = (XDXFWordsListData*)data;
01446 GPatternSpec* regex;
01447 regex = g_pattern_spec_new (loc_data->pattern);
01448
01449 if( ('k' == el[0]) && ('\0' == el[1]) )
01450 {
01451 loc_data->one_word = 0;
01452 }
01453 else
01454 {
01455 return;
01456 }
01457
01458 gchar *tmp1 = g_strconcat (loc_data->last_word, " ", NULL);
01459 tmp = g_utf8_casefold(tmp1, -1);
01460 g_free (tmp1);
01461 tmp1 = g_utf8_casefold(loc_data->last_word, -1);
01462
01463 if (( g_pattern_match_string (regex, tmp) == TRUE ) ||
01464 ( g_pattern_match_string (regex, tmp1) == TRUE ) )
01465 {
01466 matched = TRUE;
01467 gchar* new = g_strdup(loc_data->last_word);
01468 g_array_append_val((loc_data->result), new);
01469 g_debug("New Word for pattern \"%s\" found: %s\n",
01470 loc_data->pattern,
01471 new );
01472 }
01473 else
01474 {
01475 matched = FALSE;
01476 }
01477
01478
01479 loc_data->last_word_length = 0;
01480
01481 if( (loc_data->result->len > 0) && (!matched) )
01482 {
01483 loc_data->cont = FALSE;
01484 };
01485
01486 g_free(tmp); tmp = NULL;
01487 g_free(tmp1);
01488 g_pattern_spec_free (regex);
01489 }
01490
01491 static void search_word_list_text(void *data, const XML_Char *txt, int len)
01492 {
01493 XDXFWordsListData* loc_data = (XDXFWordsListData*)data;
01494
01495 if(1 == loc_data->one_word)
01496 {
01497 memcpy( &(loc_data->last_word[loc_data->last_word_length]),
01498 (gchar*)txt,
01499 len );
01500 loc_data->last_word_length += (guint)len;
01501 loc_data->last_word[loc_data->last_word_length] = '\0';
01502 };
01503 }
01504
01511 static void word_list_cache(XDXFData* data,
01512 gchar* pattern,
01513 GArray* result,
01514 gpointer cb_data)
01515 {
01516 gnome_vfs_seek(data->cache, GNOME_VFS_SEEK_START, 0);
01517
01518 GnomeVFSFileSize bytes_readed;
01519 guint record_length = 0;
01520 gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE];
01521 gchar* buf;
01522 guint already = 0;
01523 guint max_length = 0;
01524 guint64 file_size = get_file_size(data->cache);
01525 gchar* casefold_pattern = g_utf8_casefold(pattern, -1);
01526
01527
01528 GPatternSpec* regex;
01529 regex = g_pattern_spec_new (casefold_pattern);
01530
01531 guint i = 0;
01532 while(TRUE)
01533 {
01534 gnome_vfs_read( data->cache,
01535 buffer,
01536 DICT_SEARCHING_WORD_LIST_BUFF_SIZE,
01537 &bytes_readed );
01538
01539 max_length = get_max_length(buffer, (guint)bytes_readed);
01540 already += max_length;
01541 buf = buffer;
01542
01543 guint how_far = 0;
01544 while(how_far < max_length)
01545 {
01546 ++i;
01547 memcpy(&record_length, buf, sizeof(guint));
01548 buf[record_length-sizeof(guint)*2] = '\0';
01549
01550 gchar *tmp1 = g_strconcat( buf + sizeof(guint),
01551 " ",
01552 NULL );
01553 gchar* tmp = g_utf8_casefold(tmp1, -1);
01554 g_free (tmp1);
01555
01556 if ( g_pattern_match_string (regex, tmp) == TRUE )
01557 {
01558 gchar* new = g_strndup(buf + sizeof(guint),
01559 record_length -
01560 3*sizeof(guint) );
01561 g_array_append_val(result, new);
01562 g_debug("New Word for pattern \"%s\" found: "
01563 "%s (pos:%d)\n",
01564 pattern,
01565 new,
01566 i );
01567 };
01568 how_far += record_length;
01569 buf = buf + record_length;
01570 g_free(tmp); tmp = NULL;
01571 }
01572 if( (bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE) ||
01573 (already > (file_size -3)) )
01574 {
01575 break;
01576 }
01577
01578 gnome_vfs_seek( data->cache,
01579 GNOME_VFS_SEEK_CURRENT,
01580 (gint)max_length -
01581 DICT_SEARCHING_WORD_LIST_BUFF_SIZE );
01582 }
01583
01584
01585
01586 data->cb_search_word_list( result,
01587 pattern,
01588 cb_data,
01589 ENGINE_NO_ERROR );
01590 g_free(casefold_pattern);
01591 casefold_pattern = NULL;
01592
01593 }
01594
01601 static void word_list_xdxf(XDXFData* data,
01602 gchar* pattern,
01603 GArray* result,
01604 gpointer cb_data)
01605 {
01606 gnome_vfs_seek(data->xdxf, GNOME_VFS_SEEK_START, 0);
01607 GnomeVFSResult vfs_result;
01608 GnomeVFSFileSize bytes_readed = DICT_SEARCHING_WORD_LIST_BUFF_SIZE;
01609 gchar buffer[DICT_SEARCHING_WORD_LIST_BUFF_SIZE+1];
01610 guint64 file_size = get_file_size(data->xdxf);
01611 gchar* casefold_pattern = g_utf8_casefold(pattern, -1);
01612 guint pattern_len = strlen(casefold_pattern);
01613
01614
01615 XML_Parser parser = XML_ParserCreate(NULL);
01616 if (!parser)
01617 {
01618 g_warning("XDXF/%s->%s() Could not open initialize XML "
01619 "parser.\n",
01620 __FILE__,
01621 __FUNCTION__
01622 );
01623
01624 return;
01625 };
01626
01627 gchar tmp[DICT_MAX_WORD_LENGTH];
01628 XML_SetElementHandler( parser,
01629 search_word_list_start,
01630 search_word_list_end );
01631 XML_SetCharacterDataHandler(parser, search_word_list_text);
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642 XDXFWordsListData search_data = { tmp,
01643 casefold_pattern,
01644 pattern_len,
01645 0,
01646 result,
01647 0,
01648 TRUE
01649 };
01650 XML_SetUserData(parser, &search_data);
01651
01652 gdouble last_prog = 0;
01653 while(TRUE) {
01654 vfs_result = gnome_vfs_read( data->xdxf,
01655 buffer,
01656 DICT_SEARCHING_WORD_LIST_BUFF_SIZE,
01657 &bytes_readed );
01658 XML_Parse( parser,
01659 buffer,
01660 bytes_readed,
01661 bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE );
01662
01663 if(NULL != data->cb_progress_word_list)
01664 {
01665 GnomeVFSFileSize act_pos;
01666 gnome_vfs_tell(data->xdxf, &act_pos);
01667 gdouble progress = ((gdouble)act_pos)/
01668 ((gdouble)file_size);
01669 if((((progress - last_prog)/
01670 (data->cb_progress_word_list_seed)) > 1.0) ||
01671 (progress >= 1.0))
01672 {
01673 data->cb_progress_word_list(
01674 progress,
01675 data->cb_progress_word_list_data,
01676 ENGINE_NO_ERROR );
01677 last_prog = progress;
01678 };
01679 };
01680
01681 if(bytes_readed < DICT_SEARCHING_WORD_LIST_BUFF_SIZE)
01682 {
01683 break;
01684 };
01685
01686 if(FALSE == search_data.cont)
01687 {
01688 g_debug("XDXF/%s->%s() We found every words matching "
01689 "pattern \"%s\". Abort further searching.\n",
01690 __FILE__,
01691 __FUNCTION__,
01692 pattern
01693 );
01694 break;
01695 };
01696 }
01697 XML_ParserFree(parser);
01698 g_free(casefold_pattern); casefold_pattern = NULL;
01699
01700
01701
01702 data->cb_search_word_list( result,
01703 pattern,
01704 cb_data,
01705 ENGINE_NO_ERROR );
01706
01707 }
01708
01714 void xdxf_engine_search_word_list(Engine* engine,
01715 gchar* pattern,
01716 gpointer user_data)
01717 {
01718 g_debug("XDXF/%s->%s() called. Searching words list\n"
01719 "-->PARAM:engine at adress=%p\n"
01720 "-->PARAM:pattern=\"%s\"\n",
01721 __FILE__,
01722 __FUNCTION__,
01723 engine,
01724 pattern );
01725
01726 g_assert(engine != NULL);
01727 g_assert(pattern != NULL);
01728
01729
01730 XDXFData* data = (XDXFData*)(engine->engine_data);
01731 if(data->cb_search_word_list == NULL)
01732 {
01733 g_warning( "XDXF/%s->%s() callback for Word List not set. "
01734 "Searching aborted.\n",
01735 __FILE__,
01736 __FUNCTION__ );
01737
01738 return;
01739 };
01740
01741 gpointer cb_data = user_data;
01742 if ( NULL == cb_data )
01743 {
01744 cb_data = data->cb_search_word_list_data;
01745 }
01746
01747 GArray* result = g_array_new(TRUE,FALSE,sizeof(gchar*));
01748
01749 if(data->cache != NULL)
01750 {
01751 word_list_cache(data, pattern, result, cb_data);
01752 }
01753 else
01754 {
01755
01756 word_list_xdxf(data, pattern, result, cb_data);
01757 };
01758
01759 guint i = 0;
01760 if (result!=NULL){
01761 for (i = 0; i < result->len; i++)
01762 {
01763 g_free(g_array_index(result, gchar*, i));
01764 }
01765 g_array_free(result, TRUE);
01766 result = NULL;
01767 }
01768
01769 g_debug("XDXF/%s->%s() finished definately its work.\n",
01770 __FILE__,
01771 __FUNCTION__
01772 );
01773 return;
01774 }
01775