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

📄 dict.cpp

📁 Motorola E680I QtE 词典软件NDIct源码。
💻 CPP
字号:
#include "Dict.h"
#include "BitIo.h"

#define DISP_BITS 11
#define COUNT_BITS 3
struct tDocHeader {
	char sName[32];		// 32 bytes
	DWORD dwUnknown1;	// 36
	DWORD dwTime1;		// 40
	DWORD dwTime2;		// 44
	DWORD dwTime3;		// 48
	DWORD dwLastSync;	// 52
	DWORD ofsSort;		// 56
	DWORD ofsCatagories;	// 60
	char dwCreator[4];	// 64
	char dwType[4];		// 68
	DWORD dwUnknown2;	// 72
	DWORD dwUnknown3;	// 76
	WORD  wNumRecs;		// 78
};
#define DOCHEADSZ 78
struct tRecord0head{
	WORD  Unknown1;	// 0
	WORD  wdicnum;		// 2 always be 1,maybe dictionaries num...or compressed flag?
	WORD  wsecnum;		// 4
	WORD  Unknown2;     //6 always be 1
	char  Unknown3[8];		// 48
};


WORD SwapWord21(WORD r)
{
	return (r>>8) + (r<<8);
};
WORD SwapWord12(WORD r)
{
	return r;  
};
DWORD SwapLong4321(DWORD r)
{
	return  ((r>>24) & 0xFF) + (r<<24) + ((r>>8) & 0xFF00) + ((r<<8) & 0xFF0000);
};
DWORD SwapLong1234(DWORD r)
{
	return r;
};


// copy bytes into a word and double word and see how they fall,
// then choose the appropriate swappers to make things come out
// in the right order.
int Dict::SwapChoose()
{
	union { char b[2]; WORD w; } w;
	union { char b[4]; DWORD d; } d;

	strncpy(w.b, "\1\2", 2);
	strncpy(d.b, "\1\2\3\4", 4);

	if (w.w == 0x0201)
		SwapWord = SwapWord21;
	else if (w.w == 0x0102)
		SwapWord = SwapWord12;
	else
		return 0;

	if (d.d == 0x04030201)
		SwapLong = SwapLong4321;
	else if (d.d == 0x01020304)
		SwapLong = SwapLong1234;
	else
		return 0;

	return 1;
}
char *Dict::getLine(FILE *in)
{
	int i=0;
	char *buf=new char[4096];
	while(buf[i]=fgetc(in))
	{
		if(i>4096) break;
		if(buf[i]==EOF) break;                      
		i++;
	}
	buf=(char *)realloc(buf,i+1);
	if(!buf) printf("none buffer!");
	buf[i]='\0';
	return buf; 
}

bool Dict::OpenDict(char * fileName)
{

	SwapChoose();
	//delete out-of-date data
	CloseDict();
	tDocHeader docHeader;
	tRecord0head recHead;
	fin=fopen(fileName,"rb");
	if(!fin)
	{
		open=false;
		return 0;
	}
	//read the doc header
	fread(&docHeader, 1, DOCHEADSZ, fin);
	docHeader.wNumRecs=SwapWord(docHeader.wNumRecs);

	//printf("dict name: %s\nCreator: %s\nType: %s\nRecord Numbers: %d\n",docHeader.sName,docHeader.dwCreator,docHeader.dwType,docHeader.wNumRecs);
	strncpy(dictName,docHeader.sName,sizeof(dictName));
	if(strncmp( docHeader.dwCreator,"Kdict",5) && strncmp(docHeader.dwCreator,"Zdict",5) && strncmp(docHeader.dwCreator,"Dict",4))
	{
		fclose(fin);
		open=false;
		return 0;
	}
	//get the record header
	fseek(fin,0x4e,SEEK_SET);
	DWORD dwPos;
	fread(&dwPos, 4, 1, fin);					//read start pos
	dwPos = SwapLong(dwPos);
	//printf("First record located at %u\n",dwPos);

	fseek(fin,dwPos,SEEK_SET);
	fread(&recHead,sizeof(recHead),1,fin);		//read header
	recHead.wdicnum=SwapWord(recHead.wdicnum);
	secNumber=recHead.wsecnum=SwapWord(recHead.wsecnum);
	//printf("dict number: %u\nsec number: %u\n",recHead.wdicnum,recHead.wsecnum);	
	//get the section size
	WORD size;
	secSize = new int[recHead.wsecnum+1];
	secSize[0]=recHead.wsecnum;
	for(int i=0;i<secSize[0];i++)
	{
		fread(&size,2,1,fin);					//read the section size
		secSize[i+1]=SwapWord(size);
		//printf("sec%d size:%u\n",i,secSize[i+1]);
	}
	//get the indexs
	dicIndex = new char*[2*recHead.wsecnum];	//every section two lines
	for(int i=0;i<2*secSize[0];i++)
	{
		dicIndex[i]=getLine(fin);
		//printf("%s\n",dicIndex[i]);
	}
	open = true;
	return 1;
}
void Dict::CloseDict()
{
	if(secSize)
	{
		for(int i=0;i<secSize[0];i++)
			delete [] dicIndex[i];
		delete [] dicIndex;
		delete[] secSize;
		open=false;
	}
	curSecIndex=-1;
	if(fin)
		fclose(fin);
}

