Initial
This commit is contained in:
581
yproxy/hold/pdecode.cpp
Normal file
581
yproxy/hold/pdecode.cpp
Normal file
@@ -0,0 +1,581 @@
|
||||
#include <common/windows.hpp>
|
||||
#include <common/stdio.hpp>
|
||||
#include <common/stdlib.hpp>
|
||||
#include <common/finddata.hpp>
|
||||
#include <yproxy/pdecode.hpp>
|
||||
#include <yproxy/crc.hpp>
|
||||
#include <io.h>
|
||||
|
||||
PureDecoder::PureDecoder()
|
||||
: mErrors(0), mErrParts(0), mErrFiles(0), mDisplay(true), myBegin(0), myEnd(0), mAdResCrc(0), mAdResLen(0)
|
||||
{
|
||||
::memset(mAttName,0,sizeof(mAttName));
|
||||
::memset(mAtText,0,sizeof(mAtText));
|
||||
}
|
||||
|
||||
char *PureDecoder::ad_fgetscr(char * buffer, int maxlen, FILE * fp)
|
||||
{
|
||||
char * cp;
|
||||
char * dp;
|
||||
|
||||
cp=fgets(buffer,maxlen,fp);
|
||||
if(cp==NULL)return(NULL);
|
||||
dp=strrchr(buffer,'\n'); // Eliminate CRLF
|
||||
if (dp) *dp=0;
|
||||
dp=strrchr(buffer,'\r');
|
||||
if (dp) *dp=0;
|
||||
return(cp);
|
||||
}
|
||||
|
||||
unsigned long PureDecoder::hex_to_ulong(char * text)
|
||||
{
|
||||
unsigned long res;
|
||||
unsigned char c;
|
||||
|
||||
if (text==NULL) return(-1);
|
||||
res=0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
c=*text; text++;
|
||||
if ((c>='0')&(c<='9'))
|
||||
{
|
||||
res=(res<<4)+((long)(c-48) & 0x0F);
|
||||
continue;
|
||||
}
|
||||
if ((c>='A')&(c<='F'))
|
||||
{
|
||||
res=(res<<4)+((long)(c-55) & 0x0F);
|
||||
continue;
|
||||
}
|
||||
if ((c>='a')&(c<='f'))
|
||||
{
|
||||
res=(res<<4)+((long)(c-87) & 0x0F);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
int PureDecoder::yDecode(FILE * fOut, FILE * fIn, long y_line, long y_size,int y_part)
|
||||
{
|
||||
unsigned char srcbuf[4100];
|
||||
unsigned char desbuf[4100];
|
||||
unsigned char * srcp;
|
||||
unsigned char * desp;
|
||||
int deslen;
|
||||
int srclen;
|
||||
unsigned char c;
|
||||
int id;
|
||||
char * cp;
|
||||
long decolen;
|
||||
unsigned long crc32;
|
||||
char name[260];
|
||||
int esize;
|
||||
unsigned char * partbuf;
|
||||
unsigned char * partptr;
|
||||
long partsize;
|
||||
long partfree;
|
||||
long wlen;
|
||||
long flen;
|
||||
|
||||
if(mDisplay)
|
||||
{
|
||||
display("yDecoder started...\r\n");
|
||||
}
|
||||
CRC crc;
|
||||
|
||||
decolen=0;
|
||||
deslen=0;
|
||||
desp=desbuf;
|
||||
|
||||
if(y_part) // This is a multipart message !
|
||||
{
|
||||
cp=ad_fgetscr((char*) srcbuf,4097,fIn); // fgets especially with ad_length
|
||||
if (cp==NULL)
|
||||
{
|
||||
error("Unexpected eof in yEncoded file\r\n");
|
||||
mErrors++;
|
||||
return(1);
|
||||
}
|
||||
if(mDisplay)
|
||||
{
|
||||
String str;
|
||||
::sprintf(str,"=ypart-line: %s\r\n",srcbuf);
|
||||
display(str);
|
||||
}
|
||||
if (strncmp((char*) srcbuf,"=ypart ",7))
|
||||
{
|
||||
error("Missing =ypart line in yEncoded multipart message\r\n");
|
||||
mErrors++;
|
||||
return(2);
|
||||
}
|
||||
cp=strstr((char*)srcbuf,"end=");
|
||||
if (cp==NULL)
|
||||
{
|
||||
error("Missing end= in yEncoded multipart message\r\n");
|
||||
mErrors++;
|
||||
return(2);
|
||||
}
|
||||
myEnd=atol(cp+4);
|
||||
cp=strstr((char*)srcbuf,"begin=");
|
||||
if (cp==NULL)
|
||||
{
|
||||
error("Missing begin= in yEncoded multipart message\r\n");
|
||||
mErrors++;
|
||||
return(2);
|
||||
}
|
||||
myBegin=atol(cp+6);
|
||||
if(mDisplay)
|
||||
{
|
||||
String str;
|
||||
::sprintf(str,"part-begin: %ld\r\n",myBegin);
|
||||
display(str);
|
||||
sprintf(str,"part-end : %ld\r\n",myEnd);
|
||||
display(str);
|
||||
}
|
||||
partbuf=(unsigned char*)malloc(myEnd-myBegin+10); // Allocate a buffer for the part
|
||||
partptr=partbuf;
|
||||
partsize=myEnd-myBegin+1;
|
||||
partfree=partsize;
|
||||
}
|
||||
|
||||
loop:
|
||||
|
||||
cp=ad_fgetscr((char*) srcbuf,4097,fIn); // fgets especially with ad_length
|
||||
if(cp==NULL)
|
||||
{
|
||||
error("Unexpected eof in yEncoded file\r\n");
|
||||
mErrors++;
|
||||
return(1);
|
||||
}
|
||||
if (strncmp((char*) srcbuf,"=yend ",6)==0)
|
||||
{
|
||||
if(mDisplay)
|
||||
{
|
||||
String str;
|
||||
sprintf(str,"Endline (%d bytes): %s\r\n",decolen,srcbuf);
|
||||
display(str);
|
||||
}
|
||||
goto end_of_file;
|
||||
}
|
||||
if (strncmp((char*) srcbuf,"=ybegin ",8)==0)
|
||||
{
|
||||
error("Unexpected =ybegin in yEncoded file\r\n");
|
||||
mErrors++;
|
||||
return(1);
|
||||
}
|
||||
srclen=strlen((char*)srcbuf);
|
||||
if (srclen<y_line)
|
||||
{
|
||||
if(mDisplay)display("Last line.\r\n");
|
||||
}
|
||||
srcp=srcbuf;
|
||||
|
||||
loop2:
|
||||
c=*srcp; srcp++;
|
||||
if(c==0)
|
||||
{
|
||||
goto loop; // End of line reached
|
||||
}
|
||||
if(c=='=') // The escape character comes in
|
||||
{
|
||||
c=*srcp; srcp++;
|
||||
if(c==0)return(2); // Last char cannot be escape char !
|
||||
c=(unsigned char)(c-64);
|
||||
}
|
||||
c=(unsigned char)(c-42); // Subtract the secret number
|
||||
*desp=c;
|
||||
desp++;
|
||||
deslen++;
|
||||
decolen++;
|
||||
|
||||
// crc.crcAdd(c);
|
||||
crc.crcAdd(c);
|
||||
|
||||
if (deslen>=4096)
|
||||
{
|
||||
if (y_part) // MultiPart --> to the partbuffer !
|
||||
{
|
||||
if (deslen>partfree)
|
||||
{
|
||||
error("Partial message corrupt: longer than (end-begin)!\r\n");
|
||||
mErrors++;
|
||||
return(11);
|
||||
}
|
||||
memcpy(partptr,desbuf,deslen);
|
||||
partptr=partptr+deslen;
|
||||
partfree=partfree-deslen;
|
||||
}
|
||||
else // Single part --> directly to target file
|
||||
{
|
||||
id=fwrite(desbuf,deslen,1,fOut);
|
||||
if (id != 1)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"Error in writing decoded file (code=%d)\r\n",errno);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
deslen=0;
|
||||
desp=desbuf;
|
||||
}
|
||||
goto loop2;
|
||||
|
||||
end_of_file:
|
||||
|
||||
if (deslen>0) // Empty the last buffer
|
||||
{
|
||||
if (y_part)
|
||||
{
|
||||
if (deslen>partfree)
|
||||
{
|
||||
error("Partial message corrupt: longer than (end-begin)!\r\n");
|
||||
mErrors++;
|
||||
return(11);
|
||||
}
|
||||
memcpy(partptr,desbuf,deslen);
|
||||
//partptr=partptr+deslen;
|
||||
//partfree=partfree-deslen;
|
||||
}
|
||||
else // Single part --> directly to target file
|
||||
{
|
||||
id=fwrite(desbuf,deslen,1,fOut);
|
||||
if (id != 1)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"Error in writing decoded file (code=%d)\r\n",errno);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
return(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
cp=strstr((char*) srcbuf,"size="); // Compare the decoded size to the =yend size
|
||||
if (cp)
|
||||
{
|
||||
esize=atoi(cp+5);
|
||||
if (esize != decolen)
|
||||
{
|
||||
sprintf(name,"%s(size=%ld)",mAttName,decolen);
|
||||
strcpy(mAttName,name);
|
||||
String strError;
|
||||
::sprintf(strError,"Corrupt yEnc binary - endsize mismatch (%s%s)\r\n",mAttName,mAtText);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
mErrFiles++;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
// Check the srcbuf for the CRC
|
||||
if (y_part==0)
|
||||
{
|
||||
cp=strstr((char*)srcbuf,"crc32=");
|
||||
if (cp)
|
||||
{
|
||||
crc32=hex_to_ulong((char*)(cp+6));
|
||||
mAdResCrc=crc.getVal() ^ 0xFFFFFFFFl;
|
||||
|
||||
if (mDisplay)
|
||||
{
|
||||
String str;
|
||||
sprintf(str,"Included CRC: $%08lx - calculated CRC: $%08lx\r\n",crc32,mAdResCrc);
|
||||
display(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cp=strstr((char*)srcbuf,"pcrc32=");
|
||||
if (cp)
|
||||
{
|
||||
crc32=hex_to_ulong((char*)(cp+7));
|
||||
mAdResCrc=crc.getVal() ^ 0xFFFFFFFFl;
|
||||
|
||||
if (mDisplay)
|
||||
{
|
||||
String str;
|
||||
sprintf(str,"Included CRC: $%08lx - calculated CRC: $%08lx\r\n",crc32,mAdResCrc);
|
||||
display(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cp!=NULL)
|
||||
{
|
||||
if (crc32 != mAdResCrc)
|
||||
{
|
||||
sprintf(name,"%s(crc=%08lx)",mAttName,mAdResCrc);
|
||||
strcpy(mAttName,name);
|
||||
String strError;
|
||||
::sprintf(strError,"Corrupt yEnc binary - CRC mismatch (%s%s)\r\n",mAttName,mAtText);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
mErrFiles++;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (y_part==0) // Single message
|
||||
{
|
||||
if ((y_part==0) & (decolen != y_size))
|
||||
{
|
||||
// eprint("Y-Decoder: Size mismatch - file corrupt.\r\n");
|
||||
|
||||
sprintf(name,"%s(len=%ld)",mAttName,decolen);
|
||||
strcpy(mAttName,name);
|
||||
|
||||
String strError;
|
||||
::sprintf(strError,"Corrupt yEnc binary - size mismatch (%s%s)\r\n",mAttName,mAtText);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
mErrFiles++;
|
||||
return(0);
|
||||
}
|
||||
mAdResLen=decolen;
|
||||
mAdResCrc=crc.getVal() ^ 0xFFFFFFFFl;
|
||||
if(mDisplay)
|
||||
{
|
||||
String str;
|
||||
sprintf(str,"yDecoder: Job done. %ld bytes written. CRC: $%08lx \r\n",decolen,mAdResCrc);
|
||||
display(str);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
if ((y_part>0) & (decolen != (myEnd-myBegin+1)))
|
||||
{
|
||||
error("yDecoder: Part size mismatch - file corrupt.\r\n");
|
||||
mErrors++;
|
||||
mErrParts++;
|
||||
return(6);
|
||||
}
|
||||
id=fseek(fOut,myBegin-1,0);
|
||||
if(id)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"Cannot write a part (fseek failed) [reason:%d]\r\n",errno);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
return(12);
|
||||
}
|
||||
flen=decolen;
|
||||
partptr=partbuf;
|
||||
if (mDisplay)
|
||||
{
|
||||
String str;
|
||||
sprintf(str,"Write part to target file (start: %ld, size: %ld)\r\n",myBegin-1,flen);
|
||||
display(str);
|
||||
}
|
||||
while (flen>0)
|
||||
{
|
||||
wlen=flen;
|
||||
if (wlen>8192) wlen=8192;
|
||||
id=fwrite(partptr,wlen,1,fOut);
|
||||
if (id != 1)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"Cannot write a part (fwrite failed) [reason:%d]\r\n",errno);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
return(12);
|
||||
}
|
||||
partptr=partptr+wlen;
|
||||
flen=flen-wlen;
|
||||
}
|
||||
free(partbuf);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int PureDecoder::AddPart(char * srcname,long y_begin, long y_end)
|
||||
{
|
||||
FILE * fSrc;
|
||||
FILE * fDes;
|
||||
char desname[260];
|
||||
char line[1024];
|
||||
long a,e;
|
||||
int copyrest;
|
||||
char * cp;
|
||||
int resparts;
|
||||
long flen;
|
||||
|
||||
if (mDisplay)
|
||||
{
|
||||
String str;
|
||||
sprintf("AddPart (%s) [%ld - %ld]\r\n",srcname,y_begin,y_end);
|
||||
display(str);
|
||||
}
|
||||
copyrest=0;
|
||||
resparts=0;
|
||||
sprintf(desname,"%s.des",srcname);
|
||||
fSrc=fopen(srcname,"rb");
|
||||
if (fSrc==NULL)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"AddPart: Part Info File not found (%s)\r\n",srcname);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
return(-1);
|
||||
}
|
||||
flen=filelength(fileno(fSrc));
|
||||
if (flen==0) // Already complete
|
||||
{
|
||||
return(-9);
|
||||
}
|
||||
fDes=fopen(desname,"wb");
|
||||
if(fDes==NULL)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"AddPart: Cannot create temporary part file (%s) [reason: %d]\r\n",desname,errno);
|
||||
error(strError);
|
||||
fclose(fSrc);
|
||||
mErrors++;
|
||||
return(-2);
|
||||
}
|
||||
loop:
|
||||
cp=fgets(line,1000,fSrc);
|
||||
if (cp==NULL) goto eof1;
|
||||
cp=strrchr(line,'\n');
|
||||
if (cp) *cp=0;
|
||||
cp=strrchr(line,'\r');
|
||||
if (cp) *cp=0;
|
||||
|
||||
// print("%s\r\n",line);
|
||||
|
||||
if (copyrest) // Analysis done - copy rest & done.
|
||||
{
|
||||
fprintf(fDes,"%s\r\n",line);
|
||||
resparts++;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
a=atol(line);
|
||||
if (a==0)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"Corrupt part-info file (%s)\r\n",line);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
fclose(fSrc); fclose(fDes); return(-3);
|
||||
}
|
||||
cp=strchr(line,',');
|
||||
if (cp==NULL)
|
||||
{
|
||||
String strError;
|
||||
::sprintf(strError,"Corrupt part-info file (%s)\r\n",line);
|
||||
error(strError);
|
||||
mErrors++;
|
||||
fclose(fSrc); fclose(fDes); return(-4);
|
||||
}
|
||||
e=atol(cp+1);
|
||||
// print("a:%6d, e:%6d\r\n",a,e);
|
||||
|
||||
// ----- Case Analysis -----
|
||||
// .............[yb--------ye] (The new, incoming block)
|
||||
// 1...a****e (The old, missing block)
|
||||
// 2...a********-----e (***) Newly written missing block
|
||||
// 3...a********--------------****e
|
||||
// .............[yb--------ye]
|
||||
// 4............a-----e
|
||||
// 5............a------------e
|
||||
// 6............a-------------****e
|
||||
// .............[yb--------ye]
|
||||
// 7............................a***e
|
||||
// .............[yb--------ye]
|
||||
// 8................a----e
|
||||
// 9................a---------****e
|
||||
|
||||
|
||||
|
||||
|
||||
if (a<y_begin) // A previous section was missed
|
||||
{
|
||||
if (e<y_begin) // A previous section was missed entirely
|
||||
{
|
||||
// Case-1
|
||||
fprintf(fDes,"%ld,%ld\r\n",a,e); // --> Keep that entry
|
||||
resparts++;
|
||||
goto loop;
|
||||
}
|
||||
if (e<=y_end) // Rduce the old section
|
||||
{
|
||||
// Case-2
|
||||
fprintf(fDes,"%ld,%ld\r\n",a,y_begin-1); // --> Reduce that entry
|
||||
resparts++;
|
||||
goto loop;
|
||||
}
|
||||
// The new section is splitting the old missing section
|
||||
// Case-3
|
||||
fprintf(fDes,"%ld,%ld\r\n",a,y_begin-1); // --> First part
|
||||
fprintf(fDes,"%ld,%ld\r\n",y_end+1,e); // --> First part
|
||||
resparts++; resparts++;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (a==y_begin) // New part matches this segment
|
||||
{
|
||||
if (e<y_end) // Just a smaller section was missed
|
||||
{
|
||||
// case 4
|
||||
goto loop; // Skip this and analyse next
|
||||
}
|
||||
if (e==y_end) // This missing section was exactly -> remove it & done.
|
||||
{
|
||||
// case 5
|
||||
copyrest=1; goto loop;
|
||||
}
|
||||
if (e>y_end) // The first part was found
|
||||
{
|
||||
// case-6
|
||||
fprintf(fDes,"%ld,%ld\r\n",y_end+1,e); // Write the rest
|
||||
resparts++;
|
||||
copyrest=1; goto loop;
|
||||
}
|
||||
}
|
||||
|
||||
if (a>y_begin)
|
||||
{
|
||||
if (a>y_end) // the found section completely in front of this one.
|
||||
{
|
||||
// Case-7
|
||||
fprintf(fDes,"%ld,%ld\r\n",a,e); // Rewrite it & copy the rest
|
||||
resparts++;
|
||||
copyrest=1; goto loop;
|
||||
}
|
||||
if (e<=y_end) // The section was completely found
|
||||
{
|
||||
// Case-8
|
||||
goto loop; // Analyse the rest
|
||||
}
|
||||
// The first part of the missing section was found
|
||||
// case-9
|
||||
fprintf(fDes,"%ld,%ld\r\n",y_end+1,e); // Reduce it & copy the rest
|
||||
resparts++;
|
||||
copyrest=1; goto loop;
|
||||
}
|
||||
|
||||
eof1:
|
||||
fclose(fSrc); fclose(fDes);
|
||||
remove(srcname);
|
||||
|
||||
rename(desname,srcname);
|
||||
|
||||
return(resparts);
|
||||
}
|
||||
|
||||
// virtuals
|
||||
|
||||
void PureDecoder::error(const String &error)
|
||||
{
|
||||
::OutputDebugString(error.str());
|
||||
}
|
||||
|
||||
void PureDecoder::display(const String &string)
|
||||
{
|
||||
::OutputDebugString(string.str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user