00001
00002
00003 #include "xmltk.h"
00004 #include "tokenmap.h"
00005
00006 class CTSAX2Bin : public ITSAX2Bin
00007 {
00008 public:
00009
00010 CL_STDMETHOD(QueryInterface) (RCLIID riid, void **ppvObj);
00011 CL_STDMETHOD_(ULONG,AddRef) ();
00012 CL_STDMETHOD_(ULONG,Release) ();
00013
00014
00015 CL_STDMETHOD(startDocument) ();
00016 CL_STDMETHOD(endDocument) ();
00017 CL_STDMETHOD(startElement) (XTOKEN xtName);
00018 CL_STDMETHOD(endElement) (XTOKEN xtName);
00019 CL_STDMETHOD(attribute) (XTOKEN xtName, char *pszChars, int cchChars);
00020 CL_STDMETHOD(characters) (char *pszChars, int cchChars);
00021 CL_STDMETHOD(cdata) (char *pszChars, int cchChars);
00022 CL_STDMETHOD(extendedint) (XTOKEN xt, int iInt);
00023
00024
00025 CL_STDMETHOD(Init) (IStream *pws, bool bEmitTableEntries);
00026
00027 CTSAX2Bin() : m_pstm(NULL), m_cRef(1), m_xtNext(XT_FIRST),
00028 m_bEmitTableEntries(true)
00029 {
00030 }
00031
00032 virtual ~CTSAX2Bin()
00033 {
00034 if (m_pstm)
00035 m_pstm->Release();
00036 }
00037
00038 private:
00039
00040 void _fputsTerm(char *psz)
00041 {
00042 m_pstm->Write(psz, strlen(psz));
00043 m_pstm->WriteChar(0);
00044 }
00045
00046 XTOKEN _GetNewXTOKEN()
00047 {
00048
00049
00050
00051 if (m_xtNext == 0x1A)
00052 {
00053 m_xtNext++;
00054 }
00055 return m_xtNext++;
00056 }
00057
00058 void _OutputTableEntry(XTOKEN xt, XTOKEN xtOut)
00059 {
00060
00061
00062
00063
00064
00065
00066
00067 m_pstm->WriteChar(XT_TABLE);
00068
00069 fwriteMultiByteUINT(m_pstm, xtOut);
00070
00071 DWORD dwType = g_ptt->TypeFromXTOKEN(xt);
00072 m_pstm->WriteChar(dwType);
00073
00074 STRPAIR* ppair = g_ptt->PairFromXTOKEN(xt);
00075 _fputsTerm(ppair->first);
00076
00077 if (dwType == XST_EXTENDEDINT)
00078 {
00079 _fputsTerm(ppair->second);
00080 }
00081 else
00082 {
00083 assert(ppair->second == NULL);
00084 }
00085
00086 m_pstm->WriteChar(XT_END);
00087 }
00088
00089 void _EmitToken(XTOKEN xt)
00090 {
00091 XTOKEN xtOut;
00092 if (m_bEmitTableEntries)
00093 {
00094 xtOut = m_tmap.GetMapping(xt);
00095 if (xtOut == XT_UNKNOWN)
00096 {
00097 xtOut = _GetNewXTOKEN();
00098 m_tmap.AddMapping(xt, xtOut);
00099 _OutputTableEntry(xt, xtOut);
00100 }
00101 }
00102 else
00103 {
00104 xtOut = xt;
00105 }
00106 fwriteMultiByteUINT(m_pstm, xtOut);
00107 }
00108
00109 CTokenMap m_tmap;
00110 IStream *m_pstm;
00111 ULONG m_cRef;
00112 XTOKEN m_xtNext;
00113 bool m_bEmitTableEntries;
00114 };
00115
00116
00117 bool CTSAX2Bin::QueryInterface(RCLIID riid, void **ppvObj)
00118 {
00119 if (IsEqualCLIID(riid, &IID_IUnknownCL) ||
00120 IsEqualCLIID(riid, &IID_ITSAXContentHandler) ||
00121 IsEqualCLIID(riid, &IID_ITSAX2Bin))
00122 {
00123 *ppvObj = static_cast<ITSAX2Bin*>(this);
00124 }
00125 else
00126 {
00127 return false;
00128 }
00129 AddRef();
00130 return true;
00131 }
00132
00133 ULONG CTSAX2Bin::AddRef()
00134 {
00135 return ++m_cRef;
00136 }
00137
00138 ULONG CTSAX2Bin::Release()
00139 {
00140 --m_cRef;
00141 if (m_cRef > 0)
00142 {
00143 return m_cRef;
00144 }
00145 delete this;
00146 return 0;
00147 }
00148
00149 bool CTSAX2Bin::characters(char *pszChars, int cchChars)
00150 {
00151 m_pstm->WriteChar(XT_STRING);
00152 _fputsTerm(pszChars);
00153 return true;
00154 }
00155
00156 bool CTSAX2Bin::extendedint(XTOKEN xt, int iInt)
00157 {
00158 _EmitToken(xt);
00159 fwriteMultiByteUINT(m_pstm, (UINT)iInt);
00160
00161 return true;
00162 }
00163
00164 bool CTSAX2Bin::endDocument()
00165 {
00166 return true;
00167 }
00168
00169 bool CTSAX2Bin::startDocument()
00170 {
00171 XBINHEADER xh = { XBIN_VERSION };
00172 m_pstm->Write(&xh, sizeof(xh));
00173 return true;
00174 }
00175
00176 bool CTSAX2Bin::endElement(XTOKEN xtName)
00177 {
00178 m_pstm->WriteChar(XT_END);
00179 return true;
00180 }
00181
00182 bool CTSAX2Bin::startElement(XTOKEN xtName)
00183 {
00184 _EmitToken(xtName);
00185 return true;
00186 }
00187
00188 bool CTSAX2Bin::attribute(XTOKEN xtName, char *pszChars, int cchChars)
00189 {
00190 _EmitToken(xtName);
00191 _fputsTerm(pszChars);
00192 return true;
00193 }
00194
00195 bool CTSAX2Bin::cdata(char *pszChars, int cchChars)
00196 {
00197 m_pstm->WriteChar(XT_CDATA);
00198 fwriteMultiByteUINT(m_pstm, (UINT)cchChars);
00199 m_pstm->Write(pszChars, cchChars);
00200 return true;
00201 }
00202
00203
00204 bool CTSAX2Bin::Init(IStream *pstm, bool bEmitTableEntries)
00205 {
00206 if (m_pstm)
00207 m_pstm->Release();
00208 m_pstm = pstm;
00209 if (m_pstm)
00210 m_pstm->AddRef();
00211
00212 m_bEmitTableEntries = bEmitTableEntries;
00213 return true;
00214 }
00215
00216 bool CreateTSAX2Bin(RCLIID riid, void **ppvObj)
00217 {
00218 bool bResult = false;
00219
00220 CTSAX2Bin *ptb = new CTSAX2Bin();
00221 if (ptb)
00222 {
00223 bResult = ptb->QueryInterface(riid, ppvObj);
00224 ptb->Release();
00225 }
00226
00227 return bResult;
00228 }