long Dict::SearchSector(const char* queryWord)
{
	if(!open)
		return -1;
	//printf("Searching:%s\n",queryWord);
	int s,e,mid,cmp;
	for(s=0,e=secSize[0]-1;s<e;)
	{
		mid=2*(int)((s+e)/2);//be carefull 3,4=>3
		//printf("querying '%s'\n",dicIndex[mid]);
		cmp=strcmp(queryWord,dicIndex[mid]);
		if(cmp>0)
			s=mid/2+1;
		if(cmp<0)
			e=mid/2;
		if(cmp==0)
			s=e=mid/2+1;
	}
	s-=1;
	if(s<0)
		return -1;
	if(strcmp(queryWord,dicIndex[s*2+1])<=0)
		return s;
	else
		return -1;
}
int Dict::Decompresslzss(char* enc,long len,char** dec)
{
	*dec = new byte[6000];	//申请空间
	tIobuf *in_buf,*output;
	in_buf=new tIobuf();
	output=new tIobuf();
	BIT_FILE* input;

	output->len=6000;
	output->buf=*dec;
	in_buf->buf=enc;
	in_buf->len=len;
	input=OpenInputBitFile(in_buf);//输入内容
	//len=ExpandFile(in_file,&out_buf);
	///////////////////////////just put the things in ExpandFile here!    
	int i; 
	int current_position; 
	int c; 
	int match_length; 
	int match_position;
	int totalbytes=0;
	current_position = 1;
	for ( ; ; ) { 
		if (c=InputBit( input ) ) {     
			c = (int)InputBits( input, 8 );
			output->putbyte(c);totalbytes++; 
			window[ current_position ] = (unsigned char) c; 
			current_position = MOD_WINDOW( current_position + 1 ); 
		} else { 
			match_position = (int) InputBits( input, INDEX_BIT_COUNT ); 
			if ( match_position == END_OF_STREAM ) 
				break; 
			match_length = (int) InputBits( input, LENGTH_BIT_COUNT ); 
			match_length += BREAK_EVEN; 
			for ( i = 0 ; i <= match_length ; i++ ) { 
				c = window[ MOD_WINDOW( match_position + i ) ]; 
				output->putbyte(c); totalbytes++;
				window[ current_position ] = (unsigned char) c; 
				current_position = MOD_WINDOW( current_position + 1 ); 
			} 
		} 
	} 
	CloseInputBitFile(input);
	*dec=(char*)realloc(*dec,totalbytes+1);
	(*dec)[totalbytes]='\0';
	return totalbytes;
}
long Dict::GetSector(long secIndex, char** enc)
{
	if(!open)
		return -1;
	int sz=secSize[secIndex+1];
	if(secIndex>=secSize[0])
		return -1;
	fseek(fin,0x56+8*secIndex,SEEK_SET);
	DWORD dwPos;
	fread(&dwPos,4,1,fin);
	fseek(fin,SwapLong(dwPos),SEEK_SET);
	if(*enc)
		delete[] *enc;
	*enc=new char[sz];
	if(sz!=fread(*enc,1,sz,fin))
		return -1;
	return sz;
}
int Dict::GetWordList(const char* queryWord, char ***list)
{
	if(!open)
		return -1;
	long secIndex=SearchSector(queryWord);
	if(secIndex==-1)
		return -1;
	if(curSecIndex!=secIndex)
	{
		curSecIndex=secIndex;
		char* enc_buf=NULL;
		long len=GetSector(secIndex,&enc_buf);
		dec_len=Decompresslzss(enc_buf,len,&dec_buf);
		delete[] enc_buf;
	}

	char* buf=new char[255];
	bool flag=0;
	int listIndex=0;
	(*list)=new char*[MaxList+1];
	for(int i=0,j=0;i<dec_len;i++)
	{
		if(dec_buf[i]==0x09)
		{
			flag=1;
			buf[j]='\0';
			//printf("listing:%s\n",buf);
			if(strcmp(buf,queryWord)>=0)
			{
				//printf("no%d:%s\n",listIndex,buf);
				(*list)[listIndex]=new char[j+1];
				
				strcpy((*list)[listIndex],buf);
				//printf("no%d:%s\n",listIndex,(*list)[listIndex]);
				if(listIndex++>=MaxList)
					break;
			}
			j=0;

		}
		if(!flag)
			buf[j++]=dec_buf[i];
		if(dec_buf[i]==0x0a)
			flag=0;
	}
	if(listIndex<=MaxList&&++secIndex<secNumber){
		curSecIndex=secIndex;
		char *enc_buf=NULL;
		long len=GetSector(secIndex,&enc_buf);
		dec_len=Decompresslzss(enc_buf,len,&dec_buf);
		delete[] enc_buf;
		for(int i=0,j=0;i<dec_len;i++){
			if(dec_buf[i]==0x09){
				flag=1;
				buf[j]='\0';
				//printf("listing:%s\n",buf);
				if(strcmp(buf,queryWord)>=0){
					//printf("no%d:%s\n",listIndex,buf);
					(*list)[listIndex]=new char[j+1];
					
					strcpy((*list)[listIndex],buf);
					//printf("no%d:%s\n",listIndex,(*list)[listIndex]);
					if(listIndex++>=MaxList)
						break;
				}
				j=0;
			}
			if(!flag)
				buf[j++]=dec_buf[i];
			if(dec_buf[i]==0x0a)
				flag=0;
		}
	}
	delete[] buf;
	return listIndex;
}
int Dict::GetExp(const char* queryWord, char **exp)
{
	if(!open)
		return -1;
	long secIndex=SearchSector(queryWord);
	if(secIndex==-1)
		return -1;
	if(curSecIndex!=secIndex)
	{
		curSecIndex=secIndex;
		char* enc_buf=NULL;
		long len=GetSector(secIndex,&enc_buf);
		dec_len=Decompresslzss(enc_buf,len,&dec_buf);
	}
	char* buf=new char[6000];
	bool flag=0,find=0;
	int i,j;
	for(i=0,j=0;i<dec_len;i++)
	{
		if(dec_buf[i]==0x09)//extra signal word
		{
			if(flag==0)
			{
				flag=1;
				buf[j]='\0';
				if(strcmp(buf,queryWord)==0)//compare with dest word
				{
					find=1;
					buf[j++]='\n';
				}
				else
					j=0;
			}
		}
		if(!flag)
			buf[j++]=dec_buf[i];
		if(dec_buf[i]==0x0a)
		{
			flag=0;
		}
		if(find)//copy and dealing explain strings.
		{
			if(dec_buf[i]=='\t')
				;//buf[j++]='\n';
			else if(dec_buf[i]=='n' && buf[j-1]=='\\')
				buf[j-1]='\n';
			else if(dec_buf[i]==0x0a)
			{
				buf[j]='\0';
				break;
			}
			else
				buf[j++]=dec_buf[i];
		}
	}
	if(find)
	{
		if(j>6000)
			j=6000;
		*exp=new char[j+1];
		memcpy(*exp,buf,j+1);
	}
	delete[] buf;
	return find?j+1:-1;
}

⌨️ 快捷键说明

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