tak的内嵌cue提取

tak的内嵌cue提取非常简单。内嵌的cue位于文件尾部,以utf-8编码存放。只要捕捉到起始点和结束点,拷贝出来即可。
内嵌cue的起始标记是Cuesheet,大小写不敏感,结束标记是之后遇到的第一个连续终止符串(六个终止符以上)
为了不用读取整个tak文件,将文件指针移到最后20K处,将之后的数据拷贝出来,在这20K的数据中搜索。一般的cue也不会有那么长吧

	CFile OpenFile;
	if (!OpenFile.Open(TakFilePathName,CFile::modeRead|CFile::shareDenyWrite|CFile::typeBinary))
	{
		OpenFile.Close();
		::AfxMessageBox(_T("打开失败!"),MB_OK);
		return FALSE;
	}

	if (OpenFile.GetLength()<20480) // 小于20K,文档太小了
	{
		OpenFile.Close();
		return FALSE;
	}

	OpenFile.Seek(-20480,CFile::end);
	unsigned char Buffer[20480]; //20k的缓冲区
	memset(Buffer,0,20480);
	OpenFile.Read(Buffer,20480);
	OpenFile.Close();

	//查找 Cuesheet 标记,自动机模型,大小写不敏感
	int state=0,BeginPos=0,EndPos=0,Length=0;
	for (int i=0;i<20480;++i)
	{
		if ((Buffer[i]>=0x41)&&(Buffer[i]<=0x5A))
			Buffer[i]=Buffer[i]+0x20;

		switch (Buffer[i])
		{
		case 'c':
			state=1;      //C
			break;
		case 'u':
			if (state==1)
				state=2;  //Cu
			else
				state=0;
			break;
		case 'e':
			switch (state)
			{
			case 2:
				state=3;  //Cue
				break;
			case 5:
				state=6;  //Cueshe
				break;
			case 6:
				state=7;  //Cueshee
				break;
			default:
				state=0;
			}
			break;
		case 's':
			if (state==3)
				state=4;  //Cues
			else
				state=0;
			break;
		case 'h':
			if (state==4)
				state=5;  //Cuesh
			else
				state=0;
			break;
		case 't':
			if (state==7)
			{
				state=8;  //Cuesheet
			}
			else
				state=0;
			break;
		default:
			state=0;
		}
		if (state==8)
		{
			BeginPos=i+2;
			break;
		}
	}

	if (BeginPos==0)
		return FALSE;

	//查找终止符 0D 0A ? 00 00 00 00 00 00 (连续六个终止符以上)
	state=0;
	for (int i=BeginPos;i<20480;++i)
	{
		switch (Buffer[i])
		{
		case '\0':
			state++;
			break;
		default:
			state=0;
		}
		if (state==6)
		{
			EndPos=i-6; //指向0D 0A后的第一个字符
			break;
		}
	}

	if (EndPos<=1)
		return FALSE;

	if ((Buffer[EndPos-2]=='\x0D')&&(Buffer[EndPos-1]=='\x0A'))
		EndPos--;

	Length=EndPos-BeginPos+1;
	if (Length<=10) //too short
		return FALSE;

	unsigned char *CueString;
	CueString=new unsigned char[Length+1];
	memcpy(CueString,Buffer+BeginPos,Length);
	CueString[Length]='\0';

	delete []CueString;
	return TRUE;

CueString中存放的即是utf-8编码的cue字符串,写入到文件即可。
这自动机模型捕捉Cuesheet写得很优美(擦汗

2010年9月6日 | 归档于 技术, 程序
标签: , , , , ,
本文目前尚无任何评论.

发表评论

XHTML: 您可以使用这些标签: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!: