src/plugins/stardict/src/engine_stardict.c

00001 /******************************************************************************
00002 This file is part of mdictionary.
00003 
00004 mdictionary is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 mdictionary is distributed in the hope that it will be useful, 
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License 
00015 along with mdictionary; if not, write to the Free Software
00016 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00017 
00018 Copyright 2006 ComArch S.A.
00019 ******************************************************************************/
00020 
00021 // header with data structure and function definition for XDXF engine.
00022 // Also Engine API. 
00023 #include <engine_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         // read into the buffer 'result'
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         // open file
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         // read from file to buffer
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                         // check next words
00142                         if(g_ascii_strncasecmp(tmp,word,pl) == 0 &&
00143                            strlen(tmp) == pl)
00144                         {
00145                                 // we have found word in dictionary
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                         // calculate length of word
00160                         len = strlen(tmp)+1;
00161                         // jump in buffer over this word, and ...
00162                         tmp += len;
00163                         // ...skip offset and length of translation
00164                         tmp += 2 * sizeof(guint);
00165                         // update i value
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         // there are no information about this parameter of dictionaries in
00322         // StarDict format
00323         data->lang_from = NULL;
00324         data->lang_to = NULL;
00325         // StarDict dictionaries do NOT support different icons, so set global
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 //      guint pl = strlen(pattern);
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                         // check next words
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                         // calculate length of word
00433                         len = strlen(tmp)+1;
00434                         // jump in buffer over this word, and ...
00435                         tmp += len;
00436                         // ...skip offset and length of translation
00437                         tmp += 2 * sizeof(guint);
00438                         // update i value
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         // start sd_timer for this function
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         // "parse" returned part of file with article about word
00531         gchar* trans = sd_parse_stardict_article(trans0,
00532                                                 data->types,
00533                                                 part->length
00534                                                 );
00535         g_free(trans0); trans0 = NULL;
00536 
00537         // check if returned article has apprioprate format (only text)
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         // calling callback for word translation
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         /*if(data->auto_free) {
00567                 eg_debug("---> %s() deleting all dynamic data because "
00568                         "AUTO_FREE=TRUE\n",
00569                         __FUNCTION__
00570                 );
00571                 g_free(trans);
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                 // printf first 100 bytes
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                 //print last 100 bytes
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                 // check if this is a text or binary data
00664                 // all text data are signaled by low level letter
00665                 if(g_ascii_islower(next_type))
00666                 {
00667                         // text, so add this to translation
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                         // binary, so skip it
00685                         // read hom many bytes to skip
00686                         guint len = 0;
00687                         g_memmove(&len, ptr, sizeof(guint));
00688                         //omit in buf and len - field containting size of data
00689                         length -= sizeof(guint);
00690                         ptr += sizeof(guint);
00691                         // conver network byte oredered guint to host ordered
00692                         len = ntohl(len);
00693                         // skip uneeded bytes
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 //----------------------------------------------------------- FINISHED FUNCTIONS
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         // we just want to end some sd_timer - print some information about 
00928         // working time;
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                 // stack is empty so we delete everything
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         // cleaning from leading and trailing whitespaces
00985         g_strstrip(arg); 
00986         // add current directory if this is not absolute directory
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         // this is not a directory
00994         if (!g_file_test(arg, G_FILE_TEST_IS_DIR))
00995         {
00996                 // if this is wrong filepath, string was wrong
00997                 if (!g_file_test(arg, G_FILE_TEST_IS_REGULAR))
00998                 {
00999                         g_free(arg);
01000                         new = NULL;
01001                 }
01002                 //if this is a file, remove filename
01003                 else
01004                 {
01005                         new = g_path_get_dirname (arg);
01006                         g_free(arg);
01007                 }
01008         }
01009         // this is a directory
01010         else
01011         {
01012                 // remove suffix "/" if neded...     
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         // now in new should be proper filepath, if not, string was wrong
01024         if (!g_file_test(new, G_FILE_TEST_IS_DIR))
01025         {
01026                 // if that directory does not exist, passed string wasn't proper
01027                 g_free(new);
01028                 new = NULL;
01029         };
01030         // replace string under passed address
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 // for macro: dict_eng_set_progress_seed(engine, signal, val)
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         /* ----- as far unsupported field from *.ifo files
01519         else if(g_ascii_strncasecmp(key,"author",100))
01520         {
01521         }
01522         else if(g_ascii_strncasecmp(key,"email",100))
01523         {
01524         }
01525         else if(g_ascii_strncasecmp(key,"website",100))
01526         {
01527         }
01528         else if(g_ascii_strncasecmp(key,"description",100))
01529         {
01530         }
01531         else if(g_ascii_strncasecmp(key,"date",100))
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         // open the file
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         // read whole content
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         // now we have in tmp whole content of file, we have to "parse it"
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 //-------------------------------------------------------------- STANDARD ------
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 //------------------------------------------------------- GZIPPED --------------
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 }

Generated on Fri Jan 11 14:30:17 2008 for mDictionary Project by  doxygen 1.5.1