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
00025
00026 #ifndef NOLOGS
00027 #include <glib/gstdio.h>
00028 #define LOGS g_debug
00029 #else
00030 #define LOGS(frm,...) while(FALSE)
00031 #endif
00032
00033
00034
00035 static gint bm_compare_key_trans(const DBT *a, const DBT *b) {
00036 guint tmpa;
00037 guint tmpb;
00038 memcpy(&tmpa, a->data, sizeof(guint));
00039 memcpy(&tmpb, b->data, sizeof(guint));
00040
00041 if(tmpa == tmpb) return 0;
00042 if(tmpa > tmpb) return 1;
00043 else return -1;
00044 }
00045
00046 static gint bm_compare_key_words(const DBT *a, const DBT *b) {
00047 gchar* tmpa = g_utf8_casefold((gchar*)(a->data),-1);
00048 gchar* tmpb = g_utf8_casefold((gchar*)(b->data),-1);
00049 gint result = g_utf8_collate(tmpa,tmpb);
00050 g_free(tmpa); tmpa = NULL;
00051 g_free(tmpb); tmpb = NULL;
00052 return result;
00053 }
00054
00055 static void bm_save_freeID(BookData* data) {
00056 LOGS("Saveing new freeID=%u...\n",data->freeID);
00057 guint temp = 0;
00058 DBT key = { &temp , sizeof(guint)};
00059 DBT val = { &(data->freeID) , sizeof(guint) };
00060
00061 gint res = data->db_trans->del(data->db_trans, &key, 0);
00062 if(-1 == res)
00063 {
00064 data->last_error = ENGINE_INTERNAL_ERROR;
00065 LOGS("Error while trying to delete old freeID!\n");
00066 return;
00067 }
00068 else {
00069 LOGS("Old freeID=%u deleted successfully!\n",data->freeID-1);
00070 }
00071
00072 res = data->db_trans->put(data->db_trans, &key, &val, R_NOOVERWRITE);
00073 if(-1 == res || 1 == res)
00074 {
00075 data->last_error = ENGINE_INTERNAL_ERROR;
00076 LOGS("Error while trying to write new value for freeID!\n");
00077 }
00078 else {
00079 LOGS("New freeID=%u written successfully!\n",data->freeID);
00080 }
00081
00082 res = data->db_trans->sync(data->db_trans, 0);
00083 if(-1 == res || 1 == res)
00084 {
00085 data->last_error = ENGINE_INTERNAL_ERROR;
00086 LOGS("Error while trying to write data to fuile!\n");
00087 }
00088 else {
00089 LOGS("New data saved successfully to file!\n");
00090 }
00091 }
00092
00093 static void bm_load_freeID(BookData* data) {
00094 guint temp = 0;
00095 DBT key = { &temp , sizeof(guint) };
00096 DBT val = { NULL , 0 };
00097
00098 gint res = data->db_trans->get(data->db_trans, &key, &val, 0);
00099 if(-1 == res)
00100 {
00101 data->last_error = ENGINE_INTERNAL_ERROR;
00102 LOGS("Bookmark/%s->%s() Error while getting access to trans "
00103 "database!",
00104 (gchar*)__FILE__,
00105 (gchar*)__FUNCTION__
00106 );
00107 }
00108 else if( 1 != res)
00109 {
00110 memcpy(&(data->freeID), val.data, sizeof(guint));
00111
00112 LOGS("Bookmark/%s->%s() Available next free ID is equal = %d",
00113 (gchar*)__FILE__,
00114 (gchar*)__FUNCTION__,
00115 data->freeID
00116 );
00117 }
00118 else
00119 {
00120 LOGS("Bookmark/%s->%s() Could not load the minimal, available"
00121 " ID for next record - translation!",
00122 (gchar*)__FILE__,
00123 (gchar*)__FUNCTION__
00124 );
00125 data->freeID = 1;
00126 data->last_error = ENGINE_INTERNAL_ERROR;
00127 }
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 gboolean bm_engine_add_word(Engine* engine,
00139 gchar* word,
00140 gchar* translation) {
00141 LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n"
00142 "word: %s\ntranslation address: %p\n",
00143 (gchar*)__FILE__,
00144 (gchar*)__FUNCTION__,
00145 engine,
00146 word,
00147 translation
00148 );
00149 g_assert(engine != NULL);
00150 g_assert(word != NULL);
00151 g_assert(translation != NULL);
00152
00153
00154 bm_timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__);
00155
00156 gboolean result = TRUE;
00157 BookData* data = (BookData*)(engine->engine_data);
00158 guint length = strlen(word) + 1;
00159 DBT key = { word , length };
00160 DBT val = { NULL , 0 };
00161
00162
00163 gint db_res = data->db_words->get(data->db_words, &key, &val, 0);
00164 if ( 0 == db_res )
00165 {
00166
00167
00168 LOGS("Bookmark/%s->%s() updating entry for key: %s",
00169 (gchar*)__FILE__,
00170 (gchar*)__FUNCTION__,
00171 (gchar*)(key.data)
00172 );
00173
00174 guint hash = g_str_hash(translation);
00175 guint* values = (guint*)(val.data);
00176 guint N = values[0];
00177 memcpy(&N, values, sizeof(guint));
00178 guint i = N;
00179 guint tmp_hash = 0;
00180 gboolean exist = FALSE;
00181 ++values;
00182 while(i--)
00183 {
00184 memcpy(&tmp_hash, values + (i*2+1), sizeof(guint));
00185 if( tmp_hash == hash)
00186 {
00187 exist = TRUE;
00188 break;
00189 }
00190 }
00191 if(!exist)
00192 {
00193 LOGS("Bookmark/%s->%s() Adding new translation to "
00194 "already exist word in dictionary.\n",
00195 (gchar*)__FILE__,
00196 (gchar*)__FUNCTION__
00197 );
00198 values = (guint*)(val.data);
00199 guint* tmp = g_malloc(val.size + sizeof(guint)*2);
00200 g_memmove(tmp, values, val.size);
00201 tmp[0]++;
00202 tmp[N*2+1] = data->freeID;
00203 tmp[N*2+2] = hash;
00204 val.data = tmp;
00205 val.size += 2*sizeof(guint);
00206 gint o = data->db_words->del(data->db_words,&key,0);
00207 if(0 != o)
00208 {
00209 LOGS("Bookmark/%s->%s() Error while removing!",
00210 (gchar*)__FILE__,
00211 (gchar*)__FUNCTION__
00212 );
00213 }
00214 o = data->db_words->sync(data->db_words, 0);
00215 if(0 != o) {
00216 LOGS("Error while 1st synchronizing file with data!\n");
00217 }
00218
00219 o = data->db_words->put(data->db_words,
00220 &key,
00221 &val,
00222 R_NOOVERWRITE);
00223 if(0 != o) {
00224 LOGS("Error while putting new info about word!\n");
00225 }
00226 o = data->db_words->sync(data->db_words, 0);
00227 if(0 != o) {
00228 LOGS("Error while 2nd synchronizing file with data!\n");
00229 }
00230 bm_add_only_translation(data,translation,data->freeID);
00231 (data->freeID)++;
00232 bm_save_freeID(data);
00233 if(NULL != tmp) {
00234 g_free(tmp);
00235 tmp = NULL;
00236 }
00237 }
00238 else
00239 {
00240 LOGS("Bookmark/%s->%s() This translation already exist!",
00241 (gchar*)__FILE__,
00242 (gchar*)__FUNCTION__
00243 );
00244 }
00245 }
00246 else if ( 1 == db_res )
00247 {
00248
00249 LOGS("Bookmark/%s->%s() adding new entry for key: %s",
00250 (gchar*)__FILE__,
00251 (gchar*)__FUNCTION__,
00252 (gchar*)(key.data)
00253 );
00254 result = bm_add_new_entry(word,translation,data);
00255 }
00256 else {
00257
00258 LOGS("Bookmark/%s->%s() Error while trying to add new word: %s",
00259 (gchar*)__FILE__,
00260 (gchar*)__FUNCTION__,
00261 (gchar*)(key.data)
00262 );
00263 data->last_error = ENGINE_COULDNT_READ;
00264 result = FALSE;
00265 }
00266
00267 bm_timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__);
00268 return result;
00269 }
00270
00271 static gboolean bm_add_only_translation(BookData* data,
00272 gchar* translation,
00273 guint id)
00274 {
00275 DBT key = { &id , sizeof(id) };
00276 DBT val = { translation , strlen(translation) + 1 };
00277 gint res = data->db_trans->put(data->db_trans,
00278 &key,
00279 &val,
00280 R_NOOVERWRITE);
00281 if(-1 == res) {
00282 LOGS("Error while adding only translation!\n");
00283 return FALSE;
00284 }
00285 res = data->db_trans->sync(data->db_trans, 0);
00286 if(-1 == res) {
00287 LOGS("Error while synchronizing file with data\n");
00288 return FALSE;
00289 }
00290 return TRUE;
00291 }
00292
00293 static gboolean bm_add_new_entry(gchar* word,gchar* translation,BookData* data)
00294 {
00295 guint hash = g_str_hash(translation);
00296 gboolean result = TRUE;
00297
00298 DBT new_key = { &(data->freeID) , sizeof(guint) };
00299 DBT new_val = { translation , strlen(translation) + 1};
00300 gint db_res = data->db_trans->put(data->db_trans,
00301 &new_key,
00302 &new_val,
00303 R_NOOVERWRITE
00304 );
00305 if(-1 == db_res)
00306 {
00307 data->last_error = ENGINE_COULDNT_WRITE;
00308 result = FALSE;
00309 }
00310 else
00311 {
00312 new_key.data = word;
00313 new_key.size = strlen(word) + 1;
00314
00315
00316 guint temp[3] = { 1 , data->freeID, hash };
00317 new_val.data = temp;
00318 new_val.size = sizeof(guint) * 3;
00319
00320 db_res = data->db_words->put(data->db_words,
00321 &new_key,
00322 &new_val,
00323 R_NOOVERWRITE
00324 );
00325 if(-1 == db_res)
00326 {
00327 new_key.data = &(data->freeID);
00328 new_key.size = sizeof(guint);
00329 data->db_trans->del(data->db_trans, &new_key, 0);
00330 result = FALSE;
00331 data->last_error = ENGINE_INTERNAL_ERROR;
00332 }
00333 else
00334 {
00335 result = TRUE;
00336 (data->freeID)++;
00337 bm_save_freeID(data);
00338 }
00339 }
00340 db_res = data->db_words->sync(data->db_words,0);
00341 db_res |= data->db_trans->sync(data->db_trans,0);
00342 if(0 == db_res)
00343 {
00344 LOGS("Bookmark/%s->%s() adding new bookmark successful.\n",
00345 (gchar*)__FILE__,(gchar*)__FUNCTION__);
00346 }
00347 else
00348 {
00349 LOGS("Bookmark/%s->%s() adding new bookmark failed.\n",
00350 (gchar*)__FILE__,(gchar*)__FUNCTION__);
00351 }
00352 return result;
00353 }
00354
00355 gboolean bm_engine_remove_word(Engine* engine,
00356 gchar* word) {
00357 gboolean result = TRUE;
00358
00359 LOGS("Bookmark/%s->%s() called. Param\nEngine at address: %p\n"
00360 "word: %s\n",(gchar*)__FILE__,(gchar*)__FUNCTION__,engine,word);
00361 g_assert(engine != NULL);
00362 g_assert(word != NULL);
00363 bm_timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__);
00364
00365 BookData* data = (BookData*)(engine->engine_data);
00366
00367 DBT key = { word , strlen(word) + 1 };
00368 DBT val = { NULL , 0 };
00369
00370 gint db_res = data->db_words->get(data->db_words, &key, &val, 0);
00371 if ( 0 == db_res )
00372 {
00373 guint* t = (guint*)(val.data);
00374 guint N = t[0];
00375 guint id = 0;
00376 memcpy(&N, t, sizeof(guint));
00377 ++t;
00378 guint i = 0;
00379 key.size = sizeof(guint);
00380 key.data = &id;
00381 while( i < N ) {
00382 memcpy(&id, t + i*2, sizeof(guint));
00383 db_res = data->db_trans->del(data->db_trans, &key, 0);
00384 if(0 != db_res) {
00385 LOGS("Error while removing translation # %u for word: %s",i+1,word);
00386 }
00387 ++i;
00388 }
00389 }
00390 else if( -1 == db_res) {
00391 LOGS("Bookmark/%s->%s() Error while removing word: %s!",
00392 (gchar*)__FILE__,
00393 (gchar*)__FUNCTION__,
00394 word
00395 );
00396 return FALSE;
00397 }
00398 else {
00399 LOGS("Bookmark/%s->%s() Ther is no such a word!",
00400 (gchar*)__FILE__,
00401 (gchar*)__FUNCTION__
00402 );
00403 return TRUE;
00404 };
00405
00406
00407
00408
00409 DBT key_del = { word , strlen(word) + 1 };
00410 db_res = data->db_words->del(data->db_words,&key_del,0);
00411 if(-1 == db_res)
00412 {
00413 LOGS("Bookmark/%s->%s() Error while removing!\n",
00414 (gchar*)__FILE__,
00415 (gchar*)__FUNCTION__
00416 );
00417 }
00418 else if(1 == db_res)
00419 {
00420 LOGS("Bookmark/%s->%s() There is no such a word!\n",
00421 (gchar*)__FILE__,
00422 (gchar*)__FUNCTION__
00423 );
00424 }
00425 else if(0 == db_res)
00426 {
00427 LOGS("Bookmark/%s->%s() word deleted successfully!\n",
00428 (gchar*)__FILE__,
00429 (gchar*)__FUNCTION__
00430 );
00431 }
00432 db_res = data->db_words->sync(data->db_words, 0);
00433
00434 if((0 != db_res) || (NULL == data->db_words) || (NULL == data->db_trans)) {
00435 LOGS("Error while 2nd synchronizing file with data!\n");
00436 }
00437
00438
00439 bm_timer(TIMER_STOP, (gchar*)(gchar*)__FUNCTION__);
00440 LOGS("Bookmark/%s->%s() finished work.\n",
00441 (gchar*)__FILE__,
00442 (gchar*)__FUNCTION__
00443 );
00444 return result;
00445 }
00446
00447 gchar* bm_engine_get_lang_from(Engine* engine) {
00448 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
00449 gchar* result = g_strdup("any");
00450 LOGS("Bookmark/%s->%s() return string=%s\n",
00451 (gchar*)__FILE__,
00452 (gchar*)__FUNCTION__,
00453 result
00454 );
00455 return result;
00456 }
00457
00458 gchar* bm_engine_get_lang_to(Engine* engine) {
00459 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
00460 gchar* result = g_strdup("any");
00461 LOGS("Bookmark/%s->%s() return string=%s\n",
00462 (gchar*)__FILE__,
00463 (gchar*)__FUNCTION__,
00464 result
00465 );
00466 return result;
00467 }
00468
00469 gchar* bm_engine_get_title(Engine* engine) {
00470 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
00471 gchar* result = g_strconcat(g_get_user_name(),"s' bookmarks",NULL);
00472 LOGS("Bookmark/%s->%s() return string=%s\n",
00473 (gchar*)__FILE__,
00474 (gchar*)__FUNCTION__,
00475 result
00476 );
00477 return result;
00478 }
00479
00480 gchar* bm_engine_get_icon_path(Engine* engine) {
00481 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
00482 gchar* result = g_strdup("/usr/share/pixmaps/ws_eng_bookmark_icon.png");
00483 LOGS("Bookmark/%s->%s() return string=%s\n",
00484 (gchar*)__FILE__,
00485 (gchar*)__FUNCTION__,
00486 result
00487 );
00488 return result;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 void bm_engine_search_word_translation(Engine* engine,
00500 gchar* word,
00501 gpointer cb_data)
00502 {
00503 LOGS("Bookmark/%s->%s() called.\n-->PARAM:engine at adress=%p\n"
00504 "-->PARAM:word=\'%s\'\n",
00505 (gchar*)__FILE__,
00506 (gchar*)__FUNCTION__,
00507 engine,
00508 word
00509 );
00510 g_assert(engine != NULL);
00511 g_assert(word != NULL);
00512
00513 bm_timer(TIMER_START, (gchar*)(gchar*)__FUNCTION__);
00514 BookData* data = (BookData*)(engine->engine_data);
00515
00516 gchar* down_word = g_utf8_strdown(word,-1);
00517 DBT search = { down_word , strlen(down_word) + 1 };
00518 DBT info = { NULL , 0 };
00519 DBT trans = { NULL , 0 };
00520 gchar* tran = NULL;
00521 gchar* tran_ = NULL;
00522
00523 gint tmp = data->db_words->get(data->db_words, &search, &info, 0);
00524 if(0 == tmp)
00525 {
00526
00527
00528 guint* records = (guint*)(info.data);
00529 guint count = records[0];
00530 memcpy(&count, records, sizeof(guint));
00531
00532 ++records;
00533 guint id = 0;
00534 search.data = &id;
00535 search.size = sizeof(guint);
00536
00537 while(count-- > 0 && count < 100)
00538 {
00539
00540 memcpy(search.data, records, sizeof(guint));
00541 records += 2;
00542 tmp = data->db_trans->get(data->db_trans, &search, &trans, 0);
00543 if(0 == tmp)
00544 {
00545 if(NULL == tran)
00546 {
00547 tran = g_strdup(trans.data);
00548 }
00549 else
00550 {
00551 tran_ =
00552 g_strconcat(tran,"<br />",trans.data,NULL);
00553 g_free(tran);
00554 tran = tran_;
00555 tran_ = NULL;
00556 }
00557 }
00558 }
00559 };
00560 g_free(down_word);
00561 bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__);
00562 bm_timer(TIMER_START,"callback for returning word's translation START");
00563
00564
00565 if ( NULL == cb_data )
00566 {
00567 cb_data = data->cb_search_word_trans_data;
00568 }
00569 data->cb_search_word_trans(tran, word, cb_data, ENGINE_NO_ERROR);
00570
00571 bm_timer(TIMER_STOP,"callback for returning word's translation END");
00572
00573
00574
00575
00576
00577
00578
00579
00580 g_free(tran);
00581 tran = NULL;
00582 }
00583
00584
00585 void bm_engine_close(Engine* engine)
00586 {
00587 LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n",
00588 (gchar*)__FILE__,
00589 (gchar*)__FUNCTION__,
00590 engine);
00591 g_assert(engine != NULL);
00592
00593 BookData* data = (BookData*)(engine->engine_data);
00594 data->db_words->close(data->db_words);
00595 data->db_trans->close(data->db_trans);
00596
00597 LOGS("Bookmark/%s->%s() engine at adress=%p is deleted.\n",
00598 (gchar*)__FILE__,
00599 (gchar*)__FUNCTION__,
00600 engine);
00601 g_free(data->dict_path);
00602 g_free(data);
00603 data = NULL;
00604 g_free(engine);
00605 engine = NULL;
00606 }
00607
00608
00609 Engine* bm_engine_create(gchar* location,
00610 EngineOptimizationFlag auto_cache,
00611 cb_progress progress_handler,
00612 gpointer progress_data,
00613 gdouble seed)
00614 {
00615 LOGS("Bookmark/%s->%s() called.\n"
00616 "-->PARAM:location=\'%s\'\n"
00617 "-->PARAM:auto_cache=%d\n",
00618 (gchar*)__FILE__,
00619 (gchar*)__FUNCTION__,
00620 location,
00621 (guint)auto_cache
00622 );
00623 bm_timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__);
00624
00625 gchar* tmp = g_strdup(location);
00626 string_to_path(&tmp);
00627
00628 Engine* result = (Engine*)g_try_malloc(sizeof(Engine));
00629 result->engine_location = bm_engine_location;
00630 result->engine_is_optimized = bm_engine_is_optimized;
00631 result->engine_optimize = bm_engine_optimize;
00632 result->engine_search_word_list = bm_engine_search_word_list;
00633 result->engine_search_word_translation =
00634 bm_engine_search_word_translation;
00635 result->engine_close = bm_engine_close;
00636 result->engine_status = bm_engine_status;
00637 result->engine_status_message = bm_engine_status_message;
00638 result->engine_set_callback = bm_engine_set_callback;
00639 result->engine_set_progress_seed = bm_engine_set_progress_seed;
00640 result->engine_set_auto_free = bm_engine_set_auto_free;
00641
00642 result->engine_add_word = bm_engine_add_word;
00643 result->engine_remove_word = bm_engine_remove_word;
00644 result->engine_get_lang_from = bm_engine_get_lang_from;
00645 result->engine_get_lang_to = bm_engine_get_lang_to;
00646 result->engine_get_title = bm_engine_get_title;
00647 result->engine_get_icon_path = bm_engine_get_icon_path;
00648
00649
00650 BookData* data = (BookData*)g_try_malloc(sizeof(BookData));
00651 result->engine_data = (gpointer)data;
00652
00653 LOGS("Bookmark/%s->%s() opening file...\'%s\'.\n",
00654 (gchar*)__FILE__,
00655 (gchar*)__FUNCTION__,
00656 location
00657 );
00658
00659 u_int32_t flags = O_CREAT | O_RDWR;
00660 gchar* tmp_w = g_strconcat(tmp,"/bm_words.db",NULL);
00661 gchar* tmp_t = g_strconcat(tmp,"/bm_trans.db",NULL);
00662
00663 BTREEINFO inf = {
00664 0,
00665 0,
00666 0,
00667 0,
00668 0,
00669 bm_compare_key_words,
00670 NULL
00671 };
00672 data->info_words = inf;
00673 inf.compare = bm_compare_key_trans;
00674 data->info_trans = inf;
00675
00676 data->db_words =
00677 dbopen(tmp_w,
00678 flags,
00679 0755,
00680 DB_BTREE,
00681 &(data->info_words)
00682 );
00683 if(data->db_words == NULL)
00684 {
00685 g_free(data);
00686 g_free(result);
00687 result = NULL;
00688 }
00689 else {
00690 data->db_trans =
00691 dbopen(tmp_t,
00692 flags,
00693 0755,
00694 DB_BTREE,
00695 &(data->info_trans)
00696 );
00697
00698 if(data->db_trans == NULL)
00699 {
00700 data->db_words->close(data->db_words);
00701 g_free(data);
00702 g_free(result);
00703 result = NULL;
00704 }
00705
00706 }
00707 g_free(tmp_w); tmp_w = NULL;
00708 g_free(tmp_t); tmp_t = NULL;
00709 if(result == NULL) {
00710 LOGS("Bookmark/%s->%s() opening bookmark file failed.\n",
00711 (gchar*)__FILE__,
00712 (gchar*)__FUNCTION__
00713 );
00714 }
00715 else {
00716 LOGS("Bookmark/%s->%s()opening dictionary file successed.\n",
00717 (gchar*)__FILE__,
00718 (gchar*)__FUNCTION__
00719 );
00720 data->dict_path = g_strdup(tmp);
00721 data->cb_progress_caching = progress_handler;
00722 data->cb_progress_caching_data = progress_data;
00723 data->cb_progress_caching_seed = seed;
00724 data->cb_progress_word_list = NULL;
00725 data->cb_progress_word_list_data = NULL;
00726 data->cb_progress_word_list_seed = 0.01;
00727 data->cb_progress_word_trans = NULL;
00728 data->cb_progress_word_trans_data = NULL;
00729 data->cb_progress_word_trans_seed = 0.01;
00730
00731 data->cb_search_word_list = NULL;
00732 data->cb_search_word_list_data = NULL;
00733
00734 data->cb_search_word_trans = NULL;
00735 data->cb_search_word_trans_data = NULL;
00736
00737 data->auto_free = FALSE;
00738
00739 bm_load_freeID(data);
00740
00741 }
00742 g_free(tmp); tmp = NULL;
00743
00744 bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__);
00745 LOGS("Bookmark/%s->%s() returned Engine at adress=%p\n",
00746 (gchar*)__FILE__,
00747 (gchar*)__FUNCTION__,
00748 result
00749 );
00750 return result;
00751 }
00752
00753
00754
00755
00756 static gboolean is_Bookmark_db_file(gchar* file) {
00757 LOGS("Bookmark/%s->%s() called.\n\
00758 -->PARAM:file=\'%s\'\n",
00759 (gchar*)__FILE__,
00760 (gchar*)__FUNCTION__,
00761 file
00762 );
00763
00764 u_int32_t flags = O_RDWR;
00765 DB* dbp = dbopen(file,flags,0755,DB_BTREE,NULL);
00766
00767 if(NULL == dbp)
00768 {
00769 LOGS("Could no open! Wrong database! Not a bookmark.\n");
00770 return FALSE;
00771 };
00772
00773 DBT search = {"four",sizeof("four")};
00774 DBT result = {NULL, 0};
00775
00776 int errCode = dbp->get(dbp,&search,&result,0);
00777 dbp->close(dbp);
00778 g_free(result.data);
00779
00780 if(-1 == errCode)
00781 {
00782 LOGS("Could not read! Wrong database! Not a bookmark.\n");
00783 return FALSE;
00784 };
00785 return TRUE;
00786 }
00787
00788
00789
00790 void bm_engine_optimize(Engine* engine)
00791 {
00792 LOGS("Bookmark/%s->%s() called for engine at adress=%p\n",
00793 (gchar*)__FILE__,
00794 (gchar*)__FUNCTION__,
00795 engine
00796 );
00797 LOGS("Unsupported optimization mechanizm for this engine!\n");
00798 LOGS("Bookmark/%s->%s()'s work finished.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
00799 }
00800
00801 gboolean bm_engine_check(gchar* location)
00802 {
00803 LOGS("Bookmark/%s->%s() called.\n-->PARAM:location=\'%s\'\n",
00804 (gchar*)__FILE__,
00805 (gchar*)__FUNCTION__,
00806 location
00807 );
00808 bm_timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__);
00809 gboolean result = TRUE;
00810 gchar* filepath = g_strdup(location);
00811 gchar* tmp = NULL;
00812 gchar* tmp2 = NULL;
00813
00814 string_to_path(&filepath);
00815 if (filepath == NULL) {
00816 result = FALSE;
00817 LOGS("Bookmark/%s->%s() location \'%s\' is not a proper "
00818 "path!\n",
00819 (gchar*)__FILE__,
00820 (gchar*)__FUNCTION__,
00821 location
00822 );
00823 }
00824 else {
00825 tmp = g_strconcat(filepath,"/bm_words.db",NULL);
00826 tmp2 = g_strconcat(filepath,"/bm_trans.db",NULL);
00827 g_free(filepath);
00828 filepath = tmp;
00829 tmp = NULL;
00830
00831 LOGS("Bookmark/%s->%s() finnal file to check is: %s\n",
00832 (gchar*)__FILE__,
00833 (gchar*)__FUNCTION__,
00834 filepath
00835 );
00836 if (!g_file_test(filepath, G_FILE_TEST_IS_REGULAR) ||
00837 !g_file_test(tmp2, G_FILE_TEST_IS_REGULAR)
00838 ) {
00839 LOGS("Bookmark/%s->%s() file \'%s\' does not exists!\n",
00840 (gchar*)__FILE__,
00841 (gchar*)__FUNCTION__,
00842 filepath
00843 );
00844 result = FALSE;
00845 };
00846 };
00847 if (result != FALSE) {
00848 result = is_Bookmark_db_file(filepath) &
00849 is_Bookmark_db_file(tmp2);
00850 };
00851
00852 g_free(filepath); filepath = NULL;
00853 g_free(tmp2); tmp2 = NULL;
00854 bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__);
00855 LOGS("Bookmark/%s->%s() returned bool statement=%s.\n",
00856 (gchar*)__FILE__,
00857 (gchar*)__FUNCTION__,
00858 PRINT_STATE(result)
00859 );
00860 return result;
00861 }
00862
00863
00864 gboolean bm_engine_is_optimized(Engine* engine)
00865 {
00866 LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n",
00867 (gchar*)__FILE__,
00868 (gchar*)__FUNCTION__,
00869 engine
00870 );
00871 g_assert(engine != NULL);
00872 gboolean result = FALSE;
00873 LOGS("Bookmark/%s->%s() returned bool statement=%s.\n",
00874 (gchar*)__FILE__,
00875 (gchar*)__FUNCTION__,
00876 PRINT_STATE(result)
00877 );
00878 return result;
00879 }
00880
00881
00882 void bm_engine_search_word_list(Engine* engine,
00883 gchar* pattern,
00884 gpointer cb_data)
00885 {
00886 LOGS("Bookmark/%s->%s() called. Searching words list\n"
00887 "-->PARAM:engine at adress=%p\n"
00888 "-->PARAM:pattern=\"%s\"\n",
00889 (gchar*)__FILE__,
00890 (gchar*)__FUNCTION__,
00891 engine,
00892 pattern
00893 );
00894 g_assert(engine != NULL);
00895 g_assert(pattern != NULL);
00896
00897 bm_timer(TIMER_START,(gchar*)(gchar*)__FUNCTION__);
00898 BookData* data = (BookData*)(engine->engine_data);
00899 if(data->cb_search_word_list == NULL) {
00900 LOGS("Bookmark/%s->%s() callback for Word List not set. "
00901 "Searching aborted.\n",
00902 (gchar*)__FILE__,
00903 (gchar*)__FUNCTION__
00904 );
00905 bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__);
00906 return;
00907 };
00908
00909 GArray* result = g_array_new(TRUE, TRUE, sizeof(gchar*) );
00910 guint a = G_MAXUINT32;
00911 DBT search = { &a , sizeof(a) };
00912 DBT reply = { NULL , 0 };
00913 gchar* down_word = NULL;
00914 gchar *tmp;
00915
00916 GPatternSpec* regex;
00917 regex = g_pattern_spec_new (g_utf8_casefold(pattern,-1));
00918
00919 gint code = data->db_words->sync(data->db_words, 0);
00920 code = data->db_words->seq(data->db_words, &search, &reply, R_FIRST);
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 while(0 == code) {
00936 tmp = g_strconcat ((gchar*)(search.data), " ", NULL);
00937 down_word = g_utf8_casefold(tmp,-1);
00938 g_free (tmp);
00939 tmp = g_utf8_casefold ((gchar*)(search.data),-1);
00940
00941 if(( g_pattern_match_string( regex, down_word ) == TRUE ) ||
00942 ( g_pattern_match_string( regex, tmp ) == TRUE ))
00943 {
00944 g_free (tmp);
00945 tmp = g_strdup(search.data);
00946 g_array_append_val(result, tmp );
00947 };
00948
00949
00950 if(NULL != down_word)
00951 {
00952 g_free(down_word);
00953 down_word = NULL;
00954 }
00955 code = data->db_words->seq(data->db_words, &search, &reply, R_NEXT);
00956 }
00957
00958 bm_timer(TIMER_STOP,(gchar*)(gchar*)__FUNCTION__);
00959 g_pattern_spec_free (regex);
00960
00961
00962 bm_timer(TIMER_START,"callback for returning words LIST START");
00963
00964
00965 if ( NULL == cb_data )
00966 {
00967 cb_data = data->cb_search_word_list_data;
00968 }
00969 data->cb_search_word_list(result, pattern, cb_data, ENGINE_NO_ERROR);
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985 guint len = 0;
00986
00987 while(NULL != (tmp = g_array_index(result,gchar*,len++)))
00988 {
00989 g_free(tmp); tmp = NULL;
00990 }
00991 g_array_free(result, TRUE);
00992 bm_timer(TIMER_STOP,"callback for returning word LIST END");
00993 }
00994
00995
00996
00997
00998
00999
01000
01001 EngineModule engine_global_functions()
01002 {
01003 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01004 EngineModule result;
01005 result.engine_check = bm_engine_check;
01006 result.engine_description = bm_engine_description;
01007 result.engine_format = bm_engine_format;
01008 result.engine_version = bm_engine_version;
01009 result.engine_create = bm_engine_create;
01010 LOGS("Bookmark/%s->%s()returned EngineModule at adress=%p.\n",
01011 (gchar*)__FILE__,
01012 (gchar*)__FUNCTION__,
01013 &result
01014 );
01015 return result;
01016 }
01017
01018
01019 gchar* bm_engine_status_message(EngineStatus error)
01020 {
01021 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01022 switch (error) {
01023 case ENGINE_NO_ERROR:
01024 return "No error.";
01025 case ENGINE_WRONG_FILE:
01026 return "File which You are trying to use is wrong type.";
01027 case ENGINE_COULDNT_READ:
01028 return "Could not read from file.";
01029 case ENGINE_NO_FILE:
01030 return "There is no such a file.";
01031 case ENGINE_OUT_OF_MEMORY:
01032 return "There were no enough memory for this action.";
01033 default:
01034 return "Wrong engine's status identifier!";
01035 }
01036 }
01037
01038
01039 gchar* bm_engine_version()
01040 {
01041 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01042 gchar* result = g_strdup(DIC_ENG_VERSION);
01043 LOGS("Bookmark/%s->%s() return string=%s\n",
01044 (gchar*)__FILE__,
01045 (gchar*)__FUNCTION__,
01046 result
01047 );
01048 return result;
01049 }
01050
01051
01052 gchar* bm_engine_format()
01053 {
01054 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01055 gchar* result = g_strdup(DIC_ENG_FORMAT);
01056 LOGS("Bookmark/%s->%s() return string=%s\n",
01057 (gchar*)__FILE__,
01058 (gchar*)__FUNCTION__,
01059 result
01060 );
01061 return result;
01062 }
01063
01064
01065 gchar* bm_engine_description()
01066 {
01067 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01068 gchar* result = g_strdup(DIC_ENG_DESCRIPTION);
01069 LOGS("Bookmark/%s->%s() return string=%s\n",
01070 (gchar*)__FILE__,
01071 (gchar*)__FUNCTION__,
01072 result
01073 );
01074 return result;
01075 }
01076
01077
01078 gchar* bm_engine_location(Engine* engine)
01079 {
01080 LOGS("Bookmark/%s->%s() called.\n-->PARAM: engine adress=%p\n",
01081 (gchar*)__FILE__,
01082 (gchar*)__FUNCTION__,
01083 engine
01084 );
01085 g_assert(engine != NULL);
01086 BookData* data = (BookData*)(engine->engine_data);
01087
01088 gchar* result;
01089 if(data->auto_free) {
01090 result = data->dict_path;
01091 }
01092 else {
01093 result = g_strdup(data->dict_path);
01094 }
01095
01096 LOGS("Bookmark/%s->%s() returned string=%s\n",
01097 (gchar*)__FILE__,
01098 (gchar*)__FUNCTION__,
01099 result
01100 );
01101 return result;
01102 }
01103
01104
01105 void bm_engine_set_auto_free(Engine* engine, gboolean state)
01106 {
01107 LOGS("Bookmark/%s->%s() called.\n"
01108 "-->PARAM:engine at adress=%p\n"
01109 "-->PARAM:state=%s\n",
01110 (gchar*)__FILE__,
01111 (gchar*)__FUNCTION__,
01112 engine,
01113 PRINT_STATE(state)
01114 );
01115 g_assert(engine != NULL);
01116 BookData* data = (BookData*)(engine->engine_data);
01117
01118 data->auto_free = state;
01119 LOGS("Bookmark/%s->%s() Current auto_free is %s\n",
01120 (gchar*)__FILE__,
01121 (gchar*)__FUNCTION__,
01122 PRINT_STATE(data->auto_free)
01123 );
01124 }
01125
01126
01127 EngineStatus bm_engine_status(Engine* engine)
01128 {
01129 LOGS("Bookmark/%s->%s() called.\n"
01130 "-->PARAM:engine at adress=%p\n",
01131 (gchar*)__FILE__,
01132 (gchar*)__FUNCTION__,
01133 engine
01134 );
01135 BookData* data = (BookData*)(engine->engine_data);
01136 LOGS("Bookmark/%s->%s() returned error code: %d\n",
01137 (gchar*)__FILE__,
01138 (gchar*)__FUNCTION__,
01139 (gint)(data->last_error)
01140 );
01141 return data->last_error;
01142 }
01143
01144
01145 void bm_engine_set_progress_seed(Engine* engine, gchar* signal, gdouble seed) {
01146 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01147 BookData* data = (BookData*)(engine->engine_data);
01148 if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) {
01149 data->cb_progress_caching_seed = seed;
01150 LOGS("Bookmark/%s->%s() sets new seed=%0.2f for for signal "
01151 "\"%s\".\n",
01152 (gchar*)__FILE__,
01153 (gchar*)__FUNCTION__,
01154 seed,
01155 signal
01156 );
01157 }
01158 else {
01159 LOGS("Bookmark/%s->%s() unsupported signalfor progress: %s.\n",
01160 (gchar*)__FILE__,
01161 (gchar*)__FUNCTION__,
01162 signal
01163 );
01164 };
01165 }
01166
01167
01168 gpointer bm_engine_set_callback(Engine* engine,
01169 gchar* signal,
01170 gpointer c_handler,
01171 gpointer user_data)
01172 {
01173 LOGS("Bookmark/%s->%s() called.\n",(gchar*)__FILE__,(gchar*)__FUNCTION__);
01174 g_assert(engine != NULL);
01175 g_assert(signal != NULL);
01176 g_assert(c_handler != NULL);
01177 BookData* data = (BookData*)(engine->engine_data);
01178 if(g_ascii_strcasecmp(signal,ENGINE_PROGRESS_OPTIMIZING_SIGNAL) == 0) {
01179 gpointer result = data->cb_progress_caching;
01180 data->cb_progress_caching = c_handler;
01181 data->cb_progress_caching_data = user_data;
01182 LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n",
01183 (gchar*)__FILE__,
01184 (gchar*)__FUNCTION__,
01185 signal
01186 );
01187 LOGS("Bookmark/%s->%s() Function at adress = %d.\n",
01188 (gchar*)__FILE__,
01189 (gchar*)__FUNCTION__,
01190 (guint)c_handler
01191 );
01192 LOGS("Bookmark/%s->%s() Data at adress = %d.\n",
01193 (gchar*)__FILE__,
01194 (gchar*)__FUNCTION__,
01195 (guint)user_data
01196 );
01197 return result;
01198 }
01199 else if(g_ascii_strcasecmp(signal, ENGINE_WORD_LIST_SIGNAL) == 0) {
01200 gpointer result = data->cb_search_word_list;
01201 data->cb_search_word_list = c_handler;
01202 data->cb_search_word_list_data = user_data;
01203 LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n",
01204 (gchar*)__FILE__,
01205 (gchar*)__FUNCTION__,
01206 signal
01207 );
01208 LOGS("Bookmark/%s->%s() Function at adress = %d.\n",
01209 (gchar*)__FILE__,
01210 (gchar*)__FUNCTION__,
01211 (guint)c_handler
01212 );
01213 LOGS("Bookmark/%s->%s() Data at adress = %d.\n",
01214 (gchar*)__FILE__,
01215 (gchar*)__FUNCTION__,
01216 (guint)user_data
01217 );
01218 return result;
01219 }
01220 else if(g_ascii_strcasecmp(signal,
01221 ENGINE_WORD_TRANSLATION_SIGNAL) == 0) {
01222 gpointer result = data->cb_search_word_trans;
01223 data->cb_search_word_trans = c_handler;
01224 data->cb_search_word_trans_data = user_data;
01225 LOGS("Bookmark/%s->%s() sets handler for signal \"%s\".\n",
01226 (gchar*)__FILE__,
01227 (gchar*)__FUNCTION__,
01228 signal
01229 );
01230 LOGS("Bookmark/%s->%s() Function at adress = %d.\n",
01231 (gchar*)__FILE__,
01232 (gchar*)__FUNCTION__,
01233 (guint)c_handler
01234 );
01235 LOGS("Bookmark/%s->%s() Data at adress = %d.\n",
01236 (gchar*)__FILE__,
01237 (gchar*)__FUNCTION__,
01238 (guint)user_data
01239 );
01240 return result;
01241 }
01242 else {
01243 g_warning("Bookmark/%s->%s() unsupported signal: %s.\n",
01244 (gchar*)__FILE__,
01245 (gchar*)__FUNCTION__,
01246 signal
01247 );
01248 return NULL;
01249 }
01250 }
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 static gchar* string_to_path(gchar** string) {
01261 LOGS("Bookmark/%s->%s() called.\n\
01262 -->PARAM:string=\'%s\'\n",
01263 (gchar*)__FILE__,
01264 (gchar*)__FUNCTION__,
01265 string[0]
01266 );
01267 gchar* arg = string[0];
01268 gchar* new = NULL;
01269
01270 g_strstrip(arg);
01271
01272 if (!g_path_is_absolute(arg)) {
01273 gchar* tmp = g_get_current_dir();
01274 new = g_strconcat(tmp,"/",arg,NULL);
01275 g_free(arg); arg = new; new = NULL;
01276 };
01277
01278 if (!g_file_test(arg, G_FILE_TEST_IS_DIR)) {
01279
01280 if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR)) {
01281 g_free(arg);
01282 new = NULL;
01283 }
01284
01285 else
01286 {
01287 new = g_path_get_dirname (arg);
01288 g_free(arg);
01289 }
01290 }
01291
01292 else {
01293
01294 if (g_str_has_suffix(arg,"/") ) {
01295 new = g_path_get_dirname (arg);
01296 g_free(arg);
01297 }
01298 else {
01299 new = arg;
01300 }
01301 };
01302
01303 if (!g_file_test(new, G_FILE_TEST_IS_DIR)) {
01304
01305 g_free(new);
01306 new = NULL;
01307 };
01308
01309 string[0] = new;
01310 LOGS("Bookmark/%s->%s() returned string=\'%s\'\n",
01311 (gchar*)__FILE__,
01312 (gchar*)__FUNCTION__,
01313 string[0]
01314 );
01315 return new;
01316 }
01317
01318 static double bm_timer(gboolean start, gchar* message)
01319 {
01320 static GArray* stack = NULL;
01321 static gboolean first_run = TRUE;
01322 static struct timeval actual_time;
01323 static struct timeval last_time;
01324 static struct timeval result;
01325 static double seconds = 0.0;
01326 if(first_run) {
01327 first_run = FALSE;
01328 stack = g_array_new(TRUE, TRUE, sizeof(struct timeval));
01329 };
01330
01331 if (start) {
01332 LOGS("Bookmark->%s() start bm_timer for function '%s()'.\n",
01333 (gchar*)__FUNCTION__,
01334 message
01335 );
01336 g_array_prepend_val(stack, actual_time);
01337 gettimeofday(&g_array_index(stack, struct timeval, 0),NULL);
01338 return -1.0;
01339 }
01340
01341
01342 else {
01343 gettimeofday(&actual_time,NULL);
01344 last_time = g_array_index(stack, struct timeval, 0);
01345 g_array_remove_index(stack, 0);
01346
01347 if (actual_time.tv_usec < last_time.tv_usec) {
01348 int nsec = (last_time.tv_usec - actual_time.tv_usec) /
01349 (1000000 + 1);
01350 last_time.tv_usec -= 1000000 * nsec;
01351 last_time.tv_sec += nsec;
01352 }
01353 if (actual_time.tv_usec - last_time.tv_usec > 1000000) {
01354 int nsec = (last_time.tv_usec - actual_time.tv_usec) /
01355 1000000;
01356 last_time.tv_usec += 1000000 * nsec;
01357 last_time.tv_sec -= nsec;
01358 }
01359 result.tv_sec = actual_time.tv_sec - last_time.tv_sec;
01360 result.tv_usec = actual_time.tv_usec - last_time.tv_usec;
01361 seconds = (((double)(result.tv_usec)) / 1e6) +
01362 ((double)(result.tv_sec));
01363
01364 LOGS("Bookmark->%s() function \'%s()\' was working for: %g "
01365 "[s] or %ld [us].\n",
01366 (gchar*)__FUNCTION__,
01367 message,
01368 seconds,
01369 ((long)(result.tv_sec*1e6)+(result.tv_usec))
01370 );
01371
01372 if(stack->len == 0)
01373 {
01374 g_array_free(stack, TRUE);
01375 first_run = TRUE;
01376 }
01377 }
01378 return seconds;
01379 }
01380