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

📄 asf_helper.cpp

📁 ASFR+是在ASFRecorder的基础上的改进版本,它可以: ◇支持中文文件名. ◇多线程下载ASF文件. ◇断点续传,自动重试. ◇支持MMS(TCP)协议和HTTP协议(自动探测). ◇在下载
💻 CPP
字号:
#include "../asfr.h"

#include "asf_commonh.h"
#include "asf_helper.h"

unsigned char ASF_HDR_ID[16] = {
	0xa1,0xdc,0xab,0x8c,0x47,0xa9,0xcf,0x11,0x8e,0xe4,0x00,0xc0,0x0c,0x20,0x53,0x65};

/* get 64bit integer (Little endian) */
void get_quad(unsigned char *pos, unsigned long *hi, unsigned long *lo)
{
	unsigned char c1 = *pos++, c2 = *pos++, c3 = *pos++, c4 = *pos++;
	unsigned char c5 = *pos++, c6 = *pos++, c7 = *pos++, c8 = *pos++;
	(*hi) = (c8<<24) + (c7<<16) + (c6<<8) + c5;
	(*lo) = (c4<<24) + (c3<<16) + (c2<<8) + c1;
}

/* write 64bit integer to stream (Little endian) */
void write_quad(FILE *outfile, unsigned int hi, unsigned int lo)
{
	unsigned char c1 = (lo & 0xff), c2 = ((lo>>8) & 0xff), c3 = ((lo>>16) & 0xff), c4 = ((lo>>24) & 0xff);
	unsigned char c5 = (hi & 0xff), c6 = ((hi>>8) & 0xff), c7 = ((hi>>16) & 0xff), c8 = ((hi>>24) & 0xff);
	fputc(c1, outfile);
	fputc(c2, outfile);
	fputc(c3, outfile);
	fputc(c4, outfile);
	fputc(c5, outfile);
	fputc(c6, outfile);
	fputc(c7, outfile);
	fputc(c8, outfile);
}

/* get 32bit integer (Little endian) */
void get_long(unsigned char *pos, unsigned long *val)
{
	unsigned char c1 = *pos++, c2 = *pos++, c3 = *pos++, c4 = *pos++;
	(*val) = (c4<<24) + (c3<<16) + (c2<<8) + c1;
}

/* put 32 bit integer (Little endian) */
void put_long(unsigned char *pos, unsigned long val)
{
	*pos++ = (val & 0xff);
	*pos++ = ((val>>8) & 0xff), *pos++ = ((val>>16) & 0xff), *pos++ = ((val>>24) & 0xff);
}

/* write a 32 bit integer to stream (Little endian) */
void write_long(FILE *outfile, unsigned long val)
{
	unsigned char c1 = (val & 0xff), c2 = ((val>>8) & 0xff), c3 = ((val>>16) & 0xff), c4 = ((val>>24) & 0xff);
	fputc(c1, outfile);
	fputc(c2, outfile);
	fputc(c3, outfile);
	fputc(c4, outfile);
}

/* get short integer (Little endian) */
void get_short(unsigned char *pos, unsigned short *val)
{
	unsigned char c1 = *pos++, c2 = *pos++;
	(*val) = (c2<<8) + c1;
}

/* write a 32 bit integer to stream (Little endian) */
void write_short(FILE *outfile, unsigned int val)
{
	unsigned char c1 = (val & 0xff), c2 = ((val>>8) & 0xff);
	fputc(c1, outfile);
	fputc(c2, outfile);
}

/* 64 bit subtraction with unsigned integers */
void quad_subtraction(unsigned int *dst_hi, unsigned int *dst_lo, unsigned int hi, unsigned int lo)
{
	unsigned int tmp;

	*dst_hi -= hi;

	tmp = *dst_lo;
	*dst_lo -= lo;

	/* handle "carry bit" */
	if (*dst_lo > tmp) *dst_hi--;
}

