Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 86379 | Differences between
and this patch

Collapse All | Expand All

(-)stardict-cur-accepted/configure.in (-4 / +3 lines)
Lines 55-65 Link Here
55
55
56
dnl ******************************
56
dnl ******************************
57
57
58
AC_ARG_ENABLE(schemas-install,AC_HELP_STRING([--disable-schemas-install],
58
dnl AC_ARG_ENABLE(schemas-install,AC_HELP_STRING([--disable-schemas-install], [Disable installation of the gconf schemas]))
59
                                             [Disable installation of the gconf
60
schemas]))
61
59
62
AM_CONDITIONAL(SCHEMAS_INSTALL, test x$enable_schemas_install != xno)
60
dnl AM_CONDITIONAL(SCHEMAS_INSTALL, test x$enable_schemas_install != xno)
63
61
64
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
62
AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
65
if test x"$GCONFTOOL" = xno; then
63
if test x"$GCONFTOOL" = xno; then
Lines 68-73 Link Here
68
fi
66
fi
69
AM_GCONF_SOURCE_2
67
AM_GCONF_SOURCE_2
70
68
69
AM_CONDITIONAL(SCHEMAS_INSTALL, test x$schemas_install = xtrue)
71
70
72
dnl
71
dnl
73
dnl Check popt
72
dnl Check popt
(-)stardict-cur-accepted/src/dictmanagedlg.cpp (-129 / +24 lines)
Lines 44-172 Link Here
44
		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 1);
44
		gtk_notebook_set_current_page(GTK_NOTEBOOK(oDictManageDlg->notebook), 1);
45
}
45
}
46
46
47
gboolean DictManageDlg::get_dict_info(gboolean istreedict, const gchar *ifofilename, glong *wordcount, gchar **bookname, gchar **author, gchar **email,
48
				gchar **website, gchar **date, gchar **description)
49
{
50
	struct stat stats;		
51
	if (stat (ifofilename, &stats) == -1) {
52
		return false;
53
	}
54
		
55
	FILE *file;
56
	if (!(file = fopen (ifofilename, "rb"))) {
57
		return false;
58
	}
59
	gchar *buffer = (gchar *)g_malloc (stats.st_size + 1);
60
	fread (buffer, 1, stats.st_size, file);
61
	buffer[stats.st_size] = '\0';
62
	fclose (file);
63
	
64
	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"))) {
65
		g_free(buffer);
66
		return false;
67
	}
68
69
	gchar *p1,*p2,*p3;
70
	if (istreedict)
71
		p1 = buffer + sizeof("StarDict's treedict ifo file\nversion=2.4.2\n") -1 -1;
72
	else
73
		p1 = buffer + sizeof("StarDict's dict ifo file\nversion=2.4.2\n") -1 -1;
74
75
	p2 = strstr(p1,"\nwordcount=");
76
	if (p2) {
77
		p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n');
78
		gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1);
79
		tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0';
80
		*wordcount = atol(tmpstr);
81
		g_free(tmpstr);
82
	}
83
	else {
84
		*wordcount = 0;
85
	}
86
	
87
	p2 = strstr(p1,"\nbookname=");
88
	if (p2) {
89
		p2 = p2 + sizeof("\nbookname=") -1;
90
		p3 = strchr(p2, '\n');
91
		*bookname = g_strndup(p2, p3-p2);
92
	}
93
	else {
94
		*bookname = NULL;
95
	}
96
97
	p2 = strstr(p1,"\nauthor=");
98
	if (p2) {
99
		p2 = p2 + sizeof("\nauthor=") -1;
100
		p3 = strchr(p2, '\n');
101
		*author = g_strndup(p2, p3-p2);
102
	}
103
	else {
104
		*author = NULL;
105
	}
106
107
	p2 = strstr(p1,"\nemail=");
108
	if (p2) {
109
		p2 = p2 + sizeof("\nemail=") -1;
110
		p3 = strchr(p2, '\n');
111
		*email = g_strndup(p2, p3-p2);
112
	}
113
	else {
114
		*email = NULL;
115
	}
116
117
	p2 = strstr(p1,"\nwebsite=");
118
	if (p2) {
119
		p2 = p2 + sizeof("\nwebsite=") -1;
120
		p3 = strchr(p2, '\n');
121
		*website = g_strndup(p2, p3-p2);
122
	}
123
	else {
124
		*website = NULL;
125
	}
126
127
	p2 = strstr(p1,"\ndate=");
128
	if (p2) {
129
		p2 = p2 + sizeof("\ndate=") -1;
130
		p3 = strchr(p2, '\n');
131
		*date = g_strndup(p2, p3-p2);
132
	}
133
	else {
134
		*date = NULL;
135
	}								
136
137
	p2 = strstr(p1,"\ndescription=");
138
	if (p2) {
139
		p2 = p2 + sizeof("\ndescription=") -1;
140
		p3 = strchr(p2, '\n');
141
		*description = g_strndup(p2, p3-p2);
142
	}
143
	else {
144
		*description = NULL;
145
	}
146
147
	g_free(buffer);
148
	return true;				
149
}
150
151
void DictManageDlg::load_dir(gboolean istreedict, const gchar *dirname, const GSList *order_list, const GSList *disable_list, GtkListStore *model)
47
void DictManageDlg::load_dir(gboolean istreedict, const gchar *dirname, const GSList *order_list, const GSList *disable_list, GtkListStore *model)
152
{
48
{
153
	GDir *dir = g_dir_open(dirname, 0, NULL);	
49
	GDir *dir = g_dir_open(dirname, 0, NULL);	
154
	if (dir)
50
  if (dir) {
155
	{
156
		GtkTreeIter iter;
51
		GtkTreeIter iter;
157
		const gchar *filename;	
52
		const gchar *filename;	
158
		gchar fullfilename[256];
53
		gchar fullfilename[256];
159
		gboolean loaded;
54
		gboolean loaded;
160
		const GSList *tmplist1,*tmplist2;
55
		const GSList *tmplist1,*tmplist2;
161
		gboolean disabled;
56
		gboolean disabled;
162
		glong wordcount;
57
    DictInfo dict_info;
163
		gchar *bookname, *author, *email, *website, *description, *date;
164
		while ((filename = g_dir_read_name(dir))!=NULL) {
58
		while ((filename = g_dir_read_name(dir))!=NULL) {
165
			sprintf(fullfilename, "%s/%s", dirname, filename);
59
			sprintf(fullfilename, "%s/%s", dirname, filename);
166
			if (g_file_test(fullfilename, G_FILE_TEST_IS_DIR)) {
60
			if (g_file_test(fullfilename, G_FILE_TEST_IS_DIR)) {
167
				load_dir(istreedict, fullfilename, order_list, disable_list, model);
61
				load_dir(istreedict, fullfilename, order_list, disable_list, model);
168
			}
62
      } else if (g_str_has_suffix(filename,".ifo")) {
169
			else if (g_str_has_suffix(filename,".ifo")) {
170
				tmplist1 = order_list;
63
				tmplist1 = order_list;
171
				loaded = false;
64
				loaded = false;
172
				while (tmplist1) {
65
				while (tmplist1) {
Lines 178-184 Link Here
178
				}
71
				}
179
				if (loaded)
72
				if (loaded)
180
					continue;
73
					continue;
181
				if (get_dict_info(istreedict, fullfilename, &wordcount, &bookname, &author, &email, &website, &description, &date)) {
74
	if (dict_info.load_from_ifo_file(fullfilename, istreedict)) {
182
					tmplist2 = disable_list;
75
					tmplist2 = disable_list;
183
					disabled = false;
76
					disabled = false;
184
					while (tmplist2) {
77
					while (tmplist2) {
Lines 189-201 Link Here
189
						tmplist2 = g_slist_next(tmplist2);
82
						tmplist2 = g_slist_next(tmplist2);
190
					}
83
					}
191
					gtk_list_store_append (model, &iter);				
84
					gtk_list_store_append (model, &iter);				
192
					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);
85
	  gtk_list_store_set (model, &iter, 0, !disabled, 
193
					g_free(bookname);
86
			      1, dict_info.bookname.c_str(), 
194
					g_free(author);
87
			      2, dict_info.wordcount, 
195
					g_free(email);
88
			      3, dict_info.author.c_str(), 
196
					g_free(website);
89
			      4, dict_info.email.c_str(), 
197
					g_free(description);
90
			      5, dict_info.website.c_str(), 
198
					g_free(date);
91
			      6, dict_info.date.c_str(), 
92
			      7, dict_info.description.c_str(), 
93
			      8, fullfilename, 9, true, -1);
199
				}
94
				}
200
			}
95
			}
201
		}
96
		}
Lines 218-225 Link Here
218
    disable_list=conf->get_dict_disable_list();    
113
    disable_list=conf->get_dict_disable_list();    
219
	}
114
	}
220
	
115
	
221
	glong wordcount;
222
	gchar *bookname, *author, *email, *website, *description, *date;
223
	
116
	
224
	GtkTreeIter iter;
117
	GtkTreeIter iter;
225
	
118
	
Lines 230-238 Link Here
230
	while (tmplist1) {
123
	while (tmplist1) {
231
		ifofilename = (gchar *)(tmplist1->data);
124
		ifofilename = (gchar *)(tmplist1->data);
232
		tmplist1 = g_slist_next(tmplist1);
125
		tmplist1 = g_slist_next(tmplist1);
233
		
126
    DictInfo dict_info;
234
		if (g_file_test(ifofilename, G_FILE_TEST_EXISTS)) {
127
		if (g_file_test(ifofilename, G_FILE_TEST_EXISTS)) {
235
			if (get_dict_info(istreedict, ifofilename, &wordcount, &bookname, &author, &email, &website, &description, &date)) {
128
      if (dict_info.load_from_ifo_file(ifofilename, istreedict)) {
236
				tmplist2 = disable_list;
129
				tmplist2 = disable_list;
237
				disabled = false;
130
				disabled = false;
238
				while (tmplist2) {
131
				while (tmplist2) {
Lines 243-255 Link Here
243
					tmplist2 = g_slist_next(tmplist2);
136
					tmplist2 = g_slist_next(tmplist2);
244
				}
137
				}
245
				gtk_list_store_append (model, &iter);				
138
				gtk_list_store_append (model, &iter);				
246
				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);
139
	gtk_list_store_set (model, &iter, 0, !disabled, 
247
				g_free(bookname);
140
			    1, dict_info.bookname.c_str(), 
248
				g_free(author);
141
			    2, dict_info.wordcount, 
249
				g_free(email);
142
			    3, dict_info.author.c_str(), 
250
				g_free(website);
143
			    4, dict_info.email.c_str(), 
251
				g_free(description);
144
			    5, dict_info.website.c_str(),
252
				g_free(date);
145
			    6, dict_info.description.c_str(), 
146
			    7, dict_info.date.c_str(), 
147
			    8, ifofilename, 9, true, -1);
253
			}
148
			}
254
		}
149
		}
255
	}
150
	}
(-)stardict-cur-accepted/src/dictmanagedlg.h (-2 lines)
Lines 19-26 Link Here
19
		
19
		
20
	GtkWidget *create_buttons();
20
	GtkWidget *create_buttons();
21
21
22
	static gboolean get_dict_info(gboolean istreedict, const gchar *ifofilename, glong *wordcount, gchar **bookname, gchar **author, gchar **email,
23
				gchar **website, gchar **date, gchar **description);	
24
	void write_order_list(gboolean istreedict);
22
	void write_order_list(gboolean istreedict);
25
23
26
	static void on_wazard_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg);
24
	static void on_wazard_button_toggled(GtkToggleButton *button, DictManageDlg *oDictManageDlg);
(-)stardict-cur-accepted/src/distance.cpp (-1 / +3 lines)
Lines 32-43 Link Here
32
    * DNA analysis
32
    * DNA analysis
33
    * Plagiarism detection 
33
    * Plagiarism detection 
34
*/
34
*/
35
#include "distance.h"
35
36
36
37
#include <stdlib.h>
37
#include <stdlib.h>
38
#include <string.h>
38
#include <string.h>
39
//#include <stdio.h>
39
//#include <stdio.h>
40
40
41
#include "distance.h"
42
41
#define OPTIMIZE_ED
43
#define OPTIMIZE_ED
42
/*
44
/*
43
Cover transposition, in addition to deletion,
45
Cover transposition, in addition to deletion,
(-)stardict-cur-accepted/src/distance.h (-1 / +1 lines)
Lines 5-11 Link Here
5
#include <config.h>
5
#include <config.h>
6
#endif
6
#endif
7
7
8
#include <gtk/gtk.h>
8
#include <glib.h>
9
9
10
class EditDistance {
10
class EditDistance {
11
private:
11
private:
(-)stardict-cur-accepted/src/floatwin.cpp (-53 / +70 lines)
Lines 185-193 Link Here
185
	mark += "</big></b>";
185
	mark += "</big></b>";
186
	
186
	
187
	gchar *p;
187
	gchar *p;
188
	glong data_size,sec_size;
188
  guint32 data_size, sec_size=0;
189
	for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++)
189
  for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++) {
190
	{
191
		if (word[i]) {
190
		if (word[i]) {
192
			mark += "\n<span foreground=\"blue\">*--- ";
191
			mark += "\n<span foreground=\"blue\">*--- ";
193
			m_str = g_markup_escape_text(gpAppFrame->oAppCore.oLibs.GetBookname(i),-1);
192
			m_str = g_markup_escape_text(gpAppFrame->oAppCore.oLibs.GetBookname(i),-1);
Lines 204-231 Link Here
204
			}
203
			}
205
		}
204
		}
206
		if (data[i]) {			
205
		if (data[i]) {			
207
			memcpy(&data_size,data[i],sizeof(glong));
206
      p=data[i];
208
			p=data[i]+sizeof(glong);
207
      data_size=*reinterpret_cast<guint32 *>(p);
209
			while (p - (data[i] + sizeof(glong))< data_size)
208
      p+=sizeof(guint32);
210
			{
209
      while (guint32(p - (data[i] + sizeof(guint32)))< data_size) {
211
				switch (*p)
210
	switch (*p++) {
212
				{
213
					case 'm':
211
					case 'm':
214
					case 'o': //need more work...
212
	case 'l'://need more work
215
						sec_size = strlen(p+sizeof(gchar));
213
	  sec_size = strlen(p);
216
						if (sec_size) {							
214
						if (sec_size) {							
217
							mark+= "\n";
215
							mark+= "\n";
218
							m_str = g_markup_escape_text(p+sizeof(gchar),sec_size);
216
	    m_str = g_markup_escape_text(p, sec_size);
219
							mark += m_str;
217
							mark += m_str;
220
							g_free(m_str);							
218
							g_free(m_str);							
221
						}
219
						}
222
						sec_size++;
220
						sec_size++;
223
						break;
221
						break;
222
	case 'g':
223
	  sec_size = strlen(p);
224
	  if (sec_size) {
225
	    mark += "\n";
226
	    mark += p;
227
	  }
228
	  sec_size++;
229
	  break;
224
					case 't':
230
					case 't':
225
						sec_size = strlen(p+sizeof(gchar));
231
	  sec_size = strlen(p);
226
						if (sec_size) {
232
						if (sec_size) {
227
							mark += "\n<big>[";
233
							mark += "\n<big>[";
228
							m_str = g_markup_escape_text(p+sizeof(gchar),sec_size);
234
	    m_str = g_markup_escape_text(p, sec_size);
229
							mark += m_str;
235
							mark += m_str;
230
							g_free(m_str);
236
							g_free(m_str);
231
							mark+= "]</big>";
237
							mark+= "]</big>";
Lines 233-242 Link Here
233
						sec_size++;
239
						sec_size++;
234
						break;
240
						break;
235
					case 'y':
241
					case 'y':
236
						sec_size = strlen(p+sizeof(gchar));
242
	  sec_size = strlen(p);
237
						if (sec_size) {
243
						if (sec_size) {
238
							mark += "\n<span foreground=\"red\">[";
244
							mark += "\n<span foreground=\"red\">[";
239
							m_str = g_markup_escape_text(p+sizeof(gchar),sec_size);
245
	    m_str = g_markup_escape_text(p, sec_size);
240
							mark += m_str;
246
							mark += m_str;
241
							g_free(m_str);
247
							g_free(m_str);
242
							mark+= "]</span>";
248
							mark+= "]</span>";
Lines 244-259 Link Here
244
						sec_size++;						
250
						sec_size++;						
245
						break;
251
						break;
246
					case 'W':
252
					case 'W':
247
						memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
253
	  sec_size=*reinterpret_cast<guint32 *>(p);
254
	  sec_size=g_ntohl(sec_size);
248
						//enbale sound button.
255
						//enbale sound button.
249
						sec_size+= sizeof(glong);
256
	  sec_size+=sizeof(guint32);
250
						break;
257
						break;
251
					case 'P':
258
					case 'P':
252
						memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
259
	  sec_size=*reinterpret_cast<guint32 *>(p);
253
						sec_size+= sizeof(glong);
260
	  sec_size=g_ntohl(sec_size);
261
	  sec_size+= sizeof(guint32);
254
						break;						
262
						break;						
263
	default:
264
	  /*nothing*/;
255
				}								
265
				}								
256
				p = p+sizeof(gchar)+sec_size;
266
	p += sec_size;
257
			}
267
			}
258
		}		
268
		}		
259
	}
269
	}
Lines 262-269 Link Here
262
	gboolean canRead = gpAppFrame->oReadWord.canRead(sOriginWord);
272
	gboolean canRead = gpAppFrame->oReadWord.canRead(sOriginWord);
