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_stardict.h>
00024
00025
00026 #define eg_debug g_debug
00027 #define eg_warning g_warning
00028
00029
00038 static gchar* sd_read_file_part_dz(FilePart* part, gchar* file)
00039 {
00040 eg_debug("-> %s() called.\n",__FUNCTION__);
00041 timer(TIMER_START,(gchar*)__FUNCTION__);
00042 gchar* result = NULL;
00043
00044
00045 dictData* header = NULL;
00046 header = dict_data_open(file , 0 );
00047 result = dict_data_read_(header,part->offset,part->length,NULL,NULL);
00048 dict_data_close(header);
00049
00050 timer(TIMER_STOP,(gchar*)__FUNCTION__);
00051 eg_debug("<- %s() returned string=\n%s.\n",__FUNCTION__,result);
00052 return result;
00053 }
00054
00063 static gchar* sd_read_file_part(FilePart* part, gchar* file)
00064 {
00065 eg_debug("-> %s() called.\n",__FUNCTION__);
00066 timer(TIMER_START,(gchar*)__FUNCTION__);
00067 guint length = part->length;
00068
00069
00070 gint fd = open(file, O_RDONLY);
00071 if(fd == -1)
00072 {
00073 eg_debug("---> Error: could not open *.dict file!\n");
00074 timer(TIMER_STOP,(gchar*)__FUNCTION__);
00075 eg_debug("<- %s() finished with error.\n",
00076 __FUNCTION__);
00077 return NULL;
00078 }
00079
00080
00081 gchar* result = (gchar*)g_try_malloc0(length+1);
00082 gint readed = (gint)read(fd, result, length);
00083 if(readed != part->length)
00084 {
00085 eg_debug("---> Error: could not read *.dict file!\n");
00086 g_free(result);
00087 result = NULL;
00088 }
00089 result[length] = '\0';
00090
00091 timer(TIMER_STOP,(gchar*)__FUNCTION__);
00092 eg_debug("<- %s() returned string=\n%s.\n",__FUNCTION__,result);
00093 return result;
00094 }
00095
00103 FilePart* sd_find_file_part(SDData* data, gchar* word)
00104 {
00105 eg_debug("-> %s() called.\n",__FUNCTION__);
00106 timer(TIMER_START,(gchar*)__FUNCTION__);
00107
00108 FilePart* result = NULL;
00109 data->sd_seek_idx(data->idx_file, 0, _FILES_WRAPPER_BEG);
00110 gchar buffer[WORD_LIST_BUFFER_LENGTH + 1];
00111 gint readed =0;
00112 gint offset = 0;
00113 gchar* tmp = NULL;
00114 guint len = 0;
00115 guint pl = strlen(word);
00116 gboolean further = FALSE;
00117 do
00118 {
00119 readed = data->sd_read_idx(data->idx_file,
00120 buffer + offset,
00121 WORD_LIST_BUFFER_LENGTH - offset
00122 );
00123 if(readed < 0)
00124 {
00125 eg_debug("---> Error while reading file for searching"
00126 " matched FilePart in dictionary to word: %s",
00127 word
00128 );
00129 break;
00130 }
00131 else
00132 {
00133 further = (readed == (WORD_LIST_BUFFER_LENGTH-offset));
00134 }
00135 tmp = buffer;
00136
00137 guint i = 0;
00138 gint min = _MIN(readed, WORD_LIST_BUFFER_LENGTH-270);
00139 while(i<min)
00140 {
00141
00142 if(g_ascii_strncasecmp(tmp,word,pl) == 0 &&
00143 strlen(tmp) == pl)
00144 {
00145
00146 guint val = 0;
00147 result =
00148 (FilePart*)g_try_malloc0(sizeof(FilePart));
00149 len = strlen(tmp)+1;
00150 tmp += len;
00151 memcpy(&val,tmp,sizeof(guint));
00152 result->offset = ntohl(val);
00153 tmp = tmp + sizeof(guint);
00154 memcpy(&val,tmp,sizeof(guint));
00155 result->length = ntohl(val);
00156 further = FALSE;
00157 break;
00158 }
00159
00160 len = strlen(tmp)+1;
00161
00162 tmp += len;
00163
00164 tmp += 2 * sizeof(guint);
00165
00166 i = i + len + 2 * sizeof(guint);
00167 }
00168 if(!further) break;
00169 offset = WORD_LIST_BUFFER_LENGTH - i;
00170 g_memmove(buffer,buffer+WORD_LIST_BUFFER_LENGTH-offset, offset);
00171 }
00172 while(further);
00173
00174 timer(TIMER_STOP,(gchar*)__FUNCTION__);
00175 if(result)
00176 {
00177 eg_debug("<- %s() return: OFFSET=%d LENGTH=%d.\n",
00178 __FUNCTION__,
00179 result->offset,
00180 result->length
00181 );
00182 }
00183 else
00184 {
00185 eg_debug("<- %s() didn't find proper FilePart!\n",__FUNCTION__);
00186 }
00187 return result;
00188 }
00189
00198 void sd_engine_close(Engine* engine)
00199 {
00200 eg_debug("StarDict/%s->%s() called.\n-->PARAM: engine adress=%p\n",
00201 __FILE__,
00202 __FUNCTION__,
00203 engine
00204 );
00205
00206 g_assert(engine != NULL);
00207 SDData* data = (SDData*)(engine->engine_data);
00208
00209 data->sd_close_idx(data->idx_file);
00210 g_free(data->idx_file);
00211 g_free(data->dict_path);
00212 g_free(data->idx_file_name);
00213 g_free(data->ifo_file_name);
00214 g_free(data->dic_file_name);
00215 g_free(data->icon);
00216 g_free(data->lang_from);
00217 g_free(data->lang_to);
00218 g_free(data->title);
00219 g_free(data);
00220 g_free(engine);
00221 eg_debug("StarDict/%s->%s() engine at adress=%p is deleted.\n",
00222 __FILE__,
00223 __FUNCTION__,
00224 engine
00225 );
00226 engine = NULL;
00227 }
00228
00245 Engine* sd_engine_create(gchar* location,
00246 EngineOptimizationFlag auto_cache,
00247 cb_progress progress_handler,
00248 gpointer progress_data,
00249 gdouble seed
00250 )
00251 {
00252 eg_debug("StarDict/%s->%s() called.\n"
00253 "-->PARAM:location=\'%s\'\n"
00254 "-->PARAM:auto_cache=%d\n",
00255 __FILE__,
00256 __FUNCTION__,
00257 location,
00258 (guint)auto_cache
00259 );
00260 g_assert(location != NULL);
00261
00262 sd_timer(TIMER_START,(gchar*)__FUNCTION__);
00263
00264 gchar* tmp = g_strdup(location);
00265 string_to_path(&tmp);
00266
00267 Engine* result = (Engine*)g_try_malloc0(sizeof(Engine));
00268 result->engine_location = sd_engine_location;
00269 result->engine_is_optimized = sd_engine_is_optimized;
00270 result->engine_optimize = sd_engine_optimize;
00271 result->engine_search_word_list = sd_engine_search_word_list;
00272 result->engine_search_word_translation =
00273 sd_engine_search_word_translation;
00274 result->engine_close = sd_engine_close;
00275 result->engine_status = sd_engine_status;
00276 result->engine_status_message = sd_engine_status_message;
00277 result->engine_set_callback = sd_engine_set_callback;
00278 result->engine_set_progress_seed = sd_engine_set_progress_seed;
00279 result->engine_set_auto_free = sd_engine_set_auto_free;
00280 result->engine_get_lang_to = sd_engine_get_lang_to;
00281 result->engine_get_lang_from = sd_engine_get_lang_from;
00282 result->engine_get_title = sd_engine_get_title;
00283 result->engine_get_icon_path = sd_engine_get_icon_path;
00284 result->engine_add_word = sd_engine_add_word;
00285 result->engine_remove_word = sd_engine_remove_word;
00286
00287 SDData* data = (SDData*)g_try_malloc0(sizeof(SDData));
00288 result->engine_data = (gpointer)data;
00289 data->dict_path = g_strdup(tmp);
00290 data->cb_progress_caching = progress_handler;
00291 data->cb_progress_caching_data = progress_data;
00292 data->cb_progress_caching_seed = seed;
00293 data->cb_progress_word_list = NULL;
00294 data->cb_progress_word_list_data = NULL;
00295 data->cb_progress_word_list_seed = 0.01;
00296 data->cb_progress_word_trans = NULL;
00297 data->cb_progress_word_trans_data = NULL;
00298 data->cb_progress_word_trans_seed = 0.01;
00299 data->cb_search_word_list = NULL;
00300 data->cb_search_word_list_data = NULL;
00301 data->cb_search_word_trans = NULL;
00302 data->cb_search_word_trans_data = NULL;
00303 data->auto_free = FALSE;
00304
00305 if(!sd_read_files_names(data))
00306 {
00307 eg_warning("Error while loading dictionaries filenames!\n");
00308 result->engine_close(result);
00309 result = NULL;
00310 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00311 return result;
00312 }
00313 if(!sd_parse_ifo_file(data))
00314 {
00315 eg_warning("Error while reading *.ifo file!\n");
00316 result->engine_close(result);
00317 result = NULL;
00318 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00319 return result;
00320 }
00321
00322
00323 data->lang_from = NULL;
00324 data->lang_to = NULL;
00325
00326 data->icon = g_strdup(ICON_PATH);
00327
00328 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00329 eg_debug("StarDict/%s->%s() returned Engine at adress=%p\n",
00330 __FILE__,
00331 __FUNCTION__,
00332 result
00333 );
00334 g_free(tmp); tmp = NULL;
00335 return result;
00336 }
00337
00343 void sd_engine_search_word_list(Engine* engine,
00344 gchar* pattern,
00345 gpointer cb_data)
00346 {
00347 eg_debug("-> %s() called. Searching words list\n"
00348 "--->PARAM:engine at adress=%p\n"
00349 "--->PARAM:pattern=\"%s\"\n",
00350 __FUNCTION__,
00351 engine,
00352 pattern
00353 );
00354 g_assert(engine != NULL);
00355 g_assert(pattern != NULL);
00356 pattern = g_utf8_casefold(pattern, -1);
00357 sd_timer(TIMER_START,(gchar*)__FUNCTION__);
00358 SDData* data = (SDData*)(engine->engine_data);
00359 if(data->cb_search_word_list == NULL) {
00360 eg_warning("---> %s() callback for Word List not set. "
00361 "Searching aborted.\n",
00362 __FUNCTION__
00363 );
00364 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00365 return;
00366 };
00367
00368 data->sd_seek_idx(data->idx_file, 0, _FILES_WRAPPER_BEG);
00369 gchar buffer[WORD_LIST_BUFFER_LENGTH + 1];
00370 gint readed =0;
00371 gint offset = 0;
00372 gchar* tmp = NULL;
00373 gchar* tmp1 = NULL;
00374 gchar* tmp2 = NULL;
00375 guint len = 0;
00376
00377 GPatternSpec* regex;
00378
00379 tmp = g_utf8_casefold (pattern, -1);
00380 regex = g_pattern_spec_new (tmp);
00381 g_free (tmp);
00382
00383 gboolean further = FALSE;
00384 guint count = 0;
00385 GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*));
00386 do
00387 {
00388 readed = data->sd_read_idx(data->idx_file,
00389 buffer + offset,
00390 WORD_LIST_BUFFER_LENGTH - offset
00391 );
00392 if(readed < 0)
00393 {
00394 eg_debug("---> Error while reading file for searching"
00395 " matched words in dictionary to pattern: %s",
00396 pattern
00397 );
00398 break;
00399 }
00400 else
00401 {
00402 further = (readed == (WORD_LIST_BUFFER_LENGTH-offset));
00403 }
00404 tmp = buffer;
00405
00406 guint i = 0;
00407 gint min = _MIN(readed, WORD_LIST_BUFFER_LENGTH-270);
00408 while(i<min)
00409 {
00410 tmp1 = g_strconcat (tmp, " ", NULL);
00411 tmp2 = g_utf8_casefold(tmp1, -1);
00412 g_free (tmp1);
00413 tmp1 = g_utf8_casefold(tmp, -1);
00414
00415
00416 if ((g_pattern_match_string (regex, tmp1) == TRUE) ||
00417 (g_pattern_match_string (regex, tmp2) == TRUE))
00418 {
00419 gchar* new = g_strdup(tmp);
00420 g_array_append_val(result,new);
00421 ++count;
00422 eg_debug("New word %d. \'%s\' matched to "
00423 "pattern \'%s\'\n",
00424 count,
00425 new,
00426 pattern
00427 );
00428 }
00429
00430 g_free (tmp1);
00431 g_free (tmp2);
00432
00433 len = strlen(tmp)+1;
00434
00435 tmp += len;
00436
00437 tmp += 2 * sizeof(guint);
00438
00439 i = i + len + 2 * sizeof(guint);
00440 }
00441
00442 offset = WORD_LIST_BUFFER_LENGTH - i;
00443 g_memmove(buffer,buffer+WORD_LIST_BUFFER_LENGTH-offset, offset);
00444 }
00445 while(further);
00446
00447 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00448 sd_timer(TIMER_START,"callback for returning words LIST START");
00449 if (NULL == cb_data )
00450 {
00451 cb_data = data->cb_search_word_list_data;
00452 }
00453 data->cb_search_word_list(result,
00454 pattern,
00455 cb_data,
00456 ENGINE_NO_ERROR
00457 );
00458 sd_timer(TIMER_STOP,"callback for returning word LIST END");
00459 guint i = 0;
00460 for (i=0; i<result->len; i++)
00461 {
00462 g_free(g_array_index(result, gchar*, i));
00463 }
00464 g_array_free(result, TRUE);
00465 g_pattern_spec_free (regex);
00466 }
00467
00473 void sd_engine_search_word_translation(Engine* engine,
00474 gchar* word,
00475 gpointer cb_data)
00476 {
00477 eg_debug("-> %s() called.\n"
00478 "-->PARAM:engine at adress=%p\n"
00479 "-->PARAM:word=\'%s\'\n",
00480 __FUNCTION__,
00481 engine,
00482 word);
00483 g_assert(engine != NULL);
00484 g_assert(word != NULL);
00485
00486 sd_timer(TIMER_START, (gchar*)__FUNCTION__);
00487 SDData* data = (SDData*)(engine->engine_data);
00488 gchar* trans0 = NULL;
00489
00490 if (NULL == cb_data )
00491 {
00492 cb_data = data->cb_search_word_list_data;
00493 }
00494
00495 FilePart* part = sd_find_file_part(data, word);
00496 if(!part)
00497 {
00498 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00499 eg_debug("<- %s did not found any article for word: %s",
00500 __FUNCTION__,
00501 word
00502 );
00503
00504 data->cb_search_word_trans(NULL,
00505 word,
00506 cb_data,
00507 ENGINE_NO_ERROR
00508 );
00509 return;
00510 }
00511
00512 trans0 = data->sd_read_dic_part(part,data->dic_file_name);
00513
00514 if(!trans0)
00515 {
00516 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00517 eg_debug("<- %s could not read from *.dict[.dz] file: %s",
00518 __FUNCTION__,
00519 data->dic_file_name
00520 );
00521
00522 data->cb_search_word_trans(NULL,
00523 word,
00524 cb_data,
00525 ENGINE_NO_ERROR
00526 );
00527 return;
00528 }
00529
00530
00531 gchar* trans = sd_parse_stardict_article(trans0,
00532 data->types,
00533 part->length
00534 );
00535 g_free(trans0); trans0 = NULL;
00536
00537
00538 if(!trans)
00539 {
00540 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00541 eg_debug("<- %s could not parse stardict article!",
00542 __FUNCTION__
00543 );
00544
00545 data->cb_search_word_trans(NULL,
00546 word,
00547 cb_data,
00548 ENGINE_NO_ERROR
00549 );
00550 return;
00551 }
00552
00553 sd_timer(TIMER_STOP,(gchar*)__FUNCTION__);
00554 sd_timer(TIMER_START,"callback for returning word's translation START");
00555
00556
00557 data->cb_search_word_trans(trans,
00558 word,
00559 cb_data,
00560 ENGINE_NO_ERROR
00561 );
00562
00563
00564 sd_timer(TIMER_STOP,"callback for returning word's translation END");
00565
00566
00567
00568
00569
00570
00571
00572
00573 g_free(trans);
00574 trans = NULL;
00575 }
00576
00581 static void sd_print_buffer_partial(gchar* buffer)
00582 {
00583 #ifndef NOLOGS
00584 #define PRINT_LEN 100
00585 #define EDGE "\n-------------------------------------------------------------\n"
00586 gchar tmp = 0;
00587 guint len = strlen(buffer);
00588 if(!buffer)
00589 {
00590 eg_debug("Buffer is empty!\n");
00591 }
00592 else if(PRINT_LEN >= len)
00593 {
00594 eg_debug("Buffer(%p):whole=%s%s%s", buffer, EDGE, buffer, EDGE);
00595 }
00596 else
00597 {
00598
00599 tmp = buffer[PRINT_LEN+1];
00600 buffer[PRINT_LEN+1] = '\0';
00601 eg_debug("Buffer(%p): first %db=%s%s (....)\n\n",
00602 buffer,
00603 PRINT_LEN,
00604 EDGE,
00605 buffer
00606 );
00607 buffer[PRINT_LEN+1] = tmp;
00608
00609
00610 eg_debug("Buffer(%p): last %db=\n(....)%s%s",
00611 buffer,
00612 PRINT_LEN,
00613 buffer+len-PRINT_LEN,
00614 EDGE
00615 );
00616 }
00617 #endif
00618 }
00619
00632 gchar* sd_parse_stardict_article(gchar* buf, gchar* type, guint length)
00633 {
00634 eg_debug("-> %s()\n--->PARAM:type=%p\n--->PARAM:length=%d",
00635 __FUNCTION__,
00636 type,
00637 length
00638 );
00639 sd_print_buffer_partial(buf);
00640 sd_timer(TIMER_START, (gchar*)__FUNCTION__);
00641 g_assert(buf != NULL);
00642 g_assert(length > 0);
00643
00644 gchar* result = (gchar*)g_try_malloc0(sizeof(gchar));
00645 result[0] = '\0';
00646 gchar next_type = 0;
00647 gchar* ptr = buf;
00648
00649 while(length > 0)
00650 {
00651 if(type == NULL)
00652 {
00653 memcpy(&next_type, ptr, sizeof(gchar));
00654 ++ptr;
00655 --length;
00656 }
00657 else
00658 {
00659 next_type = type[0];
00660 ++type;
00661 }
00662
00663
00664
00665 if(g_ascii_islower(next_type))
00666 {
00667
00668 gchar* new_txt = sd_get_buffer_from_article(&ptr,
00669 &length
00670 );
00671 gchar* new_tra = g_strconcat(result,
00672 new_txt,
00673 "\n<br/>",
00674 NULL
00675 );
00676 g_free(result);
00677 result = new_tra;
00678 new_tra = NULL;
00679 g_free(new_txt);
00680 new_txt = NULL;
00681 }
00682 else
00683 {
00684
00685
00686 guint len = 0;
00687 g_memmove(&len, ptr, sizeof(guint));
00688
00689 length -= sizeof(guint);
00690 ptr += sizeof(guint);
00691
00692 len = ntohl(len);
00693
00694 length -= len;
00695 ptr += len;
00696 }
00697 }
00698
00699 sd_timer(TIMER_STOP, (gchar*)__FUNCTION__);
00700 eg_debug("<- %s() returned buffer at %p\n",__FUNCTION__,result);
00701 return result;
00702 }
00703
00714 gchar* sd_get_buffer_from_article(gchar** buffer, guint* len)
00715 {
00716 eg_debug("-> %s\n",__FUNCTION__);
00717 g_assert(len > 0);
00718
00719 guint buf_len = 0;
00720 gchar* tmp = *buffer;
00721 while(tmp && *len > 0)
00722 {
00723 ++buf_len;
00724 ++tmp;
00725 --(*len);
00726 }
00727
00728 gchar* result = (gchar*)g_try_malloc0(buf_len+1);
00729 g_memmove(result, *buffer, buf_len);
00730 result[buf_len] = '\0';
00731
00732 *buffer = tmp;
00733 eg_debug("<- %s\n",__FUNCTION__);
00734 return result;
00735 }
00736
00737
00738
00739
00740
00741
00742
00751 gboolean sd_read_files_names(SDData* data) {
00752 eg_debug("-> %s()\n",__FUNCTION__);
00753 GError *dir_err = NULL;
00754 gchar* tmp = data->dict_path;
00755 GDir* dir = g_dir_open (tmp, 0, &dir_err);
00756 if(!dir)
00757 {
00758 eg_debug("---> Could not open a dir:\n%s\n",data->dict_path);
00759 return FALSE;
00760 }
00761 gboolean ifo = FALSE;
00762 gboolean idx = FALSE;
00763 gboolean dic = FALSE;
00764 const gchar* fn = g_dir_read_name(dir);
00765
00766 while((fn != NULL) && !(ifo && idx && dic))
00767 {
00768 if(g_str_has_suffix(fn, ".ifo"))
00769 {
00770 data->ifo_file_name = g_strconcat(tmp,"/",fn,NULL);
00771 ifo = TRUE;
00772 };
00773 if(g_str_has_suffix(fn, ".idx"))
00774 {
00775 data->idx_file_name = g_strconcat(tmp,"/",fn,NULL);
00776 data->idx_compressed = FALSE;
00777 data->sd_open_idx = sd_open;
00778 data->sd_read_idx = sd_read;
00779 data->sd_seek_idx = sd_seek;
00780 data->sd_close_idx = sd_close;
00781 idx = TRUE;
00782 };
00783 if(g_str_has_suffix(fn, ".idx.gz"))
00784 {
00785 data->idx_file_name = g_strconcat(tmp,"/",fn,NULL);
00786 data->idx_compressed = TRUE;
00787 data->sd_open_idx = sd_open_z;
00788 data->sd_read_idx = sd_read_z;
00789 data->sd_seek_idx = sd_seek_z;
00790 data->sd_close_idx = sd_close_z;
00791 idx = TRUE;
00792 };
00793 if(g_str_has_suffix(fn, ".dict"))
00794 {
00795 data->dic_file_name = g_strconcat(tmp,"/",fn,NULL);
00796 data->dic_compressed = FALSE;
00797 data->sd_read_dic_part = sd_read_file_part;
00798 dic = TRUE;
00799 };
00800 if(g_str_has_suffix(fn, ".dict.dz"))
00801 {
00802 data->dic_file_name = g_strconcat(tmp,"/",fn,NULL);
00803 data->dic_compressed = TRUE;
00804 data->sd_read_dic_part = sd_read_file_part_dz;
00805 dic = TRUE;
00806 };
00807 fn = g_dir_read_name(dir);
00808 }
00809 g_dir_close(dir);
00810
00811 if(ifo && idx && dic)
00812 {
00813 eg_debug("---> Dictionary files :\nifo=%s\nidx=%s\ndict=%s\n",
00814 data->idx_file_name,
00815 data->idx_file_name,
00816 data->dic_file_name
00817 );
00818 data->idx_file = data->sd_open_idx(data->idx_file_name);
00819 if(data->idx_file == NULL)
00820 {
00821 g_free(data->idx_file_name);
00822 data->idx_file_name = NULL;
00823 g_free(data->ifo_file_name);
00824 data->ifo_file_name = NULL;
00825 g_free(data->dic_file_name);
00826 data->dic_file_name = NULL;
00827 eg_debug("---> Could no open *.idx file!");
00828 return FALSE;
00829 }
00830 eg_debug("<- %s()\n",__FUNCTION__);
00831 return TRUE;
00832 }
00833 else
00834 {
00835 if(idx)
00836 {
00837 g_free(data->idx_file_name);
00838 data->idx_file_name = NULL;
00839 }
00840 if(ifo)
00841 {
00842 g_free(data->ifo_file_name);
00843 data->ifo_file_name = NULL;
00844 }
00845 if(dic)
00846 {
00847 g_free(data->dic_file_name);
00848 data->dic_file_name = NULL;
00849 }
00850 }
00851 eg_debug("<- %s()\n",__FUNCTION__);
00852 return FALSE;
00853 }
00854
00861 gboolean sd_engine_check(gchar* location)
00862 {
00863 eg_debug("-> %s()\n--->PARAM:location=%s\n",
00864 __FUNCTION__,
00865 location
00866 );
00867 g_assert(location);
00868
00869 gboolean result = TRUE;
00870 gchar* filepath = g_strdup(location);
00871 string_to_path(&filepath);
00872 if (filepath == NULL)
00873 {
00874 result = FALSE;
00875 eg_debug("---> %s is not a proper path!\n",location);
00876 }
00877 else
00878 {
00879 SDData* tmp = g_try_malloc0(sizeof(SDData));
00880 tmp->dict_path = filepath;
00881
00882 result = sd_read_files_names(tmp);
00883
00884 g_free(tmp->idx_file_name);
00885 g_free(tmp->ifo_file_name);
00886 g_free(tmp->dic_file_name);
00887 g_free(tmp); tmp = NULL;
00888 };
00889 g_free(filepath);
00890
00891 eg_debug("<- %s() returned bool statement=%s.\n",
00892 __FUNCTION__,
00893 PRINT_STATE(result)
00894 );
00895 return result;
00896 }
00897
00906 static double timer(gboolean start, gchar* message)
00907 {
00908 static GArray* stack = NULL;
00909 static gboolean first_run = TRUE;
00910 static struct timeval actual_time;
00911 static struct timeval last_time;
00912 static struct timeval result;
00913 static double seconds = 0.0;
00914 if(first_run)
00915 {
00916 first_run = FALSE;
00917 stack = g_array_new(TRUE, TRUE, sizeof(struct timeval));
00918 };
00919
00920 if (start)
00921 {
00922 eg_debug("TIMER:function %s()'s timer has started.\n",message);
00923 g_array_prepend_val(stack, actual_time);
00924 gettimeofday(&g_array_index(stack, struct timeval, 0),NULL);
00925 return -1.0;
00926 }
00927
00928
00929 else {
00930 gettimeofday(&actual_time,NULL);
00931 last_time = g_array_index(stack, struct timeval, 0);
00932 g_array_remove_index(stack, 0);
00933
00934 if (actual_time.tv_usec < last_time.tv_usec)
00935 {
00936 int nsec = (last_time.tv_usec - actual_time.tv_usec) /
00937 (1000000 + 1);
00938 last_time.tv_usec -= 1000000 * nsec;
00939 last_time.tv_sec += nsec;
00940 }
00941 if (actual_time.tv_usec - last_time.tv_usec > 1000000)
00942 {
00943 int nsec = (last_time.tv_usec - actual_time.tv_usec) /
00944 1000000;
00945 last_time.tv_usec += 1000000 * nsec;
00946 last_time.tv_sec -= nsec;
00947 }
00948 result.tv_sec = actual_time.tv_sec - last_time.tv_sec;
00949 result.tv_usec = actual_time.tv_usec - last_time.tv_usec;
00950 seconds = (((double)(result.tv_usec)) / 1e6) +
00951 ((double)(result.tv_sec));
00952
00953 eg_debug("TIMER:Function \'%s()\' was working for: %g "
00954 "[s] or %ld [us].\n",
00955 message,
00956 seconds,
00957 ((long)(result.tv_sec*1e6)+(result.tv_usec))
00958 );
00959
00960 if(stack->len == 0)
00961 {
00962 g_array_free(stack, TRUE);
00963 first_run = TRUE;
00964 }
00965 }
00966 return seconds;
00967 }
00968
00978 static gchar* string_to_path(gchar** string)
00979 {
00980 eg_debug("-> %s()\n-->PARAM:string=%s\n",__FUNCTION__,string[0]);
00981
00982 gchar* arg = string[0];
00983 gchar* new = NULL;
00984
00985 g_strstrip(arg);
00986
00987 if (!g_path_is_absolute(arg))
00988 {
00989 gchar* tmp = g_get_current_dir();
00990 new = g_strconcat(tmp,"/",arg,NULL);
00991 g_free(arg); arg = new; new = NULL;
00992 };
00993
00994 if (!g_file_test(arg, G_FILE_TEST_IS_DIR))
00995 {
00996
00997 if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR))
00998 {
00999 g_free(arg);
01000 new = NULL;
01001 }
01002
01003 else
01004 {
01005 new = g_path_get_dirname (arg);
01006 g_free(arg);
01007 }
01008 }
01009
01010 else
01011 {
01012
01013 if (g_str_has_suffix(arg,"/") )
01014 {
01015 new = g_path_get_dirname (arg);
01016 g_free(arg);
01017 }
01018 else
01019 {
01020 new = arg;
01021 }
01022 };
01023
01024 if (!g_file_test(new, G_FILE_TEST_IS_DIR))
01025 {
01026
01027 g_free(new);
01028 new = NULL;
01029 };
01030
01031 string[0] = new;
01032 eg_debug("<- %s() returned string=%s\n",__FUNCTION__,string[0]);
01033 return new;
01034 }
01035
01044 gchar* sd_engine_get_icon_path(Engine* engine)
01045 {
01046 eg_debug("-> %s\n",__FUNCTION__);
01047
01048 gchar* result;
01049 SDData* data = (SDData*)(engine->engine_data);
01050 if(data->auto_free)
01051 {
01052 result = data->icon;
01053 }
01054 else
01055 {
01056 result = g_strdup(data->icon);
01057 }
01058
01059 eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result);
01060 return result;
01061 }
01062
01065 gboolean sd_engine_add_word(Engine* engine, gchar* word, gchar* translation)
01066 {
01067 eg_debug("<->%s Operation not supported in this engine\n",__FUNCTION__);
01068 return FALSE;
01069 }
01070
01073 gboolean sd_engine_remove_word(Engine* engine, gchar* word)
01074 {
01075 eg_debug("<->%s Operation not supported in this engine\n",__FUNCTION__);
01076 return FALSE;
01077 }
01078
01083 gchar* sd_engine_get_lang_from(Engine* engine)
01084 {
01085 eg_debug("-> %s\n",__FUNCTION__);
01086
01087 gchar* result;
01088 SDData* data = (SDData*)(engine->engine_data);
01089 if(data->auto_free)
01090 {
01091 result = data->lang_from;
01092 }
01093 else
01094 {
01095 result = g_strdup(data->lang_from);
01096 }
01097
01098 eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result);
01099 return result;
01100 }
01101
01106 gchar* sd_engine_get_lang_to(Engine* engine)
01107 {
01108 eg_debug("-> %s\n",__FUNCTION__);
01109
01110 gchar* result;
01111 SDData* data = (SDData*)(engine->engine_data);
01112 if(data->auto_free)
01113 {
01114 result = data->lang_to;
01115 }
01116 else
01117 {
01118 result = g_strdup(data->lang_to);
01119 }
01120
01121 eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result);
01122 return result;
01123 }
01124
01129 gchar* sd_engine_get_title(Engine* engine)
01130 {
01131 eg_debug("-> %s\n",__FUNCTION__);
01132
01133 gchar* result;
01134 SDData* data = (SDData*)(engine->engine_data);
01135 if(data->auto_free)
01136 {
01137 result = data->title;
01138 }
01139 else
01140 {
01141 result = g_strdup(data->title);
01142 }
01143
01144 eg_debug("<- %s return string = \"%s\"\n",__FUNCTION__,result);
01145 return result;
01146 }
01147
01158 gpointer sd_engine_set_callback(Engine* engine,
01159 gchar* signal,
01160 gpointer c_handler,
01161 gpointer user_data)
01162 {
01163 eg_debug("-> %s().\n",__FUNCTION__);
01164 g_assert(engine != NULL);
01165 g_assert(signal != NULL);
01166 g_assert(c_handler != NULL);
01167 SDData* data = (SDData*)(engine->engine_data);
01168 if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0)
01169 {
01170 gpointer result = data->cb_progress_caching;
01171 data->cb_progress_caching = c_handler;
01172 data->cb_progress_caching_data = user_data;
01173 eg_debug("---> %s() sets handler for signal \"%s\".\n",
01174 __FUNCTION__,
01175 signal
01176 );
01177 eg_debug("---> %s() Function at adress = %p.\n",
01178 __FUNCTION__,
01179 c_handler
01180 );
01181 eg_debug("---> %s() Data at adress = %p.\n",
01182 __FUNCTION__,
01183 user_data
01184 );
01185 eg_debug("<- %s().\n",__FUNCTION__);
01186 return result;
01187 }
01188 else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0)
01189 {
01190 gpointer result = data->cb_search_word_list;
01191 data->cb_search_word_list = c_handler;
01192 data->cb_search_word_list_data = user_data;
01193 eg_debug("---> %s() sets handler for signal \"%s\".\n",
01194 __FUNCTION__,
01195 signal
01196 );
01197 eg_debug("---> %s() Function at adress = %p.\n",
01198 __FUNCTION__,
01199 c_handler
01200 );
01201 eg_debug("---> %s() Data at adress = %p.\n",
01202 __FUNCTION__,
01203 user_data
01204 );
01205 eg_debug("<- %s().\n",__FUNCTION__);
01206 return result;
01207 }
01208 else if(g_ascii_strcasecmp(signal, ENGINE_WORD_TRANSLATION_SIGNAL) == 0)
01209 {
01210 gpointer result = data->cb_search_word_trans;
01211 data->cb_search_word_trans = c_handler;
01212 data->cb_search_word_trans_data = user_data;
01213 eg_debug("---> %s() sets handler for signal \"%s\".\n",
01214 __FUNCTION__,
01215 signal
01216 );
01217 eg_debug("---> %s() Function at adress = %p.\n",
01218 __FUNCTION__,
01219 c_handler
01220 );
01221 eg_debug("---> %s() Data at adress = %p.\n",
01222 __FUNCTION__,
01223 user_data
01224 );
01225 eg_debug("<- %s().\n",__FUNCTION__);
01226 return result;
01227 }
01228 else
01229 {
01230 eg_warning("---> %s() unsupported signal: %s.\n",
01231 __FUNCTION__,
01232 signal
01233 );
01234 eg_debug("<- %s().\n",__FUNCTION__);
01235 return NULL;
01236 }
01237 }
01238
01239
01246 void sd_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed)
01247 {
01248 eg_debug("-> %s().\n",__FUNCTION__);
01249 SDData* data = (SDData*)(engine->engine_data);
01250 if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0)
01251 {
01252 data->cb_progress_caching_seed = seed;
01253 eg_debug("--->%s() sets new seed=%0.2f for for signal %s.\n",
01254 __FUNCTION__,
01255 seed,
01256 signal
01257 );
01258 }
01259 else
01260 {
01261 g_warning("--->%s() unsupported signal for progress: %s.\n",
01262 __FUNCTION__,
01263 signal
01264 );
01265 };
01266 eg_debug("<- %s().\n",__FUNCTION__);
01267 }
01268
01275 EngineStatus sd_engine_status(Engine* engine)
01276 {
01277 eg_debug("-> %s()\n--->PARAM:engine at adress=%p\n",
01278 __FUNCTION__,
01279 engine
01280 );
01281 SDData* data = (SDData*)(engine->engine_data);
01282 eg_debug("<- %s() returned error code: %d\n",
01283 __FUNCTION__,
01284 (gint)(data->last_error)
01285 );
01286 return data->last_error;
01287 }
01288
01291 gboolean sd_engine_is_optimized(Engine* engine)
01292 {
01293 eg_debug("-> %s() for engine at adress=%p\n",
01294 __FUNCTION__,
01295 engine
01296 );
01297 g_assert(engine != NULL);
01298
01299 gboolean result = TRUE;
01300
01301 eg_debug("<- %s() returned bool statement=%s.\n",
01302 __FUNCTION__,
01303 PRINT_STATE(result)
01304 );
01305 return result;
01306 }
01307
01310 void sd_engine_optimize(Engine* engine)
01311 {
01312 eg_debug("-> %s() called for engine at adress=%p\n",
01313 __FUNCTION__,
01314 engine
01315 );
01316 eg_debug("---> Unsupported method for this engine\n");
01317 eg_debug("<- %s()\n",__FUNCTION__);
01318 }
01319
01325 EngineModule engine_global_functions()
01326 {
01327 eg_debug("-> %s() called.\n",__FUNCTION__);
01328 EngineModule result;
01329 result.engine_check = sd_engine_check;
01330 result.engine_description= sd_engine_description;
01331 result.engine_format = sd_engine_format;
01332 result.engine_version = sd_engine_version;
01333 result.engine_create = sd_engine_create;
01334 eg_debug("<- %s() returned EngineModule at adress=%p.\n",
01335 __FUNCTION__,
01336 &result
01337 );
01338 return result;
01339 }
01340
01347 gchar* sd_engine_status_message(EngineStatus status)
01348 {
01349 eg_debug("<-> %s() called.\n",__FUNCTION__);
01350 switch (status)
01351 {
01352 case ENGINE_NO_ERROR:
01353 return "No error.";
01354 case ENGINE_WRONG_FILE:
01355 return "File, You are trying to use, is wrong type.";
01356 case ENGINE_COULDNT_READ:
01357 return "Could not read from file.";
01358 case ENGINE_NO_FILE:
01359 return "There is no such a file.";
01360 case ENGINE_OUT_OF_MEMORY:
01361 return "There were no enough memory for this action.";
01362 default:
01363 return "Wrong engine's status identifier!";
01364 }
01365 }
01366
01371 gchar* sd_engine_version()
01372 {
01373 eg_debug("-> %s()\n",__FUNCTION__);
01374 gchar* result = g_strdup(DIC_ENG_VERSION);
01375 eg_debug("<- %s() return string=%s\n",
01376 __FUNCTION__,
01377 result
01378 );
01379 return result;
01380 }
01381
01388 gchar* sd_engine_format()
01389 {
01390 eg_debug("-> %s()\n",__FUNCTION__);
01391 gchar* result = g_strdup(DIC_ENG_FORMAT);
01392 eg_debug("<- %s() return string=%s\n",
01393 __FUNCTION__,
01394 result
01395 );
01396 return result;
01397 }
01398
01404 gchar* sd_engine_description()
01405 {
01406 eg_debug("-> %s()\n",__FUNCTION__);
01407 gchar* result = g_strdup(DIC_ENG_DESCRIPTION);
01408 eg_debug("<- %s() return string=%s\n",
01409 __FUNCTION__,
01410 result
01411 );
01412 return result;
01413 }
01414
01421 gchar* sd_engine_location(Engine* engine)
01422 {
01423 eg_debug("->%s() called.\n-->PARAM: engine adress=%p\n",
01424 __FUNCTION__,
01425 engine
01426 );
01427 g_assert(engine != NULL);
01428 SDData* data = (SDData*)(engine->engine_data);
01429
01430 gchar* result;
01431 if(data->auto_free)
01432 {
01433 result = data->dict_path;
01434 }
01435 else
01436 {
01437 result = g_strdup(data->dict_path);
01438 }
01439
01440 eg_debug("<- %s() returned string=%s\n",
01441 __FUNCTION__,
01442 result
01443 );
01444 return result;
01445 }
01446
01458 void sd_engine_set_auto_free(Engine* engine, gboolean state)
01459 {
01460 eg_debug("-> %s()\n"
01461 "--->PARAM:engine at adress=%p\n--->PARAM:state=%s\n",
01462 __FUNCTION__,
01463 engine,
01464 PRINT_STATE(state)
01465 );
01466 g_assert(engine != NULL);
01467 SDData* data = (SDData*)(engine->engine_data);
01468
01469 data->auto_free = state;
01470 eg_debug("<- %s() Current auto_free is %s\n",
01471 __FUNCTION__,
01472 PRINT_STATE(data->auto_free)
01473 );
01474 }
01475
01483 void sd_parse_record(SDData* data,gchar* key, gchar* value)
01484 {
01485 if(g_ascii_strncasecmp(key,"version",100) == 0)
01486 {
01487 }
01488 else if(g_ascii_strncasecmp(key,"bookname",100) == 0)
01489 {
01490 data->title = g_strdup(value);
01491 eg_debug("%s set title to: %s\n",__FUNCTION__, data->title);
01492 }
01493 else if(g_ascii_strncasecmp(key,"wordcount",100) == 0)
01494 {
01495 data->word_count = (gint)g_ascii_strtoull( value, NULL, 10);
01496 eg_debug("%s set word count to: %d\n",
01497 __FUNCTION__,
01498 data->word_count
01499 );
01500 }
01501 else if(g_ascii_strncasecmp(key,"idxfilesize",100) == 0)
01502 {
01503 data->idx_file_length = (gint)g_ascii_strtoull(value, NULL, 10);
01504 eg_debug("%s set idx file length to: %d\n",
01505 __FUNCTION__,
01506 data->idx_file_length
01507 );
01508 }
01509 else if(g_ascii_strncasecmp(key,"sametypesequence",100) == 0)
01510 {
01511 data->types = g_strdup(value);
01512 eg_debug("%s set data types to: %s\n",__FUNCTION__,data->types);
01513 }
01514 else
01515 {
01516 eg_debug("%s trying to set usupported field\n",__FUNCTION__);
01517 }
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534 }
01535
01543 gboolean sd_parse_ifo_file(SDData* data)
01544 {
01545 GnomeVFSHandle* fd = NULL;
01546 GnomeVFSResult fr = 0;
01547 GnomeVFSFileSize n = 0;
01548 GnomeVFSFileSize k = 0;
01549
01550 if(!gnome_vfs_initialized ())
01551 {
01552 gnome_vfs_init ();
01553 };
01554
01555 fr = gnome_vfs_open (&fd, data->ifo_file_name, GNOME_VFS_OPEN_READ);
01556 if(fr != GNOME_VFS_OK)
01557 {
01558 eg_warning("Error while trying to open file:\n%s\n",
01559 data->ifo_file_name
01560 );
01561 return FALSE;
01562 }
01563 gnome_vfs_seek(fd, GNOME_VFS_SEEK_END, 0);
01564 fr = gnome_vfs_tell(fd, &n);
01565 gnome_vfs_seek(fd, GNOME_VFS_SEEK_START, 0);
01566
01567 gchar* tmp = g_try_malloc0(sizeof(gchar)*((gint)(n)));
01568 fr = gnome_vfs_read(fd, tmp, n, &k);
01569 if(fr != GNOME_VFS_OK) {
01570 eg_warning("Error while trying to read file:\n%s\n",
01571 data->ifo_file_name
01572 );
01573 gnome_vfs_close(fd);
01574 return FALSE;
01575 }
01576 gnome_vfs_close(fd);
01577
01578 gchar** table = g_strsplit(tmp, "\n", 100);
01579 gint i;
01580 for(i=0; table[i]!=NULL; ++i)
01581 {
01582 gchar* eq = g_strstr_len (table[i], 0xffff, "=");
01583 if(eq == NULL) continue;
01584 *eq = '\0';
01585 ++eq;
01586 eg_debug("SD *.ifo record -> Key=%s => Value=%s\n",table[i],eq);
01587 sd_parse_record(data, table[i], eq);
01588 }
01589
01590 g_free(tmp); tmp = NULL;
01591 g_strfreev(table); table = NULL;
01592 if(data->title)
01593 {
01594 return TRUE;
01595 }
01596 else
01597 {
01598 return FALSE;
01599 }
01600 }
01601
01602
01603
01612 static gpointer sd_open(gchar* filename)
01613 {
01614 gint tmp = open(filename, O_RDONLY);
01615 if(tmp == -1)
01616 {
01617 eg_debug("---> Error while trying to open file %s\n",filename);
01618 return NULL;
01619 }
01620 gint* result = (int*)g_try_malloc0(sizeof(gint));
01621 *result = tmp;
01622 return (gpointer)result;
01623 }
01624
01633 static gint sd_read(gpointer f, gchar* buffer, gint l)
01634 {
01635 gint tmp = *((gint*)(f));
01636 return (gint)read(tmp, buffer, l);
01637 }
01638
01650 static glong sd_seek(gpointer f, glong l, gchar from)
01651 {
01652 gint tmp = *((gint*)(f));
01653 switch(from)
01654 {
01655 case _FILES_WRAPPER_BEG:
01656 return (glong)lseek(tmp, l, SEEK_SET);
01657 case _FILES_WRAPPER_CUR:
01658 return (glong)lseek(tmp, l, SEEK_CUR);
01659 case _FILES_WRAPPER_END:
01660 return (glong)lseek(tmp, l, SEEK_END);
01661 default:
01662 eg_debug("---> Wrong relative position for sd_seek!\n");
01663 return -2;
01664 }
01665 }
01666
01671 static void sd_close(gpointer f)
01672 {
01673 gint tmp = *((gint*)(f));
01674 close(tmp);
01675 }
01676
01677
01678
01687 static gpointer sd_open_z(gchar* filename)
01688 {
01689 gzFile* out = (gzFile*)g_try_malloc0(sizeof(gzFile));
01690 *out = gzopen(filename, "rb9");
01691 if(out == NULL)
01692 {
01693 eg_debug("Error while opening compressed file with gzip!\n");
01694 }
01695 return (gpointer)out;
01696 }
01697
01706 static gint sd_read_z(gpointer f, gchar* buffer, gint l)
01707 {
01708 gzFile tmp = *((gzFile*)f);
01709 return (gint)gzread(tmp, buffer, l);
01710 }
01711
01723 static glong sd_seek_z(gpointer f, glong l, gchar from)
01724 {
01725 gzFile tmp = *((gzFile*)f);
01726 switch(from)
01727 {
01728 case _FILES_WRAPPER_BEG:
01729 return (glong)gzseek(tmp, l, SEEK_SET);
01730 case _FILES_WRAPPER_CUR:
01731 return (glong)gzseek(tmp, l, SEEK_CUR);
01732 default:
01733 eg_debug("---> Wrong position for sd_seek_z!\n");
01734 return -2;
01735 }
01736 }
01737
01742 static void sd_close_z(gpointer f)
01743 {
01744 gzFile tmp = *((gzFile*)f);
01745 gzclose(tmp);
01746 }