/* timecode helper functions */
/* get position of timecode in chunk (-1 if unknown) */
int whereis_timecode(unsigned char *Buffer)
{
	int tc_start = -1;
	/* timecode position varies with type of chunk */
	switch(Buffer[3])
	{
		case 0x00:	tc_start =  5;	break;
		case 0x01:	tc_start =  5;	break;
		case 0x08:	tc_start =  6;	break;
		case 0x09:	tc_start =  6;	break;
		case 0x10:	tc_start =  7;	break;
		case 0x11:	tc_start =  7;	break;
		case 0x48:	tc_start =  8;	break;
		case 0x49:	tc_start =  8;	break;
		case 0x50:	tc_start =  9;	break;
		case 0x51:	tc_start =  9;	break;
		default:	tc_start = -1;	gui_showstatus(STATUS_ERROR, "unknown format type: $%02x\n", (int)Buffer[3]);
	}
	return tc_start;
}

/* Create a randomized GUID string to avoid filtering ASFRecorder's */
/* stream requests by means of detecting any hardcoded GUIDs */
void randomize_guid(unsigned char *buf)
{
	int digit, dig;
	time_t curtime;

	*buf++='{';
	time(&curtime);
	srand(curtime);
	for (digit=0; digit <32; digit++)
	{
		if (digit==8 || digit == 12 || digit == 16 || digit == 20) *buf++='-';
		dig = rand()%0xf;
		if (dig<10)
			*buf++='0'+dig;
		else
			*buf++='A'+(dig-10);
	}
	*buf++='}';
	*buf++='\0';
}

/* create a timecode string from a timecode in milliseconds */
char *createtimestring(unsigned int timecode)
{
	static char timecodestring[64];

	if (timecode/1000 >= 24*3600)
		sprintf(timecodestring, "%d:%02d:%02d:%02d.%03d", (timecode/1000)/(24*3600), ((timecode/1000)/3600)%24, ((timecode/1000)/60)%60, (timecode/1000)%60, timecode%1000);
	else
		if (timecode/1000 >= 3600)
			sprintf(timecodestring, "%d:%02d:%02d.%03d", (timecode/1000)/3600, ((timecode/1000)/60)%60, (timecode/1000)%60, timecode%1000);
		else
			if (timecode/1000 >= 60)
				sprintf(timecodestring, "%d:%02d.%03d", (timecode/1000)/60, (timecode/1000)%60, timecode%1000);
			else
				sprintf(timecodestring, "%d.%03d", (timecode/1000)%60, timecode%1000);
	return timecodestring;
}

/* subroutine for base64 encoding (used in HTTP Basic authentification) */
int base64enc(char *data, unsigned char *out)
{
	char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
	int len = strlen(data);
	int i,index;
	int val;

	for (i=0, index=0; i<len; i+=3, index+=4)
	{
		int quad = 0;
		int trip = 0;

		val = (0xff & data[i]);
		val <<= 8;
		if ((i+1) < len) {
			val |= (0xff & data[i+1]);
			trip = 1;
		}
		val <<= 8;
		if ((i+2) < len) {
			val |= (0xff & data[i+2]);
			quad = 1;
		}
		out[index+3] = alphabet[(quad? (val & 0x3f): 64)];
		val >>= 6;
		out[index+2] = alphabet[(trip? (val & 0x3f): 64)];
		val >>= 6;
		out[index+1] = alphabet[val & 0x3f];
		val >>= 6;
		out[index+0] = alphabet[val & 0x3f];
	}

	out[++index] = 0;
	return index;
}

/* helper routine for ASF header parsing */
int find_id(unsigned char *id, unsigned char *Buffer, int bufsize)
{
	int offs, i, found;
	for (offs = 0; offs < bufsize-16; offs++) {
		found=1;
		for (i=0; i<16; i++) if (Buffer[offs+i] != id[i]) {
			found = 0;
			break;
		}
		if (found) return(offs);
	}
	return -1;
}

