diff --git a/src/dictziplib.cpp b/src/dictziplib.cpp index 909340d..75d697b 100644 --- a/src/dictziplib.cpp +++ b/src/dictziplib.cpp @@ -3,11 +3,11 @@ * Copyright (C) 2003-2003 Hu Zheng * 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 * Revised: Sat Mar 30 10:46:06 2002 by 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 * it under the terms of the GNU General Public License as published by @@ -46,10 +46,10 @@ #define BUFFERSIZE 10240 -/* +/* * Output buffer must be greater than or * equal to 110% of input buffer size, plus - * 12 bytes. + * 12 bytes. */ #define OUT_BUFFER_SIZE 0xffffL @@ -113,7 +113,7 @@ #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; 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 ); int count; unsigned long offset; - + if (!(str = fopen(fname.c_str(), "rb"))) { //err_fatal_errno( __FUNCTION__, // "Cannot open data file \"%s\" for read\n", filename ); - } + return -1; + } this->headerLength = GZ_XLEN - 1; this->type = DICT_UNKNOWN; - + id1 = getc( str ); id2 = getc( str ); - + if (id1 != GZ_MAGIC1 || id2 != GZ_MAGIC2) { this->type = DICT_TEXT; fstat( fileno( str ), &sb ); @@ -157,7 +158,7 @@ int dictData::read_header(const std::string &fname, int computeCRC) return 0; } this->type = DICT_GZIP; - + this->method = getc( str ); this->flags = getc( str ); 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->extraFlags = getc( str ); this->os = getc( str ); - + if (this->flags & GZ_FEXTRA) { extraLength = getc( str ) << 0; extraLength |= getc( str ) << 8; this->headerLength += extraLength + 2; si1 = getc( str ); si2 = getc( str ); - + if (si1 == GZ_RND_S1 || si2 == GZ_RND_S2) { subLength = getc( str ) << 0; subLength |= getc( str ) << 8; this->version = getc( str ) << 0; this->version |= getc( str ) << 8; - + if (this->version != 1) { //err_internal( __FUNCTION__, // "dzip header version %d not supported\n", // this->version ); } - + this->chunkLength = getc( str ) << 0; this->chunkLength |= getc( str ) << 8; this->chunkCount = getc( str ) << 0; this->chunkCount |= getc( str ) << 8; - + if (this->chunkCount <= 0) { fclose( str ); return 5; @@ -206,19 +207,19 @@ int dictData::read_header(const std::string &fname, int computeCRC) fseek( str, this->headerLength, SEEK_SET ); } } - + if (this->flags & GZ_FNAME) { /* FIXME! Add checking against header len */ pt = buffer; while ((c = getc( str )) && c != EOF) *pt++ = c; *pt = '\0'; - + this->origFilename = buffer; this->headerLength += this->origFilename.length() + 1; } else { this->origFilename = ""; } - + if (this->flags & GZ_COMMENT) { /* FIXME! Add checking for header len */ pt = buffer; while ((c = getc( str )) && c != EOF) @@ -267,10 +268,9 @@ int dictData::read_header(const std::string &fname, int computeCRC) return 0; } -bool dictData::open(const std::string& fname, int computeCRC) +bool DictData::open(const std::string& fname, int computeCRC) { struct stat sb; - int j; int fd; 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 ); return false; } - + if (read_header(fname, computeCRC)) { //err_fatal( __FUNCTION__, // "\"%s\" not in text or dzip format\n", fname ); return false; } - + if ((fd = ::open(fname.c_str(), O_RDONLY )) < 0) { //err_fatal_errno( __FUNCTION__, // "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; - ::close(fd); - if (!mapfile.open(fname.c_str(), size)) - return false; + ::close(fd); + if (!mapfile.open(fname.c_str(), size)) + return false; - this->start=mapfile.begin(); + this->start=mapfile.begin(); 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].stamp = -1; cache[j].inBuffer = nullptr; cache[j].count = 0; } - + return true; } -void dictData::close() +void DictData::close() { - int i; - if (this->chunks) free(this->chunks); 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) 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; unsigned long end; @@ -348,19 +346,19 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size) char outBuffer[OUT_BUFFER_SIZE]; int firstChunk, lastChunk; int firstOffset, lastOffset; - int i, j; + int i; int found, target, lastStamp; static int stamp = 0; - + end = start + size; - + //buffer = malloc( size + 1 ); - + //PRINTF(DBG_UNZIP, // ("dict_data_read( %p, %lu, %lu )\n", //h, start, size )); - - + + switch (this->type) { case DICT_GZIP: //err_fatal( __FUNCTION__, @@ -398,12 +396,12 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size) //" lastChunk = %d, lastOffset = %d\n", //start, end, firstChunk, firstOffset, lastChunk, lastOffset )); for (pt = buffer, i = firstChunk; i <= lastChunk; i++) { - + /* Access cache */ found = 0; target = 0; 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 (this->cache[j].chunk == i) { found = 1; @@ -416,7 +414,7 @@ void dictData::read(char *buffer, unsigned long start, unsigned long size) target = j; } } - + this->cache[target].stamp = ++stamp; if (found) { 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) this->cache[target].inBuffer = (char *)malloc( IN_BUFFER_SIZE ); inBuffer = this->cache[target].inBuffer; - + if (this->chunks[i] >= OUT_BUFFER_SIZE ) { //err_internal( __FUNCTION__, // "this->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n", // i, this->chunks[i], OUT_BUFFER_SIZE ); } memcpy( outBuffer, this->start + this->offsets[i], this->chunks[i] ); - + this->zStream.next_in = (Bytef *)outBuffer; this->zStream.avail_in = this->chunks[i]; 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", // this->zStream.avail_in, this->zStream.avail_out ); } - + count = IN_BUFFER_SIZE - this->zStream.avail_out; - + this->cache[target].count = count; } - + if (i == firstChunk) { if (i == lastChunk) { memcpy( pt, inBuffer + firstOffset, lastOffset-firstOffset); diff --git a/src/dictziplib.hpp b/src/dictziplib.hpp index a2c429c..9d48aad 100644 --- a/src/dictziplib.hpp +++ b/src/dictziplib.hpp @@ -6,22 +6,22 @@ #include "mapfile.hpp" - -#define DICT_CACHE_SIZE 5 - -struct dictCache { +struct DictCache { int chunk; char *inBuffer; int stamp; int count; }; -struct dictData { - dictData() {} +class DictData { +public: + static const size_t DICT_CACHE_SIZE = 5; + + DictData() {} + ~DictData() { close(); } bool open(const std::string& filename, int computeCRC); void close(); void read(char *buffer, unsigned long start, unsigned long size); - ~dictData() { close(); } private: const char *start; /* start of mmap'd area */ const char *end; /* end of mmap'd area */ @@ -47,7 +47,7 @@ private: unsigned long crc; unsigned long length; unsigned long compressedLength; - dictCache cache[DICT_CACHE_SIZE]; + DictCache cache[DICT_CACHE_SIZE]; MapFile mapfile; int read_header(const std::string &filename, int computeCRC); diff --git a/src/libwrapper.cpp b/src/libwrapper.cpp index 55164df..8cc0559 100644 --- a/src/libwrapper.cpp +++ b/src/libwrapper.cpp @@ -304,26 +304,25 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force) gsize bytes_read; gsize bytes_written; - GError *err = nullptr; - char *str = nullptr; + glib::Error err; + glib::CharStr str; 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 - 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, "%s\n", err->message); - g_error_free(err); return false; } - if (str[0]=='\0') + if (str[0] == '\0') return true; TSearchResultList res_list; - switch (analyze_query(str, query)) { + switch (analyze_query(get_impl(str), query)) { case qtFUZZY: LookupWithFuzzy(query, res_list); break; @@ -331,9 +330,9 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force) LookupWithRule(query, res_list); break; case qtSIMPLE: - SimpleLookup(str, res_list); + SimpleLookup(get_impl(str), res_list); if (res_list.empty()) - LookupWithFuzzy(str, res_list); + LookupWithFuzzy(get_impl(str), res_list); break; case qtDATA: 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) { 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) { 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); @@ -398,7 +397,7 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force) } else { sdcv_pager pager(force); 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) 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 { std::string loc_str; 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; } diff --git a/src/stardict_lib.cpp b/src/stardict_lib.cpp index 7f2881c..5a9d8fc 100644 --- a/src/stardict_lib.cpp +++ b/src/stardict_lib.cpp @@ -16,7 +16,7 @@ #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! namespace { @@ -31,19 +31,19 @@ namespace { 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 :). - for (int i=0; str[i]!=0; i++) + for (int i=0; str[i]!=0; i++) //if(str[i]<0) //if(str[i]<32 || str[i]>126) // tab equal 9,so this is not OK. // Better use isascii() but not str[i]<0 while char is default unsigned in arm - if (!isascii(str[i])) - return false; - return true; + if (!isascii(str[i])) + return false; + 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); if (a == 0) @@ -55,7 +55,7 @@ namespace { static void unicode_strdown(gunichar *str) { while (*str) { - *str=g_unichar_tolower(*str); + *str = g_unichar_tolower(*str); ++str; } } @@ -66,33 +66,29 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename, bool istreedict) { ifo_file_name = ifofilename; - gchar *buffer; - if (!g_file_get_contents(ifofilename.c_str(), &buffer, nullptr, nullptr)) + glib::CharStr buffer; + if (!g_file_get_contents(ifofilename.c_str(), get_addr(buffer), nullptr, nullptr)) return false; - + static const char TREEDICT_MAGIC_DATA[] = "StarDict's treedict ifo file"; static const char DICT_MAGIC_DATA[] = "StarDict's dict ifo file"; const gchar *magic_data = istreedict ? TREEDICT_MAGIC_DATA : DICT_MAGIC_DATA; static const unsigned char utf8_bom[] = { 0xEF, 0xBB, 0xBF, '\0'}; 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)) { g_free(buffer); return false; } - gchar *p1,*p2,*p3; - - p1 = buffer + strlen(magic_data)-1; + gchar *p1 = get_impl(buffer) + strlen(magic_data)-1; - p2 = strstr(p1,"\nwordcount="); - if (!p2) { - g_free(buffer); - return false; - } - - p3 = strchr(p2+ sizeof("\nwordcount=")-1,'\n'); + gchar *p2 = strstr(p1, "\nwordcount="); + if (p2 == nullptr) + return false; + + gchar *p3 = strchr(p2 + sizeof("\nwordcount=") - 1, '\n'); gchar *tmpstr = (gchar *)g_memdup(p2+sizeof("\nwordcount=")-1, p3-(p2+sizeof("\nwordcount=")-1)+1); tmpstr[p3-(p2+sizeof("\nwordcount=")-1)] = '\0'; wordcount = atol(tmpstr); @@ -100,36 +96,31 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename, if (istreedict) { p2 = strstr(p1,"\ntdxfilesize="); - if (!p2) { - g_free(buffer); + if (p2 == nullptr) return false; - } + p3 = strchr(p2+ sizeof("\ntdxfilesize=")-1,'\n'); tmpstr = (gchar *)g_memdup(p2+sizeof("\ntdxfilesize=")-1, p3-(p2+sizeof("\ntdxfilesize=")-1)+1); tmpstr[p3-(p2+sizeof("\ntdxfilesize=")-1)] = '\0'; index_file_size = atol(tmpstr); g_free(tmpstr); } else { - + p2 = strstr(p1,"\nidxfilesize="); - if (!p2) { - g_free(buffer); + if (p2 == nullptr) return false; - } - + p3 = strchr(p2+ sizeof("\nidxfilesize=")-1,'\n'); tmpstr = (gchar *)g_memdup(p2+sizeof("\nidxfilesize=")-1, p3-(p2+sizeof("\nidxfilesize=")-1)+1); tmpstr[p3-(p2+sizeof("\nidxfilesize=")-1)] = '\0'; index_file_size = atol(tmpstr); g_free(tmpstr); } - + p2 = strstr(p1,"\nbookname="); - if (!p2) { - g_free(buffer); + if (p2 == nullptr) return false; - } p2 = p2 + sizeof("\nbookname=") -1; p3 = strchr(p2, '\n'); @@ -171,35 +162,33 @@ bool DictInfo::load_from_ifo_file(const std::string& ifofilename, } p2 = strstr(p1,"\nsametypesequence="); - if (p2) { + if (p2) { p2+=sizeof("\nsametypesequence=")-1; p3 = strchr(p2, '\n'); sametypesequence.assign(p2, p3-p2); } - g_free(buffer); - - return true; + return true; } gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) { - for (int i=0; iread(origin_data, idxitem_offset, idxitem_size); - + guint32 data_size; gint sametypesequence_len = sametypesequence.length(); //there have sametypesequence_len char being omitted. @@ -225,7 +214,7 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) else data_size += sizeof(gchar); break; - } + } data = (gchar *)g_malloc(data_size); gchar *p1,*p2; p1 = data + sizeof(guint32); @@ -266,8 +255,8 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) p1+=sec_size; p2+=sec_size; break; - } - } + } + } //calculate the last item 's size. sec_size = idxitem_size - (p2-origin_data); *p1=sametypesequence[sametypesequence_len-1]; @@ -280,7 +269,7 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) case 'g': case 'x': memcpy(p1, p2, sec_size); - p1 += sec_size; + p1 += sec_size; *p1='\0';//add the end up '\0'; break; case 'W': @@ -301,18 +290,18 @@ gchar* DictBase::GetWordData(guint32 idxitem_offset, guint32 idxitem_size) } break; } - g_free(origin_data); + g_free(origin_data); set_uint32(data, data_size); - } else { + } else { data = (gchar *)g_malloc(idxitem_size + sizeof(guint32)); if (dictfile) - fread(data+sizeof(guint32), idxitem_size, 1, dictfile); + fread(data+sizeof(guint32), idxitem_size, 1, dictfile); else dictdzfile->read(data+sizeof(guint32), idxitem_offset, idxitem_size); set_uint32(data, idxitem_size+sizeof(guint32)); - } + } g_free(cache[cache_cur].data); - + cache[cache_cur].data = data; cache[cache_cur].offset = idxitem_offset; cache_cur++; @@ -351,7 +340,7 @@ bool DictBase::SearchData(std::vector &SearchWords, guint32 idxitem WordFind[j] = true; ++nfound; } - + if (nfound==nWord) return true; @@ -377,12 +366,12 @@ bool DictBase::SearchData(std::vector &SearchWords, guint32 idxitem case 'x': sec_size = idxitem_size - (p-origin_data); for (j=0; j &SearchWords, guint32 idxitem if (!WordFind[j] && strstr(p, SearchWords[j].c_str())) { WordFind[j] = true; ++nfound; - } + } if (nfound==nWord) return true; @@ -496,7 +485,7 @@ namespace { std::vector 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_; gchar *p=data; @@ -547,7 +536,7 @@ namespace { g_stat(item.c_str(), &cachestat)!=0) continue; if (cachestat.st_mtimeopen(fullfilename, 0)) { //g_print("open file %s failed!\n",fullfilename); return false; @@ -825,7 +814,7 @@ bool Dict::load(const std::string& ifofilename) fullfilename=ifofilename; fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "idx.gz"); - + if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) { idx_file.reset(new WordListIndex); } else { @@ -852,7 +841,7 @@ bool Dict::load_ifofile(const std::string& ifofilename, gulong &idxfilesize) wordcount=dict_info.wordcount; bookname=dict_info.bookname; - idxfilesize=dict_info.index_file_size; + idxfilesize=dict_info.index_file_size; 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) { int iIndexCount = 0; - + 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] = -1; // -1 is the end. - + + aIndex[iIndexCount] = -1; // -1 is the end. + return iIndexCount > 0; } @@ -888,25 +877,25 @@ void Libs::load_dict(const std::string& url) } void Libs::load(const std::list& dicts_dirs, - const std::list& order_list, + const std::list& order_list, const std::list& 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 { if (!disable) - load_dict(url); + load_dict(url); }); } -void Libs::reload(const std::list& dicts_dirs, - const std::list& order_list, +void Libs::reload(const std::list& dicts_dirs, + const std::list& order_list, const std::list& disable_list) { std::vector prev(oLib); oLib.clear(); - for_each_file(dicts_dirs, ".ifo", order_list, disable_list, - [&prev, this](const std::string& url, bool disable) -> void { + for_each_file(dicts_dirs, ".ifo", order_list, disable_list, + [&prev, this](const std::string& url, bool disable) -> void { if (!disable) { auto it = prev.begin(); for (; it != prev.end(); ++it) @@ -917,14 +906,14 @@ void Libs::reload(const std::list& dicts_dirs, prev.erase(it); oLib.push_back(res); } else - load_dict(url); + load_dict(url); } }); for (Dict *p : prev) delete p; } - + const gchar *Libs::poGetCurrentWord(glong * iCurrent) { const gchar *poCurrentWord = nullptr; @@ -938,7 +927,7 @@ const gchar *Libs::poGetCurrentWord(glong * iCurrent) poCurrentWord = poGetWord(iCurrent[iLib],iLib); } else { word = poGetWord(iCurrent[iLib],iLib); - + if (stardict_strcmp(poCurrentWord, word) > 0 ) poCurrentWord = word; } @@ -967,7 +956,7 @@ const gchar *Libs::poGetNextWord(const gchar *sWord, glong *iCurrent) iCurrentLib = iLib; } else { word = poGetWord(iCurrent[iLib],iLib); - + if (stardict_strcmp(poCurrentWord, word) > 0 ) { poCurrentWord = word; iCurrentLib = iLib; @@ -1018,7 +1007,7 @@ Libs::poGetPreWord(glong * iCurrent) } } } - + if (poCurrentWord) { iCurrent[iCurrentLib]--; for (std::vector::size_type iLib=0;iLib2) { isupcase = !strncmp(&sWord[iWordLen-2],"LY",2); @@ -1109,9 +1098,9 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) strcpy(sNewWord,sWord); sNewWord[iWordLen-2]='\0'; // cut "ly" if (iWordLen>5 && sNewWord[iWordLen-3]==sNewWord[iWordLen-4] - && !bIsVowel(sNewWord[iWordLen-4]) && + && !bIsVowel(sNewWord[iWordLen-4]) && bIsVowel(sNewWord[iWordLen-5])) {//doubled - + sNewWord[iWordLen-3]='\0'; if( oLib[iLib]->Lookup(sNewWord, iIndex) ) bFound=true; @@ -1126,7 +1115,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) } if (!bFound) sNewWord[iWordLen-3]=sNewWord[iWordLen-4]; //restore - } + } } if (!bFound) { if (oLib[iLib]->Lookup(sNewWord, iIndex)) @@ -1142,7 +1131,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) } } } - + //cut "ing" if(!bFound && iWordLen>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); sNewWord[iWordLen-3]='\0'; if ( iWordLen>6 && (sNewWord[iWordLen-4]==sNewWord[iWordLen-5]) - && !bIsVowel(sNewWord[iWordLen-5]) && - bIsVowel(sNewWord[iWordLen-6])) { //doubled + && !bIsVowel(sNewWord[iWordLen-5]) && + bIsVowel(sNewWord[iWordLen-6])) { //doubled sNewWord[iWordLen-4]='\0'; if (oLib[iLib]->Lookup(sNewWord, iIndex)) bFound=true; @@ -1178,7 +1167,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) bFound=true; } g_free(casestr); - } + } } if(!bFound) { if (isupcase) @@ -1194,25 +1183,25 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) bFound=true; } g_free(casestr); - } + } } } } - + //cut two char "es" if(!bFound && iWordLen>3) { - isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) && - (sWord[iWordLen-3] == 'S' || - sWord[iWordLen-3] == 'X' || - sWord[iWordLen-3] == 'O' || - (iWordLen >4 && sWord[iWordLen-3] == 'H' && - (sWord[iWordLen-4] == 'C' || + isupcase = (!strncmp(&sWord[iWordLen-2],"ES",2) && + (sWord[iWordLen-3] == 'S' || + sWord[iWordLen-3] == 'X' || + sWord[iWordLen-3] == 'O' || + (iWordLen >4 && sWord[iWordLen-3] == 'H' && + (sWord[iWordLen-4] == 'C' || sWord[iWordLen-4] == 'S')))); - if (isupcase || - (!strncmp(&sWord[iWordLen-2],"es",2) && - (sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || - sWord[iWordLen-3] == 'o' || - (iWordLen >4 && sWord[iWordLen-3] == 'h' && + if (isupcase || + (!strncmp(&sWord[iWordLen-2],"es",2) && + (sWord[iWordLen-3] == 's' || sWord[iWordLen-3] == 'x' || + sWord[iWordLen-3] == 'o' || + (iWordLen >4 && sWord[iWordLen-3] == 'h' && (sWord[iWordLen-4] == 'c' || sWord[iWordLen-4] == 's'))))) { strcpy(sNewWord,sWord); sNewWord[iWordLen-2]='\0'; @@ -1228,7 +1217,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) } } } - + //cut "ed" if (!bFound && iWordLen>3) { isupcase = !strncmp(&sWord[iWordLen-2],"ED",2); @@ -1236,8 +1225,8 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) strcpy(sNewWord,sWord); sNewWord[iWordLen-2]='\0'; if (iWordLen>5 && (sNewWord[iWordLen-3]==sNewWord[iWordLen-4]) - && !bIsVowel(sNewWord[iWordLen-4]) && - bIsVowel(sNewWord[iWordLen-5])) {//doubled + && !bIsVowel(sNewWord[iWordLen-4]) && + bIsVowel(sNewWord[iWordLen-5])) {//doubled sNewWord[iWordLen-3]='\0'; if (oLib[iLib]->Lookup(sNewWord, iIndex)) bFound=true; @@ -1268,7 +1257,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) } } } - + // cut "ied" , add "y". if (!bFound && iWordLen>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". if (!bFound && iWordLen>3) { isupcase = !strncmp(&sWord[iWordLen-3],"IES",3); @@ -1333,7 +1322,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib) } } } - + // cut "est". if (!bFound && iWordLen>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); - } - + } + if (bFound) iWordIndex = iIndex; #if 0 @@ -1381,7 +1370,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si if (sWord[0] == '\0') return false; - Fuzzystruct oFuzzystruct[reslist_size]; + Fuzzystruct oFuzzystruct[reslist_size]; for (int i = 0; i < reslist_size; i++) { oFuzzystruct[i].pMatchWord = nullptr; @@ -1412,13 +1401,13 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si sCheck = poGetWord(index,iLib); // tolower and skip too long or too short words iCheckWordLen = g_utf8_strlen(sCheck, -1); - if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || + if (iCheckWordLen-ucs4_str2_len>=iMaxDistance || ucs4_str2_len-iCheckWordLen>=iMaxDistance) continue; ucs4_str1 = g_utf8_to_ucs4_fast(sCheck, -1, nullptr); if (iCheckWordLen > ucs4_str2_len) ucs4_str1[ucs4_str2_len]=0; - unicode_strdown(ucs4_str1); + unicode_strdown(ucs4_str1); iDistance = oEditDistance.CalEditDistance(ucs4_str1, ucs4_str2, iMaxDistance); g_free(ucs4_str1); @@ -1428,7 +1417,7 @@ bool Libs::LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_si bool bAlreadyInList = false; int iMaxDistanceAt=0; for (int j=0; j bool { 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) return stardict_strcmp(lh.pMatchWord, rh.pMatchWord)<0; - + return false; }); - + for (gint i = 0; i < reslist_size; ++i) reslist[i] = oFuzzystruct[i].pMatchWord; - + return Found; } gint Libs::LookupWithRule(const gchar *word, gchar **ppMatchWord) -{ +{ glong aiIndex[MAX_MATCH_ITEM_PER_LIB+1]; gint iMatchCount = 0; GPatternSpec *pspec = g_pattern_spec_new(word); - + for (std::vector::size_type iLib=0; iLibLookupWithRule(pspec,aiIndex, MAX_MATCH_ITEM_PER_LIB+1)) { if (progress_func) progress_func(); @@ -1501,12 +1490,12 @@ gint Libs::LookupWithRule(const gchar *word, gchar **ppMatchWord) } } g_pattern_spec_free(pspec); - + if (iMatchCount)// sort it. std::sort(ppMatchWord, ppMatchWord+iMatchCount, [](const char *lh, const char *rh) -> bool { return stardict_strcmp(lh, rh)<0; - }); - + }); + return iMatchCount; } @@ -1577,7 +1566,7 @@ bool Libs::LookupData(const gchar *sWord, std::vector *reslist) for (i = 0; i < oLib.size(); ++i) if (!reslist[i].empty()) break; - + return i != oLib.size(); } diff --git a/src/stardict_lib.hpp b/src/stardict_lib.hpp index 1f5fbea..eea7627 100644 --- a/src/stardict_lib.hpp +++ b/src/stardict_lib.hpp @@ -56,7 +56,7 @@ public: protected: std::string sametypesequence; FILE *dictfile = nullptr; - std::unique_ptr dictdzfile; + std::unique_ptr dictdzfile; private: cacheItem cache[WORDDATA_CACHE_NUM]; gint cache_cur = 0; diff --git a/src/utils.cpp b/src/utils.cpp index dee1f8a..fa208d3 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -53,22 +53,6 @@ std::string utf8_to_locale_ign_err(const std::string& utf8_str) 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, const std::list& order_list, const std::list& disable_list, const std::function& f) diff --git a/src/utils.hpp b/src/utils.hpp index 7b0874e..637658b 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -14,6 +15,10 @@ public: ResourceWrapper& operator=(const ResourceWrapper&) = delete; T *operator->() const { return p_; } bool operator!() const { return p_ == nullptr; } + const T& operator[](size_t idx) const { + assert(p_ != nullptr); + return p_[idx]; + } void reset(T *newp) { if (p_ != newp) { @@ -56,8 +61,6 @@ namespace glib { typedef ResourceWrapper Error; } - -extern char *locale_to_utf8(const char *locstr); extern std::string utf8_to_locale_ign_err(const std::string& utf8_str); extern void for_each_file(const std::list& dirs_list, const std::string& suff,