263
	if (canRead) {
273
	if (canRead) {
264
		PronounceWord = sOriginWord;
274
		PronounceWord = sOriginWord;
265
	}
275
  } else {
266
	else {
267
		for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs(); i++) {
276
		for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs(); i++) {
268
			if (word[i] && strcmp(word[i], sOriginWord)) {
277
			if (word[i] && strcmp(word[i], sOriginWord)) {
269
				if (gpAppFrame->oReadWord.canRead(word[i])) {
278
				if (gpAppFrame->oReadWord.canRead(word[i])) {
Lines 281-287 Link Here
281
		gpAppFrame->oReadWord.read(PronounceWord.c_str());
290
		gpAppFrame->oReadWord.read(PronounceWord.c_str());
282
}
291
}
283
292
284
void FloatWin::ShowText(gchar *** pppWord, gchar *** pppWordData, const gchar ** ppOriginWord, gint count,const gchar * sOriginWord)
293
void FloatWin::ShowText(gchar *** pppWord, gchar *** pppWordData, 
294
			const gchar ** ppOriginWord, gint count,
295
			const gchar * sOriginWord)
285
{
296
{
286
	QueryingWord = sOriginWord;
297
	QueryingWord = sOriginWord;
287
	found_result = FLOAT_WIN_FUZZY_FOUND;
298
	found_result = FLOAT_WIN_FUZZY_FOUND;
Lines 297-314 Link Here
297
	mark += _("Found ");
308
	mark += _("Found ");
298
	if (count ==1)
309
	if (count ==1)
299
		mark+= _("1 word:\n");
310
		mark+= _("1 word:\n");
300
	else
311
  else {
301
	{
302
		m_str=g_strdup_printf("%d",count);
312
		m_str=g_strdup_printf("%d",count);
303
		mark += m_str;
313
		mark += m_str;
304
		g_free(m_str);
314
		g_free(m_str);
305
		mark+= _(" words:\n");
315
		mark+= _(" words:\n");
306
	}
316
	}
307
	int j;
317
	int j;
308
	for (j=0;j<count-1;j++)
318
  for (j=0; j<count-1; j++) {
309
	{
310
		mark += "<b><big>";
319
		mark += "<b><big>";
311
		m_str = g_markup_escape_text(ppOriginWord[j],-1);
320
    m_str = g_markup_escape_text(ppOriginWord[j], -1);
312
		mark += m_str;
321
		mark += m_str;
313
		g_free(m_str);
322
		g_free(m_str);
314
		mark += "</big></b> ";
323
		mark += "</big></b> ";
Lines 320-336 Link Here
320
	mark += "</big></b>";
329
	mark += "</big></b>";
321
	
330
	
322
	gchar *p;
331
	gchar *p;
323
	glong data_size,sec_size;
332
  guint32 data_size,sec_size;
324
	for (j=0;j<count;j++)
333
  for (j=0; j<count; j++) {
325
	{
326
		mark += "\n\n<span foreground=\"red\">#----- ";
334
		mark += "\n\n<span foreground=\"red\">#----- ";
327
		m_str = g_markup_escape_text(ppOriginWord[j],-1);
335
		m_str = g_markup_escape_text(ppOriginWord[j],-1);
328
		mark += m_str;
336
		mark += m_str;
329
		g_free(m_str);
337
		g_free(m_str);
330
		mark += " -----#</span>";
338
		mark += " -----#</span>";
331
		
339
		
332
		for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++)
340
    for (int i=0; i<gpAppFrame->oAppCore.oLibs.total_libs(); i++) {
333
		{
334
			if (pppWord[j][i]) {
341
			if (pppWord[j][i]) {
335
				mark += "\n<span foreground=\"blue\">*--- ";
342
				mark += "\n<span foreground=\"blue\">*--- ";
336
				m_str = g_markup_escape_text(gpAppFrame->oAppCore.oLibs.GetBookname(i),-1);
343
				m_str = g_markup_escape_text(gpAppFrame->oAppCore.oLibs.GetBookname(i),-1);
Lines 347-375 Link Here
347
				}
354
				}
348
			}
355
			}
349
			if (pppWordData[j][i]) {			
356
			if (pppWordData[j][i]) {			
350
				memcpy(&data_size,pppWordData[j][i],sizeof(glong));
357
	p=pppWordData[j][i];
351
				p=pppWordData[j][i]+sizeof(glong);
358
	data_size=*reinterpret_cast<guint32 *>(p);
352
				
359
	p+=sizeof(guint32);
353
				while (p - (pppWordData[j][i] + sizeof(glong))< data_size)
360
	while (guint32(p - (pppWordData[j][i] + sizeof(guint32)))< data_size) {
354
				{
361
	  switch (*p++) {
355
					switch (*p)
356
					{
357
						case 'm':
362
						case 'm':
358
						case 'o': //need more work...
363
	  case 'l': //need more work...
359
							sec_size = strlen(p+sizeof(gchar));
364
	    sec_size = strlen(p);
360
							if (sec_size) {
365
							if (sec_size) {
361
								mark+= "\n";
366
								mark+= "\n";
362
								m_str = g_markup_escape_text(p+sizeof(gchar),sec_size);
367
	      m_str = g_markup_escape_text(p,sec_size);
363
								mark += m_str;
368
								mark += m_str;
364
								g_free(m_str);
369
								g_free(m_str);
365
							}
370
							}
366
							sec_size++;
371
							sec_size++;
367
							break;
372
							break;
373
	  case 'g':
374
	    sec_size = strlen(p);
375
	    if (sec_size) {
376
	      mark += "\n";
377
	      mark += p;
378
	    }
379
	    sec_size++;
380
	    break;
368
						case 't':
381
						case 't':
369
							sec_size = strlen(p+sizeof(gchar));
382
	    sec_size = strlen(p);
370
							if (sec_size) {
383
							if (sec_size) {
371
								mark += "\n<big>[";
384
								mark += "\n<big>[";
372
								m_str = g_markup_escape_text(p+sizeof(gchar),sec_size);
385
	      m_str = g_markup_escape_text(p, sec_size);
373
								mark += m_str;
386
								mark += m_str;
374
								g_free(m_str);
387
								g_free(m_str);
375
								mark+= "]</big>";
388
								mark+= "]</big>";
Lines 377-386 Link Here
377
							sec_size++;
390
							sec_size++;
378
							break;
391
							break;
379
						case 'y':
392
						case 'y':
380
							sec_size = strlen(p+sizeof(gchar));
393
	    sec_size = strlen(p);
381
							if (sec_size) {
394
							if (sec_size) {
382
								mark += "\n<span foreground=\"red\">[";
395
								mark += "\n<span foreground=\"red\">[";
383
								m_str = g_markup_escape_text(p+sizeof(gchar),sec_size);
396
	      m_str = g_markup_escape_text(p, sec_size);
384
								mark += m_str;
397
								mark += m_str;
385
								g_free(m_str);
398
								g_free(m_str);
386
								mark+= "]</span>";
399
								mark+= "]</span>";
Lines 388-403 Link Here
388
							sec_size++;						
401
							sec_size++;						
389
							break;
402
							break;
390
						case 'W':
403
						case 'W':
391
							memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
404
	    sec_size=*reinterpret_cast<guint32 *>(p);
405
	    sec_size=g_ntohl(sec_size);
392
							//enbale sound button.
406
							//enbale sound button.
393
							sec_size+= sizeof(glong);
407
	    sec_size+= sizeof(guint32);
394
							break;
408
							break;
395
						case 'P':
409
						case 'P':
396
							memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
410
	    sec_size=*reinterpret_cast<guint32 *>(p);
397
							sec_size+= sizeof(glong);
411
	    sec_size=g_ntohl(sec_size);
412
	    sec_size+= sizeof(guint32);
398
							break;						
413
							break;						
414
	  default:
415
	    /*nothing*/;
399
					}								
416
					}								
400
					p = p+sizeof(gchar)+sec_size;
417
	  p += sec_size;
401
				}				
418
				}				
402
			}		
419
			}		
403
		}		
420
		}		
(-)stardict-cur-accepted/src/lib.cpp (-387 / +522 lines)
Lines 2-33 Link Here
2
#  include "config.h"
2
#  include "config.h"
3
#endif
3
#endif
4
4
5
#include <cstring>
6
#include <cctype>
5
7
6
#include "lib.h"
7
#include "stardict.h"
8
#include <sys/stat.h>
8
#include <sys/stat.h>
9
#include "string.h"
9
#include <zlib.h>
10
#include "zlib.h"
11
#ifdef HAVE_MMAP
10
#ifdef HAVE_MMAP
12
#include <sys/types.h>
11
#  include <sys/types.h>
13
#include <fcntl.h>
12
#  include <fcntl.h>
14
#include <sys/mman.h>
13
#  include <sys/mman.h>
15
#endif
14
#endif
15
#include <algorithm>
16
16
17
// Notice: read src/tools/DICTFILE_FORMAT for the dictionary file's format information!
17
#include "distance.h"
18
18
19
cacheItem::cacheItem()
19
#include "lib.h"
20
21
// Notice: read src/tools/DICTFILE_FORMAT for the dictionary 
22
// file's format information!
23
24
class MapFile {
25
public:
26
  MapFile(void) : data(NULL) {}
27
  ~MapFile();
28
  bool open(const gchar *file_name, gulong file_size);
29
  inline gchar *begin(void) { return data; }
30
private:
31
  gchar *data;
32
  gulong size;
33
#ifdef HAVE_MMAP
34
  int mmap_fd;
35
#elif defined(_WIN32)
36
  HANDLE hFile;
37
  HANDLE hFileMap;
38
#endif
39
};
40
41
inline bool MapFile::open(const gchar *file_name, gulong file_size)
20
{
42
{
21
	data= NULL;
43
  size=file_size;
44
#ifdef HAVE_MMAP
45
  if ((mmap_fd = ::open(file_name, O_RDONLY)) < 0) {
46
    //g_print("Open file %s failed!\n",fullfilename);
47
    return false;
48
  }
49
  data = (gchar *)mmap( NULL, file_size, PROT_READ, MAP_SHARED, mmap_fd, 0);
50
  if ((void *)data == (void *)(-1)) {
51
    //g_print("mmap file %s failed!\n",idxfilename);
52
    data=NULL;
53
    return false;
54
  }
55
#else
56
#  ifdef _WIN32
57
  hFile = CreateFile(file_name, GENERIC_READ, 0, NULL, OPEN_ALWAYS, 
58
		     FILE_ATTRIBUTE_NORMAL, 0);
59
  hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0,  
60
			       file_size, NULL);
61
  data = (gchar *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, file_size);
62
#  else
63
  gsize read_len;
64
  if (!g_file_get_contents(file_name, &data, &read_len, NULL))
65
    return false;
66
67
  if (read_len!=file_size)
68
    return false;		
69
#  endif
70
#endif
71
72
  return true;
22
}
73
}
23
74
24
cacheItem::~cacheItem()
75
inline MapFile::~MapFile()
25
{
76
{
26
	if (data)
77
  if (!data)
78
    return;
79
#ifdef HAVE_MMAP
80
  munmap(data, size);
81
  close(mmap_fd);
82
#else
83
#  ifdef _WIN32
84
  UnmapViewOfFile(data);
85
  CloseHandle(hFileMap);
86
  CloseHandle(hFile);
87
#  else
27
		g_free(data);
88
		g_free(data);
89
#  endif
90
#endif			
91
}
92
93
inline bool bIsVowel(gchar inputchar)
94
{
95
  gchar ch = g_ascii_toupper(inputchar);
96
  return( ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' );
97
}
98
99
bool bIsPureEnglish(const gchar *str) 
100
{ 
101
  // i think this should work even when it is UTF8 string :).
102
  for (int i=0; str[i]!=0; i++) 
103
    //if(str[i]<0)
104
    //if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK.
105
    // Better use isascii() but not str[i]<0 while char is default unsigned in arm
106
    if (!isascii(str[i])) 
107
            return false;            
108
  return true;	
109
}
110
111
inline gint stardict_strcmp(const gchar *s1, const gchar *s2) {
112
  gint a=g_ascii_strcasecmp(s1, s2);
113
  if (a == 0)
114
    return strcmp(s1, s2);
115
  else
116
    return a;
28
}
117
}
29
118
119
bool DictInfo::load_from_ifo_file(const gchar *ifofilename,
120
				  bool istreedict)
121
{
122
  ifo_file_name=ifofilename;
123
  gchar *buffer;
124
  if (!g_file_get_contents(ifofilename, &buffer, NULL, NULL))
125
    return false;
126
  
127
#define TREEDICT_MAGIC_DATA "StarDict's treedict ifo file\nversion=2.4.2\n"
128
#define DICT_MAGIC_DATA "StarDict's dict ifo file\nversion=2.4.2\n"
129
  const gchar *magic_data=istreedict ? TREEDICT_MAGIC_DATA : DICT_MAGIC_DATA;
130
  if (!g_str_has_prefix(buffer, magic_data)) {
131
    g_free(buffer);
132
    return false;
133
  }
134
135
  gchar *p1,*p2,*p3;
136
  
137
  p1 = buffer + strlen(magic_data)-1;
138
139
  p2 = strstr(p1,"\nwordcount=");
140
  if (!p2) {
141
    g_free(buffer);
142
    return false;
143
  }
144
  
145
  p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n');
146
  gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1);
147
  tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0';
148
  wordcount = atol(tmpstr);
149
  g_free(tmpstr);
150
151
  if (istreedict) {
152
    p2 = strstr(p1,"\ntdxfilesize=");
153
    if (!p2) {
154
      g_free(buffer);
155
      return false;
156
    }
157
    p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n');
158
    tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1);
159
    tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0';
160
    index_file_size = atol(tmpstr);
161
    g_free(tmpstr);
162
  } else {
163
  
164
    p2 = strstr(p1,"\nidxfilesize=");
165
    if (!p2) {
166
      g_free(buffer);
167
      return false;
168
    }
169
    
170
    p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n');
171
    tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1);
172
    tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0';
173
    index_file_size = atol(tmpstr);
174
    g_free(tmpstr);
175
  }
176
	
177
  p2 = strstr(p1,"\nbookname=");
178
179
  if (!p2) {
180
    g_free(buffer);
181
    return false;
182
  }
30
183
184
  p2 = p2 + sizeof("\nbookname=") -1;
185
  p3 = strchr(p2, '\n');
186
  bookname.assign(p2, p3-p2);
187
188
  p2 = strstr(p1,"\nauthor=");
189
  if (p2) {
190
    p2 = p2 + sizeof("\nauthor=") -1;
191
    p3 = strchr(p2, '\n');
192
    author.assign(p2, p3-p2);
193
  }
194
195
  p2 = strstr(p1,"\nemail=");
196
  if (p2) {
197
    p2 = p2 + sizeof("\nemail=") -1;
198
    p3 = strchr(p2, '\n');
199
    email.assign(p2, p3-p2);
200
  }
201
202
  p2 = strstr(p1,"\nwebsite=");
203
  if (p2) {
204
    p2 = p2 + sizeof("\nwebsite=") -1;
205
    p3 = strchr(p2, '\n');
206
    website.assign(p2, p3-p2);
207
  }
208
209
  p2 = strstr(p1,"\ndate=");
210
  if (p2) {
211
    p2 = p2 + sizeof("\ndate=") -1;
212
    p3 = strchr(p2, '\n');
213
    date.assign(p2, p3-p2);
214
  }
215
216
  p2 = strstr(p1,"\ndescription=");
217
  if (p2) {
218
    p2 = p2 + sizeof("\ndescription=")-1;
219
    p3 = strchr(p2, '\n');
220
    description.assign(p2, p3-p2);
221
  }
222
223
  p2 = strstr(p1,"\nsametypesequence=");
224
  if (p2) {		
225
    p2+=sizeof("\nsametypesequence=")-1;
226
    p3 = strchr(p2, '\n');
227
    sametypesequence.assign(p2, p3-p2);
228
  }
229
230
  g_free(buffer);
231
232
  return true;		
233
}
31
//===================================================================
234
//===================================================================
32
DictBase::DictBase()
235
DictBase::DictBase()
33
{
236
{
Lines 46-160 Link Here
46
		dict_data_close(dictdzfile);
249
		dict_data_close(dictdzfile);
47
}
250
}
48
251
49
gchar* DictBase::GetWordData(glong idxitem_offset, glong idxitem_size)
252
gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
50
{
253
{
51
	for (int i=0;i<WORDDATA_CACHE_NUM;i++)
254
  for (int i=0; i<WORDDATA_CACHE_NUM; i++)	
52
	{
255
    if (cache[i].data && cache[i].offset == idxitem_offset)
53
		if ((cache[i].data) && (cache[i].offset == idxitem_offset))
54
		{
55
			return cache[i].data;
256
			return cache[i].data;
56
		}
257
			
57
	}
258
  if (dictfile)
58
	if (dictfile) {
59
		fseek(dictfile, idxitem_offset, SEEK_SET);
259
		fseek(dictfile, idxitem_offset, SEEK_SET);
60
	}
260
	
61
	gchar *data;
261
	gchar *data;
62
	if (sametypesequence) {
262
	if (sametypesequence) {
63
		gchar *origin_data;
263
    gchar *origin_data = (gchar *)g_malloc(idxitem_size);
64
		origin_data = (gchar *)g_malloc(idxitem_size);
65
		
264
		
66
		if (dictfile)
265
		if (dictfile)
67
			fread(origin_data,idxitem_size,1,dictfile);
266
      fread(origin_data, idxitem_size, 1, dictfile);
68
		else
267
		else
69
			dict_data_read (dictdzfile, origin_data, idxitem_offset, idxitem_size);
268
      dict_data_read(dictdzfile, origin_data, idxitem_offset, idxitem_size);
70
	
269
	
71
		glong data_size;
270
    guint32 data_size;
72
		gint sametypesequence_len;
271
		gint sametypesequence_len;
73
		sametypesequence_len = strlen(sametypesequence);
272
		sametypesequence_len = strlen(sametypesequence);
74
		//there have sametypesequence_len char being omitted.
273
		//there have sametypesequence_len char being omitted.
75
		data_size = idxitem_size + sizeof(glong) + sametypesequence_len;
274
    data_size = idxitem_size + sizeof(guint32) + sametypesequence_len;
76
		//if the last item's size is determined by the end up '\0',then +=sizeof(gchar);
275
		//if the last item's size is determined by the end up '\0',then +=sizeof(gchar);
77
		//if the last item's size is determined by the head glong type data,then +=sizeof(glong);
276
    //if the last item's size is determined by the head guint32 type data,then +=sizeof(guint32);
78
		switch (sametypesequence[sametypesequence_len-1]) {
277
		switch (sametypesequence[sametypesequence_len-1]) {
79
			case 'm':
278
			case 'm':
80
			case 't':
279
			case 't':
81
			case 'y':
280
			case 'y':
82
			case 'o':
281
    case 'l':
282
    case 'g':
83
				data_size += sizeof(gchar);
283
				data_size += sizeof(gchar);
84
				break;
284
				break;
85
			case 'W':
285
			case 'W':
86
			case 'P':
286
			case 'P':
87
				data_size += sizeof(glong);				
287
      data_size += sizeof(guint32);
88
				break;
288
				break;
89
		}			
289
		}			
90
		data = (gchar *)g_malloc(data_size);
290
		data = (gchar *)g_malloc(data_size);
91
		gchar *p1,*p2;
291
		gchar *p1,*p2;
92
		p1 = data + sizeof(glong);
292
    p1 = data + sizeof(guint32);
93
		p2 = origin_data;
293
		p2 = origin_data;
94
		glong sec_size;
294
    guint32 sec_size;
95
		//copy the head items.
295
		//copy the head items.
96
		for (int i=0;i< sametypesequence_len-1;i++) {
296
    for (int i=0; i<sametypesequence_len-1; i++) {
97
			memcpy(p1, &(sametypesequence[i]), sizeof(gchar));
297
      *p1=sametypesequence[i];
98
			p1+= sizeof(gchar);
298
      p1+=sizeof(gchar);
99
			switch (sametypesequence[i]) {
299
			switch (sametypesequence[i]) {
100
				case 'm':
300
				case 'm':
101
				case 't':
301
				case 't':
102
				case 'y':
302
				case 'y':
103
				case 'o':
303
      case 'l':
304
      case 'g':
104
					sec_size = strlen(p2)+1;
305
					sec_size = strlen(p2)+1;
105
					memcpy(p1, p2, sec_size);
306
					memcpy(p1, p2, sec_size);
106
					p1+= sec_size;
307
	p1+=sec_size;
107
					p2+= sec_size;
308
	p2+=sec_size;
108
					break;
309
					break;
109
				case 'W':
310
				case 'W':
110
				case 'P':
311
				case 'P':
111
					memcpy(&sec_size, p2, sizeof(glong));
312
	sec_size = *reinterpret_cast<guint32 *>(p2);
112
					sec_size += sizeof(glong);
313
	sec_size += sizeof(guint32);
113
					memcpy(p1, p2, sec_size);
314
					memcpy(p1, p2, sec_size);
114
					p1+= sec_size;
315
	p1+=sec_size;
115
					p2+= sec_size;
316
	p2+=sec_size;
116
					break;
317
					break;
117
			}							
318
			}							
118
		}	
319
		}	
119
		//calculate the last item 's size.
320
		//calculate the last item 's size.
120
		sec_size = idxitem_size - (p2-origin_data);
321
		sec_size = idxitem_size - (p2-origin_data);
121
		memcpy(p1, &(sametypesequence[sametypesequence_len-1]), sizeof(gchar));
322
    *p1=sametypesequence[sametypesequence_len-1];
122
		p1+= sizeof(gchar);
323
    p1+=sizeof(gchar);
123
		switch (sametypesequence[sametypesequence_len-1]) {
324
		switch (sametypesequence[sametypesequence_len-1]) {
124
			case 'm':
325
			case 'm':
125
			case 't':
326
			case 't':
126
			case 'y':
327
			case 'y':
127
			case 'o':
328
    case 'l':
329
    case 'g':
128
				memcpy(p1, p2, sec_size);
330
				memcpy(p1, p2, sec_size);
129
				p1 += sec_size;				
331
				p1 += sec_size;				
130
				memcpy(p1, "", sizeof(gchar)); //add the end up '\0';
332
      *p1='\0';//add the end up '\0';
131
				break;
333
				break;
132
			case 'W':
334
			case 'W':
133
			case 'P':
335
			case 'P':
134
				memcpy(p1,&(sec_size), sizeof(glong)); //add the head glong size data.
336
      *reinterpret_cast<guint32 *>(p1)=sec_size;
135
				p1 += sizeof(glong);
337
      p1 += sizeof(guint32);
136
				memcpy(p1, p2, sec_size);
338
				memcpy(p1, p2, sec_size);
137
				break;
339
				break;
138
		}		
340
		}		
139
		g_free(origin_data);		
341
		g_free(origin_data);		
140
	}
342
    *reinterpret_cast<guint32 *>(data)=data_size;
141
	else {		
343
  } else {		
142
		data = (gchar *)g_malloc(idxitem_size + sizeof(glong));
344
    data = (gchar *)g_malloc(idxitem_size + sizeof(guint32));
143
		if (dictfile)
345
		if (dictfile)
144
			fread(data+sizeof(glong),idxitem_size,1,dictfile);		
346
      fread(data+sizeof(guint32), idxitem_size, 1, dictfile);		
145
		else
347
		else
146
			dict_data_read (dictdzfile, data+sizeof(glong), idxitem_offset, idxitem_size);
348
      dict_data_read(dictdzfile, data+sizeof(guint32), idxitem_offset, idxitem_size);
349
    *reinterpret_cast<guint32 *>(data)=idxitem_size;
147
	}	
350
	}	
148
	memcpy(data,&(idxitem_size),sizeof(glong));
149
	if (cache[cache_cur].data)
150
	{
151
		g_free(cache[cache_cur].data);
351
		g_free(cache[cache_cur].data);
152
	}
352
153
	cache[cache_cur].data = data;
353
	cache[cache_cur].data = data;
154
	cache[cache_cur].offset = idxitem_offset;
354
	cache[cache_cur].offset = idxitem_offset;
155
	cache_cur++;
355
	cache_cur++;
156
	if (cache_cur==WORDDATA_CACHE_NUM)
356
	if (cache_cur==WORDDATA_CACHE_NUM)
157
		cache_cur =0;
357
    cache_cur = 0;
158
    return data;
358
    return data;
159
}
359
}
160
360
Lines 166-243 Link Here
166
	bookname = NULL;
366
	bookname = NULL;
167
	idxfile = NULL;
367
	idxfile = NULL;
168
	wordlist = NULL;
368
	wordlist = NULL;
169
#ifdef HAVE_MMAP
170
	mmap_fd = -1;
171
	mmap_idxmap_size = 0;
172
#endif
173
	idxdatabuffer = NULL;
369
	idxdatabuffer = NULL;
174
}
370
}
175
371
176
Lib::~Lib()
372
Lib::~Lib()
177
{
373
{
178
	if (bookname)
179
		g_free(bookname);
374
		g_free(bookname);
180
	if (idxfile) {
375
	if (idxfile) {
181
		fclose(idxfile);
376
		fclose(idxfile);
182
		if (wordoffset)
183
			g_free(wordoffset);
377
			g_free(wordoffset);
184
	}
378
  } else {    
185
	else {
186
		if (wordlist)
187
			g_free(wordlist);
379
			g_free(wordlist);
188
189
#ifdef HAVE_MMAP
190
		if (mmap_fd >= 0) {
191
			if (mmap_idxmap_size)
192
				munmap(idxdatabuffer, mmap_idxmap_size);
193
			close(mmap_fd);
194
		}
195
		else {
196
			if (idxdatabuffer)
197
				g_free(idxdatabuffer);
198
		}
199
#else
200
		if (idxdatabuffer)
201
			g_free(idxdatabuffer);
202
#endif
203
	}
380
	}
204
}
381
}
205
382
206
gboolean Lib::load(const char *ifofilename)
383
bool Lib::load(const char *ifofilename)
207
{	
384
{	
208
	gulong idxfilesize;
385
	gulong idxfilesize;
209
	if (!load_ifofile(ifofilename, &idxfilesize))
386
	if (!load_ifofile(ifofilename, &idxfilesize))
210
		return false;
387
		return false;
211
388
212
	gchar fullfilename[256];
389
  std::string fullfilename(ifofilename);
213
	
390
  fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz");
214
	strcpy(fullfilename, ifofilename);
215
	strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "dict.dz");	
216
	
391
	
217
	if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) {
392
  if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {
218
		dictdzfile = dict_data_open(fullfilename, 0);
393
    dictdzfile = dict_data_open(fullfilename.c_str(), 0);
219
		if (!dictdzfile)
394
    if (!dictdzfile) {
220
		{
221
			//g_print("open file %s failed!\n",fullfilename);
395
			//g_print("open file %s failed!\n",fullfilename);
222
			return false;
396
			return false;
223
		}
397
		}
224
	}
398
  } else {
225
	else {
399
    fullfilename.erase(fullfilename.length()-sizeof(".dz")+1, sizeof(".dz")-1);
226
		fullfilename[strlen(fullfilename)-3] = '\0';
400
    dictfile = fopen(fullfilename.c_str(),"rb");
227
		dictfile = fopen(fullfilename,"rb");
401
    if (!dictfile) {
228
		if (!dictfile)
229
		{
230
			//g_print("open file %s failed!\n",fullfilename);
402
			//g_print("open file %s failed!\n",fullfilename);
231
			return false;
403
			return false;
232
		}
404
		}
233
	}
405
	}
234
406
235
	strcpy(fullfilename, ifofilename);
407
  fullfilename=ifofilename;
236
	strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "idx.gz");	
408
  fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "idx.gz");
237
	
409
	
238
	if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) {
410
  if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {
239
		gzFile in;	
411
		gzFile in;	
240
		in = gzopen(fullfilename,"rb");
412
    in = gzopen(fullfilename.c_str(),"rb");
241
		if (in == NULL) {
413
		if (in == NULL) {
242
			//g_print("Open file %s failed!\n",fullfilename);
414
			//g_print("Open file %s failed!\n",fullfilename);
243
			return false;
415
			return false;
Lines 252-311 Link Here
252
		gzclose(in);
424
		gzclose(in);
253
		if (len != idxfilesize)
425
		if (len != idxfilesize)
254
			return false;
426
			return false;
255
	}
427
  } else {
256
	else {
428
    fullfilename.erase(fullfilename.length()-sizeof(".gz")+1, sizeof(".gz")-1);
257
		fullfilename[strlen(fullfilename)-3] = '\0';
429
    MapFile map_file;
258
430
    if (!map_file.open(fullfilename.c_str(), idxfilesize))
259
#ifdef HAVE_MMAP
260
		if ((mmap_fd = open(fullfilename, O_RDONLY )) < 0) {
261
			//g_print("Open file %s failed!\n",fullfilename);
262
			return false;
263
		}
264
		idxdatabuffer = (gchar *)mmap( NULL, idxfilesize, PROT_READ, MAP_SHARED, mmap_fd, 0);		
265
		if ((void *)idxdatabuffer == (void *)(-1)) {
266
			//g_print("mmap file %s failed!\n",idxfilename);
267
			return false;
268
		}
269
		mmap_idxmap_size = idxfilesize;
270
#else
271
  #ifdef _WIN32
272
		HANDLE hFile = CreateFile(fullfilename, GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
273
		HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0,  idxfilesize, NULL);
274
		idxdatabuffer = (gchar *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, idxfilesize);
275
  #else
276
		FILE *file;
277
		if (!(file = fopen (fullfilename, "rb"))) {
278
			//g_print("Open file %s failed!\n",fullfilename);
279
			return false;
280
		}
281
		idxdatabuffer = (gchar *)g_malloc(idxfilesize);
282
		gint read_len;
283
		read_len = fread (idxdatabuffer, 1, idxfilesize, file);
284
		fclose (file);
285
		if (read_len!=idxfilesize)
286
			return false;		
431
			return false;		
287
  #endif
432
    idxdatabuffer=map_file.begin();
288
#endif
433
    
289
		if (true) {
290
			loadwordoffset();
434
			loadwordoffset();
291
#ifdef HAVE_MMAP
435
    idxdatabuffer=NULL;
292
			munmap(idxdatabuffer, mmap_idxmap_size);
436
    if (!(idxfile = fopen(fullfilename.c_str(), "rb"))) {
293
			idxdatabuffer = NULL;
294
			mmap_idxmap_size = 0;
295
			close(mmap_fd);
296
			mmap_fd = -1;
297
#else
298
  #ifdef _WIN32
299
			UnmapViewOfFile(idxdatabuffer);
300
			idxdatabuffer = NULL;
301
			CloseHandle(hFileMap);
302
			CloseHandle(hFile);
303
  #else
304
			g_free(idxdatabuffer);
305
			idxdatabuffer = NULL;
306
  #endif
307
#endif			
308
			if (!(idxfile = fopen (fullfilename, "rb"))) {
309
				if (wordoffset) {
437
				if (wordoffset) {
310
					g_free(wordoffset);
438
					g_free(wordoffset);
311
					wordoffset = NULL;
439
					wordoffset = NULL;
Lines 316-397 Link Here
316
			g_print("bookname: %s , wordcount %ld\n",bookname, wordcount);
444
			g_print("bookname: %s , wordcount %ld\n",bookname, wordcount);
317
			return true;
445
			return true;
318
		}
446
		}
319
		else {
320
			// The .idx file will load into memory. Who need this opinion?
321
		}
322
	}
323
447
324
	loadwordlist();
448
	loadwordlist();
325
	g_print("bookname: %s , wordcount %ld\n",bookname, wordcount);
449
	g_print("bookname: %s , wordcount %ld\n",bookname, wordcount);
326
	return true;
450
	return true;
327
}
451
}
328
452
329
gboolean Lib::load_ifofile(const char *ifofilename, gulong *idxfilesize)
453
bool Lib::load_ifofile(const char *ifofilename, gulong *idxfilesize)
330
{
454
{
331
	struct stat stats;		
455
  DictInfo dict_info;
332
	if (stat (ifofilename, &stats) == -1) {
456
  if (!dict_info.load_from_ifo_file(ifofilename, false))
333
		//g_print("File: %s don't exist!\n",idxfilename);
334
		return false;
335
	}
336
		
337
	FILE *file;
338
	if (!(file = fopen (ifofilename, "rb"))) {
339
		//g_print("Open file %s failed!\n",idxfilename);
340
		return false;
341
	}
342
	gchar *buffer = (gchar *)g_malloc (stats.st_size + 1);
343
	fread (buffer, 1, stats.st_size, file);
344
	buffer[stats.st_size] = '\0';
345
	fclose (file);
346
	
347
	if (!g_str_has_prefix(buffer, "StarDict's dict ifo file\nversion=2.4.2\n")) {
348
		g_print("Bad dict ifo file %s, skiped!\n", ifofilename);
349
		g_free(buffer);
350
		return false;
457
		return false;
351
	}
352
	gchar *p1= buffer + sizeof("StarDict's dict ifo file\nversion=2.4.2\n")-1 -1;
353
	
458
	
354
	gchar *p2,*p3;
459
  *idxfilesize = dict_info.index_file_size;	
355
460
  wordcount = dict_info.wordcount;
356
	p2 = strstr(p1,"\nidxfilesize=");
461
  bookname = g_strdup(dict_info.bookname.c_str());
357
	if (!p2) {
358
		g_free(buffer);
359
		return false;
360
	}
361
	p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n');
362
	gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1);
363
	tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0';
364
	*idxfilesize = atol(tmpstr);
365
	g_free(tmpstr);
366
367
	p2 = strstr(p1,"\nwordcount=");
368
	if (!p2) {
369
		g_free(buffer);
370
		return false;
371
	}
372
	p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n');
373
	tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1);
374
	tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0';
375
	wordcount = atol(tmpstr);
376
	g_free(tmpstr);
377
378
	p2 = strstr(p1,"\nbookname=");
379
	if (!p2) {
380
		g_free(buffer);
381
		return false;
382
	}
383
	p3 = strchr(p2+ sizeof("\nbookname=")-1,'\n');
384
	bookname = (gchar *)g_memdup(p2+sizeof("\nbookname=")-1, p3-(p2+sizeof("\nbookname=")-1)+1);
385
	bookname[p3-(p2+sizeof("\nbookname=")-1)] = '\0';
386
462
387
	p2 = strstr(p1,"\nsametypesequence=");
463
  if (!dict_info.sametypesequence.empty())
388
	if (p2) {		
464
    sametypesequence=g_strdup(dict_info.sametypesequence.c_str());
389
		p3 = strchr(p2+sizeof("\nsametypesequence=")-1,'\n');
390
		sametypesequence = (gchar *)g_memdup(p2+sizeof("\nsametypesequence=")-1, p3-(p2+sizeof("\nsametypesequence=")-1)+1);
391
		sametypesequence[p3-(p2+sizeof("\nsametypesequence=")-1)] = '\0';
392
	}
393
465
394
	g_free(buffer);
395
	return true;
466
	return true;
396
}
467
}
397
468
Lines 438-478 Link Here
438
	wordoffset[wordcount] = p1;
509
	wordoffset[wordcount] = p1;
439
}*/
510
}*/
440
511
441
gboolean Lib::Lookup(const char* sWord,glong *pIndex)
512
bool Lib::Lookup(const char* sWord,glong *pIndex)
442
{
513
{
443
    gboolean bFound=false;		
514
  bool bFound=false;
444
    glong iTo=length()-1;
515
    glong iTo=length()-1;
445
	if (stardict_strcmp(sWord, GetWord(0))<0) {
516
	if (stardict_strcmp(sWord, GetWord(0))<0) {
446
		*pIndex = 0;
517
		*pIndex = 0;
447
	}
518
  } else if (stardict_strcmp(sWord, GetWord(iTo)) >0) {
448
	else if (stardict_strcmp(sWord, GetWord(iTo)) >0 ) {
449
		*pIndex = INVALID_INDEX;
519
		*pIndex = INVALID_INDEX;
450
	}
520
  } else {
451
	else {
452
	    glong iThisIndex=0;
521
	    glong iThisIndex=0;
453
    	glong iFrom=0;
522
    	glong iFrom=0;
454
523
455
		int cmpint;
524
		int cmpint;
456
    	while( !bFound && iFrom<=iTo )
525
    while (iFrom<=iTo) {
457
    	{
458
        	iThisIndex=(iFrom+iTo)/2;
526
        	iThisIndex=(iFrom+iTo)/2;
459
			cmpint = stardict_strcmp(sWord, GetWord(iThisIndex));
527
			cmpint = stardict_strcmp(sWord, GetWord(iThisIndex));
460
			//g_print("lookup %s %d\n",GetWord(iThisIndex),cmpint);
528
			//g_print("lookup %s %d\n",GetWord(iThisIndex),cmpint);
461
			if (cmpint == 0)
529
      if (cmpint>0)
462
			{
463
				bFound=true;
464
			}
465
			else if (cmpint > 0)
466
			{
467
				iFrom=iThisIndex+1;
530
				iFrom=iThisIndex+1;
468
			}
531
      else if (cmpint<0)
469
			else
470
			{
471
				iTo=iThisIndex-1;
532
				iTo=iThisIndex-1;
533
      else {	
534
	bFound=true;
535
	break;
472
			}
536
			}
473
    	}
537
    	}
474
	    if (!bFound)
538
475
	    {
539
    if (!bFound) {
476
			/*glong len = g_utf8_strlen(sWord, -1);
540
			/*glong len = g_utf8_strlen(sWord, -1);
477
			gchar *last_str = g_utf8_offset_to_pointer(sWord, len-1);
541
			gchar *last_str = g_utf8_offset_to_pointer(sWord, len-1);
478
			gunichar last = g_utf8_get_char(last_str);
542
			gunichar last = g_utf8_get_char(last_str);
Lines 483-533 Link Here
483
            	*pIndex = iFrom;    //next
547
            	*pIndex = iFrom;    //next
484
			*/
548
			*/
485
			*pIndex = iFrom;    //next
549
			*pIndex = iFrom;    //next
486
    	}
550
    } else
487
		else
488
			*pIndex = iThisIndex;		
551
			*pIndex = iThisIndex;		
489
	}		
552
	}		
490
    return(bFound);
553
554
  return bFound;
491
}
555
}
492
556
493
gboolean Lib::LookupWithRule(GPatternSpec *pspec,glong *aIndex,int iBuffLen)
557
bool Lib::LookupWithRule(GPatternSpec *pspec, glong *aIndex, int iBuffLen)
494
{
558
{
495
    int iIndexCount=0;
559
    int iIndexCount=0;
496
    glong i;
560
    glong i;
497
    for(i=0;i<length() && iIndexCount<iBuffLen-1;i++)
561
  for(i=0; i<wordcount && iIndexCount<iBuffLen-1; i++)
498
    {
562
    if (g_pattern_match_string(pspec, GetWord(i)))        
499
        if(g_pattern_match_string(pspec, GetWord(i)))
500
        {
501
            aIndex[iIndexCount++]=i;
563
            aIndex[iIndexCount++]=i;
502
        }
564
            
503
    }
504
    aIndex[iIndexCount]= -1; // -1 is the end.	
565
    aIndex[iIndexCount]= -1; // -1 is the end.	
505
	
566
	
506
    return(iIndexCount>0);
567
  return (iIndexCount>0);
507
}
568
}
508
569
509
gchar *
570
gchar *
510
Lib::GetWord(glong index)
571
Lib::GetWord(glong index)
511
{
572
{
512
	if (idxfile) {
573
	if (idxfile) {
513
		if (index == cur_wordindex +1) {
574
    if (index != cur_wordindex+1)
514
			//needn't fseek().
515
		}
516
		// (index == cur_wordindex) seldom happen, so don't determine this here.
517
		else {
518
			fseek(idxfile, wordoffset[index], SEEK_SET);
575
			fseek(idxfile, wordoffset[index], SEEK_SET);
519
		}
576
		
520
		cur_wordindex = index;
577
		cur_wordindex = index;
521
		
578
		
522
		fread(wordentry_buf, wordoffset[index+1] - wordoffset[index] - 2*sizeof(glong), 1, idxfile);
579
    fread(wordentry_buf, wordoffset[index+1] - wordoffset[index] - 2*sizeof(guint32), 1, idxfile);
523
		//g_print("%s\n", wordentry_buf);
580
		//g_print("%s\n", wordentry_buf);
524
		fread(&wordentry_offset, sizeof(glong), 1, idxfile);
581
    fread(&wordentry_offset, sizeof(guint32), 1, idxfile);
525
		wordentry_offset = g_ntohl(wordentry_offset);
582
		wordentry_offset = g_ntohl(wordentry_offset);
526
		fread(&wordentry_size, sizeof(glong), 1, idxfile);
583
    fread(&wordentry_size, sizeof(guint32), 1, idxfile);
527
		wordentry_size = g_ntohl(wordentry_size);
584
		wordentry_size = g_ntohl(wordentry_size);
528
		return wordentry_buf;
585
		return wordentry_buf;
529
	}
586
  } else {
530
	else {
531
		return wordlist[index];
587
		return wordlist[index];
532
	}
588
	}
533
}
589
}
Lines 536-561 Link Here
536
Lib::GetWordData(glong index)
592
Lib::GetWordData(glong index)
537
{
593
{
538
	if (idxfile) {
594
	if (idxfile) {
539
		if (index == cur_wordindex) {
595
    if (index != cur_wordindex) {
540
			// wordentry_offset and wordentry_size are already cached by GetWord();
541
		}
542
		else {
543
			cur_wordindex = index;
596
			cur_wordindex = index;
544
			fseek(idxfile, wordoffset[index+1] - 2*sizeof(glong), SEEK_SET);
597
      fseek(idxfile, wordoffset[index+1] - 2*sizeof(guint32), SEEK_SET);
545
			fread(&wordentry_offset, sizeof(glong), 1, idxfile);
598
      fread(&wordentry_offset, sizeof(guint32), 1, idxfile);
546
			wordentry_offset = g_ntohl(wordentry_offset);
599
			wordentry_offset = g_ntohl(wordentry_offset);
547
			fread(&wordentry_size, sizeof(glong), 1, idxfile);
600
      fread(&wordentry_size, sizeof(guint32), 1, idxfile);
548
			wordentry_size = g_ntohl(wordentry_size);			
601
			wordentry_size = g_ntohl(wordentry_size);			
549
		}		
602
		}		
550
		return DictBase::GetWordData(wordentry_offset, wordentry_size);
603
		return DictBase::GetWordData(wordentry_offset, wordentry_size);
551
	}
604
  } else {
552
	else {
605
    gchar *p1 = wordlist[index+1] - 2*sizeof(guint32);
553
		gchar *p1 = wordlist[index+1] - 2*sizeof(glong);
606
    guint32 offset, size;
554
		glong offset, size;
607
    offset=*reinterpret_cast<guint32 *>(p1);
555
		memcpy(&offset,p1,sizeof(glong));
556
		offset = g_ntohl(offset);
608
		offset = g_ntohl(offset);
557
		p1 = p1 + sizeof(glong);
609
    p1 += sizeof(guint32);
558
		memcpy(&size, p1, sizeof(glong));
610
    size=*reinterpret_cast<guint32 *>(p1);
559
		size = g_ntohl(size);
611
		size = g_ntohl(size);
560
		return DictBase::GetWordData(offset, size);
612
		return DictBase::GetWordData(offset, size);
561
	}
613
	}
Lines 566-571 Link Here
566
{
618
{
567
	libcount =0;
619
	libcount =0;
568
	oLib = NULL;
620
	oLib = NULL;
621
	iMaxFuzzyDistance  = MAX_FUZZY_DISTANCE; //need to read from cfg.
569
}
622
}
570
623
571
Libs::~Libs()
624
Libs::~Libs()
Lines 592-601 Link Here
592
}
645
}
593
646
594
/********************************************************************/
647
/********************************************************************/
595
gboolean Libs::LookdupWordsWithRule(GPatternSpec *pspec,glong* aiIndexes,int iLen,int iLib)
596
{
597
	return (oLib[iLib]->LookupWithRule(pspec,aiIndexes,iLen));
598
}
599
648
600
void Libs::LoadDir(const gchar *dirname, const GSList *order_list, const GSList *disable_list)
649
void Libs::LoadDir(const gchar *dirname, const GSList *order_list, const GSList *disable_list)
601
{	
650
{	
Lines 823-837 Link Here
823
    return poCurrentWord;
872
    return poCurrentWord;
824
}
873
}
825
874
826
gboolean Libs::LookupWord(const gchar* sWord,glong& iWordIndex,int iLib)
875
bool Libs::LookupWord(const gchar* sWord,glong& iWordIndex,int iLib)
827
{
876
{
828
	return (oLib[iLib]->Lookup(sWord, &iWordIndex));
877
  return oLib[iLib]->Lookup(sWord, &iWordIndex);
829
}
878
}
830
879
831
gboolean Libs::LookupSimilarWord(const gchar* sWord,glong& iWordIndex,int iLib)
880
bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
832
{
881
{
833
    glong iIndex;
882
    glong iIndex;
834
    gboolean bFound=false;
883
  bool bFound=false;
835
	gchar *casestr;
884
	gchar *casestr;
836
885
837
	if (!bFound) {
886
	if (!bFound) {
Lines 865-885 Link Here
865
		}	
914
		}	
866
	}
915
	}
867
	
916
	
868
    if (bIsPureEnglish(sWord))
917
  if (bIsPureEnglish(sWord)) {		
869
    {		
870
        // If not Found , try other status of sWord.
918
        // If not Found , try other status of sWord.
871
        int iWordLen=strlen(sWord);
919
        int iWordLen=strlen(sWord);
872
		gboolean isupcase;
920
    bool isupcase;
873
		
921
		
874
		gchar *sNewWord = (gchar *)g_malloc(iWordLen + 1);
922
		gchar *sNewWord = (gchar *)g_malloc(iWordLen + 1);
875
923
876
        //cut one char "s" or "d"
924
        //cut one char "s" or "d"
877
        if(!bFound && iWordLen>1) {
925
        if(!bFound && iWordLen>1) {
878
			isupcase = (sWord[iWordLen-1]=='S' || (!strncmp(&sWord[iWordLen-2],"ED",2)));
926
      isupcase = sWord[iWordLen-1]=='S' || !strncmp(&sWord[iWordLen-2],"ED",2);
879
			if (isupcase || sWord[iWordLen-1]=='s' || (!strncmp(&sWord[iWordLen-2],"ed",2))) {
927
      if (isupcase || sWord[iWordLen-1]=='s' || !strncmp(&sWord[iWordLen-2],"ed",2)) {
880
	            strcpy(sNewWord,sWord);
928
	            strcpy(sNewWord,sWord);
881
	            sNewWord[iWordLen-1]='\0'; // cut "s" or "d"
929
	            sNewWord[iWordLen-1]='\0'; // cut "s" or "d"
882
    	        if(oLib[iLib]->Lookup(sNewWord,&iIndex))
930
	if (oLib[iLib]->Lookup(sNewWord,&iIndex))
883
        	        bFound=true;
931
        	        bFound=true;
884
				else if (isupcase || g_ascii_isupper(sWord[0])) {
932
				else if (isupcase || g_ascii_isupper(sWord[0])) {
885
					casestr = g_ascii_strdown(sNewWord, -1);
933
					casestr = g_ascii_strdown(sNewWord, -1);
Lines 898-906 Link Here
898
			if (isupcase || (!strncmp(&sWord[iWordLen-2],"ly",2))) {
946
			if (isupcase || (!strncmp(&sWord[iWordLen-2],"ly",2))) {
899
	            strcpy(sNewWord,sWord);
947
	            strcpy(sNewWord,sWord);
900
    	        sNewWord[iWordLen-2]='\0';  // cut "ly"
948
    	        sNewWord[iWordLen-2]='\0';  // cut "ly"
901
        	    if ( iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4])
949
	if (iWordLen>5 && sNewWord[iWordLen-3]==sNewWord[iWordLen-4]
902
            	     && !bIsVowel(sNewWord[iWordLen-4]) && bIsVowel(sNewWord[iWordLen-5]) )   //doubled
950
	    && !bIsVowel(sNewWord[iWordLen-4]) && 
903
	            {
951
	    bIsVowel(sNewWord[iWordLen-5])) {//doubled
952
		      
904
    	            sNewWord[iWordLen-3]='\0';
953
    	            sNewWord[iWordLen-3]='\0';
905
        	        if( oLib[iLib]->Lookup(sNewWord,&iIndex) )
954
        	        if( oLib[iLib]->Lookup(sNewWord,&iIndex) )
906
            	        bFound=true;
955
            	        bFound=true;
Lines 939-946 Link Here
939
	            strcpy(sNewWord,sWord);
988
	            strcpy(sNewWord,sWord);
940
    	        sNewWord[iWordLen-3]='\0';
989
    	        sNewWord[iWordLen-3]='\0';
941
        	    if ( iWordLen>6 && (sNewWord[iWordLen-4]==sNewWord[iWordLen-5])
990
        	    if ( iWordLen>6 && (sNewWord[iWordLen-4]==sNewWord[iWordLen-5])
942
            	     && !bIsVowel(sNewWord[iWordLen-5]) && bIsVowel(sNewWord[iWordLen-6]) )   //doubled
991
	     && !bIsVowel(sNewWord[iWordLen-5]) && 
943
	            {
992
	     bIsVowel(sNewWord[iWordLen-6])) {  //doubled	  
944
    	            sNewWord[iWordLen-4]='\0';
993
    	            sNewWord[iWordLen-4]='\0';
945
        	        if (oLib[iLib]->Lookup(sNewWord,&iIndex))
994
        	        if (oLib[iLib]->Lookup(sNewWord,&iIndex))
946
            	        bFound=true;
995
            	        bFound=true;
Lines 992-1004 Link Here
992
        //cut two char "es"
1041
        //cut two char "es"
993
        if(!bFound && iWordLen>3) {
1042
        if(!bFound && iWordLen>3) {
994
			isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) && 
1043
			isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) && 
995
				(sWord[iWordLen-3] == 'S' || sWord[iWordLen-3] == 'X' || sWord[iWordLen-3] == 'O'
1044
		  (sWord[iWordLen-3] == 'S' || 
996
				|| (iWordLen >4 && sWord[iWordLen-3] == 'H' && (sWord[iWordLen-4] == 'C' || sWord[iWordLen-4] == 'S'))));
1045
		   sWord[iWordLen-3] == 'X' || 
1046
		   sWord[iWordLen-3] == 'O' || 
1047
		   (iWordLen >4 && sWord[iWordLen-3] == 'H' && 
1048
		    (sWord[iWordLen-4] == 'C' || 
1049
		     sWord[iWordLen-4] == 'S'))));
997
			if (isupcase || 
1050
			if (isupcase || 
998
				(!strncmp(&sWord[iWordLen-2],"es",2) && 
1051
				(!strncmp(&sWord[iWordLen-2],"es",2) && 
999
				(sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || sWord[iWordLen-3] == 'o'
1052
	   (sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || 
1000
				|| (iWordLen >4 && sWord[iWordLen-3] == 'h' && (sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's')))))
1053
	    sWord[iWordLen-3] == 'o' || 
1001
        	{
1054
	    (iWordLen >4 && sWord[iWordLen-3] == 'h' && 
1055
	     (sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) {
1002
            	strcpy(sNewWord,sWord);
1056
            	strcpy(sNewWord,sWord);
1003
	            sNewWord[iWordLen-2]='\0';
1057
	            sNewWord[iWordLen-2]='\0';
1004
    	        if(oLib[iLib]->Lookup(sNewWord,&iIndex))
1058
    	        if(oLib[iLib]->Lookup(sNewWord,&iIndex))
Lines 1015-1031 Link Here
1015
		}
1069
		}
1016
1070
1017
        //cut "ed"
1071
        //cut "ed"
1018
        if( !bFound && iWordLen>3) {
1072
    if (!bFound && iWordLen>3) {
1019
			isupcase = !strncmp(&sWord[iWordLen-2],"ED",2);
1073
			isupcase = !strncmp(&sWord[iWordLen-2],"ED",2);
1020
			if (isupcase || !strncmp(&sWord[iWordLen-2],"ed",2) )
1074
      if (isupcase || !strncmp(&sWord[iWordLen-2],"ed",2)) {
1021
        	{
1022
	            strcpy(sNewWord,sWord);
1075
	            strcpy(sNewWord,sWord);
1023
    	        sNewWord[iWordLen-2]='\0';
1076
    	        sNewWord[iWordLen-2]='\0';
1024
        	    if ( iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4])
1077
	if (iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4])
1025
            	     && !bIsVowel(sNewWord[iWordLen-4]) && bIsVowel(sNewWord[iWordLen-5]) )   //doubled
1078
	    && !bIsVowel(sNewWord[iWordLen-4]) && 
1026
	            {
1079
	    bIsVowel(sNewWord[iWordLen-5])) {//doubled	            
1027
    	            sNewWord[iWordLen-3]='\0';
1080
    	            sNewWord[iWordLen-3]='\0';
1028
        	        if( oLib[iLib]->Lookup(sNewWord,&iIndex) )
1081
	  if (oLib[iLib]->Lookup(sNewWord,&iIndex))
1029
            	        bFound=true;
1082
            	        bFound=true;
1030
                	else {
1083
                	else {
1031
						if (isupcase || g_ascii_isupper(sWord[0])) {
1084
						if (isupcase || g_ascii_isupper(sWord[0])) {
Lines 1040-1046 Link Here
1040
                    		sNewWord[iWordLen-3]=sNewWord[iWordLen-4];  //restore
1093
                    		sNewWord[iWordLen-3]=sNewWord[iWordLen-4];  //restore
1041
					}
1094
					}
1042
            	}
1095
            	}
1043
            	if( !bFound ) {
1096
	if (!bFound) {
1044
					if (oLib[iLib]->Lookup(sNewWord,&iIndex))
1097
					if (oLib[iLib]->Lookup(sNewWord,&iIndex))
1045
                		bFound=true;
1098
                		bFound=true;
1046
					else if (isupcase || g_ascii_isupper(sWord[0])) {
1099
					else if (isupcase || g_ascii_isupper(sWord[0])) {
Lines 1056-1072 Link Here
1056
        }
1109
        }
1057
1110
1058
        // cut "ied" , add "y".
1111
        // cut "ied" , add "y".
1059
        if(!bFound && iWordLen>3) {
1112
    if (!bFound && iWordLen>3) {
1060
			isupcase = !strncmp(&sWord[iWordLen-3],"IED",3);
1113
			isupcase = !strncmp(&sWord[iWordLen-3],"IED",3);
1061
			if (isupcase || (!strncmp(&sWord[iWordLen-3],"ied",3)))
1114
      if (isupcase || (!strncmp(&sWord[iWordLen-3],"ied",3))) {
1062
    	    {
1063
				strcpy(sNewWord,sWord);
1115
				strcpy(sNewWord,sWord);
1064
	            sNewWord[iWordLen-3]='\0';
1116
	            sNewWord[iWordLen-3]='\0';
1065
				if (isupcase)
1117
				if (isupcase)
1066
					strcat(sNewWord,"Y"); // add a char "Y"
1118
					strcat(sNewWord,"Y"); // add a char "Y"
1067
				else
1119
				else
1068
    	        	strcat(sNewWord,"y"); // add a char "y"
1120
    	        	strcat(sNewWord,"y"); // add a char "y"
1069
        	    if(oLib[iLib]->Lookup(sNewWord,&iIndex))
1121
	if (oLib[iLib]->Lookup(sNewWord,&iIndex))
1070
            	    bFound=true;
1122
            	    bFound=true;
1071
				else if (isupcase || g_ascii_isupper(sWord[0])) {
1123
				else if (isupcase || g_ascii_isupper(sWord[0])) {
1072
					casestr = g_ascii_strdown(sNewWord, -1);
1124
					casestr = g_ascii_strdown(sNewWord, -1);
Lines 1080-1089 Link Here
1080
        }
1132
        }
1081
        
1133
        
1082
		// cut "ies" , add "y".
1134
		// cut "ies" , add "y".
1083
        if(!bFound && iWordLen>3) {
1135
    if (!bFound && iWordLen>3) {
1084
			isupcase = !strncmp(&sWord[iWordLen-3],"IES",3);
1136
			isupcase = !strncmp(&sWord[iWordLen-3],"IES",3);
1085
			if (isupcase || (!strncmp(&sWord[iWordLen-3],"ies",3)))
1137
      if (isupcase || (!strncmp(&sWord[iWordLen-3],"ies",3))) {
1086
    	    {
1087
				strcpy(sNewWord,sWord);
1138
				strcpy(sNewWord,sWord);
1088
	            sNewWord[iWordLen-3]='\0';
1139
	            sNewWord[iWordLen-3]='\0';
1089
				if (isupcase)
1140
				if (isupcase)
Lines 1104-1113 Link Here
1104
        }
1155
        }
1105
1156
1106
		// cut "er".
1157
		// cut "er".
1107
        if(!bFound && iWordLen>2) {
1158
    if (!bFound && iWordLen>2) {
1108
			isupcase = !strncmp(&sWord[iWordLen-2],"ER",2);
1159
			isupcase = !strncmp(&sWord[iWordLen-2],"ER",2);
1109
			if (isupcase || (!strncmp(&sWord[iWordLen-2],"er",2)))
1160
      if (isupcase || (!strncmp(&sWord[iWordLen-2],"er",2))) {
1110
    	    {
1111
				strcpy(sNewWord,sWord);
1161
				strcpy(sNewWord,sWord);
1112
	            sNewWord[iWordLen-2]='\0';
1162
	            sNewWord[iWordLen-2]='\0';
1113
        	    if(oLib[iLib]->Lookup(sNewWord,&iIndex))
1163
        	    if(oLib[iLib]->Lookup(sNewWord,&iIndex))
Lines 1124-1133 Link Here
1124
        }
1174
        }
1125
1175
1126
		// cut "est".
1176
		// cut "est".
1127
        if(!bFound && iWordLen>3) {
1177
    if (!bFound && iWordLen>3) {
1128
			isupcase = !strncmp(&sWord[iWordLen-3], "EST", 3);
1178
			isupcase = !strncmp(&sWord[iWordLen-3], "EST", 3);
1129
			if (isupcase || (!strncmp(&sWord[iWordLen-3],"est", 3)))
1179
      if (isupcase || (!strncmp(&sWord[iWordLen-3],"est", 3))) {
1130
    	    {
1131
				strcpy(sNewWord,sWord);
1180
				strcpy(sNewWord,sWord);
1132
	            sNewWord[iWordLen-3]='\0';
1181
	            sNewWord[iWordLen-3]='\0';
1133
        	    if(oLib[iLib]->Lookup(sNewWord,&iIndex))
1182
        	    if(oLib[iLib]->Lookup(sNewWord,&iIndex))
Lines 1154-1213 Link Here
1154
		//iWordIndex = INVALID_INDEX;
1203
		//iWordIndex = INVALID_INDEX;
1155
	}
1204
	}
1156
1205
1157
    return(bFound);	
1206
  return bFound;
1158
}
1207
}
1159
1208
1160
gboolean Libs::SimpleLookupWord(const gchar* sWord,glong& iWordIndex,int iLib)
1209
bool Libs::SimpleLookupWord(const gchar* sWord, glong & iWordIndex, int iLib)
1161
{
1210
{
1162
	gboolean bFound = oLib[iLib]->Lookup(sWord, &iWordIndex);
1211
  bool bFound = oLib[iLib]->Lookup(sWord, &iWordIndex);
1163
	if (!bFound)
1212
	if (!bFound)
1164
		bFound = LookupSimilarWord(sWord, iWordIndex, iLib);
1213
		bFound = LookupSimilarWord(sWord, iWordIndex, iLib);
1165
	return bFound;
1214
	return bFound;
1166
}
1215
}
1167
1216
1168
inline gboolean bIsVowel(gchar inputchar)
1217
inline bool operator<(const Libs::Fuzzystruct & lh, const Libs::Fuzzystruct & rh) {    
1218
  if (lh.iMatchWordDistance!=rh.iMatchWordDistance)
1219
    return lh.iMatchWordDistance<rh.iMatchWordDistance;
1220
1221
  if (lh.pMatchWord && rh.pMatchWord)
1222
    return stardict_strcmp(lh.pMatchWord, rh.pMatchWord)<0;
1223
  
1224
  return false;
1225
}
1226
1227
bool Libs::LookupWithFuzzy(const gchar *sWord, Fuzzystruct oFuzzystruct[], gint fuzzystruct_amount, TProgressFunc ProgressFunc)
1169
{
1228
{
1170
    gchar ch = g_ascii_toupper(inputchar);
1229
  if (sWord[0] == '\0')
1171
    return( ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' );
1230
    return false;
1231
           
1232
  for (int i=0; i<fuzzystruct_amount; i++) {
1233
    oFuzzystruct[i].pMatchWord = NULL;
1234
    oFuzzystruct[i].iMatchWordDistance = iMaxFuzzyDistance;
1235
  }
1236
  int iMaxDistance = iMaxFuzzyDistance;
1237
  int iDistance;
1238
  bool Found = false;
1239
  EditDistance oEditDistance;
1240
1241
  glong iCheckWordLen;
1242
  int sCheckLen;
1243
  const char *sCheck;
1244
  gunichar *ucs4_str1,*ucs4_str2;
1245
  glong ucs4_str2_len;
1246
  char *sLowerCheckWord;
1247
  gchar *sLowerWord = g_utf8_strdown(sWord, -1);	
1248
  ucs4_str2 = g_utf8_to_ucs4_fast(sLowerWord,-1,&ucs4_str2_len);
1249
  g_free(sLowerWord);
1250
  for (int iLib=0; iLib<libcount; iLib++) {
1251
    if (ProgressFunc)
1252
      ProgressFunc();
1253
    if (stardict_strcmp(sWord, poGetWord(0,iLib))>=0 && 
1254
	stardict_strcmp(sWord, poGetWord(iLength(iLib)-1,iLib))<=0) {
1255
      //there are Chinese dicts and English dicts...        
1256
      const int iwords = iLength(iLib);
1257
      for (int index=0; index<iwords; index++) {
1258
	sCheck = poGetWord(index,iLib);
1259
	// tolower and skip too long or too short words
1260
	sCheckLen = strlen(sCheck);
1261
	iCheckWordLen = g_utf8_strlen(sCheck, sCheckLen);
1262
	if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || 
1263
	    ucs4_str2_len-iCheckWordLen>=iMaxDistance)
1264
	  continue;
1265
	sLowerCheckWord = g_utf8_strdown(sCheck, sCheckLen);
1266
	if (iCheckWordLen > ucs4_str2_len)
1267
	  (*g_utf8_offset_to_pointer(sLowerCheckWord, ucs4_str2_len)) = '\0';
1268
	ucs4_str1 = g_utf8_to_ucs4_fast(sLowerCheckWord, -1,NULL);
1269
	g_free(sLowerCheckWord);
1270
	iDistance = oEditDistance.CalEditDistance(ucs4_str1,ucs4_str2,iMaxDistance);
1271
	g_free(ucs4_str1);								
1272
	if (iDistance<iMaxDistance && iDistance < ucs4_str2_len) {
1273
	  // when ucs4_str2_len=1,2 we need less fuzzy.
1274
	  Found = true;
1275
	  bool bAlreadyInList = false;
1276
	  int iMaxDistanceAt=0;
1277
	  for (int j=0; j<fuzzystruct_amount; j++) {
1278
	    if (oFuzzystruct[j].pMatchWord && 
1279
		strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) {//already in list
1280
	      bAlreadyInList = true;
1281
	      break;
1282
	    }
1283
	    //find the position,it will certainly be found (include the first time) as iMaxDistance is set by last time.
1284
	    if (oFuzzystruct[j].iMatchWordDistance == iMaxDistance ) {
1285
	      iMaxDistanceAt = j;
1286
	    }
1287
	  }
1288
	  if (!bAlreadyInList) {
1289
	    if (oFuzzystruct[iMaxDistanceAt].pMatchWord)
1290
	      g_free(oFuzzystruct[iMaxDistanceAt].pMatchWord);
1291
	    oFuzzystruct[iMaxDistanceAt].pMatchWord = g_strdup(sCheck);
1292
	    oFuzzystruct[iMaxDistanceAt].iMatchWordDistance = iDistance;
1293
	    // calc new iMaxDistance
1294
	    iMaxDistance = iDistance;
1295
	    for (int j=0; j<fuzzystruct_amount; j++) {
1296
	      if (oFuzzystruct[j].iMatchWordDistance > iMaxDistance)
1297
		iMaxDistance = oFuzzystruct[j].iMatchWordDistance;
1298
	    } // calc new iMaxDistance
1299
	  }   // add to list
1300
	}   // find one
1301
      }   // each word
1302
    }   // ok for search
1303
  }   // each lib
1304
  g_free(ucs4_str2);
1305
	
1306
  if (Found)// sort with distance
1307
    std::sort(oFuzzystruct, oFuzzystruct+fuzzystruct_amount);
1308
  
1309
  return Found;
1172
}
1310
}
1173
1311
1312
inline bool less_for_compare(const char *lh, const char *rh) {
1313
  return stardict_strcmp(lh, rh)<0;
1314
}
1174
1315
1316
gint Libs::LookupWithRule(const gchar *word, TProgressFunc ProgressFunc, gchar **ppMatchWord)
1317
{	
1318
  glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1];
1319
  gint iMatchCount = 0;
1320
  GPatternSpec *pspec = g_pattern_spec_new(word);
1321
	
1322
  for (int iLib=0; iLib<libcount; iLib++) {
1323
    //if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1-iMatchCount,iLib)) 
1324
    // -iMatchCount,so save time,but may got less result and the word may repeat.
1325
    
1326
    if (oLib[iLib]->LookupWithRule(pspec,aiIndex, MAX_MATCH_ITEM_PER_LIB+1)) {
1327
      if (ProgressFunc)
1328
	ProgressFunc();
1329
      for (int i=0; aiIndex[i]!=-1; i++) {
1330
	gchar * sMatchWord = poGetWord(aiIndex[i],iLib);
1331
	bool bAlreadyInList = false;
1332
	for (int j=0; j<iMatchCount; j++) {
1333
	  if (strcmp(ppMatchWord[j],sMatchWord)==0) {//already in list
1334
	    bAlreadyInList = true;
1335
	    break;
1336
	  }
1337
	}
1338
	if (!bAlreadyInList)
1339
	  ppMatchWord[iMatchCount++] = g_strdup(sMatchWord);
1340
      }
1341
    }
1342
  }
1343
  g_pattern_spec_free(pspec);
1344
1345
  if (iMatchCount)// sort it.
1346
    std::sort(ppMatchWord, ppMatchWord+iMatchCount, less_for_compare); 
1347
1348
  return iMatchCount;
1349
}
1175
1350
1176
/**************************************************/
1351
/**************************************************/
1177
gboolean TreeDict::load(const char *ifofilename, GtkTreeStore *model)
1352
bool TreeDict::load(const char *ifofilename, GtkTreeStore *model)
1178
{
1353
{
1179
	gulong tdxfilesize;
1354
	gulong tdxfilesize;
1180
	if (!load_ifofile(ifofilename, &tdxfilesize))
1355
	if (!load_ifofile(ifofilename, &tdxfilesize))
1181
		return false;
1356
		return false;
1182
1357
1183
	gchar fullfilename[256];
1358
  std::string fullfilename(ifofilename);
1184
	
1359
  fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz");
1185
	strcpy(fullfilename, ifofilename);
1186
	strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "dict.dz");	
1187
	
1360
	
1188
	if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) {
1361
  if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {
1189
		dictdzfile = dict_data_open(fullfilename, 0);
1362
    dictdzfile = dict_data_open(fullfilename.c_str(), 0);
1190
		if (!dictdzfile) {
1363
		if (!dictdzfile) {
1191
			//g_print("open file %s failed!\n",fullfilename);
1364
			//g_print("open file %s failed!\n",fullfilename);
1192
			return false;
1365
			return false;
1193
		}
1366
		}
1194
	}
1367
  } else {
1195
	else {
1368
    fullfilename.erase(fullfilename.length()-sizeof(".dz")+1, sizeof(".dz")-1);
1196
		fullfilename[strlen(fullfilename)-3] = '\0';
1369
    dictfile = fopen(fullfilename.c_str(),"rb");
1197
		dictfile = fopen(fullfilename,"rb");
1198
		if (!dictfile) {
1370
		if (!dictfile) {
1199
			//g_print("open file %s failed!\n",fullfilename);
1371
			//g_print("open file %s failed!\n",fullfilename);
1200
			return false;
1372
			return false;
1201
		}
1373
		}
1202
	}
1374
	}
1203
1375
1204
	strcpy(fullfilename, ifofilename);
1376
  fullfilename=ifofilename;
1205
	strcpy(fullfilename+strlen(fullfilename)-sizeof("ifo") +1, "tdx.gz");	
1377
  fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "tdx.gz");
1206
	
1378
	
1207
	gchar *buffer= NULL;
1379
	gchar *buffer= NULL;
1208
	if (g_file_test(fullfilename, G_FILE_TEST_EXISTS)) {
1380
  if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {
1209
		gzFile in;	
1381
		gzFile in;	
1210
		in = gzopen(fullfilename,"rb");
1382
    in = gzopen(fullfilename.c_str(),"rb");
1211
		if (in == NULL) {
1383
		if (in == NULL) {
1212
			//g_print("Open file %s failed!\n",idxfilename);
1384
			//g_print("Open file %s failed!\n",idxfilename);
1213
			return false;
1385
			return false;
Lines 1226-1243 Link Here
1226
			g_free(buffer);
1398
			g_free(buffer);
1227
			return false;
1399
			return false;
1228
		}
1400
		}
1229
	}
1401
  } else {
1230
	else {
1402
    fullfilename.erase(fullfilename.length()-sizeof(".gz")+1, sizeof(".gz")-1);
1231
		fullfilename[strlen(fullfilename)-3] = '\0';
1232
		FILE *file;
1403
		FILE *file;
1233
		if (!(file = fopen (fullfilename, "rb"))) {
1404
    if (!(file = fopen (fullfilename.c_str(), "rb"))) {
1234
			//g_print("Open file %s failed!\n",fullfilename);
1405
			//g_print("Open file %s failed!\n",fullfilename);
1235
			return false;
1406
			return false;
1236
		}
1407
		}
1237
		buffer = (gchar *)g_malloc(tdxfilesize);
1408
		buffer = (gchar *)g_malloc(tdxfilesize);
1238
		gulong read_len;
1409
		gulong read_len;
1239
		read_len = fread (buffer, 1, tdxfilesize, file);
1410
    read_len = fread(buffer, 1, tdxfilesize, file);
1240
		fclose (file);
1411
    fclose(file);
1241
		if (read_len!=tdxfilesize) {
1412
		if (read_len!=tdxfilesize) {
1242
			g_free(buffer);
1413
			g_free(buffer);
1243
			return false;
1414
			return false;
Lines 1250-1301 Link Here
1250
	return true;
1421
	return true;
1251
}
1422
}
1252
1423
1253
gboolean TreeDict::load_ifofile(const char *ifofilename, gulong *tdxfilesize)
1424
bool TreeDict::load_ifofile(const char *ifofilename, gulong *tdxfilesize)
1254
{
1425
{
1255
	struct stat stats;
1426
  DictInfo dict_info;
1256
	if (stat (ifofilename, &stats) == -1) {
1427
  if (!dict_info.load_from_ifo_file(ifofilename, true))
1257
		//g_print("File: %s don't exist!\n",idxfilename);
1258
		return false;
1259
	}
1260
		
1261
	FILE *file;
1262
	if (!(file = fopen (ifofilename, "rb"))) {
1263
		//g_print("Open file %s failed!\n",idxfilename);
1264
		return false;
1265
	}
1266
	gchar *buffer = (gchar *)g_malloc (stats.st_size + 1);
1267
	fread (buffer, 1, stats.st_size, file);
1268
	buffer[stats.st_size] = '\0';
1269
	fclose (file);
1270
	
1271
	if (!g_str_has_prefix(buffer, "StarDict's treedict ifo file\nversion=2.4.2\n")) {
1272
		g_print("Bad treedict ifo file %s, skiped!\n", ifofilename);
1273
		g_free(buffer);
1274
		return false;
1275
	}
1276
	gchar *p1= buffer + sizeof("StarDict's treedict ifo file\nversion=2.4.2\n")-1 -1;
1277
	
1278
	gchar *p2,*p3;
1279
1280
	p2 = strstr(p1,"\ntdxfilesize=");
1281
	if (!p2) {
1282
		g_free(buffer);
1283
		return false;
1428
		return false;
1284
	}
1285
	p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n');
1286
	gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1);
1287
	tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0';
1288
	*tdxfilesize = atol(tmpstr);
1289
	g_free(tmpstr);
1290
1429
1291
	p2 = strstr(p1,"\nsametypesequence=");
1430
  *tdxfilesize = dict_info.index_file_size;
1292
	if (p2) {		
1431
  if (!dict_info.sametypesequence.empty())
1293
		p3 = strchr(p2+sizeof("\nsametypesequence=")-1,'\n');
1432
    sametypesequence=g_strdup(dict_info.sametypesequence.c_str());
1294
		sametypesequence = (gchar *)g_memdup(p2+sizeof("\nsametypesequence=")-1, p3-(p2+sizeof("\nsametypesequence=")-1)+1);
1295
		sametypesequence[p3-(p2+sizeof("\nsametypesequence=")-1)] = '\0';
1296
	}	
1297
	
1433
	
1298
	g_free(buffer);	
1299
	return true;
1434
	return true;
1300
}
1435
}
1301
1436
(-)stardict-cur-accepted/src/lib.h (-32 / +52 lines)
Lines 11-45 Link Here
11
11
12
#include "dictziplib.h"
12
#include "dictziplib.h"
13
13
14
const int MAX_MATCH_ITEM_PER_LIB=100;
15
const int MAX_FUZZY_DISTANCE= 3; // at most MAX_FUZZY_DISTANCE-1 differences allowed when find similar words
14
16
15
struct cacheItem
17
extern bool bIsPureEnglish(const gchar *str);
16
{
18
17
	glong offset;
19
struct cacheItem {
20
  guint32 offset;
18
	gchar *data;
21
	gchar *data;
19
	cacheItem();
22
  //write code here to make it inline
20
	~cacheItem();
23
  cacheItem() {data= NULL;}
24
  ~cacheItem() {g_free(data);}
21
};
25
};
22
26
23
const int WORDDATA_CACHE_NUM = 10;
27
const int WORDDATA_CACHE_NUM = 10;
24
const int INVALID_INDEX=-100;
28
const int INVALID_INDEX=-100;
25
29
26
class DictBase
30
class DictBase {
27
{
28
public:
31
public:
29
	DictBase();
32
	DictBase();
30
	~DictBase();
33
	~DictBase();
31
	gchar * GetWordData(glong idxitem_offset, glong idxitem_size);
34
  gchar * GetWordData(guint32 idxitem_offset, guint32 idxitem_size);
32
protected:
35
protected:
33
	gchar *sametypesequence;
36
	gchar *sametypesequence;
34
	FILE *dictfile;
37
	FILE *dictfile;
35
	dictData *dictdzfile;
38
	dictData *dictdzfile;
36
private:
39
private:
37
	struct cacheItem cache[WORDDATA_CACHE_NUM];
40
  cacheItem cache[WORDDATA_CACHE_NUM];
38
	gint cache_cur;	
41
	gint cache_cur;	
39
};
42
};
40
43
41
class Lib : public DictBase
44
//this structure contain all information about dictionary
42
{
45
struct DictInfo {
46
  std::string ifo_file_name;
47
  glong wordcount;
48
  std::string bookname;
49
  std::string author;
50
  std::string email;
51
  std::string website;
52
  std::string date;
53
  std::string description;
54
  gulong index_file_size;
55
  std::string sametypesequence;
56
  bool load_from_ifo_file(const gchar *ifofilename, bool istreedict);
57
};
58
59
class Lib : public DictBase {
43
private:
60
private:
44
	glong wordcount;
61
	glong wordcount;
45
	gchar *bookname;
62
	gchar *bookname;
Lines 51-82 Link Here
51
		glong *wordoffset;
68
		glong *wordoffset;
52
	};
69
	};
53
70
54
#ifdef HAVE_MMAP
55
	int mmap_fd;
56
	unsigned long mmap_idxmap_size;
57
#endif
58
59
	union {
71
	union {
60
		gchar *idxdatabuffer;
72
		gchar *idxdatabuffer;
61
		glong cur_wordindex;
73
		glong cur_wordindex;
62
	};
74
	};
63
75
64
	gchar wordentry_buf[256]; // The length of "word_str" should be less than 256. See src/tools/DICTFILE_FORMAT.
76
	gchar wordentry_buf[256]; // The length of "word_str" should be less than 256. See src/tools/DICTFILE_FORMAT.
65
	glong wordentry_offset;
77
  guint32 wordentry_offset;
66
	glong wordentry_size;
78
  guint32 wordentry_size;
67
	
79
	
68
	gboolean load_ifofile(const char *ifofilename, gulong *idxfilesize);
80
  bool load_ifofile(const char *ifofilename, gulong *idxfilesize);
69
81
70
	void loadwordlist();
82
	void loadwordlist();
71
	void loadwordoffset();
83
	void loadwordoffset();
72
public:
84
public:
73
	Lib();
85
	Lib();
74
    ~Lib();
86
    ~Lib();
75
	gboolean load(const char *ifofilename);
87
  bool load(const char *ifofilename);
76
	inline glong length() { return(wordcount); }
88
  inline glong length() { return wordcount; }
77
	inline gchar* GetBookname() { return(bookname); }
89
  inline gchar* GetBookname() { return bookname; }
78
	gboolean Lookup(const char* sWord,glong *pIndex);
90
  bool Lookup(const char* sWord,glong *pIndex);
79
	gboolean LookupWithRule(GPatternSpec *pspec,glong *aIndex,int iBuffLen);
91
  bool LookupWithRule(GPatternSpec *pspec,glong *aIndex,int iBuffLen);
80
	gchar * GetWord(glong index);
92
	gchar * GetWord(glong index);
81
	gchar * GetWordData(glong index);
93
	gchar * GetWordData(glong index);
82
};
94
};
Lines 86-91 Link Here
86
private:
98
private:
87
	Lib **oLib; // word library.
99
	Lib **oLib; // word library.
88
	gint libcount;
100
	gint libcount;
101
  int iMaxFuzzyDistance;
89
	
102
	
90
  void LoadDir(const gchar *dirname, const GSList *order_list, const GSList *disable_list);
103
  void LoadDir(const gchar *dirname, const GSList *order_list, const GSList *disable_list);
91
public:
104
public:
Lines 94-120 Link Here
94
  void Load(const gchar *dicts_dir, const GSList *order_list, const GSList *disable_list);
107
  void Load(const gchar *dicts_dir, const GSList *order_list, const GSList *disable_list);
95
	glong iLength(int iLib);
108
	glong iLength(int iLib);
96
	gchar* GetBookname(int iLib);
109
	gchar* GetBookname(int iLib);
97
	inline gint total_libs() { return(libcount); }
110
  inline gint total_libs() {return libcount;}
98
	gchar * poGetWord(glong iIndex,int iLib);
111
	gchar * poGetWord(glong iIndex,int iLib);
99
	gchar * poGetWordData(glong iIndex,int iLib);
112
	gchar * poGetWordData(glong iIndex,int iLib);
100
	gchar * poGetCurrentWord(glong * iCurrent);
113
	gchar * poGetCurrentWord(glong * iCurrent);
101
	gchar * poGetNextWord(const gchar *word,glong * iCurrent);
114
	gchar * poGetNextWord(const gchar *word,glong * iCurrent);
102
	gchar * poGetPreWord(glong * iCurrent);
115
	gchar * poGetPreWord(glong * iCurrent);
103
	gboolean LookupWord(const gchar* sWord,glong& iWordIndex,int iLib);
116
  bool LookupWord(const gchar* sWord,glong& iWordIndex,int iLib);
104
	gboolean LookupSimilarWord(const gchar* sWord,glong& iWordIndex,int iLib);
117
  bool LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib);
105
	gboolean SimpleLookupWord(const gchar* sWord,glong& iWordIndex,int iLib);
118
  bool SimpleLookupWord(const gchar* sWord, glong & iWordIndex, int iLib);
106
	gboolean LookdupWordsWithRule(GPatternSpec *pspec,glong* aiIndexes,int iLen,int iLib);
119
120
  struct Fuzzystruct {
121
    char * pMatchWord;
122
    int iMatchWordDistance;
123
  };
124
  typedef void (*TProgressFunc)(void);
125
126
  bool LookupWithFuzzy(const gchar *sWord, Fuzzystruct oFuzzystruct[], gint fuzzystruct_amount, TProgressFunc ProgressFunc);
127
  gint LookupWithRule(const gchar *word, TProgressFunc ProgressFunc, gchar **ppMatchWord);
107
};
128
};
108
129
109
inline gboolean bIsVowel(gchar inputchar);
110
130
111
class TreeDict : public DictBase
131
class TreeDict : public DictBase
112
{
132
{
113
private:	
133
private:	
114
	gboolean load_ifofile(const char *ifofilename, gulong *tdxfilesize);
134
	bool load_ifofile(const char *ifofilename, gulong *tdxfilesize);
115
	void load_model(gchar **buffer, GtkTreeStore *model, GtkTreeIter *parent, gint count);
135
	void load_model(gchar **buffer, GtkTreeStore *model, GtkTreeIter *parent, gint count);
116
public:
136
public:
117
	gboolean load(const char *ifofilename, GtkTreeStore *model);
137
	bool load(const char *ifofilename, GtkTreeStore *model);
118
};
138
};
119
139
120
class TreeDicts {
140
class TreeDicts {
(-)stardict-cur-accepted/src/mainwin.cpp (-54 / +62 lines)
Lines 198-204 Link Here
198
	gpAppFrame->oAppCore.oTopWin.InsertHisList(gpAppFrame->oAppCore.oTopWin.GetText());
198
	gpAppFrame->oAppCore.oTopWin.InsertHisList(gpAppFrame->oAppCore.oTopWin.GetText());
199
	gpAppFrame->oAppCore.oTopWin.SetText(((BackListData *)((gpAppFrame->oAppCore.oTopWin.BackList)->data))->word);
199
	gpAppFrame->oAppCore.oTopWin.SetText(((BackListData *)((gpAppFrame->oAppCore.oTopWin.BackList)->data))->word);
200
	if (((BackListData *)(gpAppFrame->oAppCore.oTopWin.BackList->data))->adjustment_value != -1) {
200
	if (((BackListData *)(gpAppFrame->oAppCore.oTopWin.BackList->data))->adjustment_value != -1) {
201
		gpAppFrame->ProcessGtkEvent();
201
		ProcessGtkEvent();
202
		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);
202
		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);
203
	}
203
	}
204
	g_free(((BackListData *)((gpAppFrame->oAppCore.oTopWin.BackList)->data))->word);
204
	g_free(((BackListData *)((gpAppFrame->oAppCore.oTopWin.BackList)->data))->word);
Lines 255-261 Link Here
255
	if (GTK_WIDGET_HAS_FOCUS(GTK_WIDGET(GTK_COMBO(WordCombo)->entry)))
255
	if (GTK_WIDGET_HAS_FOCUS(GTK_WIDGET(GTK_COMBO(WordCombo)->entry)))
256
		gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(WordCombo)->entry),0,-1);
256
		gtk_editable_select_region(GTK_EDITABLE(GTK_COMBO(WordCombo)->entry),0,-1);
257
	if (((BackListData *)(list->data))->adjustment_value != -1) {
257
	if (((BackListData *)(list->data))->adjustment_value != -1) {
258
		gpAppFrame->ProcessGtkEvent(); // so all the definition text have been inserted.
258
		ProcessGtkEvent(); // so all the definition text have been inserted.
259
		gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(gpAppFrame->oAppCore.oMidWin.oTextWin.scrolled_window)), ((BackListData *)(list->data))->adjustment_value);
259
		gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(gpAppFrame->oAppCore.oMidWin.oTextWin.scrolled_window)), ((BackListData *)(list->data))->adjustment_value);
260
	}
260
	}
261
	g_free(((BackListData *)(list->data))->word);
261
	g_free(((BackListData *)(list->data))->word);
Lines 1325-1331 Link Here
1325
void TextWin::Show(gchar **Word, gchar **WordData, const gchar * sOriginWord)
1325
void TextWin::Show(gchar **Word, gchar **WordData, const gchar * sOriginWord)
1326
{
1326
{
1327
	gchar *p;
1327
	gchar *p;
1328
	glong data_size,sec_size;
1328
  guint32 data_size,sec_size=0;
1329
	GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
1329
	GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
1330
	gtk_text_buffer_begin_user_action(buffer); // will this speed up the showing?
1330
	gtk_text_buffer_begin_user_action(buffer); // will this speed up the showing?
1331
	
1331
	
Lines 1336-1396 Link Here
1336
	
1336
	
1337
	GtkTextIter iter;
1337
	GtkTextIter iter;
1338
	gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
1338
	gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
1339
	for (int i=0;i< gpAppFrame->oAppCore.oLibs.total_libs();i++)
1339
  for (int i=0; i<gpAppFrame->oAppCore.oLibs.total_libs(); i++)	{
1340
	{
1341
		if (Word[i]) {
1340
		if (Word[i]) {
1342
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "<--- ",-1, "DictNameTag", NULL);
1341
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "<--- ",-1, "DictNameTag", NULL);
1343
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, gpAppFrame->oAppCore.oLibs.GetBookname(i),-1, "DictNameTag", NULL);
1342
      gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, gpAppFrame->oAppCore.oLibs.GetBookname(i),
1343
					       -1, "DictNameTag", NULL);
1344
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, " --->\n",-1, "DictNameTag", NULL);
1344
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, " --->\n",-1, "DictNameTag", NULL);
1345
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, Word[i],-1, "WordTag", NULL);	
1345
			gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, Word[i],-1, "WordTag", NULL);	
1346
			gtk_text_buffer_insert (buffer, &iter,"\n", 1);
1346
			gtk_text_buffer_insert (buffer, &iter,"\n", 1);
1347
		}
1347
		}
1348
		if (WordData[i]) {
1348
		if (WordData[i]) {
1349
			memcpy(&data_size,WordData[i],sizeof(glong));
1349
      p=WordData[i];
1350
			p=WordData[i]+sizeof(glong);
1350
      data_size=*reinterpret_cast<guint32 *>(p);
1351
			while (p - (WordData[i] + sizeof(glong))< data_size)
1351
      p+=sizeof(guint32);
1352
			{	
1352
      while (guint32(p - (WordData[i] + sizeof(guint32)))< data_size) {
1353
				switch (*p)
1353
	switch (*p++) {
1354
				{
1355
					case 'm':
1354
					case 'm':
1356
					case 'o': //need more work...
1355
	case 'l'://need more work...
1357
						sec_size = strlen(p+sizeof(gchar));
1356
	case 'g':
1358
						if (sec_size) {
1357
	  sec_size = strlen(p);
1359
							gtk_text_buffer_insert (buffer, &iter,p+sizeof(gchar),sec_size);
1358
	  if (sec_size)
1360
						}
1359
	    gtk_text_buffer_insert(buffer, &iter, p, sec_size);	  
1361
						sec_size++;
1360
						sec_size++;
1362
						break;
1361
						break;
1363
					case 't':
1362
					case 't':
1364
						sec_size = strlen(p+sizeof(gchar));
1363
	  sec_size = strlen(p);
1365
						if (sec_size) {
1364
						if (sec_size) {
1366
							gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"PhoneticTag",NULL);
1365
	    gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "PhoneticTag", NULL);
1367
							gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"PhoneticTag",NULL);
1366
	    gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "PhoneticTag", NULL);
1368
							gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"PhoneticTag",NULL);
1367
	    gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "PhoneticTag", NULL);
1369
						}
1368
						}
1370
						sec_size++;						
1369
						sec_size++;						
1371
						break;
1370
						break;
1372
					case 'y':
1371
					case 'y':
1373
						sec_size = strlen(p+sizeof(gchar));
1372
	  sec_size = strlen(p);
1374
						if (sec_size) {
1373
						if (sec_size) {
1375
							gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"YinBiaoTag",NULL);
1374
	    gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "YinBiaoTag", NULL);
1376
							gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"YinBiaoTag",NULL);
1375
	    gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "YinBiaoTag", NULL);
1377
							gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"YinBiaoTag",NULL);
1376
	    gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "YinBiaoTag", NULL);
1378
						}
1377
						}
1379
						sec_size++;
1378
						sec_size++;
1380
						break;
1379
						break;
1381
					case 'W':
1380
					case 'W':
1382
						memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
1381
	  sec_size=*reinterpret_cast<guint32 *>(p);
1382
	  sec_size=g_ntohl(sec_size);
1383
						//enbale sound button.
1383
						//enbale sound button.
1384
						sec_size+= sizeof(glong);
1384
	  sec_size += sizeof(guint32);
1385
						break;
1385
						break;
1386
					case 'P':
1386
					case 'P':
1387
						memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
1387
	  sec_size=*reinterpret_cast<guint32 *>(p);
1388
	  sec_size=g_ntohl(sec_size);
1388
						//show this picture.
1389
						//show this picture.
1389
						sec_size+= sizeof(glong);
1390
	  sec_size += sizeof(guint32);
1390
						break;
1391
						break;
1392
	default:
1393
	  /*nothing*/;
1391
				}
1394
				}
1392
				gtk_text_buffer_insert (buffer, &iter,"\n", 1);
1395
	gtk_text_buffer_insert(buffer, &iter, "\n", 1);
1393
				p = p+sizeof(gchar)+sec_size;
1396
	p += sec_size;
1394
			}
1397
			}
1395
		}		
1398
		}		
1396
	}
