⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib.cpp

📁 使用Qt4编写的星际译王(stardict)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	std::string cache_dir=std::string(g_get_user_cache_dir())+G_DIR_SEPARATOR_S+"sdcv";	if (!g_file_test(cache_dir.c_str(), G_FILE_TEST_EXISTS)) {		if (g_mkdir(cache_dir.c_str(), 0700)==-1)			return res;	} else if (!g_file_test(cache_dir.c_str(), G_FILE_TEST_IS_DIR))		return res;	gchar *base=g_path_get_basename(url.c_str());	res.push_back(cache_dir+G_DIR_SEPARATOR_S+base+".oft");	g_free(base);	return res;}bool offset_index::save_cache(const std::string& url){	strlist_t vars=get_cache_variant(url);	for (strlist_t::const_iterator it=vars.begin(); it!=vars.end(); ++it) {		FILE *out=fopen(it->c_str(), "wb");		if (!out)			continue;		if (fwrite(CACHE_MAGIC, 1, strlen(CACHE_MAGIC), out)!=strlen(CACHE_MAGIC))			continue;		if (fwrite(&wordoffset[0], sizeof(wordoffset[0]), wordoffset.size(), out)!=wordoffset.size())			continue;		fclose(out);		printf("save to cache %s\n", url.c_str());		return true;	}	return false;}bool offset_index::load(const std::string& url, gulong wc, gulong fsize){	wordcount=wc;	gulong npages=(wc-1)/ENTR_PER_PAGE+2;	wordoffset.resize(npages);	if (!load_cache(url)) {//map file will close after finish of block		MapFile map_file;		if (!map_file.open(url.c_str(), fsize))			return false;				const gchar *idxdatabuffer=map_file.begin();		const gchar *p1 = idxdatabuffer;		gulong index_size;		guint32 j=0;		for (guint32 i=0; i<wc; i++) {			index_size=strlen(p1) +1 + 2*sizeof(guint32);			if (i % ENTR_PER_PAGE==0) {				wordoffset[j]=p1-idxdatabuffer;				++j;			}			p1 += index_size;		}		wordoffset[j]=p1-idxdatabuffer;		if (!save_cache(url))			fprintf(stderr, "cache update failed\n");	}	if (!(idxfile = fopen(url.c_str(), "rb"))) {		wordoffset.resize(0);		return false;	}	first.assign(0, read_first_on_page_key(0));	last.assign(wordoffset.size()-2, read_first_on_page_key(wordoffset.size()-2));	middle.assign((wordoffset.size()-2)/2, read_first_on_page_key((wordoffset.size()-2)/2));	real_last.assign(wc-1, get_key(wc-1));	return true;}inline gulong offset_index::load_page(glong page_idx){	gulong nentr=ENTR_PER_PAGE;	if (page_idx==glong(wordoffset.size()-2))		if ((nentr=wordcount%ENTR_PER_PAGE)==0)			nentr=ENTR_PER_PAGE;		if (page_idx!=page.idx) {		page_data.resize(wordoffset[page_idx+1]-wordoffset[page_idx]);		fseek(idxfile, wordoffset[page_idx], SEEK_SET);		fread(&page_data[0], 1, page_data.size(), idxfile);		page.fill(&page_data[0], nentr, page_idx);	}	return nentr;}const gchar *offset_index::get_key(glong idx){	load_page(idx/ENTR_PER_PAGE);	glong idx_in_page=idx%ENTR_PER_PAGE;	wordentry_offset=page.entries[idx_in_page].off;	wordentry_size=page.entries[idx_in_page].size;	return page.entries[idx_in_page].keystr;}void offset_index::get_data(glong idx){	get_key(idx);}const gchar *offset_index::get_key_and_data(glong idx){	return get_key(idx);}bool offset_index::lookup(const char *str, glong &idx){	bool bFound=false;	glong iFrom;	glong iTo=wordoffset.size()-2;	gint cmpint;	glong iThisIndex;	if (stardict_strcmp(str, first.keystr.c_str())<0) {		idx = 0;		return false;	} else if (stardict_strcmp(str, real_last.keystr.c_str()) >0) {		idx = INVALID_INDEX;		return false;	} else {		iFrom=0;		iThisIndex=0;		while (iFrom<=iTo) {			iThisIndex=(iFrom+iTo)/2;			cmpint = stardict_strcmp(str, get_first_on_page_key(iThisIndex));			if (cmpint>0)				iFrom=iThisIndex+1;			else if (cmpint<0)				iTo=iThisIndex-1;			else {					bFound=true;				break;			}		}		if (!bFound)			idx = iTo;    //prev		else			idx = iThisIndex;			}	if (!bFound) {		gulong netr=load_page(idx);		iFrom=1; // Needn't search the first word anymore.		iTo=netr-1;		iThisIndex=0;		while (iFrom<=iTo) {			iThisIndex=(iFrom+iTo)/2;			cmpint = stardict_strcmp(str, page.entries[iThisIndex].keystr);			if (cmpint>0)				iFrom=iThisIndex+1;			else if (cmpint<0)				iTo=iThisIndex-1;			else {				bFound=true;				break;			}		}		idx*=ENTR_PER_PAGE;		if (!bFound)			idx += iFrom;    //next		else			idx += iThisIndex;	} else {		idx*=ENTR_PER_PAGE;	}	return bFound;}wordlist_index::~wordlist_index(){		g_free(idxdatabuf);}bool wordlist_index::load(const std::string& url, gulong wc, gulong fsize){	gzFile in = gzopen(url.c_str(), "rb");	if (in == NULL)			return false;				idxdatabuf = (gchar *)g_malloc(fsize);			gulong len = gzread(in, idxdatabuf, fsize);	gzclose(in);	if (len != fsize)		return false;  wordlist.resize(wc+1);	gchar *p1 = idxdatabuf;  guint32 i;  for (i=0; i<wc; i++) {		wordlist[i] = p1;    p1 += strlen(p1) +1 + 2*sizeof(guint32);	}	wordlist[wc] = p1;	return true;}const gchar *wordlist_index::get_key(glong idx){	return wordlist[idx];}void wordlist_index::get_data(glong idx){	gchar *p1 = wordlist[idx]+strlen(wordlist[idx])+sizeof(gchar);	wordentry_offset = g_ntohl(*reinterpret_cast<guint32 *>(p1));	p1 += sizeof(guint32);	wordentry_size = g_ntohl(*reinterpret_cast<guint32 *>(p1));}const gchar *wordlist_index::get_key_and_data(glong idx){	get_data(idx);	return get_key(idx);}bool wordlist_index::lookup(const char *str, glong &idx){	bool bFound=false;	glong iTo=wordlist.size()-2;	if (stardict_strcmp(str, get_key(0))<0) {		idx = 0;	} else if (stardict_strcmp(str, get_key(iTo)) >0) {		idx = INVALID_INDEX;	} else {		glong iThisIndex=0;		glong iFrom=0;		gint cmpint;		while (iFrom<=iTo) {			iThisIndex=(iFrom+iTo)/2;			cmpint = stardict_strcmp(str, get_key(iThisIndex));			if (cmpint>0)				iFrom=iThisIndex+1;			else if (cmpint<0)				iTo=iThisIndex-1;			else {				bFound=true;				break;			}		}	if (!bFound)		idx = iFrom;    //next	else		idx = iThisIndex;		  }  return bFound;}//===================================================================bool Dict::load(const std::string& ifofilename){		gulong idxfilesize;	if (!load_ifofile(ifofilename, idxfilesize))		return false;	std::string fullfilename(ifofilename);	fullfilename.replace(fullfilename.length()-sizeof("ifo")+1, sizeof("ifo")-1, "dict.dz");		if (g_file_test(fullfilename.c_str(), G_FILE_TEST_EXISTS)) {		dictdzfile.reset(new dictData);		if (!dictdzfile->open(fullfilename, 0)) {			//g_print("open file %s failed!\n",fullfilename);			return false;		}	} else {		fullfilename.erase(fullfilename.length()-sizeof(".dz")+1, sizeof(".dz")-1);		dictfile = fopen(fullfilename.c_str(),"rb");		if (!dictfile) {			//g_print("open file %s failed!\n",fullfilename);			return false;		}	}	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 wordlist_index);	} else {		fullfilename.erase(fullfilename.length()-sizeof(".gz")+1, sizeof(".gz")-1);		idx_file.reset(new offset_index);	}	if (!idx_file->load(fullfilename, wordcount, idxfilesize))		return false;	//g_print("bookname: %s , wordcount %lu\n", bookname.c_str(), narticles());	return true;}bool Dict::load_ifofile(const std::string& ifofilename, gulong &idxfilesize){	DictInfo dict_info;	if (!dict_info.load_from_ifo_file(ifofilename, false))		return false;	if (dict_info.wordcount==0)		return false;		ifo_file_name=dict_info.ifo_file_name;	wordcount=dict_info.wordcount;	bookname=dict_info.bookname;	idxfilesize=dict_info.index_file_size;  	sametypesequence=dict_info.sametypesequence;	return true;}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)))        			aIndex[iIndexCount++]=i;                aIndex[iIndexCount]= -1; // -1 is the end.		  return (iIndexCount>0);}//===================================================================Libs::Libs(progress_func_t f){	progress_func=f;	iMaxFuzzyDistance  = MAX_FUZZY_DISTANCE; //need to read from cfg.}Libs::~Libs(){		for (std::vector<Dict *>::iterator p=oLib.begin(); p!=oLib.end(); ++p)		delete *p;}void Libs::load_dict(const std::string& url){	Dict *lib=new Dict;	if (lib->load(url))		oLib.push_back(lib);	else		delete lib;}class DictLoader {public:	DictLoader(Libs& lib_): lib(lib_) {}	void operator()(const std::string& url, bool disable) { 		if (!disable)			lib.load_dict(url); 	}private:	Libs& lib;};void Libs::load(const strlist_t& dicts_dirs,		const strlist_t& order_list, 		const strlist_t& disable_list){	for_each_file(dicts_dirs, ".ifo", order_list, disable_list, 		      DictLoader(*this));}class DictReLoader {public:	DictReLoader(std::vector<Dict *> &p, std::vector<Dict *> &f,							 Libs& lib_) : prev(p), future(f), lib(lib_)	{	}	void operator()(const std::string& url, bool disable) { 		if (!disable) {			Dict *dict=find(url);			if (dict)				future.push_back(dict);			else				lib.load_dict(url); 		}	}private:	std::vector<Dict *> &prev;	std::vector<Dict *> &future;	Libs& lib;	Dict *find(const std::string& url) {		std::vector<Dict *>::iterator it;		for (it=prev.begin(); it!=prev.end(); ++it)			if ((*it)->ifofilename()==url)				break;		if (it!=prev.end()) {			Dict *res=*it;			prev.erase(it);			return res;		}		return NULL;	}};void Libs::reload(const strlist_t& dicts_dirs, 									const strlist_t& order_list, 									const strlist_t& disable_list){	std::vector<Dict *> prev(oLib);	oLib.clear();	for_each_file(dicts_dirs, ".ifo", order_list, disable_list, 								DictReLoader(prev, oLib, *this));	for (std::vector<Dict *>::iterator it=prev.begin(); it!=prev.end(); ++it)		delete *it;}	const gchar *Libs::poGetCurrentWord(glong * iCurrent){  const gchar *poCurrentWord = NULL;  const gchar *word;  for (std::vector<Dict *>::size_type iLib=0; iLib<oLib.size(); iLib++) {    if (iCurrent[iLib]==INVALID_INDEX)      continue;    if ( iCurrent[iLib]>=narticles(iLib) || iCurrent[iLib]<0)      continue;    if ( poCurrentWord == NULL ) {      poCurrentWord = poGetWord(iCurrent[iLib],iLib);    } else {      word = poGetWord(iCurrent[iLib],iLib);            if (stardict_strcmp(poCurrentWord, word) > 0 )				poCurrentWord = word;    }  }  return poCurrentWord;}const gchar *Libs::poGetNextWord(const gchar *sWord, glong *iCurrent){	// the input can be:	// (word,iCurrent),read word,write iNext to iCurrent,and return next word. used by TopWin::NextCallback();	// (NULL,iCurrent),read iCurrent,write iNext to iCurrent,and return next word. used by AppCore::ListWords();	const gchar *poCurrentWord = NULL;	std::vector<Dict *>::size_type iCurrentLib=0;	const gchar *word;	for (std::vector<Dict *>::size_type iLib=0;iLib<oLib.size();iLib++) {		if (sWord)			oLib[iLib]->Lookup(sWord, iCurrent[iLib]);		if (iCurrent[iLib]==INVALID_INDEX)			continue;		if (iCurrent[iLib]>=narticles(iLib) || iCurrent[iLib]<0)			continue;		if (poCurrentWord == NULL ) {			poCurrentWord = poGetWord(iCurrent[iLib],iLib);			iCurrentLib = iLib;		}	else {			word = poGetWord(iCurrent[iLib],iLib);						if (stardict_strcmp(poCurrentWord, word) > 0 ) {				poCurrentWord = word;				iCurrentLib = iLib;			}		}	}	if (poCurrentWord) {		iCurrent[iCurrentLib]++;		for (std::vector<Dict *>::size_type iLib=0;iLib<oLib.size();iLib++) {			if (iLib == iCurrentLib)				continue;			if (iCurrent[iLib]==INVALID_INDEX)				continue;			if ( iCurrent[iLib]>=narticles(iLib) || iCurrent[iLib]<0)				continue;			if (strcmp(poCurrentWord, poGetWord(iCurrent[iLib],iLib)) == 0 )				iCurrent[iLib]++;		}		poCurrentWord = poGetCurrentWord(iCurrent);	}	return poCurrentWord;}const gchar *Libs::poGetPreWord(glong * iCurrent){	// used by TopWin::PreviousCallback(); the iCurrent is cached by AppCore::TopWinWordChange();	const gchar *poCurrentWord = NULL;	std::vector<Dict *>::size_type iCurrentLib=0;	const gchar *word;	for (std::vector<Dict *>::size_type iLib=0;iLib<oLib.size();iLib++) {		if (iCurrent[iLib]==INVALID_INDEX)			iCurrent[iLib]=narticles(iLib);		else {			if ( iCurrent[iLib]>narticles(iLib) || iCurrent[iLib]<=0)				continue;		}		if ( poCurrentWord == NULL ) {			poCurrentWord = poGetWord(iCurrent[iLib]-1,iLib);			iCurrentLib = iLib;		} else {			word = poGetWord(iCurrent[iLib]-1,iLib);			if (stardict_strcmp(poCurrentWord, word) < 0 ) {				poCurrentWord = word;				iCurrentLib = iLib;			}		}	}		if (poCurrentWord) {		iCurrent[iCurrentLib]--;		for (std::vector<Dict *>::size_type iLib=0;iLib<oLib.size();iLib++) {			if (iLib == iCurrentLib)				continue;			if (iCurrent[iLib]>narticles(iLib) || iCurrent[iLib]<=0)				continue;			if (strcmp(poCurrentWord, poGetWord(iCurrent[iLib]-1,iLib)) == 0) {				iCurrent[iLib]--;			} else {				if (iCurrent[iLib]==narticles(iLib))					iCurrent[iLib]=INVALID_INDEX;			}		}	}	return poCurrentWord;}bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib){	glong iIndex;  bool bFound=false;	gchar *casestr;	if (!bFound) {		// to lower case.		casestr = g_utf8_strdown(sWord, -1);		if (strcmp(casestr, sWord)) {			if(oLib[iLib]->Lookup(casestr, iIndex))				bFound=true;		}		g_free(casestr);		// to upper case.		if (!bFound) {			casestr = g_utf8_strup(sWord, -1);			if (strcmp(casestr, sWord)) {				if(oLib[iLib]->Lookup(casestr, iIndex))					bFound=true;			}			g_free(casestr);		}			// Upper the first character and lower others.		if (!bFound) {			gchar *nextchar = g_utf8_next_char(sWord);			gchar *firstchar = g_utf8_strup(sWord, nextchar - sWord);			nextchar = g_utf8_strdown(nextchar, -1);			casestr = g_strdup_printf("%s%s", firstchar, nextchar);			g_free(firstchar);			g_free(nextchar);			if (strcmp(casestr, sWord)) {				if(oLib[iLib]->Lookup(casestr, iIndex))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -