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

📄 rtfdecoder.cpp

📁 此文件为RTF文件转换为TXT文件的解码程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************************/    /*                             Modification  History                                        *//*   By Whom            When                     For What                                   *//********************************************************************************************/#include "stdafx.h"#include "RtfDecoder.h"
int Charset2Cpg[256];

// Property descriptions
PROP rgprop [ipropMax] = {
    actnByte,   propChp,    offsetof(CHP, fBold),       // ipropBold
		actnByte,   propChp,    offsetof(CHP, fItalic),     // ipropItalic
		actnByte,   propChp,    offsetof(CHP, fUnderline),  // ipropUnderline
		actnWord,   propPap,    offsetof(PAP, xaLeft),      // ipropLeftInd
		actnWord,   propPap,    offsetof(PAP, xaRight),     // ipropRightInd
		actnWord,   propPap,    offsetof(PAP, xaFirst),     // ipropFirstInd
		actnWord,   propSep,    offsetof(SEP, cCols),       // ipropCols
		actnWord,   propSep,    offsetof(SEP, xaPgn),       // ipropPgnX
		actnWord,   propSep,    offsetof(SEP, yaPgn),       // ipropPgnY
		actnWord,   propDop,    offsetof(DOP, xaPage),      // ipropXaPage
		actnWord,   propDop,    offsetof(DOP, yaPage),      // ipropYaPage
		actnWord,   propDop,    offsetof(DOP, xaLeft),      // ipropXaLeft
		actnWord,   propDop,    offsetof(DOP, xaRight),     // ipropXaRight
		actnWord,   propDop,    offsetof(DOP, yaTop),       // ipropYaTop
		actnWord,   propDop,    offsetof(DOP, yaBottom),    // ipropYaBottom
		actnWord,   propDop,    offsetof(DOP, pgnStart),    // ipropPgnStart
		actnByte,   propSep,    offsetof(SEP, sbk),         // ipropSbk
		actnByte,   propSep,    offsetof(SEP, pgnFormat),   // ipropPgnFormat
		actnByte,   propDop,    offsetof(DOP, fFacingp),    // ipropFacingp
		actnByte,   propDop,    offsetof(DOP, fLandscape),  // ipropLandscape
		actnByte,   propPap,    offsetof(PAP, just),        // ipropJust
		actnSpec,   propPap,    0,                          // ipropPard
		actnSpec,   propChp,    0,                          // ipropPlain
		actnSpec,   propSep,    0,                          // ipropSectd
};

// Keyword descriptions
SYM rgsymRtf[] = {
	//  keyword     dflt    fPassDflt   kwd         idx
	    "b",        1,      fFalse,     kwdProp,    ipropBold,
		"u",        1,      fFalse,     kwdProp,    ipropUnderline,
		"i",        1,      fFalse,     kwdProp,    ipropItalic,
		"li",       0,      fFalse,     kwdProp,    ipropLeftInd,
		"ri",       0,      fFalse,     kwdProp,    ipropRightInd,
		"fi",       0,      fFalse,     kwdProp,    ipropFirstInd,
		"cols",     1,      fFalse,     kwdProp,    ipropCols,
		"sbknone",  sbkNon, fTrue,      kwdProp,    ipropSbk,
		"sbkcol",   sbkCol, fTrue,      kwdProp,    ipropSbk,
		"sbkeven",  sbkEvn, fTrue,      kwdProp,    ipropSbk,
		"sbkodd",   sbkOdd, fTrue,      kwdProp,    ipropSbk,
		"sbkpage",  sbkPg,  fTrue,      kwdProp,    ipropSbk,
		"pgnx",     0,      fFalse,     kwdProp,    ipropPgnX,
		"pgny",     0,      fFalse,     kwdProp,    ipropPgnY,
		"pgndec",   pgDec,  fTrue,      kwdProp,    ipropPgnFormat,
		"pgnucrm",  pgURom, fTrue,      kwdProp,    ipropPgnFormat,
		"pgnlcrm",  pgLRom, fTrue,      kwdProp,    ipropPgnFormat,
		"pgnucltr", pgULtr, fTrue,      kwdProp,    ipropPgnFormat,
		"pgnlcltr", pgLLtr, fTrue,      kwdProp,    ipropPgnFormat,
		"qc",       justC,  fTrue,      kwdProp,    ipropJust,
		"ql",       justL,  fTrue,      kwdProp,    ipropJust,
		"qr",       justR,  fTrue,      kwdProp,    ipropJust,
		"qj",       justF,  fTrue,      kwdProp,    ipropJust,
		"paperw",   12240,  fFalse,     kwdProp,    ipropXaPage,
		"paperh",   15480,  fFalse,     kwdProp,    ipropYaPage,
		"margl",    1800,   fFalse,     kwdProp,    ipropXaLeft,
		"margr",    1800,   fFalse,     kwdProp,    ipropXaRight,
		"margt",    1440,   fFalse,     kwdProp,    ipropYaTop,
		"margb",    1440,   fFalse,     kwdProp,    ipropYaBottom,
		"pgnstart", 1,      fTrue,      kwdProp,    ipropPgnStart,
		"facingp",  1,      fTrue,      kwdProp,    ipropFacingp,
		"landscape",1,      fTrue,      kwdProp,    ipropLandscape,
		"par",      0,      fFalse,     kwdChar,    0x0a,
		"\0x0a",    0,      fFalse,     kwdChar,    0x0a,
		"\0x0d",    0,      fFalse,     kwdChar,    0x0a,
		"tab",      0,      fFalse,     kwdChar,    0x09,
		"ldblquote",0,      fFalse,     kwdChar,    '"',
		"rdblquote",0,      fFalse,     kwdChar,    '"',
		"bin",      0,      fFalse,     kwdSpec,    ipfnBin,
		"*",        0,      fFalse,     kwdSpec,    ipfnSkipDest,
		"'",        0,      fFalse,     kwdSpec,    ipfnHex,
		"author",   0,      fFalse,     kwdDest,    idestSkip,
		"buptim",   0,      fFalse,     kwdDest,    idestSkip,
		"colortbl", 0,      fFalse,     kwdDest,    idestSkip,
		"comment",  0,      fFalse,     kwdDest,    idestSkip,
		"creatim",  0,      fFalse,     kwdDest,    idestSkip,
		"doccomm",  0,      fFalse,     kwdDest,    idestSkip,
		//cjg add
		"fcharset",  0,      fFalse,    kwdSpec,    idestSkip,
		
		"fonttbl",  0,      fFalse,     kwdDest,    idestSkip,
		"footer",   0,      fFalse,     kwdDest,    idestSkip,
		"footerf",  0,      fFalse,     kwdDest,    idestSkip,
		"footerl",  0,      fFalse,     kwdDest,    idestSkip,
		"footerr",  0,      fFalse,     kwdDest,    idestSkip,
		"footnote", 0,      fFalse,     kwdDest,    idestSkip,
		"ftncn",    0,      fFalse,     kwdDest,    idestSkip,
		"ftnsep",   0,      fFalse,     kwdDest,    idestSkip,
		"ftnsepc",  0,      fFalse,     kwdDest,    idestSkip,
		"header",   0,      fFalse,     kwdDest,    idestSkip,
		"headerf",  0,      fFalse,     kwdDest,    idestSkip,
		"headerl",  0,      fFalse,     kwdDest,    idestSkip,
		"headerr",  0,      fFalse,     kwdDest,    idestSkip,
		"info",     0,      fFalse,     kwdDest,    idestSkip,
		"keywords", 0,      fFalse,     kwdDest,    idestSkip,
		"operator", 0,      fFalse,     kwdDest,    idestSkip,
		"pict",     0,      fFalse,     kwdDest,    idestSkip,
		"printim",  0,      fFalse,     kwdDest,    idestSkip,
		"private1", 0,      fFalse,     kwdDest,    idestSkip,
		"revtim",   0,      fFalse,     kwdDest,    idestSkip,
		"rxe",      0,      fFalse,     kwdDest,    idestSkip,
		"stylesheet",   0,      fFalse,     kwdDest,    idestSkip,
		"subject",  0,      fFalse,     kwdDest,    idestSkip,
		"tc",       0,      fFalse,     kwdDest,    idestSkip,
		"title",    0,      fFalse,     kwdDest,    idestSkip,
		"txe",      0,      fFalse,     kwdDest,    idestSkip,
		"xe",       0,      fFalse,     kwdDest,    idestSkip,
		"{",        0,      fFalse,     kwdChar,    '{',
		"}",        0,      fFalse,     kwdChar,    '}',
		"\\",       0,      fFalse,     kwdChar,    '\\'
};