1399
	}
Lines 1410-1460 Link Here
1410
	GtkTextIter iter;
1413
	GtkTextIter iter;
1411
	gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
1414
	gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
1412
1415
1413
	const gchar *p;
1414
	glong data_size,sec_size;
1415
1416
1416
	memcpy(&data_size,data,sizeof(glong));
1417
  guint32 data_size,sec_size=0;
1417
	p=data+sizeof(glong);
1418
  const gchar *p=data;
1418
	while (p - (data + sizeof(glong))< data_size) {						
1419
  data_size=*reinterpret_cast<const guint32 *>(p);
1419
		switch (*p) {
1420
  p+=sizeof(guint32);
1421
  while (guint32(p - (data + sizeof(guint32)))< data_size) {
1422
    switch (*p++) {
1420
			case 'm':
1423
			case 'm':
1421
			case 'o': //need more work...
1424
    case 'l'://need more work...
1422
				sec_size = strlen(p+sizeof(gchar));
1425
    case 'g':
1426
      sec_size = strlen(p);
1423
				if (sec_size)
1427
				if (sec_size)
1424
					gtk_text_buffer_insert (buffer, &iter,p+sizeof(gchar),sec_size);
1428
	gtk_text_buffer_insert(buffer, &iter, p, sec_size);
1425
				sec_size++;
1429
				sec_size++;
1426
				break;
1430
				break;
1427
			case 't':
1431
			case 't':
1428
				sec_size = strlen(p+sizeof(gchar));
1432
      sec_size = strlen(p);
1429
				if (sec_size) {
1433
				if (sec_size) {
1430
					gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"PhoneticTag",NULL);
1434
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "PhoneticTag", NULL);
1431
					gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"PhoneticTag",NULL);
1435
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "PhoneticTag", NULL);
1432
					gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"PhoneticTag",NULL);
1436
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "PhoneticTag", NULL);
1433
				}
1437
				}
1434
				sec_size++;						
1438
				sec_size++;						
1435
				break;
1439
				break;
1436
			case 'y':
1440
			case 'y':
1437
				sec_size = strlen(p+sizeof(gchar));
1441
      sec_size = strlen(p);
1438
				if (sec_size) {
1442
				if (sec_size) {
1439
					gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"[",1,"YinBiaoTag",NULL);
1443
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "[", 1, "YinBiaoTag", NULL);
1440
					gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,p+sizeof(gchar),sec_size,"YinBiaoTag",NULL);
1444
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, p, sec_size, "YinBiaoTag", NULL);
1441
					gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,"]",1,"YinBiaoTag",NULL);
1445
	gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "]", 1, "YinBiaoTag", NULL);
1442
				}
1446
				}
1443
				sec_size++;
1447
				sec_size++;
1444
				break;
1448
				break;
1445
			case 'W':
1449
			case 'W':
1446
				memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
1450
      sec_size=*reinterpret_cast<const guint32 *>(p);
1451
      sec_size=g_ntohl(sec_size);
1447
				//enbale sound button.
1452
				//enbale sound button.
1448
				sec_size+= sizeof(glong);
1453
      sec_size += sizeof(guint32);
1449
				break;
1454
				break;
1450
			case 'P':
1455
			case 'P':
1451
				memcpy(&sec_size,p+sizeof(gchar),sizeof(glong));
1456
      sec_size=*reinterpret_cast<const guint32 *>(p);
1457
      sec_size=g_ntohl(sec_size);
1452
				//show this picture.
1458
				//show this picture.
1453
				sec_size+= sizeof(glong);
1459
      sec_size += sizeof(guint32);
1454
				break;
1460
				break;
1461
    default:
1462
      /*nothing*/;
1455
		}
1463
		}
1456
		gtk_text_buffer_insert (buffer, &iter,"\n", 1);
1464
    gtk_text_buffer_insert(buffer, &iter,"\n", 1);
1457
		p = p+sizeof(gchar)+sec_size;
1465
    p += sec_size;
1458
	}
1466
	}
1459
	gtk_text_buffer_end_user_action(buffer);
1467
	gtk_text_buffer_end_user_action(buffer);
1460
}
1468
}
(-)stardict-cur-accepted/src/stardict.cpp (-322 / +56 lines)
Lines 36-42 Link Here
36
#  include "stardict-application-server.h"
36
#  include "stardict-application-server.h"
37
#  include "GNOME_Stardict.h"
37
#  include "GNOME_Stardict.h"
38
#endif
38
#endif
39
#include "distance.h"
40
#include "splash.h"
39
#include "splash.h"
41
40
42
#ifndef _WIN32
41
#ifndef _WIN32
Lines 84-90 Link Here
84
AppCore::AppCore(AppFrame *pAppFrame)
84
AppCore::AppCore(AppFrame *pAppFrame)
85
{
85
{
86
	poAppFrame = pAppFrame;
86
	poAppFrame = pAppFrame;
87
	iMaxFuzzyDistance  = MAX_FUZZY_DISTANCE; //need to read from cfg.
88
	window = NULL; //need by save_yourself_cb().
87
	window = NULL; //need by save_yourself_cb().
89
	prefs_dlg = NULL;
88
	prefs_dlg = NULL;
90
	dict_manage_dlg = NULL;
89
	dict_manage_dlg = NULL;
Lines 358-364 Link Here
358
	return return_val;
357
	return return_val;
359
}
358
}
360
359
361
gboolean AppCore::SimpleLookupToFloat(const char* sWord,gboolean bShowIfNotFound)
360
bool AppCore::SimpleLookupToFloat(const char* sWord, bool bShowIfNotFound)
362
{
361
{
363
    if ( sWord==NULL || sWord[0]=='\0')
362
    if ( sWord==NULL || sWord[0]=='\0')
364
        return true;
363
        return true;
Lines 415-421 Link Here
415
                ppWordData[iLib] = NULL;
414
                ppWordData[iLib] = NULL;
416
			}
415
			}
417
        }
416
        }
418
        if (bFound==true)
417
        if (bFound)
419
        {
418
        {
420
            ShowDataToFloatWin(ppWord, ppWordData,SearchWord);
419
            ShowDataToFloatWin(ppWord, ppWordData,SearchWord);
421
            oTopWin.InsertHisList(SearchWord);
420
            oTopWin.InsertHisList(SearchWord);
Lines 454-466 Link Here
454
    return false;
453
    return false;
455
}
454
}
456
455
457
gboolean AppCore::SimpleLookupToTextWin(const char* sWord,glong* piIndex,gboolean piIndexValid, gboolean bTryMoreIfNotFound)
456
//the input can be:
457
// (sWord,NULL,false) look up the sWord.
458
// (sWord,piIndex,false),look up the sWord,and set piIndex to the new indexes that found.
459
// (sWord,piIndex,true), show word by piIndex's information. it will always found, so bTryMoreIfNotFound is useless.
460
bool AppCore::SimpleLookupToTextWin(const char* sWord, glong* piIndex, bool piIndexValid, bool bTryMoreIfNotFound)
458
{
461
{
459
	//the input can be:
462
  bool bFound = false;
460
	// (sWord,NULL,false) look up the sWord.
461
	// (sWord,piIndex,false),look up the sWord,and set piIndex to the new indexes that found.
462
	// (sWord,piIndex,true), show word by piIndex's information. it will always found, so bTryMoreIfNotFound is useless.
463
	gboolean bFound = false;
464
	gchar **ppWord = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());
463
	gchar **ppWord = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());
465
	gchar **ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());
464
	gchar **ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());
466
	glong *iIndex;
465
	glong *iIndex;
Lines 469-505 Link Here
469
	else
468
	else
470
		iIndex = piIndex;
469
		iIndex = piIndex;
471
	    
470
	    
472
    for (int iLib=0;iLib<oLibs.total_libs();iLib++) {
471
  for (int iLib=0; iLib<oLibs.total_libs(); iLib++) {
473
		if (!piIndexValid) {
472
		if (!piIndexValid) {
474
        	if (oLibs.LookupWord(sWord,iIndex[iLib],iLib)) {
473
        	if (oLibs.LookupWord(sWord,iIndex[iLib],iLib)) {
475
				ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
474
				ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
476
				ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
475
				ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
477
            	bFound = true;
476
            	bFound = true;
478
        	}
477
      } else {
479
        	else {
480
				ppWord[iLib] = NULL;
478
				ppWord[iLib] = NULL;
481
            	ppWordData[iLib] = NULL;
479
            	ppWordData[iLib] = NULL;
482
			}
480
			}
483
		}
481
    } else {
484
		else {
482
      if (piIndex[iLib] != INVALID_INDEX && 
485
			if (piIndex[iLib] != INVALID_INDEX && (!strcmp((ppWord[iLib] = oLibs.poGetWord(piIndex[iLib],iLib)),sWord))) {				
483
	  !strcmp((ppWord[iLib] = oLibs.poGetWord(piIndex[iLib],iLib)), sWord)) {
486
				ppWordData[iLib] = oLibs.poGetWordData(piIndex[iLib],iLib);
484
				ppWordData[iLib] = oLibs.poGetWordData(piIndex[iLib],iLib);
487
				bFound = true;
485
				bFound = true;
488
			}
486
      }	else {
489
			else {
490
				ppWord[iLib] = NULL;
487
				ppWord[iLib] = NULL;
491
				ppWordData[iLib] = NULL;
488
				ppWordData[iLib] = NULL;
492
			}
489
			}
493
		}
490
		}
494
    }
491
    }
495
	if ((!bFound)&&(!piIndexValid)) {
492
496
		for (int iLib=0;iLib<oLibs.total_libs();iLib++) {
493
  if (!bFound && !piIndexValid) {
494
    for (int iLib=0; iLib<oLibs.total_libs(); iLib++) {
497
        	if (oLibs.LookupSimilarWord(sWord,iIndex[iLib],iLib)) {
495
        	if (oLibs.LookupSimilarWord(sWord,iIndex[iLib],iLib)) {
498
				ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
496
				ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
499
				ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
497
				ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
500
            	bFound = true;
498
            	bFound = true;
501
        	}
499
      } else {
502
        	else {
503
				ppWord[iLib] = NULL;
500
				ppWord[iLib] = NULL;
504
            	ppWordData[iLib] = NULL;
501
            	ppWordData[iLib] = NULL;
505
			}
502
			}
Lines 515-541 Link Here
515
			if (*hword) {
512
			if (*hword) {
516
				if (!strcmp(hword,sWord)) {
513
				if (!strcmp(hword,sWord)) {
517
					ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);
514
					ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);
518
				}
515
	} else {
519
				else {
520
					for (int iLib=0;iLib<oLibs.total_libs();iLib++) {
516
					for (int iLib=0;iLib<oLibs.total_libs();iLib++) {
521
			        	if (oLibs.LookupWord(hword,iIndex[iLib],iLib)) {
517
			        	if (oLibs.LookupWord(hword,iIndex[iLib],iLib)) {
522
							ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
518
							ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
523
							ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
519
							ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
524
            				bFound = true;
520
            				bFound = true;
525
        				}
521
	    } else {
526
        				else {
527
							ppWord[iLib] = NULL;
522
							ppWord[iLib] = NULL;
528
            				ppWordData[iLib] = NULL;
523
            				ppWordData[iLib] = NULL;
529
						}
524
						}
530
					}
525
					}
531
					if (!bFound) {
526
					if (!bFound) {
532
						for (int iLib=0;iLib<oLibs.total_libs();iLib++) {
527
	    for (int iLib=0; iLib<oLibs.total_libs(); iLib++) {
533
				        	if (oLibs.LookupSimilarWord(hword,iIndex[iLib],iLib)) {
528
				        	if (oLibs.LookupSimilarWord(hword,iIndex[iLib],iLib)) {
534
								ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
529
								ppWord[iLib] = oLibs.poGetWord(iIndex[iLib],iLib);
535
								ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
530
								ppWordData[iLib] = oLibs.poGetWordData(iIndex[iLib],iLib);
536
            					bFound = true;
531
            					bFound = true;
537
        					}
532
	      } else {
538
				        	else {
539
								ppWord[iLib] = NULL;
533
								ppWord[iLib] = NULL;
540
				            	ppWordData[iLib] = NULL;
534
				            	ppWordData[iLib] = NULL;
541
							}
535
							}
Lines 546-558 Link Here
546
					else
540
					else
547
						ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);		
541
						ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);		
548
				}
542
				}
549
			}			
543
      } else {
550
			else {
551
				ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);
544
				ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);
552
			}
545
			}
553
			g_free(word);
546
			g_free(word);
554
		}
547
    } else {
555
		else {
556
			ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);
548
			ShowNotFoundToTextWin(sWord,_("<Not Found!>"), TEXT_WIN_NOT_FOUND);
557
		}
549
		}
558
	}
550
	}
Lines 562-585 Link Here
562
	
554
	
563
	g_free(ppWord);
555
	g_free(ppWord);
564
	g_free(ppWordData);
556
	g_free(ppWordData);
565
	return bFound;
566
}
567
557
568
int AppCore::FuzzystructCompare(const void * s1, const void * s2)
558
  return bFound;
569
{
570
    if (s1==NULL || s2==NULL)
571
        return 0;
572
    const struct Fuzzystruct * o1 = (struct Fuzzystruct*)s1;
573
    const struct Fuzzystruct * o2 = (struct Fuzzystruct*)s2;
574
    
575
    if ( o1->iMatchWordDistance > o2->iMatchWordDistance )
576
        return 1;
577
    else if ( o1->iMatchWordDistance < o2->iMatchWordDistance )
578
        return -1;
579
    else if ( o1->pMatchWord && o2->pMatchWord )
580
        return stardict_strcmp(o1->pMatchWord, o2->pMatchWord);
581
    else
582
        return 0;
583
}
559
}
584
560
585
void AppCore::LookupWithFuzzyToMainWin(const gchar *sWord)
561
void AppCore::LookupWithFuzzyToMainWin(const gchar *sWord)
Lines 589-701 Link Here
589
   
565
   
590
	gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor);
566
	gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor);
591
        
567
        
592
    struct Fuzzystruct oFuzzystruct[MAX_FUZZY_MATCH_ITEM];
568
  Libs::Fuzzystruct oFuzzystruct[MAX_FUZZY_MATCH_ITEM];
593
    for (int i=0;i<MAX_FUZZY_MATCH_ITEM;i++)
569
  bool Found=oLibs.LookupWithFuzzy(sWord, oFuzzystruct, 
594
    {
570
				   MAX_FUZZY_MATCH_ITEM, ProcessGtkEvent);
595
        oFuzzystruct[i].pMatchWord = NULL;
596
        oFuzzystruct[i].iMatchWordDistance = iMaxFuzzyDistance;
597
    }
598
    int iMaxDistance = iMaxFuzzyDistance;
599
    int iDistance;
600
    gboolean Found = false;
601
    class EditDistance oEditDistance;
602
603
    glong iCheckWordLen;
604
	int sCheckLen;
605
	const char *sCheck;
606
	gunichar *ucs4_str1,*ucs4_str2;
607
	glong ucs4_str2_len;
608
	char *sLowerCheckWord;
609
	gchar *sLowerWord = g_utf8_strdown(sWord, -1);	
610
	ucs4_str2 = g_utf8_to_ucs4_fast(sLowerWord,-1,&ucs4_str2_len);
611
	g_free(sLowerWord);
612
    for(int iLib=0;iLib<oLibs.total_libs();iLib++)
613
    {
614
        ProcessGtkEvent();
615
        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...
616
        {
617
            const int iwords = oLibs.iLength(iLib);
618
            for (int index=0;index<iwords;index++)
619
            {
620
                //ProcessGtkEvent(); // too slow if here
621
                sCheck = oLibs.poGetWord(index,iLib);
622
                // tolower and skip too long or too short words
623
				sCheckLen = strlen(sCheck);
624
                iCheckWordLen = g_utf8_strlen(sCheck, sCheckLen);
625
                if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || ucs4_str2_len-iCheckWordLen>=iMaxDistance )
626
                    continue;				
627
				sLowerCheckWord = g_utf8_strdown(sCheck, sCheckLen);
628
				if (iCheckWordLen > ucs4_str2_len)
629
					(*g_utf8_offset_to_pointer(sLowerCheckWord, ucs4_str2_len)) = '\0';
630
				ucs4_str1 = g_utf8_to_ucs4_fast(sLowerCheckWord, -1,NULL);
631
				g_free(sLowerCheckWord);
632
                iDistance = oEditDistance.CalEditDistance(ucs4_str1,ucs4_str2,iMaxDistance);				
633
				g_free(ucs4_str1);								
634
                if ( iDistance < iMaxDistance && iDistance < ucs4_str2_len) // when ucs4_str2_len=1,2 we need less fuzzy.
635
                {
636
                    Found = true;
637
                    gboolean bAlreadyInList = false;
638
                    int iMaxDistanceAt=0;
639
                    for (int j=0;j<MAX_FUZZY_MATCH_ITEM;j++)
640
                    {
641
                      	if ( oFuzzystruct[j].pMatchWord && strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 )   //already in list
642
						{
643
                            bAlreadyInList = true;
644
							break;
645
						}
646
						//find the position,it will certainly be found (include the first time) as iMaxDistance is set by last time.
647
                        if ( oFuzzystruct[j].iMatchWordDistance == iMaxDistance )
648
						{
649
                            iMaxDistanceAt = j;
650
						}
651
                    }
652
                    if (!bAlreadyInList )
653
                    {
654
						if (oFuzzystruct[iMaxDistanceAt].pMatchWord)
655
							g_free(oFuzzystruct[iMaxDistanceAt].pMatchWord);
656
                        oFuzzystruct[iMaxDistanceAt].pMatchWord = g_strdup(sCheck);
657
                        oFuzzystruct[iMaxDistanceAt].iMatchWordDistance = iDistance;
658
                        // calc new iMaxDistance
659
                        iMaxDistance = iDistance;
660
                        for (int j=0;j<MAX_FUZZY_MATCH_ITEM;j++)
661
                        {
662
                            if ( oFuzzystruct[j].iMatchWordDistance > iMaxDistance )
663
                                iMaxDistance = oFuzzystruct[j].iMatchWordDistance;
664
                        } // calc new iMaxDistance
665
                    }   // add to list
666
                }   // find one
667
            }   // each word
668
        }   // ok for search
669
    }   // each lib
670
    g_free(ucs4_str2);
671
	
571
	
672
    // show
572
    // show
673
    oMidWin.oIndexWin.oListWin.Clear();
573
    oMidWin.oIndexWin.oListWin.Clear();
674
    if (Found) {		
574
    if (Found) {		
675
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_FUZZY_LIST;
575
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_FUZZY_LIST;
676
        // sort with distance
677
        qsort(oFuzzystruct,MAX_FUZZY_MATCH_ITEM,sizeof(Fuzzystruct),FuzzystructCompare);
678
576
679
		//SimpleLookupToTextWin(oFuzzystruct[0].pMatchWord,NULL);
577
		//SimpleLookupToTextWin(oFuzzystruct[0].pMatchWord,NULL);
680
		SimpleLookupToTextWin(oFuzzystruct[0].pMatchWord, iCurrentIndex, false); // so iCurrentIndex is refreshed.
578
		SimpleLookupToTextWin(oFuzzystruct[0].pMatchWord, iCurrentIndex, false); // so iCurrentIndex is refreshed.
681
579
682
        for (int i=0;i<MAX_FUZZY_MATCH_ITEM;i++) {
580
    for (int i=0; i<MAX_FUZZY_MATCH_ITEM; i++) {
683
            if ( oFuzzystruct[i].pMatchWord ) {
581
      if (oFuzzystruct[i].pMatchWord) {
684
                oMidWin.oIndexWin.oListWin.InsertLast(oFuzzystruct[i].pMatchWord);
582
                oMidWin.oIndexWin.oListWin.InsertLast(oFuzzystruct[i].pMatchWord);
685
				g_free(oFuzzystruct[i].pMatchWord);
583
				g_free(oFuzzystruct[i].pMatchWord);
686
                //printf("fuzzy %s,%d\n",oFuzzystruct[i].pMatchWord,oFuzzystruct[i].iMatchWordDistance);
584
                //printf("fuzzy %s,%d\n",oFuzzystruct[i].pMatchWord,oFuzzystruct[i].iMatchWordDistance);
687
            }
585
      } else
688
			else {
689
				break;
586
				break;
690
			}
587
			}
691
        }
692
		oMidWin.oIndexWin.oListWin.ReScroll();
588
		oMidWin.oIndexWin.oListWin.ReScroll();
693
    }
589
  } else {
694
    else {
695
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_EMPTY;
590
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_EMPTY;
696
        ShowNotFoundToTextWin(sWord,_("There are too many spelling errors :-("), TEXT_WIN_FUZZY_NOT_FOUND);
591
        ShowNotFoundToTextWin(sWord,_("There are too many spelling errors :-("), TEXT_WIN_FUZZY_NOT_FOUND);
697
	}	
592
	}	
698
	gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor);
593
  gdk_window_set_cursor(window->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor);
699
}
594
}
700
595
701
void AppCore::LookupWithFuzzyToFloatWin(const gchar *sWord)
596
void AppCore::LookupWithFuzzyToFloatWin(const gchar *sWord)
Lines 705-796 Link Here
705
    
600
    
706
	gdk_window_set_cursor (oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor);
601
	gdk_window_set_cursor (oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor);
707
	    
602
	    
708
    struct Fuzzystruct oFuzzystruct[MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM];
603
  Libs::Fuzzystruct oFuzzystruct[MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM];
709
    for (int i=0;i<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;i++)
710
    {
711
        oFuzzystruct[i].pMatchWord = NULL;
712
        oFuzzystruct[i].iMatchWordDistance = iMaxFuzzyDistance;
713
    }
714
    int iMaxDistance = iMaxFuzzyDistance;
715
    int iDistance;
716
    gboolean Found = false;
717
    class EditDistance oEditDistance;
718
604
719
	glong iCheckWordLen;
605
  bool Found = oLibs.LookupWithFuzzy(sWord, oFuzzystruct, 
720
	int sCheckLen;
606
				     MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM,
721
	const char * sCheck;
607
				     ProcessGtkEvent);
722
	gunichar *ucs4_str1,*ucs4_str2;
608
	
723
	glong ucs4_str2_len;    