/* These routines are used to parse the packet and find */
/* and modify timecodes for live streams */
unsigned int get_data(unsigned char **bp, unsigned int type)
{
	unsigned int res = 0;
	switch (type) {
	case 0:
		break;
	case 1:
		res = *(*bp+0);
		*bp+=1;
		break;
	case 2:
		res = *(*bp+0) + (*(*bp+1) << 8);
		*bp+=2;
		break;
	case 3:
		res = *(*bp+0) + (*(*bp+1) << 8) + (*(*bp+2) << 16) + (*(*bp+3) << 24);
		*bp+=4;
		break;
	default:
		gui_showstatus(STATUS_CRITICALERROR, "unknown format type %d\n", type);
		break;
	}
	return res;
}

/* Replace specific characters in the URL string by an escape sequence */
/* works like strcpy(), but without return argument */
void escape_url_string(char *outbuf, char *inbuf)
{
	unsigned char c;
	do
	    {
		c = *inbuf++;

		if ((c >= 'A' && c <= 'Z') ||
		    (c >= 'a' && c <= 'z') ||
	   		(c >= '0' && c <= '9') ||
			(c >= 0x7f) ||										/* fareast languages(Chinese, Korean, Japanese) */
			c=='-' || c=='_'  || c=='.' || c=='!' || c=='~'  || /* mark characters */
			c=='*' || c=='\'' || c=='(' || c==')' || c=='%'  || /* do not touch escape character */
			c==';' || c=='/'  || c=='?' || c==':' || c=='@'  || /* reserved characters */
			c=='&' || c=='='  || c=='+' || c=='$' || c==','  || /* see RFC 2396 */
			c=='\0' )
		{
			*outbuf++ = c;
		}
		else
		    {
			/* all others will be escaped */
			unsigned char c1 = ((c & 0xf0) >> 4);
			unsigned char c2 =  (c & 0x0f);
			if (c1 < 10) c1+='0';
			else c1+='A';
			if (c2 < 10) c2+='0';
			else c2+='A';
			*outbuf++ = '%';
			*outbuf++ = c1;
			*outbuf++ = c2;
		}
	}
	while (c != '\0');
}

int fix_timecodes(unsigned char *Buffer, int bodylength, unsigned int deltatime, unsigned int in_chunk_no, struct CUSTOM_INFO_ASF *ci)
{
	unsigned char *ptr1,b1;
	unsigned int	f1, flag_more_than_one_segment,	flag_packet_size, flag_padding_size, flag_chunk_no, l4, l5, l6, l7, l8, segments,	n;
	unsigned long 	packet_size, chunk_no, padding_size, send_time,	v5=0, v6, v7, v8, v9, v10;

	if ((Buffer[0]!=0x82) || (Buffer[1]!=0x00) || (Buffer[2]!=0x00))
	{
		gui_showstatus(STATUS_ERROR, "Illegal header bytes in chunk %d!\n",in_chunk_no);
		return 1;
	}

	/* Get flags from Packet Flags */
	ptr1 = &Buffer[3];
	b1 = *ptr1++;						/* Flags */
	f1 = (b1&0x80) >> 7;					/* 0x80 bit */
	if (f1 == 0)
	{
		flag_packet_size = (b1&0x60) >> 5;			/* 0x40, 0x20 bit, presence of packet size*/
		flag_padding_size = (b1&0x18) >> 3;			/* 0x10, 0x08 bit, presence of padding */
		flag_chunk_no = (b1&0x06) >> 1;				/* 0x04, 0x02 bit, chunk No. */
		flag_more_than_one_segment = (b1&0x01);		/* 0x01 bit */
	}
	else
	{
		gui_showstatus(STATUS_ERROR, "Chunks carrying error correction information are not supported yet!\n");
		return 1;
	}

	/* Get flags from Segment Type ID */
	b1 = *ptr1++;							/* Buffer[4],Segment type ID */
	l4 = (b1&0xc0) >> 6;					/* 0x80 , 0x40 bit */
	l5 = (b1&0x30) >> 4;					/* 0x20 , 0x10 bit */
	l6 = (b1&0x0c) >> 2;					/* 0x08 , 0x0c bit */
	l7 = (b1&0x03);							/* 0x02 , 0x01 bit */

	/* Parse info from Packet Flags */
	packet_size = get_data(&ptr1,flag_packet_size);				/* packet size */
	chunk_no = get_data(&ptr1,flag_chunk_no);					/* chunk number */
	padding_size = get_data(&ptr1,flag_padding_size);			/* padding size */
	send_time = get_data(&ptr1,3);								/* send time */

	/* Fix send time if needed */
	send_time = (deltatime < send_time) ? send_time -= deltatime : 0;
	put_long(ptr1 - 4,send_time);

	if (flag_packet_size == 0)
	    packet_size = ci->ChunkLength;
	if (flag_chunk_no == 0)
	    chunk_no = in_chunk_no;
	if (padding_size > 0)
		memset(Buffer + packet_size - padding_size, 0, padding_size);

	ptr1 += 2;													/* Duration,skipped */
	b1 = *ptr1++;												/* Number of Segments & Segment properties */

	if (flag_more_than_one_segment)
	{
		l8 = 2;
		segments = b1 & 0x1f;
	}
	else
	{
		l8 = 0;
		segments = 1;
	}

	for (n=0 ; (n<segments) ; n++)
	{
		if (flag_more_than_one_segment)
			v5 = get_data(&ptr1,l4);
		v6 = get_data(&ptr1,l5);
		v7 = get_data(&ptr1,l6);
		v8 = get_data(&ptr1,l7);

		if (v8 == 8)
		{
			get_long(ptr1+4,&v10);
			v10 = (deltatime < v10) ? v10-=deltatime : 0;
			put_long(ptr1+4,v10);
		}

		if (v8 > 0)
			ptr1 += v8;

		if (flag_more_than_one_segment)
			v9 = get_data(&ptr1,l8);
		else
			v9=(packet_size-padding_size)-(ptr1-Buffer);

		if (v9 > 0)
			ptr1+=v9;

		if ((unsigned int)(ptr1-Buffer) > ci->ChunkLength)
		{
			gui_showstatus(STATUS_ERROR, "WARNING! buffer pointer %d bytes after packet!\n",	(unsigned int)(ptr1-Buffer)-ci->ChunkLength);
			return 1;
		}

		if ((unsigned int)(ptr1-Buffer) > ci->ChunkLength - padding_size)
		{
			gui_showstatus(STATUS_ERROR, "WARNING! buffer pointer %d bytes after packet-padlen!\n", (unsigned int)(ptr1-Buffer)-(ci->ChunkLength - padding_size));
			return 1;
		}
	}

	if ((ptr1-Buffer)<(int)ci->ChunkLength-(int)padding_size)
		gui_showstatus(STATUS_ERROR, "NOTE: %d bytes not covered by payload\n",ci->ChunkLength-padding_size-(ptr1-Buffer));
	return 0;
}

int my_sprintf(unsigned char *pos, unsigned char *CWord, int number)
{
	//if(number==0) number = ustrlen(CWord);
	if(number==0) number = strlen((char *)CWord);
	memcpy(pos, CWord, number);
	return number;
}

int my_swprintf(unsigned char *pos, const char *CWord, int number)
{
#ifdef __WIN32__
	int count;
	if(number==0) number = strlen(CWord);
	count = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, CWord, number, (WCHAR*)pos, number);
	return count*2;

#else /* iconv way */
	int i, count;
	unsigned short *SWord;
	if(number==0) number = strlen(CWord);
	SWord = (unsigned short *)malloc(number*2);
	for(i=0, count=0 ; i<number ; i++)
	{
		if(((unsigned char)CWord[i] > 0x7f) && ((unsigned char)CWord[i+1] > 0x7f))
		{
			SWord[count++] = CWord[i+1]*256 + CWord[i];
			i++;
		}
		else
		{
			SWord[count++] = CWord[i];
		}
	}
	memcpy(pos, SWord, count*2);
	free(SWord);
	return count*2;

#endif /* __WIN32__ */
}

⌨️ 快捷键说明

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