class NULL_CLASS
{
public:
	NULL_CLASS()
	{
		memset(Charset2Cpg,-1,sizeof(Charset2Cpg));
		Charset2Cpg[0]=1252;		//ANSI_CHARSET
		Charset2Cpg[2]=936;			//ANSI_CHARSET
		Charset2Cpg[128]=932;		//SHIFTJIS_CHARSET
		Charset2Cpg[129]=949;		//HANGUL_CHARSET
		Charset2Cpg[134]=936;		//GB2312_CHARSET
		Charset2Cpg[136]=950;		//CHINESEBIG5_CHARSET
		Charset2Cpg[161]=1253;		//GREEK_CHARSET
		Charset2Cpg[162]=1254;		//TURKISH_CHARSET
		Charset2Cpg[177]=1255;		//HEBREW_CHARSET
		Charset2Cpg[178]=1256;		//ARABIC_CHARSET
		Charset2Cpg[186]=1257;		//BALTIC_CHARSET
		Charset2Cpg[204]=1251;		//RUSSIAN_CHARSET
		Charset2Cpg[222]=874;		//THAI_CHARSET
		Charset2Cpg[238]=1250;		//EE_CHARSET
		Charset2Cpg[255]=1252;		//OEM_CHARSET
	}
	~NULL_CLASS()
	{}
}aa;


CRtfDecoder::CRtfDecoder(CPublicResource *ps):
			CDecoderBase(ps)
{
	coderName="RTF";
	version=0x0100;
	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=true;
	rds=rdsNorm;
	ris=risNorm;
	memset(&chp,0,sizeof(CHP));
	memset(&pap,0,sizeof(PAP));
	memset(&sep,0,sizeof(SEP));
	memset(&dop,0,sizeof(DOP));
	psave=NULL;
	isymMax = sizeof(rgsymRtf) / sizeof(SYM);
	p_midbuf=new unsigned char[MIDBUFSIZE];
	p_outbuf=new unsigned char[OUTBUFSIZE];
	memset(p_midbuf,0,MIDBUFSIZE);
	memset(p_outbuf,0,OUTBUFSIZE);
	memset(allCharset,0,sizeof(allCharset));

}

CRtfDecoder::~CRtfDecoder()
{
	if(p_midbuf)delete p_midbuf;
	p_midbuf=NULL;
	if(p_outbuf)delete p_outbuf;
	p_outbuf=NULL;
}
// ecApplyPropChange
// Set the property identified by _iprop_ to the value _val_.
int CRtfDecoder::ecApplyPropChange(IPROP iprop, int val)
{
    char *pb;

    if (rds == rdsSkip)                 // If we're skipping text,
        return ecOK;                    // don't do anything.

    switch (rgprop[iprop].prop)
    {
    case propDop:
        pb = (char *)&dop;
        break;
    case propSep:
        pb = (char *)&sep;
        break;
    case propPap:
        pb = (char *)&pap;
        break;
    case propChp:
        pb = (char *)&chp;
        break;
    default:
        if (rgprop[iprop].actn != actnSpec)
            return ecBadTable;
        break;
    }
    switch (rgprop[iprop].actn)
    {
    case actnByte:
        pb[rgprop[iprop].offset] = (unsigned char) val;
        break;
    case actnWord:
        (*(int *) (pb+rgprop[iprop].offset)) = val;
        break;
    case actnSpec:
        return ecParseSpecialProperty(iprop, val);
        break;
    default:
        return ecBadTable;
    }
    return ecOK;
}

// ecParseSpecialProperty
// Set a property that requires code to evaluate.
int CRtfDecoder::ecParseSpecialProperty(IPROP iprop, int val)
{
    switch (iprop)
    {
    case ipropPard:
        memset(&pap, 0, sizeof(pap));
        return ecOK;
    case ipropPlain:
        memset(&chp, 0, sizeof(chp));
        return ecOK;
    case ipropSectd:
        memset(&sep, 0, sizeof(sep));
        return ecOK;
    default:
        return ecBadTable;
    }
    return ecBadTable;
}

// ecTranslateKeyword.
// Search rgsymRtf for szKeyword and evaluate it appropriately.
// Inputs:
// szKeyword:   The RTF control to evaluate.
// param:       The parameter of the RTF control.
// fParam:      fTrue if the control had a parameter; (that is, if param is valid)
//              fFalse if it did not.
int CRtfDecoder::ecTranslateKeyword(char *szKeyword, int param, bool fParam)
{
    int isym;
	
	if(fParam)
	{
		if(!strcmp(szKeyword,"f"))
		{
			if(param>m_previousparam)
			{
				m_previousparam=param;
			}
			else
			{
				m_curCharset=allCharset[param];
				m_curCodePage=Charset2Cpg[m_curCharset];
				ecMidBuftoOutBuf();
				m_previousCodeP=m_curCodePage;
			}
		}
		if(!strcmp(szKeyword,"fcharset"))
		{
			allCharset[m_previousparam]=param;
		}
	}
    // search for szKeyword in rgsymRtf
	
    for (isym = 0; isym < isymMax; isym++)
        if (strcmp(szKeyword, rgsymRtf[isym].szKeyword) == 0)
            break;
    if (isym == isymMax)            // control word not found
    {
        if (m_fSkipDestIfUnk)         // if this is a new destination
            rds = rdsSkip;          // skip the destination
                                    // else just discard it
        m_fSkipDestIfUnk = fFalse;
        return ecOK;
    }
    // found it!  use kwd and idx to determine what to do with it.

    m_fSkipDestIfUnk = fFalse;
    switch (rgsymRtf[isym].kwd)
    {
    case kwdProp:
        if (rgsymRtf[isym].fPassDflt || !fParam)
            param = rgsymRtf[isym].dflt;
        return ecApplyPropChange((IPROP)rgsymRtf[isym].idx, param);
    case kwdChar:
        return ecParseChar(rgsymRtf[isym].idx);
    case kwdDest:
        return ecChangeDest((IDEST)rgsymRtf[isym].idx);
    case kwdSpec:
        return ecParseSpecialKeyword((IPFN)rgsymRtf[isym].idx);
    default:
        return ecBadTable;
    }
    return ecBadTable;
}

// ecChangeDest
// Change to the destination specified by idest.
// There's usually more to do here than this...
int CRtfDecoder::ecChangeDest(IDEST idest)
{
    if (rds == rdsSkip)             // if we're skipping text,
        return ecOK;                // don't do anything

    rds = rdsSkip ;
	/*switch (idest)
    {
    default:
        rds = rdsSkip;              // when in doubt, skip it...
        break;
    }*/
    return ecOK;
}

//ecEndGroupAction
// The destination specified by rds is coming to a close.
// If there's any cleanup that needs to be done, do it now.
int CRtfDecoder::ecEndGroupAction(RDS rds)
{
    return ecOK;
}

// ecParseSpecialKeyword
// Evaluate an RTF control that needs special processing.
int CRtfDecoder::ecParseSpecialKeyword(IPFN ipfn)
{
    if (rds == rdsSkip && ipfn != ipfnBin)  // if we're skipping, and it's not
        return ecOK;                        // the \bin keyword, ignore it.
    switch (ipfn)
    {
    case ipfnBin:
        ris = risBin;
        m_cbBin = m_lParam;
        break;
    case ipfnSkipDest:
        m_fSkipDestIfUnk = fTrue;
        break;
    case ipfnHex:

⌨️ 快捷键说明

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