📄 rtfdecoder.cpp
字号:
ris = risHex;
break;
default:
return ecBadTable;
}
return ecOK;
}
// Isolate RTF keywords and send them to ecParseRtfKeyword;// Push and pop state at the start and end of RTF groups;// Send text to ecParseChar for further processing.int CRtfDecoder::ecRtfParse(u_char *inbuf,int insize){ int ch; int ec; int cNibble = 2; int b = 0;
u_char *p=inbuf;
for(int i=0;i<insize;) {
ch=p[i++]; if (m_cGroup < 0) return ecStackUnderflow; if (ris == risBin) // if we're parsing binary data, handle it directly { if ((ec = ecParseChar(ch)) != ecOK) return ec; } else {
char x=ch; switch (ch) { case '{': if ((ec = ecPushRtfState()) != ecOK) return ec; break; case '}': if ((ec = ecPopRtfState()) != ecOK) return ec; break; case '\\': if ((ec = ecParseRtfKeyword(p,i,insize)) != ecOK) return ec; break; case 0x0d: case 0x0a: // cr and lf are noise characters... break; default: if (ris == risNorm) { if ((ec = ecParseChar(ch)) != ecOK) return ec; } else { // parsing hex data if (ris != risHex) return ecAssertion; b = b << 4; if (isdigit(ch)) b += (char) ch - '0'; else { if (islower(ch)) { if (ch < 'a' || ch > 'f') return ecInvalidHex; b += (char) ch - 'a'+10; } else { if (ch < 'A' || ch > 'F') return ecInvalidHex; b += (char) ch - 'A'+10; } } cNibble--; if (!cNibble) { if ((ec = ecParseChar(b)) != ecOK) return ec; cNibble = 2; b = 0; ris = risNorm; } } // end else (ris != risNorm) break; } // switch } // else (ris != risBin) } // for
ecMidBuftoOutBuf();
if (m_cGroup < 0) return ecStackUnderflow; if (m_cGroup > 0) return ecUnmatchedBrace; return ecOK;}
int CRtfDecoder::ecIntToStr(int ch,unsigned char *out)
{
int a,i=0,k=0;
unsigned char temp[10];
do
{
a=ch%10;
temp[i++]=(char)a+'0';
ch=ch/10;
}while(ch!=0);
for(int j=i-1;j>=0;j--)
{
out[k++]=temp[j];
}
return i;
}
// ecMidBuftoOutBuf
// If p_midbuf is not NULL and current CodePage is greater than 0,
// then Convert p_midbuf to p_outbuf and clear p_midbuf.
int CRtfDecoder::ecMidBuftoOutBuf(void)
{
if(m_midbuflen>0 && m_previousCodeP>0)
{
unsigned char str[10]={0};
if(m_firstentry)
{
p_outbuf[m_outbuflen++]=0x1B; //ESC控制符
p_outbuf[m_outbuflen++]='{';
int len=ecIntToStr(m_previousCodeP,str);
memcpy(p_outbuf+m_outbuflen,str,len);
m_outbuflen+=len;
p_outbuf[m_outbuflen++]='}';
memcpy(p_outbuf+m_outbuflen,p_midbuf,m_midbuflen);
m_outbuflen+=m_midbuflen;
m_firstentry=false;
m_outCodePage=m_previousCodeP;
}
else
{
if(m_previousCodeP==m_outCodePage)
{
memcpy(p_outbuf+m_outbuflen,p_midbuf,m_midbuflen);
m_outbuflen+=m_midbuflen;
}
else
{
p_outbuf[m_outbuflen++]=0x1B; //ESC控制符
p_outbuf[m_outbuflen++]='{';
int len=ecIntToStr(m_previousCodeP,str);
memcpy(p_outbuf+m_outbuflen,str,len);
m_outbuflen+=len;
p_outbuf[m_outbuflen++]='}';
memcpy(p_outbuf+m_outbuflen,p_midbuf,m_midbuflen);
m_outbuflen+=m_midbuflen;
m_outCodePage=m_previousCodeP;
}
}
m_midbuflen=0;
}
return 0;
}
// ecPushRtfState// Save relevant info on a linked list of SAVE structures.//int CRtfDecoder::ecPushRtfState(void){ SAVE *psaveNew = new SAVE[sizeof(SAVE)]; if (!psaveNew) return ecStackOverflow; psaveNew -> pNext = psave; psaveNew -> chp = chp; psaveNew -> pap = pap; psaveNew -> sep = sep; psaveNew -> dop = dop; psaveNew -> rds = rds; psaveNew -> ris = ris; ris = risNorm; psave = psaveNew; m_cGroup++; return ecOK;}// ecPopRtfState// If we're ending a destination (that is, the destination is changing),// call ecEndGroupAction.// Always restore relevant info from the top of the SAVE list.int CRtfDecoder::ecPopRtfState(void){ SAVE *psaveOld; int ec; if (!psave) return ecStackUnderflow; if (rds != psave->rds) { if ((ec = ecEndGroupAction(rds)) != ecOK) return ec; } chp = psave->chp; pap = psave->pap; sep = psave->sep; dop = psave->dop; rds = psave->rds; ris = psave->ris; psaveOld = psave; psave = psave->pNext; m_cGroup--; delete psaveOld; return ecOK;}// ecParseRtfKeyword// get a control word (and its associated value) and// call ecTranslateKeyword to dispatch the control.int CRtfDecoder::ecParseRtfKeyword(u_char *buf,int &pos,int size){ int ch; bool fParam = fFalse; char fNeg = fFalse; int param = 0; char *pch; char szKeyword[30]; char szParameter[20]; szKeyword[0] = '\0'; szParameter[0] = '\0'; if (pos==size) return ecEndOfFile;
ch=buf[pos++]; if (!isalpha(ch)) // a control symbol; no delimiter. { szKeyword[0] = (char) ch; szKeyword[1] = '\0'; return ecTranslateKeyword(szKeyword, 0, fParam); } for (pch = szKeyword; isalpha(ch); ch = buf[pos++]) *pch++ = (char) ch; *pch = '\0'; if (ch == '-') { fNeg = fTrue; if (pos==size)
return ecEndOfFile;
ch=buf[pos++];
} if (isdigit(ch)) { fParam = fTrue; // a digit after the control means we have a parameter for (pch = szParameter; isdigit(ch); ch = buf[pos++]) *pch++ = (char) ch; *pch = '\0'; param = atoi(szParameter); if (fNeg) param = -param; m_lParam = atol(szParameter); if (fNeg) param = -param; } if (ch != ' ') pos--; return ecTranslateKeyword(szKeyword, param, fParam);}// ecParseChar// Route the character to the appropriate destination stream.int CRtfDecoder::ecParseChar(int ch){ if (ris == risBin && --m_cbBin <= 0) ris = risNorm; switch (rds) { case rdsSkip: // Toss this character. return ecOK; case rdsNorm: // Output a character. Properties are valid at this point. return ecPrintChar(ch); default: // handle other destinations.... return ecOK; }}
// ecPrintChar// Send a character to the output int CRtfDecoder::ecPrintChar(int ch){ // Store the Extracted Character to Output p_midbuf[m_midbuflen++]=ch;
return ecOK;}
bool CRtfDecoder::reset()
{
m_cGroup=0;
m_cbBin=0;
m_fSkipDestIfUnk=fFalse;
m_lParam=0;
m_previousparam=-1;
m_midbuflen=0;
m_outbuflen=0;
m_curCharset=0;
m_curCodePage=-1;
m_previousCodeP=-1;
m_firstentry=fTrue;
rds=rdsNorm;
ris=risNorm;
psave=NULL;
memset(&chp,0,sizeof(CHP));
memset(&pap,0,sizeof(PAP));
memset(&sep,0,sizeof(SEP));
memset(&dop,0,sizeof(DOP));
memset(p_midbuf,0,MIDBUFSIZE);
memset(p_outbuf,0,OUTBUFSIZE);
memset(allCharset,0,sizeof(allCharset));
return true;
}
int CRtfDecoder::is_me(u_char *buf,int len)
{
char RtfHeader[4];
memcpy(RtfHeader,buf+2,3);
RtfHeader[3]='\0';
_strlwr(RtfHeader);
if(!strcmp(RtfHeader,"rtf"))
return 100;
else
return 0;
}
bool CRtfDecoder::decode(u_char *inbuf,int insize, u_char *outbuf,int outbufsize)
{
ecRtfParse(inbuf,insize);
if(m_outbuflen>0)
return true;
else
return false;
}
u_char *CRtfDecoder::get_result(int &retsize,int &type)
{
retsize=m_outbuflen;
type=IS_UNICODE;
return p_outbuf;
}
bool CRtfDecoder::continue_decode()
{
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -