remove not used code, use glib wrappers where possible

This commit is contained in:
Evgeniy Dushistov
2013-07-07 20:12:03 +00:00
parent d05de97521
commit 5f8d2cb174
7 changed files with 202 additions and 230 deletions

View File

@@ -3,11 +3,11 @@
* Copyright (C) 2003-2003 Hu Zheng <huzheng_001@163.com> * Copyright (C) 2003-2003 Hu Zheng <huzheng_001@163.com>
* This file is a modify version of dictd-1.9.7's data.c * This file is a modify version of dictd-1.9.7's data.c
* *
* data.c -- * data.c --
* Created: Tue Jul 16 12:45:41 1996 by faith@dict.org * Created: Tue Jul 16 12:45:41 1996 by faith@dict.org
* Revised: Sat Mar 30 10:46:06 2002 by faith@dict.org * Revised: Sat Mar 30 10:46:06 2002 by faith@dict.org
* Copyright 1996, 1997, 1998, 2000, 2002 Rickard E. Faith (faith@dict.org) * Copyright 1996, 1997, 1998, 2000, 2002 Rickard E. Faith (faith@dict.org)
* *
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@@ -46,10 +46,10 @@
#define BUFFERSIZE 10240 #define BUFFERSIZE 10240
/* /*
* Output buffer must be greater than or * Output buffer must be greater than or
* equal to 110% of input buffer size, plus * equal to 110% of input buffer size, plus
* 12 bytes. * 12 bytes.
*/ */
#define OUT_BUFFER_SIZE 0xffffL #define OUT_BUFFER_SIZE 0xffffL
@@ -113,7 +113,7 @@
#define DICT_DZIP 3 #define DICT_DZIP 3
int dictData::read_header(const std::string &fname, int computeCRC) int DictData::read_header(const std::string &fname, int computeCRC)
{ {
FILE *str; FILE *str;
int id1, id2, si1, si2; int id1, id2, si1, si2;
@@ -126,18 +126,19 @@ int dictData::read_header(const std::string &fname, int computeCRC)
unsigned long crc = crc32( 0L, Z_NULL, 0 ); unsigned long crc = crc32( 0L, Z_NULL, 0 );
int count; int count;
unsigned long offset; unsigned long offset;
if (!(str = fopen(fname.c_str(), "rb"))) { if (!(str = fopen(fname.c_str(), "rb"))) {
//err_fatal_errno( __FUNCTION__, //err_fatal_errno( __FUNCTION__,
// "Cannot open data file \"%s\" for read\n", filename ); // "Cannot open data file \"%s\" for read\n", filename );
} return -1;
}
this->headerLength = GZ_XLEN - 1; this->headerLength = GZ_XLEN - 1;
this->type = DICT_UNKNOWN; this->type = DICT_UNKNOWN;
id1 = getc( str ); id1 = getc( str );
id2 = getc( str ); id2 = getc( str );
if (id1 != GZ_MAGIC1 || id2 != GZ_MAGIC2) { if (id1 != GZ_MAGIC1 || id2 != GZ_MAGIC2) {
this->type = DICT_TEXT; this->type = DICT_TEXT;
fstat( fileno( str ), &sb ); fstat( fileno( str ), &sb );
@@ -157,7 +158,7 @@ int dictData::read_header(const std::string &fname, int computeCRC)
return 0; return 0;
} }
this->type = DICT_GZIP; this->type = DICT_GZIP;
this->method = getc( str ); this->method = getc( str );
this->flags = getc( str ); this->flags = getc( str );
this->mtime = getc( str ) << 0; this->mtime = getc( str ) << 0;
@@ -166,31 +167,31 @@ int dictData::read_header(const std::string &fname, int computeCRC)
this->mtime |= getc( str ) << 24; this->mtime |= getc( str ) << 24;
this->extraFlags = getc( str ); this->extraFlags = getc( str );
this->os = getc( str ); this->os = getc( str );
if (this->flags & GZ_FEXTRA) { if (this->flags & GZ_FEXTRA) {
extraLength = getc( str ) << 0; extraLength = getc( str ) << 0;
extraLength |= getc( str ) << 8; extraLength |= getc( str ) << 8;
this->headerLength += extraLength + 2; this->headerLength += extraLength + 2;
si1 = getc( str ); si1 = getc( str );
si2 = getc( str ); si2 = getc( str );
if (si1 == GZ_RND_S1 || si2 == GZ_RND_S2) { if (si1 == GZ_RND_S1 || si2 == GZ_RND_S2) {
subLength = getc( str ) << 0; subLength = getc( str ) << 0;
subLength |= getc( str ) << 8; subLength |= getc( str ) << 8;
this->version = getc( str ) << 0; this->version = getc( str ) << 0;
this->version |= getc( str ) << 8; this->version |= getc( str ) << 8;
if (this->version != 1) { if (this->version != 1) {
//err_internal( __FUNCTION__, //err_internal( __FUNCTION__,
// "dzip header version %d not supported\n", // "dzip header version %d not supported\n",
// this->version ); // this->version );
} }
this->chunkLength = getc( str ) << 0; this->chunkLength = getc( str ) << 0;
this->chunkLength |= getc( str ) << 8; this->chunkLength |= getc( str ) << 8;
this->chunkCount = getc( str ) << 0; this->chunkCount = getc( str ) << 0;
this->chunkCount |= getc( str ) << 8; this->chunkCount |= getc( str ) << 8;
if (this->chunkCount <= 0) { if (this->chunkCount <= 0) {
fclose( str ); fclose( str );
return 5; return 5;
@@ -206,19 +207,19 @@ int dictData::read_header(const std::string &fname, int computeCRC)
fseek( str, this->headerLength, SEEK_SET ); fseek( str, this->headerLength, SEEK_SET );
} }
} }
if (this->flags & GZ_FNAME) { /* FIXME! Add checking against header len */ if (this->flags & GZ_FNAME) { /* FIXME! Add checking against header len */
pt = buffer; pt = buffer;
while ((c = getc( str )) && c != EOF) while ((c = getc( str )) && c != EOF)
*pt++ = c; *pt++ = c;
*pt = '\0'; *pt = '\0';
this->origFilename = buffer; this->origFilename = buffer;
this->headerLength += this->origFilename.length() + 1; this->headerLength += this->origFilename.length() + 1;
} else { } else {
this->origFilename = ""; this->origFilename = "";
} }
if (this->flags & GZ_COMMENT) { /* FIXME! Add checking for header len */ if (this->flags & GZ_COMMENT) { /* FIXME! Add checking for header len */
pt = buffer; pt = buffer;
while ((c = getc( str )) && c != EOF) while ((c = getc( str )) && c != EOF)
@@ -267,10 +268,9 @@ int dictData::read_header(const std::string &fname, int computeCRC)
return 0; return 0;
} }
bool dictData::open(const std::string& fname, int computeCRC) bool DictData::open(const std::string& fname, int computeCRC)
{ {
struct stat sb; struct stat sb;
int j;
int fd; int fd;
this->initialized = 0; this->initialized = 0;
@@ -280,13 +280,13 @@ bool dictData::open(const std::string& fname, int computeCRC)
// "%s is not a regular file -- ignoring\n", fname ); // "%s is not a regular file -- ignoring\n", fname );
return false; return false;
} }
if (read_header(fname, computeCRC)) { if (read_header(fname, computeCRC)) {
//err_fatal( __FUNCTION__, //err_fatal( __FUNCTION__,
// "\"%s\" not in text or dzip format\n", fname ); // "\"%s\" not in text or dzip format\n", fname );
return false; return false;
} }
if ((fd = ::open(fname.c_str(), O_RDONLY )) < 0) { if ((fd = ::open(fname.c_str(), O_RDONLY )) < 0) {
//err_fatal_errno( __FUNCTION__, //err_fatal_errno( __FUNCTION__,
// "Cannot open data file \"%s\"\n", fname ); // "Cannot open data file \"%s\"\n", fname );
@@ -299,27 +299,25 @@ bool dictData::open(const std::string& fname, int computeCRC)
} }
this->size = sb.st_size; this->size = sb.st_size;
::close(fd); ::close(fd);
if (!mapfile.open(fname.c_str(), size)) if (!mapfile.open(fname.c_str(), size))
return false; return false;
this->start=mapfile.begin(); this->start=mapfile.begin();
this->end = this->start + this->size; this->end = this->start + this->size;
for (j = 0; j < DICT_CACHE_SIZE; j++) { for (size_t j = 0; j < DICT_CACHE_SIZE; j++) {
cache[j].chunk = -1; cache[j].chunk = -1;
cache[j].stamp = -1; cache[j].stamp = -1;
cache[j].inBuffer = nullptr; cache[j].inBuffer = nullptr;
cache[j].count = 0; cache[j].count = 0;
} }
return true; return true;
} }
void dictData::close() void DictData::close()
{ {
int i;
if (this->chunks) if (this->chunks)
free(this->chunks); free(this->chunks);
if (this->offsets) if (this->offsets)
@@ -333,13 +331,13 @@ void dictData::close()
} }
} }
for (i = 0; i < DICT_CACHE_SIZE; ++i){ for (size_t i = 0; i < DICT_CACHE_SIZE; ++i){
if (this -> cache [i].inBuffer) if (this -> cache [i].inBuffer)
free (this -> cache [i].inBuffer); free (this -> cache [i].inBuffer);
} }
} }
void dictData::read(char *buffer, unsigned long start, unsigned long size) void DictData::read(char *buffer, unsigned long start, unsigned long size)
{ {
char *pt; char *pt;
unsigned long end; unsigned long end;
@@ -348,19 +346,19 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size)
char outBuffer[OUT_BUFFER_SIZE]; char outBuffer[OUT_BUFFER_SIZE];
int firstChunk, lastChunk; int firstChunk, lastChunk;
int firstOffset, lastOffset; int firstOffset, lastOffset;
int i, j; int i;
int found, target, lastStamp; int found, target, lastStamp;
static int stamp = 0; static int stamp = 0;
end = start + size; end = start + size;
//buffer = malloc( size + 1 ); //buffer = malloc( size + 1 );
//PRINTF(DBG_UNZIP, //PRINTF(DBG_UNZIP,
// ("dict_data_read( %p, %lu, %lu )\n", // ("dict_data_read( %p, %lu, %lu )\n",
//h, start, size )); //h, start, size ));
switch (this->type) { switch (this->type) {
case DICT_GZIP: case DICT_GZIP:
//err_fatal( __FUNCTION__, //err_fatal( __FUNCTION__,
@@ -398,12 +396,12 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size)
//" lastChunk = %d, lastOffset = %d\n", //" lastChunk = %d, lastOffset = %d\n",
//start, end, firstChunk, firstOffset, lastChunk, lastOffset )); //start, end, firstChunk, firstOffset, lastChunk, lastOffset ));
for (pt = buffer, i = firstChunk; i <= lastChunk; i++) { for (pt = buffer, i = firstChunk; i <= lastChunk; i++) {
/* Access cache */ /* Access cache */
found = 0; found = 0;
target = 0; target = 0;
lastStamp = INT_MAX; lastStamp = INT_MAX;
for (j = 0; j < DICT_CACHE_SIZE; j++) { for (size_t j = 0; j < DICT_CACHE_SIZE; j++) {
#if USE_CACHE #if USE_CACHE
if (this->cache[j].chunk == i) { if (this->cache[j].chunk == i) {
found = 1; found = 1;
@@ -416,7 +414,7 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size)
target = j; target = j;
} }
} }
this->cache[target].stamp = ++stamp; this->cache[target].stamp = ++stamp;
if (found) { if (found) {
count = this->cache[target].count; count = this->cache[target].count;
@@ -426,14 +424,14 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size)
if (!this->cache[target].inBuffer) if (!this->cache[target].inBuffer)
this->cache[target].inBuffer = (char *)malloc( IN_BUFFER_SIZE ); this->cache[target].inBuffer = (char *)malloc( IN_BUFFER_SIZE );
inBuffer = this->cache[target].inBuffer; inBuffer = this->cache[target].inBuffer;
if (this->chunks[i] >= OUT_BUFFER_SIZE ) { if (this->chunks[i] >= OUT_BUFFER_SIZE ) {
//err_internal( __FUNCTION__, //err_internal( __FUNCTION__,
// "this->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n", // "this->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n",
// i, this->chunks[i], OUT_BUFFER_SIZE ); // i, this->chunks[i], OUT_BUFFER_SIZE );
} }
memcpy( outBuffer, this->start + this->offsets[i], this->chunks[i] ); memcpy( outBuffer, this->start + this->offsets[i], this->chunks[i] );
this->zStream.next_in = (Bytef *)outBuffer; this->zStream.next_in = (Bytef *)outBuffer;
this->zStream.avail_in = this->chunks[i]; this->zStream.avail_in = this->chunks[i];
this->zStream.next_out = (Bytef *)inBuffer; this->zStream.next_out = (Bytef *)inBuffer;
@@ -446,12 +444,12 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size)
// "inflate did not flush (%d pending, %d avail)\n", // "inflate did not flush (%d pending, %d avail)\n",
// this->zStream.avail_in, this->zStream.avail_out ); // this->zStream.avail_in, this->zStream.avail_out );
} }
count = IN_BUFFER_SIZE - this->zStream.avail_out; count = IN_BUFFER_SIZE - this->zStream.avail_out;
this->cache[target].count = count; this->cache[target].count = count;
} }
if (i == firstChunk) { if (i == firstChunk) {
if (i == lastChunk) { if (i == lastChunk) {
memcpy( pt, inBuffer + firstOffset, lastOffset-firstOffset); memcpy( pt, inBuffer + firstOffset, lastOffset-firstOffset);

View File

@@ -6,22 +6,22 @@
#include "mapfile.hpp" #include "mapfile.hpp"
struct DictCache {
#define DICT_CACHE_SIZE 5
struct dictCache {
int chunk; int chunk;
char *inBuffer; char *inBuffer;
int stamp; int stamp;
int count; int count;
}; };
struct dictData { class DictData {
dictData() {} public:
static const size_t DICT_CACHE_SIZE = 5;
DictData() {}
~DictData() { close(); }
bool open(const std::string& filename, int computeCRC); bool open(const std::string& filename, int computeCRC);
void close(); void close();
void read(char *buffer, unsigned long start, unsigned long size); void read(char *buffer, unsigned long start, unsigned long size);
~dictData() { close(); }
private: private:
const char *start; /* start of mmap'd area */ const char *start; /* start of mmap'd area */
const char *end; /* end of mmap'd area */ const char *end; /* end of mmap'd area */
@@ -47,7 +47,7 @@ private:
unsigned long crc; unsigned long crc;
unsigned long length; unsigned long length;
unsigned long compressedLength; unsigned long compressedLength;
dictCache cache[DICT_CACHE_SIZE]; DictCache cache[DICT_CACHE_SIZE];
MapFile mapfile; MapFile mapfile;
int read_header(const std::string &filename, int computeCRC); int read_header(const std::string &filename, int computeCRC);

View File

@@ -304,26 +304,25 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
gsize bytes_read; gsize bytes_read;
gsize bytes_written; gsize bytes_written;
GError *err = nullptr; glib::Error err;
char *str = nullptr; glib::CharStr str;
if (!utf8_input_) if (!utf8_input_)
str = g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, &err); str.reset(g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, get_addr(err)));
else else
str = g_strdup(loc_str); str.reset(g_strdup(loc_str));
if (nullptr == str) { if (nullptr == get_impl(str)) {
fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str); fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str);
fprintf(stderr, "%s\n", err->message); fprintf(stderr, "%s\n", err->message);
g_error_free(err);
return false; return false;
} }
if (str[0]=='\0') if (str[0] == '\0')
return true; return true;
TSearchResultList res_list; TSearchResultList res_list;
switch (analyze_query(str, query)) { switch (analyze_query(get_impl(str), query)) {
case qtFUZZY: case qtFUZZY:
LookupWithFuzzy(query, res_list); LookupWithFuzzy(query, res_list);
break; break;
@@ -331,9 +330,9 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
LookupWithRule(query, res_list); LookupWithRule(query, res_list);
break; break;
case qtSIMPLE: case qtSIMPLE:
SimpleLookup(str, res_list); SimpleLookup(get_impl(str), res_list);
if (res_list.empty()) if (res_list.empty())
LookupWithFuzzy(str, res_list); LookupWithFuzzy(get_impl(str), res_list);
break; break;
case qtDATA: case qtDATA:
LookupData(query, res_list); LookupData(query, res_list);
@@ -367,7 +366,7 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
if (!show_all_results && !force) { if (!show_all_results && !force) {
printf(_("Found %zu items, similar to %s.\n"), res_list.size(), printf(_("Found %zu items, similar to %s.\n"), res_list.size(),
utf8_output_ ? str : utf8_to_locale_ign_err(str).c_str()); utf8_output_ ? get_impl(str) : utf8_to_locale_ign_err(get_impl(str)).c_str());
for (size_t i = 0; i < res_list.size(); ++i) { for (size_t i = 0; i < res_list.size(); ++i) {
const std::string loc_bookname = utf8_to_locale_ign_err(res_list[i].bookname); const std::string loc_bookname = utf8_to_locale_ign_err(res_list[i].bookname);
const std::string loc_def = utf8_to_locale_ign_err(res_list[i].def); const std::string loc_def = utf8_to_locale_ign_err(res_list[i].def);
@@ -398,7 +397,7 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
} else { } else {
sdcv_pager pager(force); sdcv_pager pager(force);
fprintf(pager.get_stream(), _("Found %zu items, similar to %s.\n"), fprintf(pager.get_stream(), _("Found %zu items, similar to %s.\n"),
res_list.size(), utf8_output_ ? str : utf8_to_locale_ign_err(str).c_str()); res_list.size(), utf8_output_ ? get_impl(str) : utf8_to_locale_ign_err(get_impl(str)).c_str());
for (const TSearchResult& search_res : res_list) for (const TSearchResult& search_res : res_list)
print_search_result(pager.get_stream(), search_res); print_search_result(pager.get_stream(), search_res);
} }
@@ -406,11 +405,10 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
} else { } else {
std::string loc_str; std::string loc_str;
if (!utf8_output_) if (!utf8_output_)
loc_str = utf8_to_locale_ign_err(str); loc_str = utf8_to_locale_ign_err(get_impl(str));
printf(_("Nothing similar to %s, sorry :(\n"), utf8_output_ ? str : loc_str.c_str()); printf(_("Nothing similar to %s, sorry :(\n"), utf8_output_ ? get_impl(str) : loc_str.c_str());
} }
g_free(str);
return true; return true;
} }

View File

@@ -16,7 +16,7 @@
#include "stardict_lib.hpp" #include "stardict_lib.hpp"
// Notice: read src/tools/DICTFILE_FORMAT for the dictionary // Notice: read src/tools/DICTFILE_FORMAT for the dictionary
// file's format information! // file's format information!
namespace { namespace {
@@ -31,19 +31,19 @@ namespace {
return( ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' ); return( ch=='A' || ch=='E' || ch=='I' || ch=='O' || ch=='U' );
} }
static bool bIsPureEnglish(const gchar *str) static bool bIsPureEnglish(const gchar *str)
{ {
// i think this should work even when it is UTF8 string :). // i think this should work even when it is UTF8 string :).
for (int i=0; str[i]!=0; i++) for (int i=0; str[i]!=0; i++)
//if(str[i]<0) //if(str[i]<0)
//if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK. //if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK.
// Better use isascii() but not str[i]<0 while char is default unsigned in arm // Better use isascii() but not str[i]<0 while char is default unsigned in arm
if (!isascii(str[i])) if (!isascii(str[i]))
return false; return false;
return true; return true;
} }
static inline gint stardict_strcmp(const gchar *s1, const gchar *s2) static inline gint stardict_strcmp(const gchar *s1, const gchar *s2)
{ {
const gint a = g_ascii_strcasecmp(s1, s2); const gint a = g_ascii_strcasecmp(s1, s2);
if (a == 0) if (a == 0)
@@ -55,7 +55,7 @@ namespace {
static void unicode_strdown(gunichar *str) static void unicode_strdown(gunichar *str)
{ {
while (*str) { while (*str) {
*str=g_unichar_tolower(*str); *str = g_unichar_tolower(*str);
++str; ++str;
} }
} }
@@ -66,33 +66,29 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
bool istreedict) bool istreedict)
{ {
ifo_file_name = ifofilename; ifo_file_name = ifofilename;
gchar *buffer; glib::CharStr buffer;
if (!g_file_get_contents(ifofilename.c_str(), &buffer, nullptr, nullptr)) if (!g_file_get_contents(ifofilename.c_str(), get_addr(buffer), nullptr, nullptr))
return false; return false;
static const char TREEDICT_MAGIC_DATA[] = "StarDict's treedict ifo file"; static const char TREEDICT_MAGIC_DATA[] = "StarDict's treedict ifo file";
static const char DICT_MAGIC_DATA[] = "StarDict's dict ifo file"; static const char DICT_MAGIC_DATA[] = "StarDict's dict ifo file";
const gchar *magic_data = istreedict ? TREEDICT_MAGIC_DATA : DICT_MAGIC_DATA; const gchar *magic_data = istreedict ? TREEDICT_MAGIC_DATA : DICT_MAGIC_DATA;
static const unsigned char utf8_bom[] = { 0xEF, 0xBB, 0xBF, '\0'}; static const unsigned char utf8_bom[] = { 0xEF, 0xBB, 0xBF, '\0'};
if (!g_str_has_prefix( if (!g_str_has_prefix(
g_str_has_prefix(buffer, (const gchar *)(utf8_bom)) ? buffer + 3 : buffer, g_str_has_prefix(get_impl(buffer), (const gchar *)(utf8_bom)) ? get_impl(buffer) + 3 : get_impl(buffer),
magic_data)) { magic_data)) {
g_free(buffer); g_free(buffer);
return false; return false;
} }
gchar *p1,*p2,*p3; gchar *p1 = get_impl(buffer) + strlen(magic_data)-1;
p1 = buffer + strlen(magic_data)-1;
p2 = strstr(p1,"\nwordcount="); gchar *p2 = strstr(p1, "\nwordcount=");
if (!p2) { if (p2 == nullptr)
g_free(buffer); return false;
return false;
} gchar *p3 = strchr(p2 + sizeof("\nwordcount=") - 1, '\n');
p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n');
gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1); gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1);
tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0'; tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0';
wordcount = atol(tmpstr); wordcount = atol(tmpstr);
@@ -100,36 +96,31 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
if (istreedict) { if (istreedict) {
p2 = strstr(p1,"\ntdxfilesize="); p2 = strstr(p1,"\ntdxfilesize=");
if (!p2) { if (p2 == nullptr)
g_free(buffer);
return false; return false;
}
p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n'); p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n');
tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1); tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1);
tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0'; tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0';
index_file_size = atol(tmpstr); index_file_size = atol(tmpstr);
g_free(tmpstr); g_free(tmpstr);
} else { } else {
p2 = strstr(p1,"\nidxfilesize="); p2 = strstr(p1,"\nidxfilesize=");
if (!p2) { if (p2 == nullptr)
g_free(buffer);
return false; return false;
}
p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n'); p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n');
tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1); tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1);
tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0'; tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0';
index_file_size = atol(tmpstr); index_file_size = atol(tmpstr);
g_free(tmpstr); g_free(tmpstr);
} }
p2 = strstr(p1,"\nbookname="); p2 = strstr(p1,"\nbookname=");
if (!p2) { if (p2 == nullptr)
g_free(buffer);
return false; return false;
}
p2 = p2 + sizeof("\nbookname=") -1; p2 = p2 + sizeof("\nbookname=") -1;
p3 = strchr(p2, '\n'); p3 = strchr(p2, '\n');
@@ -171,35 +162,33 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename,
} }
p2 = strstr(p1,"\nsametypesequence="); p2 = strstr(p1,"\nsametypesequence=");
if (p2) { if (p2) {
p2+=sizeof("\nsametypesequence=")-1; p2+=sizeof("\nsametypesequence=")-1;
p3 = strchr(p2, '\n'); p3 = strchr(p2, '\n');
sametypesequence.assign(p2, p3-p2); sametypesequence.assign(p2, p3-p2);
} }
g_free(buffer); return true;
return true;
} }
gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
{ {
for (int i=0; i<WORDDATA_CACHE_NUM; i++) for (int i=0; i<WORDDATA_CACHE_NUM; i++)
if (cache[i].data && cache[i].offset == idxitem_offset) if (cache[i].data && cache[i].offset == idxitem_offset)
return cache[i].data; return cache[i].data;
if (dictfile) if (dictfile)
fseek(dictfile, idxitem_offset, SEEK_SET); fseek(dictfile, idxitem_offset, SEEK_SET);
gchar *data; gchar *data;
if (!sametypesequence.empty()) { if (!sametypesequence.empty()) {
gchar *origin_data = (gchar *)g_malloc(idxitem_size); gchar *origin_data = (gchar *)g_malloc(idxitem_size);
if (dictfile) if (dictfile)
fread(origin_data, idxitem_size, 1, dictfile); fread(origin_data, idxitem_size, 1, dictfile);
else else
dictdzfile->read(origin_data, idxitem_offset, idxitem_size); dictdzfile->read(origin_data, idxitem_offset, idxitem_size);
guint32 data_size; guint32 data_size;
gint sametypesequence_len = sametypesequence.length(); gint sametypesequence_len = sametypesequence.length();
//there have sametypesequence_len char being omitted. //there have sametypesequence_len char being omitted.
@@ -225,7 +214,7 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
else else
data_size += sizeof(gchar); data_size += sizeof(gchar);
break; break;
} }
data = (gchar *)g_malloc(data_size); data = (gchar *)g_malloc(data_size);
gchar *p1,*p2; gchar *p1,*p2;
p1 = data + sizeof(guint32); p1 = data + sizeof(guint32);
@@ -266,8 +255,8 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
p1+=sec_size; p1+=sec_size;
p2+=sec_size; p2+=sec_size;
break; break;
} }
} }
//calculate the last item 's size. //calculate the last item 's size.
sec_size = idxitem_size - (p2-origin_data); sec_size = idxitem_size - (p2-origin_data);
*p1=sametypesequence[sametypesequence_len-1]; *p1=sametypesequence[sametypesequence_len-1];
@@ -280,7 +269,7 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
case 'g': case 'g':
case 'x': case 'x':
memcpy(p1, p2, sec_size); memcpy(p1, p2, sec_size);
p1 += sec_size; p1 += sec_size;
*p1='\0';//add the end up '\0'; *p1='\0';//add the end up '\0';
break; break;
case 'W': case 'W':
@@ -301,18 +290,18 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size)
} }
break; break;
} }
g_free(origin_data); g_free(origin_data);
set_uint32(data, data_size); set_uint32(data, data_size);
} else { } else {
data = (gchar *)g_malloc(idxitem_size + sizeof(guint32)); data = (gchar *)g_malloc(idxitem_size + sizeof(guint32));
if (dictfile) if (dictfile)
fread(data+sizeof(guint32), idxitem_size, 1, dictfile); fread(data+sizeof(guint32), idxitem_size, 1, dictfile);
else else
dictdzfile->read(data+sizeof(guint32), idxitem_offset, idxitem_size); dictdzfile->read(data+sizeof(guint32), idxitem_offset, idxitem_size);
set_uint32(data, idxitem_size+sizeof(guint32)); set_uint32(data, idxitem_size+sizeof(guint32));
} }
g_free(cache[cache_cur].data); g_free(cache[cache_cur].data);
cache[cache_cur].data = data; cache[cache_cur].data = data;
cache[cache_cur].offset = idxitem_offset; cache[cache_cur].offset = idxitem_offset;
cache_cur++; cache_cur++;
@@ -351,7 +340,7 @@ bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem
WordFind[j] = true; WordFind[j] = true;
++nfound; ++nfound;
} }
if (nfound==nWord) if (nfound==nWord)
return true; return true;
@@ -377,12 +366,12 @@ bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem
case 'x': case 'x':
sec_size = idxitem_size - (p-origin_data); sec_size = idxitem_size - (p-origin_data);
for (j=0; j<nWord; j++) for (j=0; j<nWord; j++)
if (!WordFind[j] && if (!WordFind[j] &&
g_strstr_len(p, sec_size, SearchWords[j].c_str())) { g_strstr_len(p, sec_size, SearchWords[j].c_str())) {
WordFind[j] = true; WordFind[j] = true;
++nfound; ++nfound;
} }
if (nfound==nWord) if (nfound==nWord)
return true; return true;
@@ -401,7 +390,7 @@ bool DictBase::SearchData(std::vector<std::string> &SearchWords, guint32 idxitem
if (!WordFind[j] && strstr(p, SearchWords[j].c_str())) { if (!WordFind[j] && strstr(p, SearchWords[j].c_str())) {
WordFind[j] = true; WordFind[j] = true;
++nfound; ++nfound;
} }
if (nfound==nWord) if (nfound==nWord)
return true; return true;
@@ -496,7 +485,7 @@ namespace {
std::vector<gchar *> wordlist; std::vector<gchar *> wordlist;
}; };
void OffsetIndex::page_t::fill(gchar *data, gint nent, glong idx_) void OffsetIndex::page_t::fill(gchar *data, gint nent, glong idx_)
{ {
idx=idx_; idx=idx_;
gchar *p=data; gchar *p=data;
@@ -547,7 +536,7 @@ namespace {
g_stat(item.c_str(), &cachestat)!=0) g_stat(item.c_str(), &cachestat)!=0)
continue; continue;
if (cachestat.st_mtime<idxstat.st_mtime) if (cachestat.st_mtime<idxstat.st_mtime)
continue; continue;
MapFile mf; MapFile mf;
if (!mf.open(item.c_str(), cachestat.st_size)) if (!mf.open(item.c_str(), cachestat.st_size))
continue; continue;
@@ -608,7 +597,7 @@ namespace {
if (!load_cache(url)) {//map file will close after finish of block if (!load_cache(url)) {//map file will close after finish of block
MapFile map_file; MapFile map_file;
if (!map_file.open(url.c_str(), fsize)) if (!map_file.open(url.c_str(), fsize))
return false; return false;
const gchar *idxdatabuffer=map_file.begin(); const gchar *idxdatabuffer=map_file.begin();
const gchar *p1 = idxdatabuffer; const gchar *p1 = idxdatabuffer;
@@ -646,7 +635,7 @@ namespace {
if (page_idx==glong(wordoffset.size()-2)) if (page_idx==glong(wordoffset.size()-2))
if ((nentr=wordcount%ENTR_PER_PAGE)==0) if ((nentr=wordcount%ENTR_PER_PAGE)==0)
nentr=ENTR_PER_PAGE; nentr=ENTR_PER_PAGE;
if (page_idx!=page.idx) { if (page_idx!=page.idx) {
page_data.resize(wordoffset[page_idx+1]-wordoffset[page_idx]); page_data.resize(wordoffset[page_idx+1]-wordoffset[page_idx]);
@@ -691,7 +680,7 @@ namespace {
iFrom=iThisIndex+1; iFrom=iThisIndex+1;
else if (cmpint<0) else if (cmpint<0)
iTo=iThisIndex-1; iTo=iThisIndex-1;
else { else {
bFound=true; bFound=true;
break; break;
} }
@@ -699,7 +688,7 @@ namespace {
if (!bFound) if (!bFound)
idx = iTo; //prev idx = iTo; //prev
else else
idx = iThisIndex; idx = iThisIndex;
} }
if (!bFound) { if (!bFound) {
gulong netr=load_page(idx); gulong netr=load_page(idx);
@@ -732,11 +721,11 @@ namespace {
bool WordListIndex::load(const std::string& url, gulong wc, gulong fsize) bool WordListIndex::load(const std::string& url, gulong wc, gulong fsize)
{ {
gzFile in = gzopen(url.c_str(), "rb"); gzFile in = gzopen(url.c_str(), "rb");
if (in == nullptr) if (in == nullptr)
return false; return false;
idxdatabuf = (gchar *)g_malloc(fsize); idxdatabuf = (gchar *)g_malloc(fsize);
const int len = gzread(in, idxdatabuf, fsize); const int len = gzread(in, idxdatabuf, fsize);
gzclose(in); gzclose(in);
if (len < 0) if (len < 0)
@@ -793,23 +782,23 @@ namespace {
if (!bFound) if (!bFound)
idx = iFrom; //next idx = iFrom; //next
else else
idx = iThisIndex; idx = iThisIndex;
} }
return bFound; return bFound;
} }
} }
bool Dict::load(const std::string& ifofilename) bool Dict::load(const std::string& ifofilename)
{ {
gulong idxfilesize; gulong idxfilesize;
if (!load_ifofile(ifofilename, idxfilesize)) if (!load_ifofile(ifofilename, idxfilesize))
return false; return false;
std::string fullfilename(ifofilename); std::string fullfilename(ifofilename);
fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz"); fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz");
if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {
dictdzfile.reset(new dictData); dictdzfile.reset(new DictData);
if (!dictdzfile->open(fullfilename, 0)) { if (!dictdzfile->open(fullfilename, 0)) {
//g_print("open file %s failed!\n",fullfilename); //g_print("open file %s failed!\n",fullfilename);
return false; return false;
@@ -825,7 +814,7 @@ bool Dict::load(const std::string& ifofilename)
fullfilename=ifofilename; fullfilename=ifofilename;
fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "idx.gz"); fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "idx.gz");
if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {
idx_file.reset(new WordListIndex); idx_file.reset(new WordListIndex);
} else { } else {
@@ -852,7 +841,7 @@ bool Dict::load_ifofile(const std::string& ifofilename, gulong &idxfilesize)
wordcount=dict_info.wordcount; wordcount=dict_info.wordcount;
bookname=dict_info.bookname; bookname=dict_info.bookname;
idxfilesize=dict_info.index_file_size; idxfilesize=dict_info.index_file_size;
sametypesequence=dict_info.sametypesequence; sametypesequence=dict_info.sametypesequence;
@@ -862,13 +851,13 @@ bool Dict::load_ifofile(const std::string& ifofilename, gulong &idxfilesize)
bool Dict::LookupWithRule(GPatternSpec *pspec, glong *aIndex, int iBuffLen) bool Dict::LookupWithRule(GPatternSpec *pspec, glong *aIndex, int iBuffLen)
{ {
int iIndexCount = 0; int iIndexCount = 0;
for (guint32 i=0; i < narticles() && iIndexCount < (iBuffLen - 1); i++) for (guint32 i=0; i < narticles() && iIndexCount < (iBuffLen - 1); i++)
if (g_pattern_match_string(pspec, get_key(i))) if (g_pattern_match_string(pspec, get_key(i)))
aIndex[iIndexCount++] = i; aIndex[iIndexCount++] = i;
aIndex[iIndexCount] = -1; // -1 is the end. aIndex[iIndexCount] = -1; // -1 is the end.
return iIndexCount > 0; return iIndexCount > 0;
} }
@@ -888,25 +877,25 @@ void Libs::load_dict(const std::string& url)
} }
void Libs::load(const std::list<std::string>& dicts_dirs, void Libs::load(const std::list<std::string>& dicts_dirs,
const std::list<std::string>& order_list, const std::list<std::string>& order_list,
const std::list<std::string>& disable_list) const std::list<std::string>& disable_list)
{ {
for_each_file(dicts_dirs, ".ifo", order_list, disable_list, for_each_file(dicts_dirs, ".ifo", order_list, disable_list,
[this](const std::string& url, bool disable) -> void { [this](const std::string& url, bool disable) -> void {
if (!disable) if (!disable)
load_dict(url); load_dict(url);
}); });
} }
void Libs::reload(const std::list<std::string>& dicts_dirs, void Libs::reload(const std::list<std::string>& dicts_dirs,
const std::list<std::string>& order_list, const std::list<std::string>& order_list,
const std::list<std::string>& disable_list) const std::list<std::string>& disable_list)
{ {
std::vector<Dict *> prev(oLib); std::vector<Dict *> prev(oLib);
oLib.clear(); oLib.clear();
for_each_file(dicts_dirs, ".ifo", order_list, disable_list, for_each_file(dicts_dirs, ".ifo", order_list, disable_list,
[&prev, this](const std::string& url, bool disable) -> void { [&prev, this](const std::string& url, bool disable) -> void {
if (!disable) { if (!disable) {
auto it = prev.begin(); auto it = prev.begin();
for (; it != prev.end(); ++it) for (; it != prev.end(); ++it)
@@ -917,14 +906,14 @@ void Libs::reload(const std::list<std::string>& dicts_dirs,
prev.erase(it); prev.erase(it);
oLib.push_back(res); oLib.push_back(res);
} else } else
load_dict(url); load_dict(url);
} }
}); });
for (Dict *p : prev) for (Dict *p : prev)
delete p; delete p;
} }
const gchar *Libs::poGetCurrentWord(glong * iCurrent) const gchar *Libs::poGetCurrentWord(glong * iCurrent)
{ {
const gchar *poCurrentWord = nullptr; const gchar *poCurrentWord = nullptr;
@@ -938,7 +927,7 @@ const gchar *Libs::poGetCurrentWord(glong * iCurrent)
poCurrentWord = poGetWord(iCurrent[iLib],iLib); poCurrentWord = poGetWord(iCurrent[iLib],iLib);
} else { } else {
word = poGetWord(iCurrent[iLib],iLib); word = poGetWord(iCurrent[iLib],iLib);
if (stardict_strcmp(poCurrentWord, word) > 0 ) if (stardict_strcmp(poCurrentWord, word) > 0 )
poCurrentWord = word; poCurrentWord = word;
} }
@@ -967,7 +956,7 @@ const gchar *Libs::poGetNextWord(const gchar *sWord, glong *iCurrent)
iCurrentLib = iLib; iCurrentLib = iLib;
} else { } else {
word = poGetWord(iCurrent[iLib],iLib); word = poGetWord(iCurrent[iLib],iLib);
if (stardict_strcmp(poCurrentWord, word) > 0 ) { if (stardict_strcmp(poCurrentWord, word) > 0 ) {
poCurrentWord = word; poCurrentWord = word;
iCurrentLib = iLib; iCurrentLib = iLib;
@@ -1018,7 +1007,7 @@ Libs::poGetPreWord(glong * iCurrent)
} }
} }
} }
if (poCurrentWord) { if (poCurrentWord) {
iCurrent[iCurrentLib]--; iCurrent[iCurrentLib]--;
for (std::vector<Dict *>::size_type iLib=0;iLib<oLib.size();iLib++) { for (std::vector<Dict *>::size_type iLib=0;iLib<oLib.size();iLib++) {
@@ -1059,7 +1048,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
bFound=true; bFound=true;
} }
g_free(casestr); g_free(casestr);
} }
// Upper the first character and lower others. // Upper the first character and lower others.
if (!bFound) { if (!bFound) {
gchar *nextchar = g_utf8_next_char(sWord); gchar *nextchar = g_utf8_next_char(sWord);
@@ -1073,14 +1062,14 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
bFound=true; bFound=true;
} }
g_free(casestr); g_free(casestr);
} }
} }
if (bIsPureEnglish(sWord)) { if (bIsPureEnglish(sWord)) {
// If not Found , try other status of sWord. // If not Found , try other status of sWord.
int iWordLen=strlen(sWord); int iWordLen=strlen(sWord);
bool isupcase; bool isupcase;
gchar *sNewWord = (gchar *)g_malloc(iWordLen + 1); gchar *sNewWord = (gchar *)g_malloc(iWordLen + 1);
//cut one char "s" or "d" //cut one char "s" or "d"
@@ -1101,7 +1090,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
//cut "ly" //cut "ly"
if(!bFound && iWordLen>2) { if(!bFound && iWordLen>2) {
isupcase = !strncmp(&sWord[iWordLen-2],"LY",2); isupcase = !strncmp(&sWord[iWordLen-2],"LY",2);
@@ -1109,9 +1098,9 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
strcpy(sNewWord,sWord); strcpy(sNewWord,sWord);
sNewWord[iWordLen-2]='\0'; // cut "ly" sNewWord[iWordLen-2]='\0'; // cut "ly"
if (iWordLen>5 && sNewWord[iWordLen-3]==sNewWord[iWordLen-4] if (iWordLen>5 && sNewWord[iWordLen-3]==sNewWord[iWordLen-4]
&& !bIsVowel(sNewWord[iWordLen-4]) && && !bIsVowel(sNewWord[iWordLen-4]) &&
bIsVowel(sNewWord[iWordLen-5])) {//doubled bIsVowel(sNewWord[iWordLen-5])) {//doubled
sNewWord[iWordLen-3]='\0'; sNewWord[iWordLen-3]='\0';
if( oLib[iLib]->Lookup(sNewWord, iIndex) ) if( oLib[iLib]->Lookup(sNewWord, iIndex) )
bFound=true; bFound=true;
@@ -1126,7 +1115,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
if (!bFound) if (!bFound)
sNewWord[iWordLen-3]=sNewWord[iWordLen-4]; //restore sNewWord[iWordLen-3]=sNewWord[iWordLen-4]; //restore
} }
} }
if (!bFound) { if (!bFound) {
if (oLib[iLib]->Lookup(sNewWord, iIndex)) if (oLib[iLib]->Lookup(sNewWord, iIndex))
@@ -1142,7 +1131,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
//cut "ing" //cut "ing"
if(!bFound && iWordLen>3) { if(!bFound && iWordLen>3) {
isupcase = !strncmp(&sWord[iWordLen-3],"ING",3); isupcase = !strncmp(&sWord[iWordLen-3],"ING",3);
@@ -1150,8 +1139,8 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
strcpy(sNewWord,sWord); strcpy(sNewWord,sWord);
sNewWord[iWordLen-3]='\0'; sNewWord[iWordLen-3]='\0';
if ( iWordLen>6 && (sNewWord[iWordLen-4]==sNewWord[iWordLen-5]) if ( iWordLen>6 && (sNewWord[iWordLen-4]==sNewWord[iWordLen-5])
&& !bIsVowel(sNewWord[iWordLen-5]) && && !bIsVowel(sNewWord[iWordLen-5]) &&
bIsVowel(sNewWord[iWordLen-6])) { //doubled bIsVowel(sNewWord[iWordLen-6])) { //doubled
sNewWord[iWordLen-4]='\0'; sNewWord[iWordLen-4]='\0';
if (oLib[iLib]->Lookup(sNewWord, iIndex)) if (oLib[iLib]->Lookup(sNewWord, iIndex))
bFound=true; bFound=true;
@@ -1178,7 +1167,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
bFound=true; bFound=true;
} }
g_free(casestr); g_free(casestr);
} }
} }
if(!bFound) { if(!bFound) {
if (isupcase) if (isupcase)
@@ -1194,25 +1183,25 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
bFound=true; bFound=true;
} }
g_free(casestr); g_free(casestr);
} }
} }
} }
} }
//cut two char "es" //cut two char "es"
if(!bFound && iWordLen>3) { if(!bFound && iWordLen>3) {
isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) && isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) &&
(sWord[iWordLen-3] == 'S' || (sWord[iWordLen-3] == 'S' ||
sWord[iWordLen-3] == 'X' || sWord[iWordLen-3] == 'X' ||
sWord[iWordLen-3] == 'O' || sWord[iWordLen-3] == 'O' ||
(iWordLen >4 && sWord[iWordLen-3] == 'H' && (iWordLen >4 && sWord[iWordLen-3] == 'H' &&
(sWord[iWordLen-4] == 'C' || (sWord[iWordLen-4] == 'C' ||
sWord[iWordLen-4] == 'S')))); sWord[iWordLen-4] == 'S'))));
if (isupcase || if (isupcase ||
(!strncmp(&sWord[iWordLen-2],"es",2) && (!strncmp(&sWord[iWordLen-2],"es",2) &&
(sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || (sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' ||
sWord[iWordLen-3] == 'o' || sWord[iWordLen-3] == 'o' ||
(iWordLen >4 && sWord[iWordLen-3] == 'h' && (iWordLen >4 && sWord[iWordLen-3] == 'h' &&
(sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) { (sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) {
strcpy(sNewWord,sWord); strcpy(sNewWord,sWord);
sNewWord[iWordLen-2]='\0'; sNewWord[iWordLen-2]='\0';
@@ -1228,7 +1217,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
//cut "ed" //cut "ed"
if (!bFound && iWordLen>3) { if (!bFound && iWordLen>3) {
isupcase = !strncmp(&sWord[iWordLen-2],"ED",2); isupcase = !strncmp(&sWord[iWordLen-2],"ED",2);
@@ -1236,8 +1225,8 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
strcpy(sNewWord,sWord); strcpy(sNewWord,sWord);
sNewWord[iWordLen-2]='\0'; sNewWord[iWordLen-2]='\0';
if (iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4]) if (iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4])
&& !bIsVowel(sNewWord[iWordLen-4]) && && !bIsVowel(sNewWord[iWordLen-4]) &&
bIsVowel(sNewWord[iWordLen-5])) {//doubled bIsVowel(sNewWord[iWordLen-5])) {//doubled
sNewWord[iWordLen-3]='\0'; sNewWord[iWordLen-3]='\0';
if (oLib[iLib]->Lookup(sNewWord, iIndex)) if (oLib[iLib]->Lookup(sNewWord, iIndex))
bFound=true; bFound=true;
@@ -1268,7 +1257,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
// cut "ied" , add "y". // cut "ied" , add "y".
if (!bFound && iWordLen>3) { if (!bFound && iWordLen>3) {
isupcase = !strncmp(&sWord[iWordLen-3],"IED",3); isupcase = !strncmp(&sWord[iWordLen-3],"IED",3);
@@ -1291,7 +1280,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
// cut "ies" , add "y". // cut "ies" , add "y".
if (!bFound && iWordLen>3) { if (!bFound && iWordLen>3) {
isupcase = !strncmp(&sWord[iWordLen-3],"IES",3); isupcase = !strncmp(&sWord[iWordLen-3],"IES",3);
@@ -1333,7 +1322,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
// cut "est". // cut "est".
if (!bFound && iWordLen>3) { if (!bFound && iWordLen>3) {
isupcase = !strncmp(&sWord[iWordLen-3], "EST", 3); isupcase = !strncmp(&sWord[iWordLen-3], "EST", 3);
@@ -1352,10 +1341,10 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
} }
} }
} }
g_free(sNewWord); g_free(sNewWord);
} }
if (bFound) if (bFound)
iWordIndex = iIndex; iWordIndex = iIndex;
#if 0 #if 0
@@ -1381,7 +1370,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
if (sWord[0] == '\0') if (sWord[0] == '\0')
return false; return false;
Fuzzystruct oFuzzystruct[reslist_size]; Fuzzystruct oFuzzystruct[reslist_size];
for (int i = 0; i < reslist_size; i++) { for (int i = 0; i < reslist_size; i++) {
oFuzzystruct[i].pMatchWord = nullptr; oFuzzystruct[i].pMatchWord = nullptr;
@@ -1412,13 +1401,13 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
sCheck = poGetWord(index,iLib); sCheck = poGetWord(index,iLib);
// tolower and skip too long or too short words // tolower and skip too long or too short words
iCheckWordLen = g_utf8_strlen(sCheck, -1); iCheckWordLen = g_utf8_strlen(sCheck, -1);
if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || if (iCheckWordLen-ucs4_str2_len>=iMaxDistance ||
ucs4_str2_len-iCheckWordLen>=iMaxDistance) ucs4_str2_len-iCheckWordLen>=iMaxDistance)
continue; continue;
ucs4_str1 = g_utf8_to_ucs4_fast(sCheck, -1, nullptr); ucs4_str1 = g_utf8_to_ucs4_fast(sCheck, -1, nullptr);
if (iCheckWordLen > ucs4_str2_len) if (iCheckWordLen > ucs4_str2_len)
ucs4_str1[ucs4_str2_len]=0; ucs4_str1[ucs4_str2_len]=0;
unicode_strdown(ucs4_str1); unicode_strdown(ucs4_str1);
iDistance = oEditDistance.CalEditDistance(ucs4_str1, ucs4_str2, iMaxDistance); iDistance = oEditDistance.CalEditDistance(ucs4_str1, ucs4_str2, iMaxDistance);
g_free(ucs4_str1); g_free(ucs4_str1);
@@ -1428,7 +1417,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
bool bAlreadyInList = false; bool bAlreadyInList = false;
int iMaxDistanceAt=0; int iMaxDistanceAt=0;
for (int j=0; j<reslist_size; j++) { for (int j=0; j<reslist_size; j++) {
if (oFuzzystruct[j].pMatchWord && if (oFuzzystruct[j].pMatchWord &&
strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) {//already in list strcmp(oFuzzystruct[j].pMatchWord,sCheck)==0 ) {//already in list
bAlreadyInList = true; bAlreadyInList = true;
break; break;
@@ -1455,7 +1444,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
} // each lib } // each lib
g_free(ucs4_str2); g_free(ucs4_str2);
if (Found)// sort with distance if (Found)// sort with distance
std::sort(oFuzzystruct, oFuzzystruct + reslist_size, [](const Fuzzystruct& lh, const Fuzzystruct& rh) -> bool { std::sort(oFuzzystruct, oFuzzystruct + reslist_size, [](const Fuzzystruct& lh, const Fuzzystruct& rh) -> bool {
if (lh.iMatchWordDistance!=rh.iMatchWordDistance) if (lh.iMatchWordDistance!=rh.iMatchWordDistance)
@@ -1463,26 +1452,26 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si
if (lh.pMatchWord && rh.pMatchWord) if (lh.pMatchWord && rh.pMatchWord)
return stardict_strcmp(lh.pMatchWord, rh.pMatchWord)<0; return stardict_strcmp(lh.pMatchWord, rh.pMatchWord)<0;
return false; return false;
}); });
for (gint i = 0; i < reslist_size; ++i) for (gint i = 0; i < reslist_size; ++i)
reslist[i] = oFuzzystruct[i].pMatchWord; reslist[i] = oFuzzystruct[i].pMatchWord;
return Found; return Found;
} }
gint Libs::LookupWithRule(const gchar *word, gchar **ppMatchWord) gint Libs::LookupWithRule(const gchar *word, gchar **ppMatchWord)
{ {
glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1]; glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1];
gint iMatchCount = 0; gint iMatchCount = 0;
GPatternSpec *pspec = g_pattern_spec_new(word); GPatternSpec *pspec = g_pattern_spec_new(word);
for (std::vector<Dict *>::size_type iLib=0; iLib<oLib.size(); iLib++) { for (std::vector<Dict *>::size_type iLib=0; iLib<oLib.size(); iLib++) {
//if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1-iMatchCount,iLib)) //if(oLibs.LookdupWordsWithRule(pspec,aiIndex,MAX_MATCH_ITEM_PER_LIB+1-iMatchCount,iLib))
// -iMatchCount,so save time,but may got less result and the word may repeat. // -iMatchCount,so save time,but may got less result and the word may repeat.
if (oLib[iLib]->LookupWithRule(pspec,aiIndex, MAX_MATCH_ITEM_PER_LIB+1)) { if (oLib[iLib]->LookupWithRule(pspec,aiIndex, MAX_MATCH_ITEM_PER_LIB+1)) {
if (progress_func) if (progress_func)
progress_func(); progress_func();
@@ -1501,12 +1490,12 @@ gint Libs::LookupWithRule(const gchar *word, gchar **ppMatchWord)
} }
} }
g_pattern_spec_free(pspec); g_pattern_spec_free(pspec);
if (iMatchCount)// sort it. if (iMatchCount)// sort it.
std::sort(ppMatchWord, ppMatchWord+iMatchCount, [](const char *lh, const char *rh) -> bool { std::sort(ppMatchWord, ppMatchWord+iMatchCount, [](const char *lh, const char *rh) -> bool {
return stardict_strcmp(lh, rh)<0; return stardict_strcmp(lh, rh)<0;
}); });
return iMatchCount; return iMatchCount;
} }
@@ -1577,7 +1566,7 @@ bool Libs::LookupData(const gchar *sWord, std::vector<gchar *> *reslist)
for (i = 0; i < oLib.size(); ++i) for (i = 0; i < oLib.size(); ++i)
if (!reslist[i].empty()) if (!reslist[i].empty())
break; break;
return i != oLib.size(); return i != oLib.size();
} }

View File

@@ -56,7 +56,7 @@ public:
protected: protected:
std::string sametypesequence; std::string sametypesequence;
FILE *dictfile = nullptr; FILE *dictfile = nullptr;
std::unique_ptr<dictData> dictdzfile; std::unique_ptr<DictData> dictdzfile;
private: private:
cacheItem cache[WORDDATA_CACHE_NUM]; cacheItem cache[WORDDATA_CACHE_NUM];
gint cache_cur = 0; gint cache_cur = 0;

View File

@@ -53,22 +53,6 @@ std::string utf8_to_locale_ign_err(const std::string& utf8_str)
return res; return res;
} }
char *locale_to_utf8(const char *loc_str)
{
if (nullptr == loc_str)
return nullptr;
gsize bytes_read, bytes_written;
glib::Error err;
gchar *str = g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, get_addr(err));
if (nullptr == str){
fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str);
fprintf(stderr, "%s\n", err->message);
exit(EXIT_FAILURE);
}
return str;
}
static void __for_each_file(const std::string& dirname, const std::string& suff, static void __for_each_file(const std::string& dirname, const std::string& suff,
const std::list<std::string>& order_list, const std::list<std::string>& disable_list, const std::list<std::string>& order_list, const std::list<std::string>& disable_list,
const std::function<void (const std::string&, bool)>& f) const std::function<void (const std::string&, bool)>& f)

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <glib.h> #include <glib.h>
#include <cassert>
#include <string> #include <string>
#include <list> #include <list>
#include <functional> #include <functional>
@@ -14,6 +15,10 @@ public:
ResourceWrapper& operator=(const ResourceWrapper&) = delete; ResourceWrapper& operator=(const ResourceWrapper&) = delete;
T *operator->() const { return p_; } T *operator->() const { return p_; }
bool operator!() const { return p_ == nullptr; } bool operator!() const { return p_ == nullptr; }
const T& operator[](size_t idx) const {
assert(p_ != nullptr);
return p_[idx];
}
void reset(T *newp) { void reset(T *newp) {
if (p_ != newp) { if (p_ != newp) {
@@ -56,8 +61,6 @@ namespace glib {
typedef ResourceWrapper<GError, GError, g_error_free> Error; typedef ResourceWrapper<GError, GError, g_error_free> Error;
} }
extern char *locale_to_utf8(const char *locstr);
extern std::string utf8_to_locale_ign_err(const std::string& utf8_str); extern std::string utf8_to_locale_ign_err(const std::string& utf8_str);
extern void for_each_file(const std::list<std::string>& dirs_list, const std::string& suff, extern void for_each_file(const std::list<std::string>& dirs_list, const std::string& suff,