Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 54227 Details for
Bug 86379
stardict-2.4.4-r1.ebuild
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
lib-fix.patch
lib-fix.patch (text/plain), 92.39 KB, created by
Evgeniy Dushistov
on 2005-03-23 05:41:59 UTC
(
hide
)
Description:
lib-fix.patch
Filename:
MIME Type:
Creator:
Evgeniy Dushistov
Created:
2005-03-23 05:41:59 UTC
Size:
92.39 KB
patch
obsolete
>diff -rbBdNu stardict-cur-accepted/configure.in stardict/configure.in >--- stardict-cur-accepted/configure.in 2004-10-19 07:05:00.000000000 +0400 >+++ stardict/configure.in 2005-02-20 13:55:57.000000000 +0300 >@@ -55,11 +55,9 @@ > > dnl ****************************** > >-AC_ARG_ENABLE(schemas-install,AC_HELP_STRING([--disable-schemas-install], >- [Disable installation of the gconf >-schemas])) >+dnl AC_ARG_ENABLE(schemas-install,AC_HELP_STRING([--disable-schemas-install], [Disable installation of the gconf schemas])) > >-AM_CONDITIONAL(SCHEMAS_INSTALL, test x$enable_schemas_install != xno) >+dnl AM_CONDITIONAL(SCHEMAS_INSTALL, test x$enable_schemas_install != xno) > > AC_PATH_PROG(GCONFTOOL, gconftool-2, no) > if test x"$GCONFTOOL" = xno; then >@@ -68,6 +66,7 @@ > fi > AM_GCONF_SOURCE_2 > >+AM_CONDITIONAL(SCHEMAS_INSTALL, test x$schemas_install = xtrue) > > dnl > dnl Check popt >diff -rbBdNu stardict-cur-accepted/src/dictmanagedlg.cpp stardict/src/dictmanagedlg.cpp >--- stardict-cur-accepted/src/dictmanagedlg.cpp 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/dictmanagedlg.cpp 2005-02-16 22:03:50.000000000 +0300 >@@ -44,129 +44,22 @@ > gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 1); > } > >-gboolean DictManageDlg::get_dict_info(gboolean istreedict, const gchar *ifofilename, glong *wordcount, gchar **bookname, gchar **author, gchar **email, >- gchar **website, gchar **date, gchar **description) >-{ >- struct stat stats; >- if (stat (ifofilename, &stats) == -1) { >- return false; >- } >- >- FILE *file; >- if (!(file = fopen (ifofilename, "rb"))) { >- return false; >- } >- gchar *buffer = (gchar *)g_malloc (stats.st_size + 1); >- fread (buffer, 1, stats.st_size, file); >- buffer[stats.st_size] = '\0'; >- fclose (file); >- >- if (!(istreedict?g_str_has_prefix(buffer, "StarDict's treedict ifo file\nversion=2.4.2\n"):g_str_has_prefix(buffer, "StarDict's dict ifo file\nversion=2.4.2\n"))) { >- g_free(buffer); >- return false; >- } >- >- gchar *p1,*p2,*p3; >- if (istreedict) >- p1 = buffer + sizeof("StarDict's treedict ifo file\nversion=2.4.2\n") -1 -1; >- else >- p1 = buffer + sizeof("StarDict's dict ifo file\nversion=2.4.2\n") -1 -1; >- >- p2 = strstr(p1,"\nwordcount="); >- if (p2) { >- p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n'); >- gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1); >- tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0'; >- *wordcount = atol(tmpstr); >- g_free(tmpstr); >- } >- else { >- *wordcount = 0; >- } >- >- p2 = strstr(p1,"\nbookname="); >- if (p2) { >- p2 = p2 + sizeof("\nbookname=") -1; >- p3 = strchr(p2, '\n'); >- *bookname = g_strndup(p2, p3-p2); >- } >- else { >- *bookname = NULL; >- } >- >- p2 = strstr(p1,"\nauthor="); >- if (p2) { >- p2 = p2 + sizeof("\nauthor=") -1; >- p3 = strchr(p2, '\n'); >- *author = g_strndup(p2, p3-p2); >- } >- else { >- *author = NULL; >- } >- >- p2 = strstr(p1,"\nemail="); >- if (p2) { >- p2 = p2 + sizeof("\nemail=") -1; >- p3 = strchr(p2, '\n'); >- *email = g_strndup(p2, p3-p2); >- } >- else { >- *email = NULL; >- } >- >- p2 = strstr(p1,"\nwebsite="); >- if (p2) { >- p2 = p2 + sizeof("\nwebsite=") -1; >- p3 = strchr(p2, '\n'); >- *website = g_strndup(p2, p3-p2); >- } >- else { >- *website = NULL; >- } >- >- p2 = strstr(p1,"\ndate="); >- if (p2) { >- p2 = p2 + sizeof("\ndate=") -1; >- p3 = strchr(p2, '\n'); >- *date = g_strndup(p2, p3-p2); >- } >- else { >- *date = NULL; >- } >- >- p2 = strstr(p1,"\ndescription="); >- if (p2) { >- p2 = p2 + sizeof("\ndescription=") -1; >- p3 = strchr(p2, '\n'); >- *description = g_strndup(p2, p3-p2); >- } >- else { >- *description = NULL; >- } >- >- g_free(buffer); >- return true; >-} >- > void DictManageDlg::load_dir(gboolean istreedict, const gchar *dirname, const GSList *order_list, const GSList *disable_list, GtkListStore *model) > { > GDir *dir = g_dir_open(dirname, 0, NULL); >- if (dir) >- { >+ if (dir) { > GtkTreeIter iter; > const gchar *filename; > gchar fullfilename[256]; > gboolean loaded; > const GSList *tmplist1,*tmplist2; > gboolean disabled; >- glong wordcount; >- gchar *bookname, *author, *email, *website, *description, *date; >+ DictInfo dict_info; > while ((filename = g_dir_read_name(dir))!=NULL) { > sprintf(fullfilename, "%s/%s", dirname, filename); > if (g_file_test(fullfilename, G_FILE_TEST_IS_DIR)) { > load_dir(istreedict, fullfilename, order_list, disable_list, model); >- } >- else if (g_str_has_suffix(filename,".ifo")) { >+ } else if (g_str_has_suffix(filename,".ifo")) { > tmplist1 = order_list; > loaded = false; > while (tmplist1) { >@@ -178,7 +71,7 @@ > } > if (loaded) > continue; >- if (get_dict_info(istreedict, fullfilename, &wordcount, &bookname, &author, &email, &website, &description, &date)) { >+ if (dict_info.load_from_ifo_file(fullfilename, istreedict)) { > tmplist2 = disable_list; > disabled = false; > while (tmplist2) { >@@ -189,13 +82,15 @@ > tmplist2 = g_slist_next(tmplist2); > } > gtk_list_store_append (model, &iter); >- gtk_list_store_set (model, &iter, 0, !disabled, 1, bookname, 2, wordcount, 3, author, 4, email, 5, website, 6, date, 7, description, 8, fullfilename, 9, true, -1); >- g_free(bookname); >- g_free(author); >- g_free(email); >- g_free(website); >- g_free(description); >- g_free(date); >+ gtk_list_store_set (model, &iter, 0, !disabled, >+ 1, dict_info.bookname.c_str(), >+ 2, dict_info.wordcount, >+ 3, dict_info.author.c_str(), >+ 4, dict_info.email.c_str(), >+ 5, dict_info.website.c_str(), >+ 6, dict_info.date.c_str(), >+ 7, dict_info.description.c_str(), >+ 8, fullfilename, 9, true, -1); > } > } > } >@@ -218,8 +113,6 @@ > disable_list=conf->get_dict_disable_list(); > } > >- glong wordcount; >- gchar *bookname, *author, *email, *website, *description, *date; > > GtkTreeIter iter; > >@@ -230,9 +123,9 @@ > while (tmplist1) { > ifofilename = (gchar *)(tmplist1->data); > tmplist1 = g_slist_next(tmplist1); >- >+ DictInfo dict_info; > if (g_file_test(ifofilename, G_FILE_TEST_EXISTS)) { >- if (get_dict_info(istreedict, ifofilename, &wordcount, &bookname, &author, &email, &website, &description, &date)) { >+ if (dict_info.load_from_ifo_file(ifofilename, istreedict)) { > tmplist2 = disable_list; > disabled = false; > while (tmplist2) { >@@ -243,13 +136,15 @@ > tmplist2 = g_slist_next(tmplist2); > } > gtk_list_store_append (model, &iter); >- gtk_list_store_set (model, &iter, 0, !disabled, 1, bookname, 2, wordcount, 3, author, 4, email, 5, website, 6, date, 7, description, 8, ifofilename, 9, true, -1); >- g_free(bookname); >- g_free(author); >- g_free(email); >- g_free(website); >- g_free(description); >- g_free(date); >+ gtk_list_store_set (model, &iter, 0, !disabled, >+ 1, dict_info.bookname.c_str(), >+ 2, dict_info.wordcount, >+ 3, dict_info.author.c_str(), >+ 4, dict_info.email.c_str(), >+ 5, dict_info.website.c_str(), >+ 6, dict_info.description.c_str(), >+ 7, dict_info.date.c_str(), >+ 8, ifofilename, 9, true, -1); > } > } > } >diff -rbBdNu stardict-cur-accepted/src/dictmanagedlg.h stardict/src/dictmanagedlg.h >--- stardict-cur-accepted/src/dictmanagedlg.h 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/dictmanagedlg.h 2005-02-16 22:02:05.000000000 +0300 >@@ -19,8 +19,6 @@ > > GtkWidget *create_buttons(); > >- static gboolean get_dict_info(gboolean istreedict, const gchar *ifofilename, glong *wordcount, gchar **bookname, gchar **author, gchar **email, >- gchar **website, gchar **date, gchar **description); > void write_order_list(gboolean istreedict); > > static void on_wazard_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg); >diff -rbBdNu stardict-cur-accepted/src/distance.cpp stardict/src/distance.cpp >--- stardict-cur-accepted/src/distance.cpp 2003-09-23 14:19:48.000000000 +0400 >+++ stardict/src/distance.cpp 2005-02-15 23:17:54.000000000 +0300 >@@ -32,12 +32,14 @@ > * DNA analysis > * Plagiarism detection > */ >-#include "distance.h" >+ > > #include <stdlib.h> > #include <string.h> > //#include <stdio.h> > >+#include "distance.h" >+ > #define OPTIMIZE_ED > /* > Cover transposition, in addition to deletion, >diff -rbBdNu stardict-cur-accepted/src/distance.h stardict/src/distance.h >--- stardict-cur-accepted/src/distance.h 2003-09-23 14:19:44.000000000 +0400 >+++ stardict/src/distance.h 2005-02-15 23:18:22.000000000 +0300 >@@ -5,7 +5,7 @@ > #include <config.h> > #endif > >-#include <gtk/gtk.h> >+#include <glib.h> > > class EditDistance { > private: >diff -rbBdNu stardict-cur-accepted/src/floatwin.cpp stardict/src/floatwin.cpp >--- stardict-cur-accepted/src/floatwin.cpp 2005-02-20 13:36:22.684560680 +0300 >+++ stardict/src/floatwin.cpp 2005-02-19 18:21:57.000000000 +0300 >@@ -185,9 +185,8 @@ > mark += "</big></b>"; > > gchar *p; >- glong data_size,sec_size; >- for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++) >- { >+ guint32 data_size, sec_size=0; >+ for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++) { > if (word[i]) { > mark += "\n<span foreground=\"blue\">*--- "; > m_str = g_markup_escape_text(gpAppFrame->oAppCore.oLibs.GetBookname(i),-1); >@@ -204,28 +203,35 @@ > } > } > if (data[i]) { >- memcpy(&data_size,data[i],sizeof(glong)); >- p=data[i]+sizeof(glong); >- while (p - (data[i] + sizeof(glong))< data_size) >- { >- switch (*p) >- { >+ p=data[i]; >+ data_size=*reinterpret_cast<guint32 *>(p); >+ p+=sizeof(guint32); >+ while (guint32(p - (data[i] + sizeof(guint32)))< data_size) { >+ switch (*p++) { > case 'm': >- case 'o': //need more work... >- sec_size = strlen(p+sizeof(gchar)); >+ case 'l'://need more work >+ sec_size = strlen(p); > if (sec_size) { > mark+= "\n"; >- m_str = g_markup_escape_text(p+sizeof(gchar),sec_size); >+ m_str = g_markup_escape_text(p, sec_size); > mark += m_str; > g_free(m_str); > } > sec_size++; > break; >+ case 'g': >+ sec_size = strlen(p); >+ if (sec_size) { >+ mark += "\n"; >+ mark += p; >+ } >+ sec_size++; >+ break; > case 't': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { > mark += "\n<big>["; >- m_str = g_markup_escape_text(p+sizeof(gchar),sec_size); >+ m_str = g_markup_escape_text(p, sec_size); > mark += m_str; > g_free(m_str); > mark+= "]</big>"; >@@ -233,10 +239,10 @@ > sec_size++; > break; > case 'y': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { > mark += "\n<span foreground=\"red\">["; >- m_str = g_markup_escape_text(p+sizeof(gchar),sec_size); >+ m_str = g_markup_escape_text(p, sec_size); > mark += m_str; > g_free(m_str); > mark+= "]</span>"; >@@ -244,16 +250,20 @@ > sec_size++; > break; > case 'W': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >+ sec_size=*reinterpret_cast<guint32 *>(p); >+ sec_size=g_ntohl(sec_size); > //enbale sound button. >- sec_size+= sizeof(glong); >+ sec_size+=sizeof(guint32); > break; > case 'P': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >- sec_size+= sizeof(glong); >+ sec_size=*reinterpret_cast<guint32 *>(p); >+ sec_size=g_ntohl(sec_size); >+ sec_size+= sizeof(guint32); > break; >+ default: >+ /*nothing*/; > } >- p = p+sizeof(gchar)+sec_size; >+ p += sec_size; > } > } > } >@@ -262,8 +272,7 @@ > gboolean canRead = gpAppFrame->oReadWord.canRead(sOriginWord); > if (canRead) { > PronounceWord = sOriginWord; >- } >- else { >+ } else { > for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs(); i++) { > if (word[i] && strcmp(word[i], sOriginWord)) { > if (gpAppFrame->oReadWord.canRead(word[i])) { >@@ -281,7 +290,9 @@ > gpAppFrame->oReadWord.read(PronounceWord.c_str()); > } > >-void FloatWin::ShowText(gchar *** pppWord, gchar *** pppWordData, const gchar ** ppOriginWord, gint count,const gchar * sOriginWord) >+void FloatWin::ShowText(gchar *** pppWord, gchar *** pppWordData, >+ const gchar ** ppOriginWord, gint count, >+ const gchar * sOriginWord) > { > QueryingWord = sOriginWord; > found_result = FLOAT_WIN_FUZZY_FOUND; >@@ -297,18 +308,16 @@ > mark += _("Found "); > if (count ==1) > mark+= _("1 word:\n"); >- else >- { >+ else { > m_str=g_strdup_printf("%d",count); > mark += m_str; > g_free(m_str); > mark+= _(" words:\n"); > } > int j; >- for (j=0;j<count-1;j++) >- { >+ for (j=0; j<count-1; j++) { > mark += "<b><big>"; >- m_str = g_markup_escape_text(ppOriginWord[j],-1); >+ m_str = g_markup_escape_text(ppOriginWord[j], -1); > mark += m_str; > g_free(m_str); > mark += "</big></b> "; >@@ -320,17 +329,15 @@ > mark += "</big></b>"; > > gchar *p; >- glong data_size,sec_size; >- for (j=0;j<count;j++) >- { >+ guint32 data_size,sec_size; >+ for (j=0; j<count; j++) { > mark += "\n\n<span foreground=\"red\">#----- "; > m_str = g_markup_escape_text(ppOriginWord[j],-1); > mark += m_str; > g_free(m_str); > mark += " -----#</span>"; > >- for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++) >- { >+ for (int i=0; i<gpAppFrame->oAppCore.oLibs.total_libs(); i++) { > if (pppWord[j][i]) { > mark += "\n<span foreground=\"blue\">*--- "; > m_str = g_markup_escape_text(gpAppFrame->oAppCore.oLibs.GetBookname(i),-1); >@@ -347,29 +354,35 @@ > } > } > if (pppWordData[j][i]) { >- memcpy(&data_size,pppWordData[j][i],sizeof(glong)); >- p=pppWordData[j][i]+sizeof(glong); >- >- while (p - (pppWordData[j][i] + sizeof(glong))< data_size) >- { >- switch (*p) >- { >+ p=pppWordData[j][i]; >+ data_size=*reinterpret_cast<guint32 *>(p); >+ p+=sizeof(guint32); >+ while (guint32(p - (pppWordData[j][i] + sizeof(guint32)))< data_size) { >+ switch (*p++) { > case 'm': >- case 'o': //need more work... >- sec_size = strlen(p+sizeof(gchar)); >+ case 'l': //need more work... >+ sec_size = strlen(p); > if (sec_size) { > mark+= "\n"; >- m_str = g_markup_escape_text(p+sizeof(gchar),sec_size); >+ m_str = g_markup_escape_text(p,sec_size); > mark += m_str; > g_free(m_str); > } > sec_size++; > break; >+ case 'g': >+ sec_size = strlen(p); >+ if (sec_size) { >+ mark += "\n"; >+ mark += p; >+ } >+ sec_size++; >+ break; > case 't': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { > mark += "\n<big>["; >- m_str = g_markup_escape_text(p+sizeof(gchar),sec_size); >+ m_str = g_markup_escape_text(p, sec_size); > mark += m_str; > g_free(m_str); > mark+= "]</big>"; >@@ -377,10 +390,10 @@ > sec_size++; > break; > case 'y': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { > mark += "\n<span foreground=\"red\">["; >- m_str = g_markup_escape_text(p+sizeof(gchar),sec_size); >+ m_str = g_markup_escape_text(p, sec_size); > mark += m_str; > g_free(m_str); > mark+= "]</span>"; >@@ -388,16 +401,20 @@ > sec_size++; > break; > case 'W': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >+ sec_size=*reinterpret_cast<guint32 *>(p); >+ sec_size=g_ntohl(sec_size); > //enbale sound button. >- sec_size+= sizeof(glong); >+ sec_size+= sizeof(guint32); > break; > case 'P': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >- sec_size+= sizeof(glong); >+ sec_size=*reinterpret_cast<guint32 *>(p); >+ sec_size=g_ntohl(sec_size); >+ sec_size+= sizeof(guint32); > break; >+ default: >+ /*nothing*/; > } >- p = p+sizeof(gchar)+sec_size; >+ p += sec_size; > } > } > } >diff -rbBdNu stardict-cur-accepted/src/lib.cpp stardict/src/lib.cpp >--- stardict-cur-accepted/src/lib.cpp 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/lib.cpp 2005-02-20 14:26:40.034853712 +0300 >@@ -2,32 +2,235 @@ > # include "config.h" > #endif > >+#include <cstring> >+#include <cctype> > >-#include "lib.h" >-#include "stardict.h" > #include <sys/stat.h> >-#include "string.h" >-#include "zlib.h" >+#include <zlib.h> > #ifdef HAVE_MMAP >-#include <sys/types.h> >-#include <fcntl.h> >-#include <sys/mman.h> >+# include <sys/types.h> >+# include <fcntl.h> >+# include <sys/mman.h> > #endif >+#include <algorithm> > >-// Notice: read src/tools/DICTFILE_FORMAT for the dictionary file's format information! >+#include "distance.h" > >-cacheItem::cacheItem() >+#include "lib.h" >+ >+// Notice: read src/tools/DICTFILE_FORMAT for the dictionary >+// file's format information! >+ >+class MapFile { >+public: >+ MapFile(void) : data(NULL) {} >+ ~MapFile(); >+ bool open(const gchar *file_name, gulong file_size); >+ inline gchar *begin(void) { return data; } >+private: >+ gchar *data; >+ gulong size; >+#ifdef HAVE_MMAP >+ int mmap_fd; >+#elif defined(_WIN32) >+ HANDLE hFile; >+ HANDLE hFileMap; >+#endif >+}; >+ >+inline bool MapFile::open(const gchar *file_name, gulong file_size) > { >- data= NULL; >+ size=file_size; >+#ifdef HAVE_MMAP >+ if ((mmap_fd = ::open(file_name, O_RDONLY)) < 0) { >+ //g_print("Open file %s failed!\n",fullfilename); >+ return false; >+ } >+ data = (gchar *)mmap( NULL, file_size, PROT_READ, MAP_SHARED, mmap_fd, 0); >+ if ((void *)data == (void *)(-1)) { >+ //g_print("mmap file %s failed!\n",idxfilename); >+ data=NULL; >+ return false; >+ } >+#else >+# ifdef _WIN32 >+ hFile = CreateFile(file_name, GENERIC_READ, 0, NULL, OPEN_ALWAYS, >+ FILE_ATTRIBUTE_NORMAL, 0); >+ hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, >+ file_size, NULL); >+ data = (gchar *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, file_size); >+# else >+ gsize read_len; >+ if (!g_file_get_contents(file_name, &data, &read_len, NULL)) >+ return false; >+ >+ if (read_len!=file_size) >+ return false; >+# endif >+#endif >+ >+ return true; > } > >-cacheItem::~cacheItem() >+inline MapFile::~MapFile() > { >- if (data) >+ if (!data) >+ return; >+#ifdef HAVE_MMAP >+ munmap(data, size); >+ close(mmap_fd); >+#else >+# ifdef _WIN32 >+ UnmapViewOfFile(data); >+ CloseHandle(hFileMap); >+ CloseHandle(hFile); >+# else > g_free(data); >+# endif >+#endif >+} >+ >+inline bool bIsVowel(gchar inputchar) >+{ >+ gchar ch = g_ascii_toupper(inputchar); >+ return( ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ); >+} >+ >+bool bIsPureEnglish(const gchar *str) >+{ >+ // i think this should work even when it is UTF8 string :). >+ for (int i=0; str[i]!=0; i++) >+ //if(str[i]<0) >+ //if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK. >+ // Better use isascii() but not str[i]<0 while char is default unsigned in arm >+ if (!isascii(str[i])) >+ return false; >+ return true; >+} >+ >+inline gint stardict_strcmp(const gchar *s1, const gchar *s2) { >+ gint a=g_ascii_strcasecmp(s1, s2); >+ if (a == 0) >+ return strcmp(s1, s2); >+ else >+ return a; > } > >+bool DictInfo::load_from_ifo_file(const gchar *ifofilename, >+ bool istreedict) >+{ >+ ifo_file_name=ifofilename; >+ gchar *buffer; >+ if (!g_file_get_contents(ifofilename, &buffer, NULL, NULL)) >+ return false; >+ >+#define TREEDICT_MAGIC_DATA "StarDict's treedict ifo file\nversion=2.4.2\n" >+#define DICT_MAGIC_DATA "StarDict's dict ifo file\nversion=2.4.2\n" >+ const gchar *magic_data=istreedict ? TREEDICT_MAGIC_DATA : DICT_MAGIC_DATA; >+ if (!g_str_has_prefix(buffer, magic_data)) { >+ g_free(buffer); >+ return false; >+ } >+ >+ gchar *p1,*p2,*p3; >+ >+ p1 = buffer + strlen(magic_data)-1; >+ >+ p2 = strstr(p1,"\nwordcount="); >+ if (!p2) { >+ g_free(buffer); >+ return false; >+ } >+ >+ p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n'); >+ gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1); >+ tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0'; >+ wordcount = atol(tmpstr); >+ g_free(tmpstr); >+ >+ if (istreedict) { >+ p2 = strstr(p1,"\ntdxfilesize="); >+ if (!p2) { >+ g_free(buffer); >+ return false; >+ } >+ p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n'); >+ tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1); >+ tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0'; >+ index_file_size = atol(tmpstr); >+ g_free(tmpstr); >+ } else { >+ >+ p2 = strstr(p1,"\nidxfilesize="); >+ if (!p2) { >+ g_free(buffer); >+ return false; >+ } >+ >+ p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n'); >+ tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1); >+ tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0'; >+ index_file_size = atol(tmpstr); >+ g_free(tmpstr); >+ } >+ >+ p2 = strstr(p1,"\nbookname="); >+ >+ if (!p2) { >+ g_free(buffer); >+ return false; >+ } > >+ p2 = p2 + sizeof("\nbookname=") -1; >+ p3 = strchr(p2, '\n'); >+ bookname.assign(p2, p3-p2); >+ >+ p2 = strstr(p1,"\nauthor="); >+ if (p2) { >+ p2 = p2 + sizeof("\nauthor=") -1; >+ p3 = strchr(p2, '\n'); >+ author.assign(p2, p3-p2); >+ } >+ >+ p2 = strstr(p1,"\nemail="); >+ if (p2) { >+ p2 = p2 + sizeof("\nemail=") -1; >+ p3 = strchr(p2, '\n'); >+ email.assign(p2, p3-p2); >+ } >+ >+ p2 = strstr(p1,"\nwebsite="); >+ if (p2) { >+ p2 = p2 + sizeof("\nwebsite=") -1; >+ p3 = strchr(p2, '\n'); >+ website.assign(p2, p3-p2); >+ } >+ >+ p2 = strstr(p1,"\ndate="); >+ if (p2) { >+ p2 = p2 + sizeof("\ndate=") -1; >+ p3 = strchr(p2, '\n'); >+ date.assign(p2, p3-p2); >+ } >+ >+ p2 = strstr(p1,"\ndescription="); >+ if (p2) { >+ p2 = p2 + sizeof("\ndescription=")-1; >+ p3 = strchr(p2, '\n'); >+ description.assign(p2, p3-p2); >+ } >+ >+ p2 = strstr(p1,"\nsametypesequence="); >+ if (p2) { >+ p2+=sizeof("\nsametypesequence=")-1; >+ p3 = strchr(p2, '\n'); >+ sametypesequence.assign(p2, p3-p2); >+ } >+ >+ g_free(buffer); >+ >+ return true; >+} > //=================================================================== > DictBase::DictBase() > { >@@ -46,115 +249,112 @@ > dict_data_close(dictdzfile); > } > >-gchar* DictBase::GetWordData(glong idxitem_offset, glong idxitem_size) >+gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) > { >- for (int i=0;i<WORDDATA_CACHE_NUM;i++) >- { >- if ((cache[i].data) && (cache[i].offset == idxitem_offset)) >- { >+ for (int i=0; i<WORDDATA_CACHE_NUM; i++) >+ if (cache[i].data && cache[i].offset == idxitem_offset) > return cache[i].data; >- } >- } >- if (dictfile) { >+ >+ if (dictfile) > fseek(dictfile, idxitem_offset, SEEK_SET); >- } >+ > gchar *data; > if (sametypesequence) { >- gchar *origin_data; >- origin_data = (gchar *)g_malloc(idxitem_size); >+ gchar *origin_data = (gchar *)g_malloc(idxitem_size); > > if (dictfile) >- fread(origin_data,idxitem_size,1,dictfile); >+ fread(origin_data, idxitem_size, 1, dictfile); > else >- dict_data_read (dictdzfile, origin_data, idxitem_offset, idxitem_size); >+ dict_data_read(dictdzfile, origin_data, idxitem_offset, idxitem_size); > >- glong data_size; >+ guint32 data_size; > gint sametypesequence_len; > sametypesequence_len = strlen(sametypesequence); > //there have sametypesequence_len char being omitted. >- data_size = idxitem_size + sizeof(glong) + sametypesequence_len; >+ data_size = idxitem_size + sizeof(guint32) + sametypesequence_len; > //if the last item's size is determined by the end up '\0',then +=sizeof(gchar); >- //if the last item's size is determined by the head glong type data,then +=sizeof(glong); >+ //if the last item's size is determined by the head guint32 type data,then +=sizeof(guint32); > switch (sametypesequence[sametypesequence_len-1]) { > case 'm': > case 't': > case 'y': >- case 'o': >+ case 'l': >+ case 'g': > data_size += sizeof(gchar); > break; > case 'W': > case 'P': >- data_size += sizeof(glong); >+ data_size += sizeof(guint32); > break; > } > data = (gchar *)g_malloc(data_size); > gchar *p1,*p2; >- p1 = data + sizeof(glong); >+ p1 = data + sizeof(guint32); > p2 = origin_data; >- glong sec_size; >+ guint32 sec_size; > //copy the head items. >- for (int i=0;i< sametypesequence_len-1;i++) { >- memcpy(p1, &(sametypesequence[i]), sizeof(gchar)); >- p1+= sizeof(gchar); >+ for (int i=0; i<sametypesequence_len-1; i++) { >+ *p1=sametypesequence[i]; >+ p1+=sizeof(gchar); > switch (sametypesequence[i]) { > case 'm': > case 't': > case 'y': >- case 'o': >+ case 'l': >+ case 'g': > sec_size = strlen(p2)+1; > memcpy(p1, p2, sec_size); >- p1+= sec_size; >- p2+= sec_size; >+ p1+=sec_size; >+ p2+=sec_size; > break; > case 'W': > case 'P': >- memcpy(&sec_size, p2, sizeof(glong)); >- sec_size += sizeof(glong); >+ sec_size = *reinterpret_cast<guint32 *>(p2); >+ sec_size += sizeof(guint32); > memcpy(p1, p2, sec_size); >- p1+= sec_size; >- p2+= sec_size; >+ p1+=sec_size; >+ p2+=sec_size; > break; > } > } > //calculate the last item 's size. > sec_size = idxitem_size - (p2-origin_data); >- memcpy(p1, &(sametypesequence[sametypesequence_len-1]), sizeof(gchar)); >- p1+= sizeof(gchar); >+ *p1=sametypesequence[sametypesequence_len-1]; >+ p1+=sizeof(gchar); > switch (sametypesequence[sametypesequence_len-1]) { > case 'm': > case 't': > case 'y': >- case 'o': >+ case 'l': >+ case 'g': > memcpy(p1, p2, sec_size); > p1 += sec_size; >- memcpy(p1, "", sizeof(gchar)); //add the end up '\0'; >+ *p1='\0';//add the end up '\0'; > break; > case 'W': > case 'P': >- memcpy(p1,&(sec_size), sizeof(glong)); //add the head glong size data. >- p1 += sizeof(glong); >+ *reinterpret_cast<guint32 *>(p1)=sec_size; >+ p1 += sizeof(guint32); > memcpy(p1, p2, sec_size); > break; > } > g_free(origin_data); >- } >- else { >- data = (gchar *)g_malloc(idxitem_size + sizeof(glong)); >+ *reinterpret_cast<guint32 *>(data)=data_size; >+ } else { >+ data = (gchar *)g_malloc(idxitem_size + sizeof(guint32)); > if (dictfile) >- fread(data+sizeof(glong),idxitem_size,1,dictfile); >+ fread(data+sizeof(guint32), idxitem_size, 1, dictfile); > else >- dict_data_read (dictdzfile, data+sizeof(glong), idxitem_offset, idxitem_size); >+ dict_data_read(dictdzfile, data+sizeof(guint32), idxitem_offset, idxitem_size); >+ *reinterpret_cast<guint32 *>(data)=idxitem_size; > } >- memcpy(data,&(idxitem_size),sizeof(glong)); >- if (cache[cache_cur].data) >- { > g_free(cache[cache_cur].data); >- } >+ > cache[cache_cur].data = data; > cache[cache_cur].offset = idxitem_offset; > cache_cur++; > if (cache_cur==WORDDATA_CACHE_NUM) >- cache_cur =0; >+ cache_cur = 0; > return data; > } > >@@ -166,78 +366,50 @@ > bookname = NULL; > idxfile = NULL; > wordlist = NULL; >-#ifdef HAVE_MMAP >- mmap_fd = -1; >- mmap_idxmap_size = 0; >-#endif > idxdatabuffer = NULL; > } > > Lib::~Lib() > { >- if (bookname) > g_free(bookname); > if (idxfile) { > fclose(idxfile); >- if (wordoffset) > g_free(wordoffset); >- } >- else { >- if (wordlist) >+ } else { > g_free(wordlist); >- >-#ifdef HAVE_MMAP >- if (mmap_fd >= 0) { >- if (mmap_idxmap_size) >- munmap(idxdatabuffer, mmap_idxmap_size); >- close(mmap_fd); >- } >- else { >- if (idxdatabuffer) >- g_free(idxdatabuffer); >- } >-#else >- if (idxdatabuffer) >- g_free(idxdatabuffer); >-#endif > } > } > >-gboolean Lib::load(const char *ifofilename) >+bool Lib::load(const char *ifofilename) > { > gulong idxfilesize; > if (!load_ifofile(ifofilename, &idxfilesize)) > return false; > >- gchar fullfilename[256]; >- >- strcpy(fullfilename, ifofilename); >- strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "dict.dz"); >+ std::string fullfilename(ifofilename); >+ fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz"); > >- if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) { >- dictdzfile = dict_data_open(fullfilename, 0); >- if (!dictdzfile) >- { >+ if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { >+ dictdzfile = dict_data_open(fullfilename.c_str(), 0); >+ if (!dictdzfile) { > //g_print("open file %s failed!\n",fullfilename); > return false; > } >- } >- else { >- fullfilename[strlen(fullfilename)-3] = '\0'; >- dictfile = fopen(fullfilename,"rb"); >- if (!dictfile) >- { >+ } else { >+ fullfilename.erase(fullfilename.length()-sizeof(".dz")+1, sizeof(".dz")-1); >+ dictfile = fopen(fullfilename.c_str(),"rb"); >+ if (!dictfile) { > //g_print("open file %s failed!\n",fullfilename); > return false; > } > } > >- strcpy(fullfilename, ifofilename); >- strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "idx.gz"); >+ fullfilename=ifofilename; >+ fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "idx.gz"); > >- if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) { >+ if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { > gzFile in; >- in = gzopen(fullfilename,"rb"); >+ in = gzopen(fullfilename.c_str(),"rb"); > if (in == NULL) { > //g_print("Open file %s failed!\n",fullfilename); > return false; >@@ -252,60 +424,16 @@ > gzclose(in); > if (len != idxfilesize) > return false; >- } >- else { >- fullfilename[strlen(fullfilename)-3] = '\0'; >- >-#ifdef HAVE_MMAP >- if ((mmap_fd = open(fullfilename, O_RDONLY )) < 0) { >- //g_print("Open file %s failed!\n",fullfilename); >- return false; >- } >- idxdatabuffer = (gchar *)mmap( NULL, idxfilesize, PROT_READ, MAP_SHARED, mmap_fd, 0); >- if ((void *)idxdatabuffer == (void *)(-1)) { >- //g_print("mmap file %s failed!\n",idxfilename); >- return false; >- } >- mmap_idxmap_size = idxfilesize; >-#else >- #ifdef _WIN32 >- HANDLE hFile = CreateFile(fullfilename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); >- HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, idxfilesize, NULL); >- idxdatabuffer = (gchar *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, idxfilesize); >- #else >- FILE *file; >- if (!(file = fopen (fullfilename, "rb"))) { >- //g_print("Open file %s failed!\n",fullfilename); >- return false; >- } >- idxdatabuffer = (gchar *)g_malloc(idxfilesize); >- gint read_len; >- read_len = fread (idxdatabuffer, 1, idxfilesize, file); >- fclose (file); >- if (read_len!=idxfilesize) >+ } else { >+ fullfilename.erase(fullfilename.length()-sizeof(".gz")+1, sizeof(".gz")-1); >+ MapFile map_file; >+ if (!map_file.open(fullfilename.c_str(), idxfilesize)) > return false; >- #endif >-#endif >- if (true) { >+ idxdatabuffer=map_file.begin(); >+ > loadwordoffset(); >-#ifdef HAVE_MMAP >- munmap(idxdatabuffer, mmap_idxmap_size); >- idxdatabuffer = NULL; >- mmap_idxmap_size = 0; >- close(mmap_fd); >- mmap_fd = -1; >-#else >- #ifdef _WIN32 >- UnmapViewOfFile(idxdatabuffer); >- idxdatabuffer = NULL; >- CloseHandle(hFileMap); >- CloseHandle(hFile); >- #else >- g_free(idxdatabuffer); >- idxdatabuffer = NULL; >- #endif >-#endif >- if (!(idxfile = fopen (fullfilename, "rb"))) { >+ idxdatabuffer=NULL; >+ if (!(idxfile = fopen(fullfilename.c_str(), "rb"))) { > if (wordoffset) { > g_free(wordoffset); > wordoffset = NULL; >@@ -316,82 +444,25 @@ > g_print("bookname: %s , wordcount %ld\n",bookname, wordcount); > return true; > } >- else { >- // The .idx file will load into memory. Who need this opinion? >- } >- } > > loadwordlist(); > g_print("bookname: %s , wordcount %ld\n",bookname, wordcount); > return true; > } > >-gboolean Lib::load_ifofile(const char *ifofilename, gulong *idxfilesize) >+bool Lib::load_ifofile(const char *ifofilename, gulong *idxfilesize) > { >- struct stat stats; >- if (stat (ifofilename, &stats) == -1) { >- //g_print("File: %s don't exist!\n",idxfilename); >- return false; >- } >- >- FILE *file; >- if (!(file = fopen (ifofilename, "rb"))) { >- //g_print("Open file %s failed!\n",idxfilename); >- return false; >- } >- gchar *buffer = (gchar *)g_malloc (stats.st_size + 1); >- fread (buffer, 1, stats.st_size, file); >- buffer[stats.st_size] = '\0'; >- fclose (file); >- >- if (!g_str_has_prefix(buffer, "StarDict's dict ifo file\nversion=2.4.2\n")) { >- g_print("Bad dict ifo file %s, skiped!\n", ifofilename); >- g_free(buffer); >+ DictInfo dict_info; >+ if (!dict_info.load_from_ifo_file(ifofilename, false)) > return false; >- } >- gchar *p1= buffer + sizeof("StarDict's dict ifo file\nversion=2.4.2\n")-1 -1; > >- gchar *p2,*p3; >- >- p2 = strstr(p1,"\nidxfilesize="); >- if (!p2) { >- g_free(buffer); >- return false; >- } >- p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n'); >- gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1); >- tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0'; >- *idxfilesize = atol(tmpstr); >- g_free(tmpstr); >- >- p2 = strstr(p1,"\nwordcount="); >- if (!p2) { >- g_free(buffer); >- return false; >- } >- p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n'); >- tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1); >- tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0'; >- wordcount = atol(tmpstr); >- g_free(tmpstr); >- >- p2 = strstr(p1,"\nbookname="); >- if (!p2) { >- g_free(buffer); >- return false; >- } >- p3 = strchr(p2+ sizeof("\nbookname=")-1,'\n'); >- bookname = (gchar *)g_memdup(p2+sizeof("\nbookname=")-1, p3-(p2+sizeof("\nbookname=")-1)+1); >- bookname[p3-(p2+sizeof("\nbookname=")-1)] = '\0'; >+ *idxfilesize = dict_info.index_file_size; >+ wordcount = dict_info.wordcount; >+ bookname = g_strdup(dict_info.bookname.c_str()); > >- p2 = strstr(p1,"\nsametypesequence="); >- if (p2) { >- p3 = strchr(p2+sizeof("\nsametypesequence=")-1,'\n'); >- sametypesequence = (gchar *)g_memdup(p2+sizeof("\nsametypesequence=")-1, p3-(p2+sizeof("\nsametypesequence=")-1)+1); >- sametypesequence[p3-(p2+sizeof("\nsametypesequence=")-1)] = '\0'; >- } >+ if (!dict_info.sametypesequence.empty()) >+ sametypesequence=g_strdup(dict_info.sametypesequence.c_str()); > >- g_free(buffer); > return true; > } > >@@ -438,41 +509,34 @@ > wordoffset[wordcount] = p1; > }*/ > >-gboolean Lib::Lookup(const char* sWord,glong *pIndex) >+bool Lib::Lookup(const char* sWord,glong *pIndex) > { >- gboolean bFound=false; >+ bool bFound=false; > glong iTo=length()-1; > if (stardict_strcmp(sWord, GetWord(0))<0) { > *pIndex = 0; >- } >- else if (stardict_strcmp(sWord, GetWord(iTo)) >0 ) { >+ } else if (stardict_strcmp(sWord, GetWord(iTo)) >0) { > *pIndex = INVALID_INDEX; >- } >- else { >+ } else { > glong iThisIndex=0; > glong iFrom=0; > > int cmpint; >- while( !bFound && iFrom<=iTo ) >- { >+ while (iFrom<=iTo) { > iThisIndex=(iFrom+iTo)/2; > cmpint = stardict_strcmp(sWord, GetWord(iThisIndex)); > //g_print("lookup %s %d\n",GetWord(iThisIndex),cmpint); >- if (cmpint == 0) >- { >- bFound=true; >- } >- else if (cmpint > 0) >- { >+ if (cmpint>0) > iFrom=iThisIndex+1; >- } >- else >- { >+ else if (cmpint<0) > iTo=iThisIndex-1; >+ else { >+ bFound=true; >+ break; > } > } >- if (!bFound) >- { >+ >+ if (!bFound) { > /*glong len = g_utf8_strlen(sWord, -1); > gchar *last_str = g_utf8_offset_to_pointer(sWord, len-1); > gunichar last = g_utf8_get_char(last_str); >@@ -483,51 +547,43 @@ > *pIndex = iFrom; //next > */ > *pIndex = iFrom; //next >- } >- else >+ } else > *pIndex = iThisIndex; > } >- return(bFound); >+ >+ return bFound; > } > >-gboolean Lib::LookupWithRule(GPatternSpec *pspec,glong *aIndex,int iBuffLen) >+bool Lib::LookupWithRule(GPatternSpec *pspec, glong *aIndex, int iBuffLen) > { > int iIndexCount=0; > glong i; >- for(i=0;i<length() && iIndexCount<iBuffLen-1;i++) >- { >- if(g_pattern_match_string(pspec, GetWord(i))) >- { >+ for(i=0; i<wordcount && iIndexCount<iBuffLen-1; i++) >+ if (g_pattern_match_string(pspec, GetWord(i))) > aIndex[iIndexCount++]=i; >- } >- } >+ > aIndex[iIndexCount]= -1; // -1 is the end. > >- return(iIndexCount>0); >+ return (iIndexCount>0); > } > > gchar * > Lib::GetWord(glong index) > { > if (idxfile) { >- if (index == cur_wordindex +1) { >- //needn't fseek(). >- } >- // (index == cur_wordindex) seldom happen, so don't determine this here. >- else { >+ if (index != cur_wordindex+1) > fseek(idxfile, wordoffset[index], SEEK_SET); >- } >+ > cur_wordindex = index; > >- fread(wordentry_buf, wordoffset[index+1] - wordoffset[index] - 2*sizeof(glong), 1, idxfile); >+ fread(wordentry_buf, wordoffset[index+1] - wordoffset[index] - 2*sizeof(guint32), 1, idxfile); > //g_print("%s\n", wordentry_buf); >- fread(&wordentry_offset, sizeof(glong), 1, idxfile); >+ fread(&wordentry_offset, sizeof(guint32), 1, idxfile); > wordentry_offset = g_ntohl(wordentry_offset); >- fread(&wordentry_size, sizeof(glong), 1, idxfile); >+ fread(&wordentry_size, sizeof(guint32), 1, idxfile); > wordentry_size = g_ntohl(wordentry_size); > return wordentry_buf; >- } >- else { >+ } else { > return wordlist[index]; > } > } >@@ -536,26 +592,22 @@ > Lib::GetWordData(glong index) > { > if (idxfile) { >- if (index == cur_wordindex) { >- // wordentry_offset and wordentry_size are already cached by GetWord(); >- } >- else { >+ if (index != cur_wordindex) { > cur_wordindex = index; >- fseek(idxfile, wordoffset[index+1] - 2*sizeof(glong), SEEK_SET); >- fread(&wordentry_offset, sizeof(glong), 1, idxfile); >+ fseek(idxfile, wordoffset[index+1] - 2*sizeof(guint32), SEEK_SET); >+ fread(&wordentry_offset, sizeof(guint32), 1, idxfile); > wordentry_offset = g_ntohl(wordentry_offset); >- fread(&wordentry_size, sizeof(glong), 1, idxfile); >+ fread(&wordentry_size, sizeof(guint32), 1, idxfile); > wordentry_size = g_ntohl(wordentry_size); > } > return DictBase::GetWordData(wordentry_offset, wordentry_size); >- } >- else { >- gchar *p1 = wordlist[index+1] - 2*sizeof(glong); >- glong offset, size; >- memcpy(&offset,p1,sizeof(glong)); >+ } else { >+ gchar *p1 = wordlist[index+1] - 2*sizeof(guint32); >+ guint32 offset, size; >+ offset=*reinterpret_cast<guint32 *>(p1); > offset = g_ntohl(offset); >- p1 = p1 + sizeof(glong); >- memcpy(&size, p1, sizeof(glong)); >+ p1 += sizeof(guint32); >+ size=*reinterpret_cast<guint32 *>(p1); > size = g_ntohl(size); > return DictBase::GetWordData(offset, size); > } >@@ -566,6 +618,7 @@ > { > libcount =0; > oLib = NULL; >+ iMaxFuzzyDistance = MAX_FUZZY_DISTANCE; //need to read from cfg. > } > > Libs::~Libs() >@@ -592,10 +645,6 @@ > } > > /********************************************************************/ >-gboolean Libs::LookdupWordsWithRule(GPatternSpec *pspec,glong* aiIndexes,int iLen,int iLib) >-{ >- return (oLib[iLib]->LookupWithRule(pspec,aiIndexes,iLen)); >-} > > void Libs::LoadDir(const gchar *dirname, const GSList *order_list, const GSList *disable_list) > { >@@ -823,15 +872,15 @@ > return poCurrentWord; > } > >-gboolean Libs::LookupWord(const gchar* sWord,glong& iWordIndex,int iLib) >+bool Libs::LookupWord(const gchar* sWord,glong& iWordIndex,int iLib) > { >- return (oLib[iLib]->Lookup(sWord, &iWordIndex)); >+ return oLib[iLib]->Lookup(sWord, &iWordIndex); > } > >-gboolean Libs::LookupSimilarWord(const gchar* sWord,glong& iWordIndex,int iLib) >+bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) > { > glong iIndex; >- gboolean bFound=false; >+ bool bFound=false; > gchar *casestr; > > if (!bFound) { >@@ -865,21 +914,20 @@ > } > } > >- if (bIsPureEnglish(sWord)) >- { >+ if (bIsPureEnglish(sWord)) { > // If not Found , try other status of sWord. > int iWordLen=strlen(sWord); >- gboolean isupcase; >+ bool isupcase; > > gchar *sNewWord = (gchar *)g_malloc(iWordLen + 1); > > //cut one char "s" or "d" > if(!bFound && iWordLen>1) { >- isupcase = (sWord[iWordLen-1]=='S' || (!strncmp(&sWord[iWordLen-2],"ED",2))); >- if (isupcase || sWord[iWordLen-1]=='s' || (!strncmp(&sWord[iWordLen-2],"ed",2))) { >+ isupcase = sWord[iWordLen-1]=='S' || !strncmp(&sWord[iWordLen-2],"ED",2); >+ if (isupcase || sWord[iWordLen-1]=='s' || !strncmp(&sWord[iWordLen-2],"ed",2)) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-1]='\0'; // cut "s" or "d" >- if(oLib[iLib]->Lookup(sNewWord,&iIndex)) >+ if (oLib[iLib]->Lookup(sNewWord,&iIndex)) > bFound=true; > else if (isupcase || g_ascii_isupper(sWord[0])) { > casestr = g_ascii_strdown(sNewWord, -1); >@@ -898,9 +946,10 @@ > if (isupcase || (!strncmp(&sWord[iWordLen-2],"ly",2))) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-2]='\0'; // cut "ly" >- if ( iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4]) >- && !bIsVowel(sNewWord[iWordLen-4]) && bIsVowel(sNewWord[iWordLen-5]) ) //doubled >- { >+ if (iWordLen>5 && sNewWord[iWordLen-3]==sNewWord[iWordLen-4] >+ && !bIsVowel(sNewWord[iWordLen-4]) && >+ bIsVowel(sNewWord[iWordLen-5])) {//doubled >+ > sNewWord[iWordLen-3]='\0'; > if( oLib[iLib]->Lookup(sNewWord,&iIndex) ) > bFound=true; >@@ -939,8 +988,8 @@ > strcpy(sNewWord,sWord); > sNewWord[iWordLen-3]='\0'; > if ( iWordLen>6 && (sNewWord[iWordLen-4]==sNewWord[iWordLen-5]) >- && !bIsVowel(sNewWord[iWordLen-5]) && bIsVowel(sNewWord[iWordLen-6]) ) //doubled >- { >+ && !bIsVowel(sNewWord[iWordLen-5]) && >+ bIsVowel(sNewWord[iWordLen-6])) { //doubled > sNewWord[iWordLen-4]='\0'; > if (oLib[iLib]->Lookup(sNewWord,&iIndex)) > bFound=true; >@@ -992,13 +1041,18 @@ > //cut two char "es" > if(!bFound && iWordLen>3) { > isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) && >- (sWord[iWordLen-3] == 'S' || sWord[iWordLen-3] == 'X' || sWord[iWordLen-3] == 'O' >- || (iWordLen >4 && sWord[iWordLen-3] == 'H' && (sWord[iWordLen-4] == 'C' || sWord[iWordLen-4] == 'S')))); >+ (sWord[iWordLen-3] == 'S' || >+ sWord[iWordLen-3] == 'X' || >+ sWord[iWordLen-3] == 'O' || >+ (iWordLen >4 && sWord[iWordLen-3] == 'H' && >+ (sWord[iWordLen-4] == 'C' || >+ sWord[iWordLen-4] == 'S')))); > if (isupcase || > (!strncmp(&sWord[iWordLen-2],"es",2) && >- (sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || sWord[iWordLen-3] == 'o' >- || (iWordLen >4 && sWord[iWordLen-3] == 'h' && (sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) >- { >+ (sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || >+ sWord[iWordLen-3] == 'o' || >+ (iWordLen >4 && sWord[iWordLen-3] == 'h' && >+ (sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-2]='\0'; > if(oLib[iLib]->Lookup(sNewWord,&iIndex)) >@@ -1015,17 +1069,16 @@ > } > > //cut "ed" >- if( !bFound && iWordLen>3) { >+ if (!bFound && iWordLen>3) { > isupcase = !strncmp(&sWord[iWordLen-2],"ED",2); >- if (isupcase || !strncmp(&sWord[iWordLen-2],"ed",2) ) >- { >+ if (isupcase || !strncmp(&sWord[iWordLen-2],"ed",2)) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-2]='\0'; >- if ( iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4]) >- && !bIsVowel(sNewWord[iWordLen-4]) && bIsVowel(sNewWord[iWordLen-5]) ) //doubled >- { >+ if (iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4]) >+ && !bIsVowel(sNewWord[iWordLen-4]) && >+ bIsVowel(sNewWord[iWordLen-5])) {//doubled > sNewWord[iWordLen-3]='\0'; >- if( oLib[iLib]->Lookup(sNewWord,&iIndex) ) >+ if (oLib[iLib]->Lookup(sNewWord,&iIndex)) > bFound=true; > else { > if (isupcase || g_ascii_isupper(sWord[0])) { >@@ -1040,7 +1093,7 @@ > sNewWord[iWordLen-3]=sNewWord[iWordLen-4]; //restore > } > } >- if( !bFound ) { >+ if (!bFound) { > if (oLib[iLib]->Lookup(sNewWord,&iIndex)) > bFound=true; > else if (isupcase || g_ascii_isupper(sWord[0])) { >@@ -1056,17 +1109,16 @@ > } > > // cut "ied" , add "y". >- if(!bFound && iWordLen>3) { >+ if (!bFound && iWordLen>3) { > isupcase = !strncmp(&sWord[iWordLen-3],"IED",3); >- if (isupcase || (!strncmp(&sWord[iWordLen-3],"ied",3))) >- { >+ if (isupcase || (!strncmp(&sWord[iWordLen-3],"ied",3))) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-3]='\0'; > if (isupcase) > strcat(sNewWord,"Y"); // add a char "Y" > else > strcat(sNewWord,"y"); // add a char "y" >- if(oLib[iLib]->Lookup(sNewWord,&iIndex)) >+ if (oLib[iLib]->Lookup(sNewWord,&iIndex)) > bFound=true; > else if (isupcase || g_ascii_isupper(sWord[0])) { > casestr = g_ascii_strdown(sNewWord, -1); >@@ -1080,10 +1132,9 @@ > } > > // cut "ies" , add "y". >- if(!bFound && iWordLen>3) { >+ if (!bFound && iWordLen>3) { > isupcase = !strncmp(&sWord[iWordLen-3],"IES",3); >- if (isupcase || (!strncmp(&sWord[iWordLen-3],"ies",3))) >- { >+ if (isupcase || (!strncmp(&sWord[iWordLen-3],"ies",3))) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-3]='\0'; > if (isupcase) >@@ -1104,10 +1155,9 @@ > } > > // cut "er". >- if(!bFound && iWordLen>2) { >+ if (!bFound && iWordLen>2) { > isupcase = !strncmp(&sWord[iWordLen-2],"ER",2); >- if (isupcase || (!strncmp(&sWord[iWordLen-2],"er",2))) >- { >+ if (isupcase || (!strncmp(&sWord[iWordLen-2],"er",2))) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-2]='\0'; > if(oLib[iLib]->Lookup(sNewWord,&iIndex)) >@@ -1124,10 +1174,9 @@ > } > > // cut "est". >- if(!bFound && iWordLen>3) { >+ if (!bFound && iWordLen>3) { > isupcase = !strncmp(&sWord[iWordLen-3], "EST", 3); >- if (isupcase || (!strncmp(&sWord[iWordLen-3],"est", 3))) >- { >+ if (isupcase || (!strncmp(&sWord[iWordLen-3],"est", 3))) { > strcpy(sNewWord,sWord); > sNewWord[iWordLen-3]='\0'; > if(oLib[iLib]->Lookup(sNewWord,&iIndex)) >@@ -1154,60 +1203,183 @@ > //iWordIndex = INVALID_INDEX; > } > >- return(bFound); >+ return bFound; > } > >-gboolean Libs::SimpleLookupWord(const gchar* sWord,glong& iWordIndex,int iLib) >+bool Libs::SimpleLookupWord(const gchar* sWord, glong & iWordIndex, int iLib) > { >- gboolean bFound = oLib[iLib]->Lookup(sWord, &iWordIndex); >+ bool bFound = oLib[iLib]->Lookup(sWord, &iWordIndex); > if (!bFound) > bFound = LookupSimilarWord(sWord, iWordIndex, iLib); > return bFound; > } > >-inline gboolean bIsVowel(gchar inputchar) >+inline bool operator<(const Libs::Fuzzystruct & lh, const Libs::Fuzzystruct & rh) { >+ if (lh.iMatchWordDistance!=rh.iMatchWordDistance) >+ return lh.iMatchWordDistance<rh.iMatchWordDistance; >+ >+ if (lh.pMatchWord && rh.pMatchWord) >+ return stardict_strcmp(lh.pMatchWord, rh.pMatchWord)<0; >+ >+ return false; >+} >+ >+bool Libs::LookupWithFuzzy(const gchar *sWord, Fuzzystruct oFuzzystruct[], gint fuzzystruct_amount, TProgressFunc ProgressFunc) > { >- gchar ch = g_ascii_toupper(inputchar); >- return( ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ); >+ if (sWord[0] == '\0') >+ return false; >+ >+ for (int i=0; i<fuzzystruct_amount; i++) { >+ oFuzzystruct[i].pMatchWord = NULL; >+ oFuzzystruct[i].iMatchWordDistance = iMaxFuzzyDistance; >+ } >+ int iMaxDistance = iMaxFuzzyDistance; >+ int iDistance; >+ bool Found = false; >+ EditDistance oEditDistance; >+ >+ glong iCheckWordLen; >+ int sCheckLen; >+ const char *sCheck; >+ gunichar *ucs4_str1,*ucs4_str2; >+ glong ucs4_str2_len; >+ char *sLowerCheckWord; >+ gchar *sLowerWord = g_utf8_strdown(sWord, -1); >+ ucs4_str2 = g_utf8_to_ucs4_fast(sLowerWord,-1,&ucs4_str2_len); >+ g_free(sLowerWord); >+ for (int iLib=0; iLib<libcount; iLib++) { >+ if (ProgressFunc) >+ ProgressFunc(); >+ if (stardict_strcmp(sWord, poGetWord(0,iLib))>=0 && >+ stardict_strcmp(sWord, poGetWord(iLength(iLib)-1,iLib))<=0) { >+ //there are Chinese dicts and English dicts... >+ const int iwords = iLength(iLib); >+ for (int index=0; index<iwords; index++) { >+ sCheck = poGetWord(index,iLib); >+ // tolower and skip too long or too short words >+ sCheckLen = strlen(sCheck); >+ iCheckWordLen = g_utf8_strlen(sCheck, sCheckLen); >+ if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || >+ ucs4_str2_len-iCheckWordLen>=iMaxDistance) >+ continue; >+ sLowerCheckWord = g_utf8_strdown(sCheck, sCheckLen); >+ if (iCheckWordLen > ucs4_str2_len) >+ (*g_utf8_offset_to_pointer(sLowerCheckWord, ucs4_str2_len)) = '\0'; >+ ucs4_str1 = g_utf8_to_ucs4_fast(sLowerCheckWord, -1,NULL); >+ g_free(sLowerCheckWord); >+ iDistance = oEditDistance.CalEditDistance(ucs4_str1,ucs4_str2,iMaxDistance); >+ g_free(ucs4_str1); >+ if (iDistance<iMaxDistance && iDistance < ucs4_str2_len) { >+ // when ucs4_str2_len=1,2 we need less fuzzy. >+ Found = true; >+ bool bAlreadyInList = false; >+ int iMaxDistanceAt=0; >+ for (int j=0; j<fuzzystruct_amount; j++) { >+ if (oFuzzystruct[j].pMatchWord && >+ strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) {//already in list >+ bAlreadyInList = true; >+ break; >+ } >+ //find the position,it will certainly be found (include the first time) as iMaxDistance is set by last time. >+ if (oFuzzystruct[j].iMatchWordDistance == iMaxDistance ) { >+ iMaxDistanceAt = j; >+ } >+ } >+ if (!bAlreadyInList) { >+ if (oFuzzystruct[iMaxDistanceAt].pMatchWord) >+ g_free(oFuzzystruct[iMaxDistanceAt].pMatchWord); >+ oFuzzystruct[iMaxDistanceAt].pMatchWord = g_strdup(sCheck); >+ oFuzzystruct[iMaxDistanceAt].iMatchWordDistance = iDistance; >+ // calc new iMaxDistance >+ iMaxDistance = iDistance; >+ for (int j=0; j<fuzzystruct_amount; j++) { >+ if (oFuzzystruct[j].iMatchWordDistance > iMaxDistance) >+ iMaxDistance = oFuzzystruct[j].iMatchWordDistance; >+ } // calc new iMaxDistance >+ } // add to list >+ } // find one >+ } // each word >+ } // ok for search >+ } // each lib >+ g_free(ucs4_str2); >+ >+ if (Found)// sort with distance >+ std::sort(oFuzzystruct, oFuzzystruct+fuzzystruct_amount); >+ >+ return Found; > } > >+inline bool less_for_compare(const char *lh, const char *rh) { >+ return stardict_strcmp(lh, rh)<0; >+} > >+gint Libs::LookupWithRule(const gchar *word, TProgressFunc ProgressFunc, gchar **ppMatchWord) >+{ >+ glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1]; >+ gint iMatchCount = 0; >+ GPatternSpec *pspec = g_pattern_spec_new(word); >+ >+ for (int iLib=0; iLib<libcount; iLib++) { >+ //if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1-iMatchCount,iLib)) >+ // -iMatchCount,so save time,but may got less result and the word may repeat. >+ >+ if (oLib[iLib]->LookupWithRule(pspec,aiIndex, MAX_MATCH_ITEM_PER_LIB+1)) { >+ if (ProgressFunc) >+ ProgressFunc(); >+ for (int i=0; aiIndex[i]!=-1; i++) { >+ gchar * sMatchWord = poGetWord(aiIndex[i],iLib); >+ bool bAlreadyInList = false; >+ for (int j=0; j<iMatchCount; j++) { >+ if (strcmp(ppMatchWord[j],sMatchWord)==0) {//already in list >+ bAlreadyInList = true; >+ break; >+ } >+ } >+ if (!bAlreadyInList) >+ ppMatchWord[iMatchCount++] = g_strdup(sMatchWord); >+ } >+ } >+ } >+ g_pattern_spec_free(pspec); >+ >+ if (iMatchCount)// sort it. >+ std::sort(ppMatchWord, ppMatchWord+iMatchCount, less_for_compare); >+ >+ return iMatchCount; >+} > > /**************************************************/ >-gboolean TreeDict::load(const char *ifofilename, GtkTreeStore *model) >+bool TreeDict::load(const char *ifofilename, GtkTreeStore *model) > { > gulong tdxfilesize; > if (!load_ifofile(ifofilename, &tdxfilesize)) > return false; > >- gchar fullfilename[256]; >- >- strcpy(fullfilename, ifofilename); >- strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "dict.dz"); >+ std::string fullfilename(ifofilename); >+ fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz"); > >- if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) { >- dictdzfile = dict_data_open(fullfilename, 0); >+ if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { >+ dictdzfile = dict_data_open(fullfilename.c_str(), 0); > if (!dictdzfile) { > //g_print("open file %s failed!\n",fullfilename); > return false; > } >- } >- else { >- fullfilename[strlen(fullfilename)-3] = '\0'; >- dictfile = fopen(fullfilename,"rb"); >+ } else { >+ fullfilename.erase(fullfilename.length()-sizeof(".dz")+1, sizeof(".dz")-1); >+ dictfile = fopen(fullfilename.c_str(),"rb"); > if (!dictfile) { > //g_print("open file %s failed!\n",fullfilename); > return false; > } > } > >- strcpy(fullfilename, ifofilename); >- strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "tdx.gz"); >+ fullfilename=ifofilename; >+ fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "tdx.gz"); > > gchar *buffer= NULL; >- if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) { >+ if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { > gzFile in; >- in = gzopen(fullfilename,"rb"); >+ in = gzopen(fullfilename.c_str(),"rb"); > if (in == NULL) { > //g_print("Open file %s failed!\n",idxfilename); > return false; >@@ -1226,18 +1398,17 @@ > g_free(buffer); > return false; > } >- } >- else { >- fullfilename[strlen(fullfilename)-3] = '\0'; >+ } else { >+ fullfilename.erase(fullfilename.length()-sizeof(".gz")+1, sizeof(".gz")-1); > FILE *file; >- if (!(file = fopen (fullfilename, "rb"))) { >+ if (!(file = fopen (fullfilename.c_str(), "rb"))) { > //g_print("Open file %s failed!\n",fullfilename); > return false; > } > buffer = (gchar *)g_malloc(tdxfilesize); > gulong read_len; >- read_len = fread (buffer, 1, tdxfilesize, file); >- fclose (file); >+ read_len = fread(buffer, 1, tdxfilesize, file); >+ fclose(file); > if (read_len!=tdxfilesize) { > g_free(buffer); > return false; >@@ -1250,52 +1421,16 @@ > return true; > } > >-gboolean TreeDict::load_ifofile(const char *ifofilename, gulong *tdxfilesize) >+bool TreeDict::load_ifofile(const char *ifofilename, gulong *tdxfilesize) > { >- struct stat stats; >- if (stat (ifofilename, &stats) == -1) { >- //g_print("File: %s don't exist!\n",idxfilename); >- return false; >- } >- >- FILE *file; >- if (!(file = fopen (ifofilename, "rb"))) { >- //g_print("Open file %s failed!\n",idxfilename); >- return false; >- } >- gchar *buffer = (gchar *)g_malloc (stats.st_size + 1); >- fread (buffer, 1, stats.st_size, file); >- buffer[stats.st_size] = '\0'; >- fclose (file); >- >- if (!g_str_has_prefix(buffer, "StarDict's treedict ifo file\nversion=2.4.2\n")) { >- g_print("Bad treedict ifo file %s, skiped!\n", ifofilename); >- g_free(buffer); >- return false; >- } >- gchar *p1= buffer + sizeof("StarDict's treedict ifo file\nversion=2.4.2\n")-1 -1; >- >- gchar *p2,*p3; >- >- p2 = strstr(p1,"\ntdxfilesize="); >- if (!p2) { >- g_free(buffer); >+ DictInfo dict_info; >+ if (!dict_info.load_from_ifo_file(ifofilename, true)) > return false; >- } >- p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n'); >- gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1); >- tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0'; >- *tdxfilesize = atol(tmpstr); >- g_free(tmpstr); > >- p2 = strstr(p1,"\nsametypesequence="); >- if (p2) { >- p3 = strchr(p2+sizeof("\nsametypesequence=")-1,'\n'); >- sametypesequence = (gchar *)g_memdup(p2+sizeof("\nsametypesequence=")-1, p3-(p2+sizeof("\nsametypesequence=")-1)+1); >- sametypesequence[p3-(p2+sizeof("\nsametypesequence=")-1)] = '\0'; >- } >+ *tdxfilesize = dict_info.index_file_size; >+ if (!dict_info.sametypesequence.empty()) >+ sametypesequence=g_strdup(dict_info.sametypesequence.c_str()); > >- g_free(buffer); > return true; > } > >diff -rbBdNu stardict-cur-accepted/src/lib.h stardict/src/lib.h >--- stardict-cur-accepted/src/lib.h 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/lib.h 2005-02-20 14:22:36.000000000 +0300 >@@ -11,35 +11,52 @@ > > #include "dictziplib.h" > >+const int MAX_MATCH_ITEM_PER_LIB=100; >+const int MAX_FUZZY_DISTANCE= 3; // at most MAX_FUZZY_DISTANCE-1 differences allowed when find similar words > >-struct cacheItem >-{ >- glong offset; >+extern bool bIsPureEnglish(const gchar *str); >+ >+struct cacheItem { >+ guint32 offset; > gchar *data; >- cacheItem(); >- ~cacheItem(); >+ //write code here to make it inline >+ cacheItem() {data= NULL;} >+ ~cacheItem() {g_free(data);} > }; > > const int WORDDATA_CACHE_NUM = 10; > const int INVALID_INDEX=-100; > >-class DictBase >-{ >+class DictBase { > public: > DictBase(); > ~DictBase(); >- gchar * GetWordData(glong idxitem_offset, glong idxitem_size); >+ gchar * GetWordData(guint32 idxitem_offset, guint32 idxitem_size); > protected: > gchar *sametypesequence; > FILE *dictfile; > dictData *dictdzfile; > private: >- struct cacheItem cache[WORDDATA_CACHE_NUM]; >+ cacheItem cache[WORDDATA_CACHE_NUM]; > gint cache_cur; > }; > >-class Lib : public DictBase >-{ >+//this structure contain all information about dictionary >+struct DictInfo { >+ std::string ifo_file_name; >+ glong wordcount; >+ std::string bookname; >+ std::string author; >+ std::string email; >+ std::string website; >+ std::string date; >+ std::string description; >+ gulong index_file_size; >+ std::string sametypesequence; >+ bool load_from_ifo_file(const gchar *ifofilename, bool istreedict); >+}; >+ >+class Lib : public DictBase { > private: > glong wordcount; > gchar *bookname; >@@ -51,32 +68,27 @@ > glong *wordoffset; > }; > >-#ifdef HAVE_MMAP >- int mmap_fd; >- unsigned long mmap_idxmap_size; >-#endif >- > union { > gchar *idxdatabuffer; > glong cur_wordindex; > }; > > gchar wordentry_buf[256]; // The length of "word_str" should be less than 256. See src/tools/DICTFILE_FORMAT. >- glong wordentry_offset; >- glong wordentry_size; >+ guint32 wordentry_offset; >+ guint32 wordentry_size; > >- gboolean load_ifofile(const char *ifofilename, gulong *idxfilesize); >+ bool load_ifofile(const char *ifofilename, gulong *idxfilesize); > > void loadwordlist(); > void loadwordoffset(); > public: > Lib(); > ~Lib(); >- gboolean load(const char *ifofilename); >- inline glong length() { return(wordcount); } >- inline gchar* GetBookname() { return(bookname); } >- gboolean Lookup(const char* sWord,glong *pIndex); >- gboolean LookupWithRule(GPatternSpec *pspec,glong *aIndex,int iBuffLen); >+ bool load(const char *ifofilename); >+ inline glong length() { return wordcount; } >+ inline gchar* GetBookname() { return bookname; } >+ bool Lookup(const char* sWord,glong *pIndex); >+ bool LookupWithRule(GPatternSpec *pspec,glong *aIndex,int iBuffLen); > gchar * GetWord(glong index); > gchar * GetWordData(glong index); > }; >@@ -86,6 +98,7 @@ > private: > Lib **oLib; // word library. > gint libcount; >+ int iMaxFuzzyDistance; > > void LoadDir(const gchar *dirname, const GSList *order_list, const GSList *disable_list); > public: >@@ -94,27 +107,34 @@ > void Load(const gchar *dicts_dir, const GSList *order_list, const GSList *disable_list); > glong iLength(int iLib); > gchar* GetBookname(int iLib); >- inline gint total_libs() { return(libcount); } >+ inline gint total_libs() {return libcount;} > gchar * poGetWord(glong iIndex,int iLib); > gchar * poGetWordData(glong iIndex,int iLib); > gchar * poGetCurrentWord(glong * iCurrent); > gchar * poGetNextWord(const gchar *word,glong * iCurrent); > gchar * poGetPreWord(glong * iCurrent); >- gboolean LookupWord(const gchar* sWord,glong& iWordIndex,int iLib); >- gboolean LookupSimilarWord(const gchar* sWord,glong& iWordIndex,int iLib); >- gboolean SimpleLookupWord(const gchar* sWord,glong& iWordIndex,int iLib); >- gboolean LookdupWordsWithRule(GPatternSpec *pspec,glong* aiIndexes,int iLen,int iLib); >+ bool LookupWord(const gchar* sWord,glong& iWordIndex,int iLib); >+ bool LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib); >+ bool SimpleLookupWord(const gchar* sWord, glong & iWordIndex, int iLib); >+ >+ struct Fuzzystruct { >+ char * pMatchWord; >+ int iMatchWordDistance; >+ }; >+ typedef void (*TProgressFunc)(void); >+ >+ bool LookupWithFuzzy(const gchar *sWord, Fuzzystruct oFuzzystruct[], gint fuzzystruct_amount, TProgressFunc ProgressFunc); >+ gint LookupWithRule(const gchar *word, TProgressFunc ProgressFunc, gchar **ppMatchWord); > }; > >-inline gboolean bIsVowel(gchar inputchar); > > class TreeDict : public DictBase > { > private: >- gboolean load_ifofile(const char *ifofilename, gulong *tdxfilesize); >+ bool load_ifofile(const char *ifofilename, gulong *tdxfilesize); > void load_model(gchar **buffer, GtkTreeStore *model, GtkTreeIter *parent, gint count); > public: >- gboolean load(const char *ifofilename, GtkTreeStore *model); >+ bool load(const char *ifofilename, GtkTreeStore *model); > }; > > class TreeDicts { >diff -rbBdNu stardict-cur-accepted/src/mainwin.cpp stardict/src/mainwin.cpp >--- stardict-cur-accepted/src/mainwin.cpp 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/mainwin.cpp 2005-02-19 18:21:23.000000000 +0300 >@@ -198,7 +198,7 @@ > gpAppFrame->oAppCore.oTopWin.InsertHisList(gpAppFrame->oAppCore.oTopWin.GetText()); > gpAppFrame->oAppCore.oTopWin.SetText(((BackListData *)((gpAppFrame->oAppCore.oTopWin.BackList)->data))->word); > if (((BackListData *)(gpAppFrame->oAppCore.oTopWin.BackList->data))->adjustment_value != -1) { >- gpAppFrame->ProcessGtkEvent(); >+ ProcessGtkEvent(); > gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(gpAppFrame->oAppCore.oMidWin.oTextWin.scrolled_window)), ((BackListData *)(gpAppFrame->oAppCore.oTopWin.BackList->data))->adjustment_value); > } > g_free(((BackListData *)((gpAppFrame->oAppCore.oTopWin.BackList)->data))->word); >@@ -255,7 +255,7 @@ > if (GTK_WIDGET_HAS_FOCUS(GTK_WIDGET(GTK_COMBO(WordCombo)->entry))) > gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(WordCombo)->entry),0,-1); > if (((BackListData *)(list->data))->adjustment_value != -1) { >- gpAppFrame->ProcessGtkEvent(); // so all the definition text have been inserted. >+ ProcessGtkEvent(); // so all the definition text have been inserted. > gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(gpAppFrame->oAppCore.oMidWin.oTextWin.scrolled_window)), ((BackListData *)(list->data))->adjustment_value); > } > g_free(((BackListData *)(list->data))->word); >@@ -1325,7 +1325,7 @@ > void TextWin::Show(gchar **Word, gchar **WordData, const gchar * sOriginWord) > { > gchar *p; >- glong data_size,sec_size; >+ guint32 data_size,sec_size=0; > GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); > gtk_text_buffer_begin_user_action(buffer); // will this speed up the showing? > >@@ -1336,61 +1336,64 @@ > > GtkTextIter iter; > gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0); >- for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++) >- { >+ for (int i=0; i<gpAppFrame->oAppCore.oLibs.total_libs(); i++) { > if (Word[i]) { > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "<--- ",-1, "DictNameTag", NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, gpAppFrame->oAppCore.oLibs.GetBookname(i),-1, "DictNameTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, gpAppFrame->oAppCore.oLibs.GetBookname(i), >+ -1, "DictNameTag", NULL); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, " --->\n",-1, "DictNameTag", NULL); > gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, Word[i],-1, "WordTag", NULL); > gtk_text_buffer_insert (buffer, &iter,"\n", 1); > } > if (WordData[i]) { >- memcpy(&data_size,WordData[i],sizeof(glong)); >- p=WordData[i]+sizeof(glong); >- while (p - (WordData[i] + sizeof(glong))< data_size) >- { >- switch (*p) >- { >+ p=WordData[i]; >+ data_size=*reinterpret_cast<guint32 *>(p); >+ p+=sizeof(guint32); >+ while (guint32(p - (WordData[i] + sizeof(guint32)))< data_size) { >+ switch (*p++) { > case 'm': >- case 'o': //need more work... >- sec_size = strlen(p+sizeof(gchar)); >- if (sec_size) { >- gtk_text_buffer_insert (buffer, &iter,p+sizeof(gchar),sec_size); >- } >+ case 'l'://need more work... >+ case 'g': >+ sec_size = strlen(p); >+ if (sec_size) >+ gtk_text_buffer_insert(buffer, &iter, p, sec_size); > sec_size++; > break; > case 't': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"PhoneticTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"PhoneticTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"PhoneticTag",NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "PhoneticTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "PhoneticTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "PhoneticTag", NULL); > } > sec_size++; > break; > case 'y': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"YinBiaoTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"YinBiaoTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"YinBiaoTag",NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "YinBiaoTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "YinBiaoTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "YinBiaoTag", NULL); > } > sec_size++; > break; > case 'W': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >+ sec_size=*reinterpret_cast<guint32 *>(p); >+ sec_size=g_ntohl(sec_size); > //enbale sound button. >- sec_size+= sizeof(glong); >+ sec_size += sizeof(guint32); > break; > case 'P': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >+ sec_size=*reinterpret_cast<guint32 *>(p); >+ sec_size=g_ntohl(sec_size); > //show this picture. >- sec_size+= sizeof(glong); >+ sec_size += sizeof(guint32); > break; >+ default: >+ /*nothing*/; > } >- gtk_text_buffer_insert (buffer, &iter,"\n", 1); >- p = p+sizeof(gchar)+sec_size; >+ gtk_text_buffer_insert(buffer, &iter, "\n", 1); >+ p += sec_size; > } > } > } >@@ -1410,51 +1413,56 @@ > GtkTextIter iter; > gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0); > >- const gchar *p; >- glong data_size,sec_size; > >- memcpy(&data_size,data,sizeof(glong)); >- p=data+sizeof(glong); >- while (p - (data + sizeof(glong))< data_size) { >- switch (*p) { >+ guint32 data_size,sec_size=0; >+ const gchar *p=data; >+ data_size=*reinterpret_cast<const guint32 *>(p); >+ p+=sizeof(guint32); >+ while (guint32(p - (data + sizeof(guint32)))< data_size) { >+ switch (*p++) { > case 'm': >- case 'o': //need more work... >- sec_size = strlen(p+sizeof(gchar)); >+ case 'l'://need more work... >+ case 'g': >+ sec_size = strlen(p); > if (sec_size) >- gtk_text_buffer_insert (buffer, &iter,p+sizeof(gchar),sec_size); >+ gtk_text_buffer_insert(buffer, &iter, p, sec_size); > sec_size++; > break; > case 't': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"PhoneticTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"PhoneticTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"PhoneticTag",NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "PhoneticTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "PhoneticTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "PhoneticTag", NULL); > } > sec_size++; > break; > case 'y': >- sec_size = strlen(p+sizeof(gchar)); >+ sec_size = strlen(p); > if (sec_size) { >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"YinBiaoTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"YinBiaoTag",NULL); >- gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"YinBiaoTag",NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "YinBiaoTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "YinBiaoTag", NULL); >+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "YinBiaoTag", NULL); > } > sec_size++; > break; > case 'W': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >+ sec_size=*reinterpret_cast<const guint32 *>(p); >+ sec_size=g_ntohl(sec_size); > //enbale sound button. >- sec_size+= sizeof(glong); >+ sec_size += sizeof(guint32); > break; > case 'P': >- memcpy(&sec_size,p+sizeof(gchar),sizeof(glong)); >+ sec_size=*reinterpret_cast<const guint32 *>(p); >+ sec_size=g_ntohl(sec_size); > //show this picture. >- sec_size+= sizeof(glong); >+ sec_size += sizeof(guint32); > break; >+ default: >+ /*nothing*/; > } >- gtk_text_buffer_insert (buffer, &iter,"\n", 1); >- p = p+sizeof(gchar)+sec_size; >+ gtk_text_buffer_insert(buffer, &iter,"\n", 1); >+ p += sec_size; > } > gtk_text_buffer_end_user_action(buffer); > } >diff -rbBdNu stardict-cur-accepted/src/stardict.cpp stardict/src/stardict.cpp >--- stardict-cur-accepted/src/stardict.cpp 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/stardict.cpp 2005-02-20 14:26:17.000000000 +0300 >@@ -36,7 +36,6 @@ > # include "stardict-application-server.h" > # include "GNOME_Stardict.h" > #endif >-#include "distance.h" > #include "splash.h" > > #ifndef _WIN32 >@@ -84,7 +84,6 @@ > AppCore::AppCore(AppFrame *pAppFrame) > { > poAppFrame = pAppFrame; >- iMaxFuzzyDistance = MAX_FUZZY_DISTANCE; //need to read from cfg. > window = NULL; //need by save_yourself_cb(). > prefs_dlg = NULL; > dict_manage_dlg = NULL; >@@ -358,7 +357,7 @@ > return return_val; > } > >-gboolean AppCore::SimpleLookupToFloat(const char* sWord,gboolean bShowIfNotFound) >+bool AppCore::SimpleLookupToFloat(const char* sWord, bool bShowIfNotFound) > { > if ( sWord==NULL || sWord[0]=='\0') > return true; >@@ -415,7 +414,7 @@ > ppWordData[iLib] = NULL; > } > } >- if (bFound==true) >+ if (bFound) > { > ShowDataToFloatWin(ppWord, ppWordData,SearchWord); > oTopWin.InsertHisList(SearchWord); >@@ -454,13 +453,13 @@ > return false; > } > >-gboolean AppCore::SimpleLookupToTextWin(const char* sWord,glong* piIndex,gboolean piIndexValid, gboolean bTryMoreIfNotFound) >+//the input can be: >+// (sWord,NULL,false) look up the sWord. >+// (sWord,piIndex,false),look up the sWord,and set piIndex to the new indexes that found. >+// (sWord,piIndex,true), show word by piIndex's information. it will always found, so bTryMoreIfNotFound is useless. >+bool AppCore::SimpleLookupToTextWin(const char* sWord, glong* piIndex, bool piIndexValid, bool bTryMoreIfNotFound) > { >- //the input can be: >- // (sWord,NULL,false) look up the sWord. >- // (sWord,piIndex,false),look up the sWord,and set piIndex to the new indexes that found. >- // (sWord,piIndex,true), show word by piIndex's information. it will always found, so bTryMoreIfNotFound is useless. >- gboolean bFound = false; >+ bool bFound = false; > gchar **ppWord = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs()); > gchar **ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs()); > glong *iIndex; >@@ -469,37 +468,35 @@ > else > iIndex = piIndex; > >- for (int iLib=0;iLib<oLibs.total_libs();iLib++) { >+ for (int iLib=0; iLib<oLibs.total_libs(); iLib++) { > if (!piIndexValid) { > if (oLibs.LookupWord(sWord,iIndex[iLib],iLib)) { > ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib); > ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib); > bFound = true; >- } >- else { >+ } else { > ppWord[iLib] = NULL; > ppWordData[iLib] = NULL; > } >- } >- else { >- if (piIndex[iLib] != INVALID_INDEX && (!strcmp((ppWord[iLib] = oLibs.poGetWord(piIndex[iLib],iLib)),sWord))) { >+ } else { >+ if (piIndex[iLib] != INVALID_INDEX && >+ !strcmp((ppWord[iLib] = oLibs.poGetWord(piIndex[iLib],iLib)), sWord)) { > ppWordData[iLib] = oLibs.poGetWordData(piIndex[iLib],iLib); > bFound = true; >- } >- else { >+ } else { > ppWord[iLib] = NULL; > ppWordData[iLib] = NULL; > } > } > } >- if ((!bFound)&&(!piIndexValid)) { >- for (int iLib=0;iLib<oLibs.total_libs();iLib++) { >+ >+ if (!bFound && !piIndexValid) { >+ for (int iLib=0; iLib<oLibs.total_libs(); iLib++) { > if (oLibs.LookupSimilarWord(sWord,iIndex[iLib],iLib)) { > ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib); > ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib); > bFound = true; >- } >- else { >+ } else { > ppWord[iLib] = NULL; > ppWordData[iLib] = NULL; > } >@@ -515,27 +512,24 @@ > if (*hword) { > if (!strcmp(hword,sWord)) { > ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND); >- } >- else { >+ } else { > for (int iLib=0;iLib<oLibs.total_libs();iLib++) { > if (oLibs.LookupWord(hword,iIndex[iLib],iLib)) { > ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib); > ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib); > bFound = true; >- } >- else { >+ } else { > ppWord[iLib] = NULL; > ppWordData[iLib] = NULL; > } > } > if (!bFound) { >- for (int iLib=0;iLib<oLibs.total_libs();iLib++) { >+ for (int iLib=0; iLib<oLibs.total_libs(); iLib++) { > if (oLibs.LookupSimilarWord(hword,iIndex[iLib],iLib)) { > ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib); > ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib); > bFound = true; >- } >- else { >+ } else { > ppWord[iLib] = NULL; > ppWordData[iLib] = NULL; > } >@@ -546,13 +540,11 @@ > else > ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND); > } >- } >- else { >+ } else { > ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND); > } > g_free(word); >- } >- else { >+ } else { > ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND); > } > } >@@ -562,24 +554,8 @@ > > g_free(ppWord); > g_free(ppWordData); >- return bFound; >-} > >-int AppCore::FuzzystructCompare(const void * s1, const void * s2) >-{ >- if (s1==NULL || s2==NULL) >- return 0; >- const struct Fuzzystruct * o1 = (struct Fuzzystruct*)s1; >- const struct Fuzzystruct * o2 = (struct Fuzzystruct*)s2; >- >- if ( o1->iMatchWordDistance > o2->iMatchWordDistance ) >- return 1; >- else if ( o1->iMatchWordDistance < o2->iMatchWordDistance ) >- return -1; >- else if ( o1->pMatchWord && o2->pMatchWord ) >- return stardict_strcmp(o1->pMatchWord, o2->pMatchWord); >- else >- return 0; >+ return bFound; > } > > void AppCore::LookupWithFuzzyToMainWin(const gchar *sWord) >@@ -589,113 +565,32 @@ > > gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor); > >- struct Fuzzystruct oFuzzystruct[MAX_FUZZY_MATCH_ITEM]; >- for (int i=0;i<MAX_FUZZY_MATCH_ITEM;i++) >- { >- oFuzzystruct[i].pMatchWord = NULL; >- oFuzzystruct[i].iMatchWordDistance = iMaxFuzzyDistance; >- } >- int iMaxDistance = iMaxFuzzyDistance; >- int iDistance; >- gboolean Found = false; >- class EditDistance oEditDistance; >- >- glong iCheckWordLen; >- int sCheckLen; >- const char *sCheck; >- gunichar *ucs4_str1,*ucs4_str2; >- glong ucs4_str2_len; >- char *sLowerCheckWord; >- gchar *sLowerWord = g_utf8_strdown(sWord, -1); >- ucs4_str2 = g_utf8_to_ucs4_fast(sLowerWord,-1,&ucs4_str2_len); >- g_free(sLowerWord); >- for(int iLib=0;iLib<oLibs.total_libs();iLib++) >- { >- ProcessGtkEvent(); >- if((stardict_strcmp(sWord,oLibs.poGetWord(0,iLib))>=0) && (stardict_strcmp(sWord,oLibs.poGetWord(oLibs.iLength(iLib)-1,iLib))<=0)) //there are Chinese dicts and English dicts... >- { >- const int iwords = oLibs.iLength(iLib); >- for (int index=0;index<iwords;index++) >- { >- //ProcessGtkEvent(); // too slow if here >- sCheck = oLibs.poGetWord(index,iLib); >- // tolower and skip too long or too short words >- sCheckLen = strlen(sCheck); >- iCheckWordLen = g_utf8_strlen(sCheck, sCheckLen); >- if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || ucs4_str2_len-iCheckWordLen>=iMaxDistance ) >- continue; >- sLowerCheckWord = g_utf8_strdown(sCheck, sCheckLen); >- if (iCheckWordLen > ucs4_str2_len) >- (*g_utf8_offset_to_pointer(sLowerCheckWord, ucs4_str2_len)) = '\0'; >- ucs4_str1 = g_utf8_to_ucs4_fast(sLowerCheckWord, -1,NULL); >- g_free(sLowerCheckWord); >- iDistance = oEditDistance.CalEditDistance(ucs4_str1,ucs4_str2,iMaxDistance); >- g_free(ucs4_str1); >- if ( iDistance < iMaxDistance && iDistance < ucs4_str2_len) // when ucs4_str2_len=1,2 we need less fuzzy. >- { >- Found = true; >- gboolean bAlreadyInList = false; >- int iMaxDistanceAt=0; >- for (int j=0;j<MAX_FUZZY_MATCH_ITEM;j++) >- { >- if ( oFuzzystruct[j].pMatchWord && strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) //already in list >- { >- bAlreadyInList = true; >- break; >- } >- //find the position,it will certainly be found (include the first time) as iMaxDistance is set by last time. >- if ( oFuzzystruct[j].iMatchWordDistance == iMaxDistance ) >- { >- iMaxDistanceAt = j; >- } >- } >- if (!bAlreadyInList ) >- { >- if (oFuzzystruct[iMaxDistanceAt].pMatchWord) >- g_free(oFuzzystruct[iMaxDistanceAt].pMatchWord); >- oFuzzystruct[iMaxDistanceAt].pMatchWord = g_strdup(sCheck); >- oFuzzystruct[iMaxDistanceAt].iMatchWordDistance = iDistance; >- // calc new iMaxDistance >- iMaxDistance = iDistance; >- for (int j=0;j<MAX_FUZZY_MATCH_ITEM;j++) >- { >- if ( oFuzzystruct[j].iMatchWordDistance > iMaxDistance ) >- iMaxDistance = oFuzzystruct[j].iMatchWordDistance; >- } // calc new iMaxDistance >- } // add to list >- } // find one >- } // each word >- } // ok for search >- } // each lib >- g_free(ucs4_str2); >+ Libs::Fuzzystruct oFuzzystruct[MAX_FUZZY_MATCH_ITEM]; >+ bool Found=oLibs.LookupWithFuzzy(sWord, oFuzzystruct, >+ MAX_FUZZY_MATCH_ITEM, ProcessGtkEvent); > > // show > oMidWin.oIndexWin.oListWin.Clear(); > if (Found) { > oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_FUZZY_LIST; >- // sort with distance >- qsort(oFuzzystruct,MAX_FUZZY_MATCH_ITEM,sizeof(Fuzzystruct),FuzzystructCompare); > > //SimpleLookupToTextWin(oFuzzystruct[0].pMatchWord,NULL); > SimpleLookupToTextWin(oFuzzystruct[0].pMatchWord, iCurrentIndex, false); // so iCurrentIndex is refreshed. > >- for (int i=0;i<MAX_FUZZY_MATCH_ITEM;i++) { >- if ( oFuzzystruct[i].pMatchWord ) { >+ for (int i=0; i<MAX_FUZZY_MATCH_ITEM; i++) { >+ if (oFuzzystruct[i].pMatchWord) { > oMidWin.oIndexWin.oListWin.InsertLast(oFuzzystruct[i].pMatchWord); > g_free(oFuzzystruct[i].pMatchWord); > //printf("fuzzy %s,%d\n",oFuzzystruct[i].pMatchWord,oFuzzystruct[i].iMatchWordDistance); >- } >- else { >+ } else > break; > } >- } > oMidWin.oIndexWin.oListWin.ReScroll(); >- } >- else { >+ } else { > oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_EMPTY; > ShowNotFoundToTextWin(sWord,_("There are too many spelling errors :-("), TEXT_WIN_FUZZY_NOT_FOUND); > } >- gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor); >+ gdk_window_set_cursor(window->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor); > } > > void AppCore::LookupWithFuzzyToFloatWin(const gchar *sWord) >@@ -705,92 +600,16 @@ > > gdk_window_set_cursor (oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor); > >- struct Fuzzystruct oFuzzystruct[MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM]; >- for (int i=0;i<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;i++) >- { >- oFuzzystruct[i].pMatchWord = NULL; >- oFuzzystruct[i].iMatchWordDistance = iMaxFuzzyDistance; >- } >- int iMaxDistance = iMaxFuzzyDistance; >- int iDistance; >- gboolean Found = false; >- class EditDistance oEditDistance; >+ Libs::Fuzzystruct oFuzzystruct[MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM]; > >- glong iCheckWordLen; >- int sCheckLen; >- const char * sCheck; >- gunichar *ucs4_str1,*ucs4_str2; >- glong ucs4_str2_len; >- gchar *sLowerCheckWord; >- gchar *sLowerWord = g_utf8_strdown(sWord, -1); >- ucs4_str2 = g_utf8_to_ucs4_fast(sLowerWord, -1,&ucs4_str2_len); >- g_free(sLowerWord); >- for(int iLib=0;iLib<oLibs.total_libs();iLib++) >- { >- ProcessGtkEvent(); >- if((stardict_strcmp(sWord,oLibs.poGetWord(0,iLib))>=0) && (stardict_strcmp(sWord,oLibs.poGetWord(oLibs.iLength(iLib)-1,iLib))<=0)) //there are Chinese dicts and English dicts... >- { >- const int iwords = oLibs.iLength(iLib); >- for (int index=0;index<iwords;index++) >- { >- //ProcessGtkEvent(); // too slow if here >- sCheck = oLibs.poGetWord(index,iLib); >- // tolower and skip too long or too short words >- sCheckLen = strlen(sCheck); >- iCheckWordLen = g_utf8_strlen(sCheck, sCheckLen); >- if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || ucs4_str2_len-iCheckWordLen>=iMaxDistance ) >- continue; >- sLowerCheckWord = g_utf8_strdown(sCheck, sCheckLen); >- if (iCheckWordLen > ucs4_str2_len) >- (*g_utf8_offset_to_pointer(sLowerCheckWord, ucs4_str2_len)) = '\0'; >- ucs4_str1 = g_utf8_to_ucs4_fast(sLowerCheckWord, -1,NULL); >- g_free(sLowerCheckWord); >- iDistance = oEditDistance.CalEditDistance(ucs4_str1,ucs4_str2,iMaxDistance); >- g_free(ucs4_str1); >- if ( iDistance < iMaxDistance && iDistance < ucs4_str2_len) // when ucs4_str2_len=1,2 we need less fuzzy. >- { >- Found = true; >- gboolean bAlreadyInList = false; >- int iMaxDistanceAt=0; >- for (int j=0;j<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;j++) >- { >- if ( oFuzzystruct[j].pMatchWord && strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) //already in list >- { >- bAlreadyInList = true; >- break; >- } >- if ( oFuzzystruct[j].iMatchWordDistance == iMaxDistance ) >- { >- iMaxDistanceAt = j; >- } >- } >- if (!bAlreadyInList ) >- { >- if (oFuzzystruct[iMaxDistanceAt].pMatchWord) >- g_free(oFuzzystruct[iMaxDistanceAt].pMatchWord); >- oFuzzystruct[iMaxDistanceAt].pMatchWord = g_strdup(sCheck); >- oFuzzystruct[iMaxDistanceAt].iMatchWordDistance = iDistance; >- // calc new iMaxDistance >- iMaxDistance = iDistance; >- for (int j=0;j<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;j++) >- { >- if ( oFuzzystruct[j].iMatchWordDistance > iMaxDistance ) >- iMaxDistance = oFuzzystruct[j].iMatchWordDistance; >- } // calc new iMaxDistance >- } // add to list >- } // find one >- } // each word >- } // ok for search >- } // each lib >- g_free(ucs4_str2); >+ bool Found = oLibs.LookupWithFuzzy(sWord, oFuzzystruct, >+ MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM, >+ ProcessGtkEvent); >+ >+ if (Found) { > >- if (Found) >- { >- // sort with distance >- qsort(oFuzzystruct,MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM,sizeof(Fuzzystruct),FuzzystructCompare); > int i,count=0; >- for (i=0;i<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;i++) >- { >+ for (i=0;i<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;i++) { > if (oFuzzystruct[i].pMatchWord) > count++; > else >@@ -802,33 +621,26 @@ > gchar **ppWord; > gchar **ppWordData; > glong iRetIndex; >- for (i=0;i<count;i++) >- { >- gboolean bFound = false; >+ for (i=0;i<count;i++) { >+ bool bFound = false; > ppWord = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs()); > ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs()); > > ppOriginWord[i] = oFuzzystruct[i].pMatchWord; >- for (int iLib=0;iLib<oLibs.total_libs();iLib++) >- { >- if (oLibs.SimpleLookupWord(oFuzzystruct[i].pMatchWord, iRetIndex,iLib)) >- { >+ for (int iLib=0; iLib<oLibs.total_libs(); iLib++) { >+ if (oLibs.SimpleLookupWord(oFuzzystruct[i].pMatchWord, iRetIndex,iLib)) { > ppWord[iLib] = oLibs.poGetWord(iRetIndex,iLib); > ppWordData[iLib] = oLibs.poGetWordData(iRetIndex,iLib); > bFound = true; >- } >- else { >+ } else { > ppWord[iLib] = NULL; > ppWordData[iLib] = NULL; > } > } >- if (bFound==true) // it is certainly be true. >- { >+ if (bFound) {// it is certainly be true. > pppWord[i]=ppWord; > pppWordData[i]=ppWordData; >- } >- else >- { >+ } else { > g_free(ppWord); > pppWord[i]=NULL; > g_free(ppWordData); >@@ -836,8 +648,7 @@ > } > } > ShowDatasToFloatWin(pppWord, pppWordData, ppOriginWord, count,sWord); >- for (i=0;i<count;i++) >- { >+ for (i=0; i<count; i++) { > if (pppWord[i]) > g_free(pppWord[i]); > if (pppWordData[i]) >@@ -849,58 +660,22 @@ > > for (i=0;i<count;i++) > g_free(oFuzzystruct[i].pMatchWord); >- } >- else >+ } else > ShowNotFoundToFloatWin(sWord,_("Fuzzy query failed, too :-("), true); >- gdk_window_set_cursor (oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor); >-} >- >-int AppCore::MatchWordCompare(const void * s1, const void * s2) >-{ >- const gchar **o1 = (const gchar **)s1; >- const gchar **o2 = (const gchar **)s2; >- return stardict_strcmp(*o1,*o2); >+ gdk_window_set_cursor(oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor); > } > > void AppCore::LookupWithRuleToMainWin(const gchar *word) > { > gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor); > >- glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1]; >- int iMatchCount = 0; > gchar **ppMatchWord = (gchar **)g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * oLibs.total_libs()); >- GPatternSpec *pspec = g_pattern_spec_new(word); >- >- for(int iLib=0;iLib<oLibs.total_libs();iLib++) >- { >- //if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1-iMatchCount,iLib)) // -iMatchCount,so save time,but may got less result and the word may repeat. >- if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1,iLib)) >- { >- ProcessGtkEvent(); >- for(int i=0;aiIndex[i]!=-1;i++) >- { >- gchar * sMatchWord = oLibs.poGetWord(aiIndex[i],iLib); >- gboolean bAlreadyInList = false; >- for (int j=0;j<iMatchCount;j++) >- { >- if ( strcmp(ppMatchWord[j],sMatchWord) == 0 ) //already in list >- { >- bAlreadyInList = true; >- break; >- } >- } >- if ( !bAlreadyInList) >- ppMatchWord[iMatchCount++] = g_strdup(sMatchWord); >- } >- } >- } >- g_pattern_spec_free(pspec); >+ gint iMatchCount=oLibs.LookupWithRule(word, ProcessGtkEvent, ppMatchWord); > oMidWin.oIndexWin.oListWin.Clear(); >- if (iMatchCount) >- { >+ if (iMatchCount) { > oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_PATTERN_LIST; >- qsort(ppMatchWord,iMatchCount,sizeof(gchar *),MatchWordCompare); // sort it. >- for(int i=0;i<iMatchCount;i++) >+ >+ for(gint i=0; i<iMatchCount; i++) > oMidWin.oIndexWin.oListWin.InsertLast(ppMatchWord[i]); > //memset(iCurrentIndex,'\0',sizeof(iCurrentIndex)); // iCurrentIndex is ineffective now. > >@@ -908,11 +683,9 @@ > //SimpleLookupToTextWin(ppMatchWord[0],NULL); > SimpleLookupToTextWin(ppMatchWord[0], iCurrentIndex, false); // so iCurrentIndex is refreshed. > oMidWin.oIndexWin.oListWin.ReScroll(); >- for(int i=0;i<iMatchCount;i++) >+ for(gint i=0; i<iMatchCount; i++) > g_free(ppMatchWord[i]); >- } >- else >- { >+ } else { > oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_EMPTY; > ShowNotFoundToTextWin(word,_("Found no words matching this pattern!"), TEXT_WIN_PATTERN_NOT_FOUND); > } >@@ -1156,11 +929,6 @@ > gtk_widget_destroy(window); > } > >-void AppCore::ProcessGtkEvent() >-{ >- poAppFrame->ProcessGtkEvent(); >-} >- > > /***************************************************/ > AppFrame::AppFrame():oAppCore(this) >@@ -1193,14 +961,6 @@ > gtk_main(); > } > >-void AppFrame::ProcessGtkEvent() >-{ >- while (gtk_events_pending()) >- { >- gtk_main_iteration(); >- } >-} >- > void AppFrame::Quit() > { > gboolean maximized=conf->get_maximized(); >@@ -1231,16 +991,6 @@ > gtk_main_quit (); > } > >-gint stardict_strcmp(const gchar *s1, const gchar *s2) >-{ >- gint a; >- a = g_ascii_strcasecmp(s1, s2); >- if (a == 0) >- return strcmp(s1, s2); >- else >- return a; >-} >- > gboolean bContainRule(const char* sWord) > { > int i; >@@ -1255,21 +1005,6 @@ > return(false); > } > >-gboolean bIsPureEnglish(const gchar *str) // i think this should work even when it is UTF8 string :). >-{ >- int i; >- for(i=0;str[i]!=0;i++) { >- //if(str[i]<0) >- //if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK. >- // Better use isascii() but not str[i]<0 while char is default unsigned in arm >- if (!isascii(str[i])) >- { >- return(false); >- } >- } >- return(true); >-} >- > gchar* GetPureEnglishAlpha(gchar *str) > { > while (*str && (!((*str >= 'a' && *str <='z')||(*str >= 'A' && *str <='Z')))) >diff -rbBdNu stardict-cur-accepted/src/stardict.h stardict/src/stardict.h >--- stardict-cur-accepted/src/stardict.h 2005-02-20 13:36:16.000000000 +0300 >+++ stardict/src/stardict.h 2005-02-15 23:16:38.000000000 +0300 >@@ -31,12 +31,10 @@ > > //notice!!! when you change these DEFAULT const value,remember that you'd better change data/stardict.schemas.in too! > >-const int MAX_MATCH_ITEM_PER_LIB=100; > const int MAX_FUZZY_MATCH_ITEM=100; > const int MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM=5; > > const int LIST_WIN_ROW_NUM = 30; //how many words show in the list win. >-const int MAX_FUZZY_DISTANCE= 3; // at most MAX_FUZZY_DISTANCE-1 differences allowed when find similar words > > > class AppCore >@@ -46,14 +44,7 @@ > > PrefsDlg *prefs_dlg; > DictManageDlg *dict_manage_dlg; >- // struct >- struct Fuzzystruct { >- char * pMatchWord; >- int iMatchWordDistance; >- }; >- int iMaxFuzzyDistance; > >- static int FuzzystructCompare(const void * s1, const void * s2); > static int MatchWordCompare(const void * s1, const void * s2); > static gboolean on_delete_event(GtkWidget * window, GdkEvent *event , AppCore *oAppCore); > static gboolean on_window_state_event(GtkWidget * window, GdkEventWindowState *event , AppCore *oAppCore); >@@ -81,11 +72,10 @@ > AppCore(AppFrame* pAppFrame); > ~AppCore(); > void Create(gchar *queryword); >- void ProcessGtkEvent(); > void End(); > void Query(const gchar *word); >- gboolean SimpleLookupToFloat(const gchar* sWord,gboolean bShowIfNotFound); >- gboolean SimpleLookupToTextWin(const gchar* sWord,glong* piIndex, gboolean piIndexValid = false, gboolean bTryMoreIfNotFound = false); >+ bool SimpleLookupToFloat(const gchar* sWord, bool bShowIfNotFound); >+ bool SimpleLookupToTextWin(const gchar* sWord,glong* piIndex, bool piIndexValid = false, bool bTryMoreIfNotFound = false); > void LookupWithFuzzyToMainWin(const gchar* word); > void LookupWithFuzzyToFloatWin(const gchar * word); > void LookupWithRuleToMainWin(const gchar* word); >@@ -122,7 +112,6 @@ > AppFrame(); > ~AppFrame(); > void Init(gchar *queryword); >- void ProcessGtkEvent(); > void Quit(); > }; > >@@ -131,12 +120,9 @@ > extern gchar stardict_data_dir[256]; > #endif > >-extern gint stardict_strcmp(const gchar *s1, const gchar *s2); > extern gboolean bContainRule(const char* sWord); >-extern gboolean bIsPureEnglish(const gchar *str); > extern gchar* GetPureEnglishAlpha(gchar *str); > extern gchar* GetHeadWord(gchar *str); >- > extern gboolean stardict_on_enter_notify (GtkWidget * widget, GdkEventCrossing * event, gpointer data); > > #endif >diff -rbBdNu stardict-cur-accepted/src/utils.cpp stardict/src/utils.cpp >--- stardict-cur-accepted/src/utils.cpp 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/utils.cpp 2005-02-15 20:57:42.000000000 +0300 >@@ -54,3 +54,9 @@ > gnome_url_show(url, NULL); > #endif > } >+ >+void ProcessGtkEvent(void) >+{ >+ while (gtk_events_pending()) >+ gtk_main_iteration(); >+} >diff -rbBdNu stardict-cur-accepted/src/utils.h stardict/src/utils.h >--- stardict-cur-accepted/src/utils.h 2005-02-20 13:36:22.000000000 +0300 >+++ stardict/src/utils.h 2005-02-15 20:58:03.000000000 +0300 >@@ -4,5 +4,6 @@ > extern void play_wav_file(const gchar *filename); > extern void show_help(const gchar *section); > extern void show_url(const gchar *url); >+extern void ProcessGtkEvent(void); > > #endif/*UTILS_H*/
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 86379
:
54223
|
54224
|
54225
|
54226
|
54227
|
54228
|
57739
|
77422