用戶:Antigng-bot/convert

#include <stdio.h>
#include "mem.h"
#include "network.h"
#include "convert.h"
const char *G2U(const char *str)
{
	return str;
}
const char hec[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

const unsigned char encoding[256]={
	3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	2,1,1,1,1,1,1,1,1,1,0,1,1,0,0,1,
	0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};

const char decoding[]={
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	1, 2, 3, 4, 5, 6, 7, 8, 9,10, 0, 0, 0, 0, 0, 0,
	0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0,11,12,13,14,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};


const char *encode_escape=
	"%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F"
	"%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F"
	"%20%21%22%23%24%25%26%27%28%29%2A%2B%2C%2D%2E%2F"
	"%30%31%32%33%34%35%36%37%38%39%3A%3B%3C%3D%3E%3F"
	"%40%41%42%43%44%45%46%47%48%49%4A%4B%4C%4D%4E%4F"
	"%50%51%52%53%54%55%56%57%58%59%5A%5B%5C%5D%5E%5F"
	"%60%61%62%63%64%65%66%67%68%69%6A%6B%6C%6D%6E%6F"
	"%70%71%72%73%74%75%76%77%78%79%7A%7B%7C%7D%7E%7F"
	"%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F"
	"%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F"
	"%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF"
	"%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF"
	"%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF"
	"%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF"
	"%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF"
	"%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
int URLEncode(const char *source,const int source_len,char *dest,const int dest_len)
{
	int source_pos,dest_pos;
	unsigned char ch;
	if((!source)||(!dest)||(source_len<0)||(dest_len<0))
	{
		return 0;
	}
	for(source_pos=0,dest_pos=0;(source[source_pos])&&(source_pos<source_len)&&(dest_pos<dest_len);source_pos++)
	{
		ch=source[source_pos];
		switch(encoding[ch])
		{
		case 0:
			dest[dest_pos++]=ch;
			break;
		case 1:
			if (dest_pos+3<dest_len)
			{
				*((unsigned int *)(dest+dest_pos))=*((unsigned int *)(encode_escape+3*((unsigned int)ch)));
				dest_pos+=3;
			}
			else goto cleanup;
			break;
		case 2:
			dest[dest_pos++]='+';
			break;
		}
	}
cleanup:
	dest[dest_pos]=0;
	return dest_pos;
}
int URLDecode(const char *source,const int source_len,char *dest,const int dest_len)
{
	int source_pos,dest_pos;
	char ch;
	if(!source||!dest||(source_len<0)||(dest_len<0))
	{
		return 0;
	}
	for(source_pos=0,dest_pos=0;(source[source_pos])&&(source_pos<source_len)&&(dest_pos<dest_len);dest_pos++)
	{
		ch=source[source_pos];
		switch(ch)
		{
		case '%':
			source_pos++;
			ch=decoding[(unsigned char)source[source_pos]];
			if(ch)
			{
				char x;
				source_pos++;
				x=decoding[(unsigned char)source[source_pos]];
				if(x)
				{
					dest[dest_pos]=16*(ch-1)+x-1;
					source_pos++;
					break;
				}
			}
			dest[dest_pos]=0;
			return -1;
			break;
		case '+':
			dest[dest_pos]=' ';
			source_pos++;
			break;
		default:
			dest[dest_pos]=ch;
			source_pos++;
			break;
		}
	}
	dest[dest_pos]=0;
	return dest_pos;
}
int URLtryDecode(const char *source,const int source_len,char *dest,const int dest_len,int status)
{
	int source_pos,dest_pos;
	char ch;
	if(!source||!dest||(source_len<0)||(dest_len<0))
	{
		return 0;
	}
	for(source_pos=0,dest_pos=0;(source[source_pos])&&(source_pos<source_len)&&(dest_pos<dest_len);dest_pos++)
	{
		ch=source[source_pos];
		switch(ch)
		{
		case '%':
			source_pos++;
			ch=decoding[(unsigned char)source[source_pos]];
			if(ch)
			{
				char x;
				source_pos++;
				x=decoding[(unsigned char)source[source_pos]];
				if(x)
				{
					dest[dest_pos]=16*(ch-1)+x-1;
					source_pos++;
					status=1;
					break;
				}
				else source_pos--;
			}
			dest[dest_pos]='%';
			status=0;
			break;
		case '+':
			dest[dest_pos]=status?' ':'+';
			source_pos++;
			break;
		default:
			dest[dest_pos]=ch;
			source_pos++;
			break;
		}
	}
	dest[dest_pos]=0;
	return dest_pos;
}
int xmlparsetag(HTTP h,char *buffer)
{
	char ch=0;
	int bufferpos=0;
	int closetag=0;
	buffer[0]=0;
	while(!heof(h))
	{
		ch=hgetc(h);
		if(ch=='<') break;
	}
	if(heof(h)) return XML_PARSE_ERROR;
	ch=hgetc(h);
	if(ch=='/') closetag=1;
	else
	{
		buffer[0]=ch;
		bufferpos=1;
	}
	do
	{
		ch=hgetc(h);
		if((ch=='/')||(ch=='>')||(ch==' ')) break;
		buffer[bufferpos]=ch;
		bufferpos++;
	}while(!heof(h));
	buffer[bufferpos]=0;
	switch(ch)
	{
	case ' ':
		return XML_HAS_VALUE;
		break;
	case '/':
		if(heof(h)||closetag) return XML_PARSE_ERROR;
		ch=hgetc(h);
		if(ch=='>') return XML_NO_VALUE;
		else return XML_PARSE_ERROR;
		break;
	case '>':
		return XML_NO_VALUE;
		break;
	default:
		return XML_PARSE_ERROR;
		break;
	}
}
static int smartxmlparse(HTTP h,char *out)
{
	int numcount;
	unsigned char ch,res;
	goto _DFAState_1;
_DFAState_1:
	switch(READ(h))
	{
	case 35:
		numcount=0;
		res=0;
		goto _DFAState_2;
		break;
	case 97:
		*out='&';
		goto _DFAState_3;
		break;
	case 103:
		*out='>';
		goto _DFAState_4;
		break;
	case 108:
		*out='<';
		goto _DFAState_4;
		break;
	case 110:
		*out='%';
		goto _DFAState_5;
		break;
	case 113:
		*out='\"';
		goto _DFAState_6;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_2:
	if(numcount>3)
	{
		goto _DFAFailure;
	}
	FORWARD(h);
	ch=(unsigned char)(READ(h))-48;
	if(ch<10)
	{
		res=res*10+ch;
		numcount++;
		goto _DFAState_2;
	}
	else if(ch==11)
	{
		*out=res;
		return 0;
	}
	goto _DFAFailure;
_DFAState_3:
	FORWARD(h);
	switch(READ(h))
	{
	case 109:
		goto _DFAState_7;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_4:
	FORWARD(h);
	switch(READ(h))
	{
	case 116:
		goto _DFAState_8;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_5:
	FORWARD(h);
	switch(READ(h))
	{
	case 98:
		goto _DFAState_9;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_6:
	FORWARD(h);
	switch(READ(h))
	{
	case 117:
		goto _DFAState_10;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_7:
	FORWARD(h);
	switch(READ(h))
	{
	case 112:
		goto _DFAState_8;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_8:
	FORWARD(h);
	switch(READ(h))
	{
	case 59:
		return 0;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_9:
	FORWARD(h);
	switch(READ(h))
	{
	case 115:
		goto _DFAState_7;
		break;
	default:
		goto _DFAFailure;
	}
_DFAState_10:
	FORWARD(h);
	switch(READ(h))
	{
	case 111:
		goto _DFAState_4;
		break;
	default:
		goto _DFAFailure;
	}
_DFAFailure:
	*out=0;
	return -1;
}
int xmlparsearg(HTTP h,unsigned int length,const char *list[],char *value[])
{
	char name[4096];
	int namepos=0;
	unsigned int i;
	int state=0;
	char ch=0;
	int valuepos=0;
	for(i=0;i<length;i++) value[i][0]=0;
	while(!heof(h))
	{
		ch=hgetc(h);
		switch(state)
		{
		case 0:
			switch(ch)
			{
			case ' ':
				break;
			case '/':
				goto _cleanup;
				break;
			case '>':
				goto _cleanup;
				break;
			default:
				name[0]=ch;
				namepos=1;
				state=1;
				break;
			}
			break;
		case 1:
			switch(ch)
			{
			case ' ':
				return XML_PARSE_ERROR;
				break;
			case '=':
				state=2;
				break;
			case '/':
				goto _cleanup;
				break;
			case '>':
				goto _cleanup;
				break;
			default:
				name[namepos]=ch;
				namepos++;
				break;
			}
			break;
		case 2:
			if(ch!='\"') return XML_PARSE_ERROR;
			else 
			{
				name[namepos]=0;
				for(i=0;i<length;i++)
				{
					if(!strcmp(name,list[i])) break;
				}
				if(i==length)
				{
					state=4;
				}
				else
				{
					valuepos=0;
					state=3;
				}
			}
			break;
		case 3:
			switch(ch)
			{
			case '>':
				goto _cleanup;
				break;
			case '\"':
				value[i][valuepos]=0;
				state=0;
				break;
			case '&':
				{
					char vl=0;
					if(smartxmlparse(h,&vl))
					{
						value[i][valuepos]=0;
						return XML_DECODE_ERROR;
					}
					else
					{
						FORWARD(h);
						value[i][valuepos]=vl;
						valuepos++;
					}
				}
				break;
			default:
				value[i][valuepos]=ch;
				valuepos++;
				break;
			}
			break;
		case 4:
			switch(ch)
			{
			case '>':
				goto _cleanup;
				break;
			case '\"':
				state=0;
				break;
			}
			break;
		}
	}
_cleanup:
	if(state)
	{
		if(state==3) value[i][valuepos]=0;
		return XML_PARSE_ERROR;
	}
	if(heof(h)) return XML_PARSE_ERROR;
	if(ch=='/')
	{
		ch=hgetc(h);
		if(ch!='>') return XML_PARSE_ERROR;
	}
	return XML_HAS_VALUE;
}
int xmlcontentready(HTTP h)
{
	while(!heof(h))
	{
		if(hgetc(h)=='>')
		{
			return XML_CONTENT_READY;
		}		
	}
	return XML_PARSE_ERROR;
}
int xmlpulltext(HTTP h,char *out)
{
	char ch=READ(h);
	switch(ch)
	{
	case 0:
		*out=0;
		return XML_PARSE_ERROR;
		break;
	case '<':
		*out=0;
		return XML_TEXT_END;
		break;
	case '&':
		FORWARD(h);
		if(smartxmlparse(h,out))
		{
			return XML_DECODE_ERROR;
		}
		else
		{
			FORWARD(h);
			return XML_TEXT_CONTINUE;
		}
		break;
	default:
		FORWARD(h);
		*out=ch;
		return XML_TEXT_CONTINUE;
	}
}
int utf8tounicode(const char *line,unsigned int *dest)
{
	int i=0;
	int countl=0;
	int state=0;
	int dest_length=0;
	unsigned int chk[5]={0};
	unsigned int mul,check;
	while(line[i])
	{
		if(state==0&&line[i])
		{
			if(-64<=line[i]&&line[i]<-32)
			{
				state=2;
				countl=0;
				chk[countl]=line[i]+64;
				countl++;
			}
			else if(-32<=line[i]&&line[i]<-16)
			{
				state=3;
				countl=0;
				chk[countl]=line[i]+32;
				countl++;
			}
			else if(-16<=line[i]&&line[i]<-8)
			{
				state=4;
				countl=0;
				chk[countl]=line[i]+16;
				countl++;
			}
			else if(line[i]>0)
			{
				dest[dest_length++]=line[i];
				state=countl=0;
			}
			else
			{
				state= -1;
			}
		}
		else if(state>0)
		{
			if(-128<=line[i]&&line[i]<-64)
			{
				chk[countl]=line[i]+128;
				countl++;
			}
			else
			{
				state=-1;
			}
			if(countl==state)
			{
				mul=1;check=0;
				for(countl--;countl>=0;countl--)
				{
					check+=mul*chk[countl];
					mul*=64;
				}
				state=0;
				countl=0;
				dest[dest_length++]=check;
			}
		}
		i++;
		if(state==-1) 
		{
			*dest=0;
			return -1;
		}
	}
	dest[dest_length]=0;
	return dest_length;
}