609
  if (Found) {
724
    gchar *sLowerCheckWord;
725
	gchar *sLowerWord = g_utf8_strdown(sWord, -1);
726
	ucs4_str2 = g_utf8_to_ucs4_fast(sLowerWord, -1,&ucs4_str2_len);
727
	g_free(sLowerWord);
728
    for(int iLib=0;iLib<oLibs.total_libs();iLib++)
729
    {
730
        ProcessGtkEvent();
731
        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...
732
        {
733
            const int iwords = oLibs.iLength(iLib);
734
            for (int index=0;index<iwords;index++)
735
            {
736
                //ProcessGtkEvent(); // too slow if here
737
                sCheck = oLibs.poGetWord(index,iLib);
738
                // tolower and skip too long or too short words
739
				sCheckLen = strlen(sCheck);
740
                iCheckWordLen = g_utf8_strlen(sCheck, sCheckLen);
741
                if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || ucs4_str2_len-iCheckWordLen>=iMaxDistance )
742
                    continue;
743
				sLowerCheckWord = g_utf8_strdown(sCheck, sCheckLen);
744
				if (iCheckWordLen > ucs4_str2_len)
745
					(*g_utf8_offset_to_pointer(sLowerCheckWord, ucs4_str2_len)) = '\0';
746
				ucs4_str1 = g_utf8_to_ucs4_fast(sLowerCheckWord, -1,NULL);
747
				g_free(sLowerCheckWord);
748
                iDistance = oEditDistance.CalEditDistance(ucs4_str1,ucs4_str2,iMaxDistance);				
749
				g_free(ucs4_str1);				
750
                if ( iDistance < iMaxDistance && iDistance < ucs4_str2_len) // when ucs4_str2_len=1,2 we need less fuzzy.
751
                {
752
                    Found = true;
753
                    gboolean bAlreadyInList = false;
754
                    int iMaxDistanceAt=0;
755
                    for (int j=0;j<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;j++)
756
                    {
757
                      	if ( oFuzzystruct[j].pMatchWord && strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 )   //already in list
758
						{
759
                            bAlreadyInList = true;
760
							break;
761
						}
762
                        if ( oFuzzystruct[j].iMatchWordDistance == iMaxDistance )
763
						{
764
                            iMaxDistanceAt = j;
765
						}
766
                    }
767
                    if (!bAlreadyInList )
768
                    {
769
						if (oFuzzystruct[iMaxDistanceAt].pMatchWord)
770
							g_free(oFuzzystruct[iMaxDistanceAt].pMatchWord);
771
                        oFuzzystruct[iMaxDistanceAt].pMatchWord = g_strdup(sCheck);
772
                        oFuzzystruct[iMaxDistanceAt].iMatchWordDistance = iDistance;
773
                        // calc new iMaxDistance
774
                        iMaxDistance = iDistance;
775
                        for (int j=0;j<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;j++)
776
                        {
777
                            if ( oFuzzystruct[j].iMatchWordDistance > iMaxDistance )
778
                                iMaxDistance = oFuzzystruct[j].iMatchWordDistance;
779
                        } // calc new iMaxDistance
780
                    }   // add to list
781
                }   // find one
782
            }   // each word
783
        }   // ok for search
784
    }   // each lib
785
    g_free(ucs4_str2);
786
	
610
	
787
    if (Found)
788
    {
789
        // sort with distance
790
        qsort(oFuzzystruct,MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM,sizeof(Fuzzystruct),FuzzystructCompare);
791
		int i,count=0;
611
		int i,count=0;
792
        for (i=0;i<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;i++)
612
    for (i=0;i<MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM;i++) {
793
        {
794
            if (oFuzzystruct[i].pMatchWord)
613
            if (oFuzzystruct[i].pMatchWord)
795
				count++;
614
				count++;
796
			else
615
			else
Lines 802-834 Link Here
802
		gchar **ppWord;
621
		gchar **ppWord;
803
		gchar **ppWordData;
622
		gchar **ppWordData;
804
		glong iRetIndex;
623
		glong iRetIndex;
805
		for (i=0;i<count;i++)
624
    for (i=0;i<count;i++) {
806
		{
625
      bool bFound = false;
807
    		gboolean bFound = false;
808
			ppWord = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());
626
			ppWord = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());
809
			ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());    		
627
			ppWordData = (gchar **)g_malloc(sizeof(gchar *) * oLibs.total_libs());    		
810
	    
628
	    
811
			ppOriginWord[i] = oFuzzystruct[i].pMatchWord;
629
			ppOriginWord[i] = oFuzzystruct[i].pMatchWord;
812
    		for (int iLib=0;iLib<oLibs.total_libs();iLib++)
630
      for (int iLib=0; iLib<oLibs.total_libs(); iLib++)	{
813
    		{
631
	if (oLibs.SimpleLookupWord(oFuzzystruct[i].pMatchWord, iRetIndex,iLib))	{
814
        		if (oLibs.SimpleLookupWord(oFuzzystruct[i].pMatchWord, iRetIndex,iLib))
815
        		{
816
					ppWord[iLib] = oLibs.poGetWord(iRetIndex,iLib);
632
					ppWord[iLib] = oLibs.poGetWord(iRetIndex,iLib);
817
					ppWordData[iLib] = oLibs.poGetWordData(iRetIndex,iLib);
633
					ppWordData[iLib] = oLibs.poGetWordData(iRetIndex,iLib);
818
            		bFound = true;
634
            		bFound = true;
819
        		}
635
	} else {
820
        		else {
821
					ppWord[iLib] = NULL;
636
					ppWord[iLib] = NULL;
822
            		ppWordData[iLib] = NULL;
637
            		ppWordData[iLib] = NULL;
823
				}
638
				}
824
    		}
639
    		}
825
    		if (bFound==true) // it is certainly be true.
640
      if (bFound) {// it is certainly be true.			
826
			{
827
				pppWord[i]=ppWord;
641
				pppWord[i]=ppWord;
828
				pppWordData[i]=ppWordData;
642
				pppWordData[i]=ppWordData;
829
			}
643
      }	else {
830
			else
831
			{
832
				g_free(ppWord);
644
				g_free(ppWord);
833
				pppWord[i]=NULL;
645
				pppWord[i]=NULL;
834
				g_free(ppWordData);
646
				g_free(ppWordData);
Lines 836-843 Link Here
836
			}			
648
			}			
837
		}
649
		}
838
		ShowDatasToFloatWin(pppWord, pppWordData, ppOriginWord, count,sWord);
650
		ShowDatasToFloatWin(pppWord, pppWordData, ppOriginWord, count,sWord);
839
		for (i=0;i<count;i++)
651
    for (i=0; i<count; i++) {
840
		{
841
			if (pppWord[i])
652
			if (pppWord[i])
842
				g_free(pppWord[i]);
653
				g_free(pppWord[i]);
843
			if (pppWordData[i])
654
			if (pppWordData[i])
Lines 849-906 Link Here
849
		
660
		
850
		for (i=0;i<count;i++)
661
		for (i=0;i<count;i++)
851
			g_free(oFuzzystruct[i].pMatchWord);
662
			g_free(oFuzzystruct[i].pMatchWord);
852
    }
663
  } else
853
    else
854
		ShowNotFoundToFloatWin(sWord,_("Fuzzy query failed, too :-("), true);
664
		ShowNotFoundToFloatWin(sWord,_("Fuzzy query failed, too :-("), true);
855
	gdk_window_set_cursor (oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor);
665
  gdk_window_set_cursor(oFloatWin.FloatWindow->window, gpAppFrame->oAppSkin.stardict.normal_cursor.cursor);
856
}
857
858
int AppCore::MatchWordCompare(const void * s1, const void * s2)
859
{
860
	const gchar **o1 = (const gchar **)s1;
861
	const gchar **o2 = (const gchar **)s2;
862
	return stardict_strcmp(*o1,*o2);
863
}
666
}
864
667
865
void AppCore::LookupWithRuleToMainWin(const gchar *word)
668
void AppCore::LookupWithRuleToMainWin(const gchar *word)
866
{
669
{
867
	gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor);
670
	gdk_window_set_cursor (window->window, gpAppFrame->oAppSkin.stardict.watch_cursor.cursor);
868
	
671
	
869
    glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1];
870
    int iMatchCount = 0;
871
	gchar **ppMatchWord = (gchar **)g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * oLibs.total_libs());
672
	gchar **ppMatchWord = (gchar **)g_malloc(sizeof(gchar *) * (MAX_MATCH_ITEM_PER_LIB) * oLibs.total_libs());
872
    GPatternSpec *pspec = g_pattern_spec_new(word);
673
  gint iMatchCount=oLibs.LookupWithRule(word, ProcessGtkEvent, ppMatchWord);
873
	
874
    for(int iLib=0;iLib<oLibs.total_libs();iLib++)
875
    {
876
        //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.
877
		if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1,iLib))
878
        {
879
            ProcessGtkEvent();
880
            for(int i=0;aiIndex[i]!=-1;i++)
881
            {
882
                gchar * sMatchWord = oLibs.poGetWord(aiIndex[i],iLib);
883
                gboolean bAlreadyInList = false;
884
                for (int j=0;j<iMatchCount;j++)
885
                {
886
                    if ( strcmp(ppMatchWord[j],sMatchWord) == 0 )   //already in list
887
                    {
888
                        bAlreadyInList = true;
889
                        break;
890
                    }
891
                }
892
                if ( !bAlreadyInList)
893
                    ppMatchWord[iMatchCount++] = g_strdup(sMatchWord);
894
            }
895
        }
896
    }
897
	g_pattern_spec_free(pspec);
898
	oMidWin.oIndexWin.oListWin.Clear();
674
	oMidWin.oIndexWin.oListWin.Clear();
899
    if (iMatchCount)
675
  if (iMatchCount) {		
900
    {		
901
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_PATTERN_LIST;
676
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_PATTERN_LIST;
902
		qsort(ppMatchWord,iMatchCount,sizeof(gchar *),MatchWordCompare); // sort it.
677
903
        for(int i=0;i<iMatchCount;i++)
678
    for(gint i=0; i<iMatchCount; i++)
904
            oMidWin.oIndexWin.oListWin.InsertLast(ppMatchWord[i]);
679
            oMidWin.oIndexWin.oListWin.InsertLast(ppMatchWord[i]);
905
        //memset(iCurrentIndex,'\0',sizeof(iCurrentIndex));    // iCurrentIndex is ineffective now.
680
        //memset(iCurrentIndex,'\0',sizeof(iCurrentIndex));    // iCurrentIndex is ineffective now.
906
        
681
        
Lines 908-918 Link Here
908
        //SimpleLookupToTextWin(ppMatchWord[0],NULL);
683
        //SimpleLookupToTextWin(ppMatchWord[0],NULL);
909
		SimpleLookupToTextWin(ppMatchWord[0], iCurrentIndex, false); // so iCurrentIndex is refreshed.
684
		SimpleLookupToTextWin(ppMatchWord[0], iCurrentIndex, false); // so iCurrentIndex is refreshed.
910
		oMidWin.oIndexWin.oListWin.ReScroll();
685
		oMidWin.oIndexWin.oListWin.ReScroll();
911
		for(int i=0;i<iMatchCount;i++)
686
    for(gint i=0; i<iMatchCount; i++)
912
			g_free(ppMatchWord[i]);
687
			g_free(ppMatchWord[i]);
913
    }    
688
  } else {
914
    else
915
    {
916
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_EMPTY;
689
		oMidWin.oIndexWin.oListWin.list_word_type = LIST_WIN_EMPTY;
917
        ShowNotFoundToTextWin(word,_("Found no words matching this pattern!"), TEXT_WIN_PATTERN_NOT_FOUND);
690
        ShowNotFoundToTextWin(word,_("Found no words matching this pattern!"), TEXT_WIN_PATTERN_NOT_FOUND);
918
    }	
691
    }	
Lines 1156-1166 Link Here
1156
	gtk_widget_destroy(window);
929
	gtk_widget_destroy(window);
1157
}
930
}
1158
931
1159
void AppCore::ProcessGtkEvent()
1160
{
1161
	poAppFrame->ProcessGtkEvent();
1162
}
1163
1164
932
1165
/***************************************************/
933
/***************************************************/
1166
AppFrame::AppFrame():oAppCore(this)
934
AppFrame::AppFrame():oAppCore(this)
Lines 1193-1206 Link Here
1193
	gtk_main();
961
	gtk_main();
1194
}
962
}
1195
963
1196
void AppFrame::ProcessGtkEvent()
1197
{
1198
	while (gtk_events_pending())
1199
	{
1200
		gtk_main_iteration();
1201
	}
1202
}
1203
1204
void AppFrame::Quit()
964
void AppFrame::Quit()
1205
{   
965
{   
1206
  gboolean maximized=conf->get_maximized();
966
  gboolean maximized=conf->get_maximized();
Lines 1231-1246 Link Here
1231
    gtk_main_quit ();
991
    gtk_main_quit ();
1232
}
992
}
1233
993
1234
gint stardict_strcmp(const gchar *s1, const gchar *s2)
1235
{
1236
	gint a;
1237
	a = g_ascii_strcasecmp(s1, s2);
1238
	if (a == 0)
1239
		return strcmp(s1, s2);
1240
	else
1241
		return a;
1242
}
1243
1244
gboolean bContainRule(const char* sWord)
994
gboolean bContainRule(const char* sWord)
1245
{
995
{
1246
    int i;
996
    int i;
Lines 1255-1275 Link Here
1255
    return(false);
1005
    return(false);
1256
}
1006
}
1257
1007
1258
gboolean bIsPureEnglish(const gchar *str) // i think this should work even when it is UTF8 string :).
1259
{
1260
    int i;
1261
    for(i=0;str[i]!=0;i++) {
1262
	//if(str[i]<0)
1263
        //if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK.
1264
	// Better use isascii() but not str[i]<0 while char is default unsigned in arm
1265
	if (!isascii(str[i]))
1266
        {
1267
            return(false);
1268
        }
1269
    }
1270
    return(true);	
1271
}
1272
1273
gchar* GetPureEnglishAlpha(gchar *str)
1008
gchar* GetPureEnglishAlpha(gchar *str)
1274
{
1009
{
1275
	while (*str && (!((*str >= 'a' && *str <='z')||(*str >= 'A' && *str <='Z'))))
1010
	while (*str && (!((*str >= 'a' && *str <='z')||(*str >= 'A' && *str <='Z'))))
(-)stardict-cur-accepted/src/stardict.h (-16 / +2 lines)
Lines 31-42 Link Here
31
31
32
//notice!!! when you change these DEFAULT const value,remember that you'd better change data/stardict.schemas.in too!
32
//notice!!! when you change these DEFAULT const value,remember that you'd better change data/stardict.schemas.in too!
33
33
34
const int MAX_MATCH_ITEM_PER_LIB=100;
35
const int MAX_FUZZY_MATCH_ITEM=100;
34
const int MAX_FUZZY_MATCH_ITEM=100;
36
const int MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM=5;
35
const int MAX_FLOAT_WINDOW_FUZZY_MATCH_ITEM=5;
37
36
38
const int LIST_WIN_ROW_NUM = 30; //how many words show in the list win.
37
const int LIST_WIN_ROW_NUM = 30; //how many words show in the list win.
39
const int MAX_FUZZY_DISTANCE= 3; // at most MAX_FUZZY_DISTANCE-1 differences allowed when find similar words
40
38
41
39
42
class AppCore
40
class AppCore
Lines 46-59 Link Here
46
44
47
	PrefsDlg *prefs_dlg;
45
	PrefsDlg *prefs_dlg;
48
	DictManageDlg *dict_manage_dlg;
46
	DictManageDlg *dict_manage_dlg;
49
    // struct
50
    struct Fuzzystruct {
51
        char * pMatchWord;
52
        int iMatchWordDistance;
53
    };
54
    int iMaxFuzzyDistance;	
55
47
56
	static int FuzzystructCompare(const void * s1, const void * s2);
57
	static int MatchWordCompare(const void * s1, const void * s2);
48
	static int MatchWordCompare(const void * s1, const void * s2);
58
	static gboolean on_delete_event(GtkWidget * window, GdkEvent *event , AppCore *oAppCore);
49
	static gboolean on_delete_event(GtkWidget * window, GdkEvent *event , AppCore *oAppCore);
59
	static gboolean on_window_state_event(GtkWidget * window, GdkEventWindowState *event , AppCore *oAppCore);
50
	static gboolean on_window_state_event(GtkWidget * window, GdkEventWindowState *event , AppCore *oAppCore);
Lines 81-91 Link Here
81
	AppCore(AppFrame* pAppFrame);
72
	AppCore(AppFrame* pAppFrame);
82
	~AppCore();
73
	~AppCore();
83
	void Create(gchar *queryword);
74
	void Create(gchar *queryword);
84
	void ProcessGtkEvent();
85
    void End();
75
    void End();
86
	void Query(const gchar *word);
76
	void Query(const gchar *word);
87
	gboolean SimpleLookupToFloat(const gchar* sWord,gboolean bShowIfNotFound);
77
	bool SimpleLookupToFloat(const gchar* sWord, bool bShowIfNotFound);
88
	gboolean SimpleLookupToTextWin(const gchar* sWord,glong* piIndex, gboolean piIndexValid = false, gboolean bTryMoreIfNotFound = false);
78
	bool SimpleLookupToTextWin(const gchar* sWord,glong* piIndex, bool piIndexValid = false, bool bTryMoreIfNotFound = false);
89
	void LookupWithFuzzyToMainWin(const gchar* word);
79
	void LookupWithFuzzyToMainWin(const gchar* word);
90
	void LookupWithFuzzyToFloatWin(const gchar * word);
80
	void LookupWithFuzzyToFloatWin(const gchar * word);
91
	void LookupWithRuleToMainWin(const gchar* word);
81
	void LookupWithRuleToMainWin(const gchar* word);
Lines 122-128 Link Here
122
	AppFrame();
112
	AppFrame();
123
	~AppFrame();
113
	~AppFrame();
124
	void Init(gchar *queryword);
114
	void Init(gchar *queryword);
125
	void ProcessGtkEvent();
126
	void Quit();
115
	void Quit();
127
};
116
};
128
117
Lines 131-142 Link Here
131
extern gchar stardict_data_dir[256];
120
extern gchar stardict_data_dir[256];
132
#endif
121
#endif
133
122
134
extern gint stardict_strcmp(const gchar *s1, const gchar *s2);
135
extern gboolean bContainRule(const char* sWord);
123
extern gboolean bContainRule(const char* sWord);
136
extern gboolean bIsPureEnglish(const gchar *str);
137
extern gchar* GetPureEnglishAlpha(gchar *str);
124
extern gchar* GetPureEnglishAlpha(gchar *str);
138
extern gchar* GetHeadWord(gchar *str);
125
extern gchar* GetHeadWord(gchar *str);
139
140
extern gboolean stardict_on_enter_notify (GtkWidget * widget, GdkEventCrossing * event, gpointer data);
126
extern gboolean stardict_on_enter_notify (GtkWidget * widget, GdkEventCrossing * event, gpointer data);
141
127
142
#endif
128
#endif
(-)stardict-cur-accepted/src/utils.cpp (+6 lines)
Lines 54-56 Link Here
54
  gnome_url_show(url, NULL);
54
  gnome_url_show(url, NULL);
55
#endif
55
#endif
56
}
56
}
57
58
void ProcessGtkEvent(void)
59
{
60
  while (gtk_events_pending())
61
    gtk_main_iteration();
62
}
(-)stardict-cur-accepted/src/utils.h (+1 lines)
Lines 4-8 Link Here
4
extern void play_wav_file(const gchar *filename);
4
extern void play_wav_file(const gchar *filename);
5
extern void show_help(const gchar *section);
5
extern void show_help(const gchar *section);
6
extern void show_url(const gchar *url);
6
extern void show_url(const gchar *url);
7
extern void ProcessGtkEvent(void);
7
8
8
#endif/*UTILS_H*/
9
#endif/*UTILS_H*/

Return to bug 86379