#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;
}