hxxmlprs.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:23k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxxmlprs.cpp,v 1.3.36.3 2004/07/09 01:44:10 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxtypes.h"
  50. #include "hxresult.h"
  51. #include "hxassert.h"
  52. #include "hxheap.h"
  53. #include "hxcom.h"
  54. #include "hxcomm.h"
  55. #include "hxfiles.h"
  56. #include "ihxpckts.h"
  57. #include "hxxml.h"
  58. #include "xmlreslt.h"
  59. #include "cbbqueue.h"
  60. #include "hxbuffer.h"
  61. #include "chxpckts.h"
  62. #include "looseprs.h"
  63. #include "hxxmlprs.h"
  64. #ifdef _DEBUG
  65. #undef HX_THIS_FILE
  66. static const char HX_THIS_FILE[] = __FILE__;
  67. #endif
  68. #ifndef _VXWORKS
  69. static const UINT32 BUFSIZE = 1024;
  70. #endif
  71. HXXMLParser::HXXMLParser(BOOL bAllowNonXMLComments):
  72.     m_lRefCount(0),
  73.     m_pParser(NULL),
  74.     m_pResponse(NULL),
  75.     m_bAllowNonXMLComments(bAllowNonXMLComments)
  76. {
  77. }
  78. HXXMLParser::~HXXMLParser()
  79. {
  80.     Close();
  81. }
  82. /*
  83.  * IUnknown methods
  84.  */
  85. STDMETHODIMP 
  86. HXXMLParser::QueryInterface(REFIID riid, void** ppvObj)
  87. {
  88.     if (IsEqualIID(riid, IID_IUnknown))
  89.     {
  90. AddRef();
  91. *ppvObj = this;
  92. return HXR_OK;
  93.     }
  94.     else if (IsEqualIID(riid, IID_IHXXMLParser))
  95.     {
  96. AddRef();
  97. *ppvObj = (IHXXMLParser*)this;
  98. return HXR_OK;
  99.     }
  100.     *ppvObj = NULL;
  101.     return HXR_NOINTERFACE;
  102. }
  103. STDMETHODIMP_(ULONG32) 
  104. HXXMLParser::AddRef()
  105. {
  106.     return InterlockedIncrement(&m_lRefCount);
  107. }
  108. STDMETHODIMP_(ULONG32) 
  109. HXXMLParser::Release()
  110. {
  111.     if (InterlockedDecrement(&m_lRefCount) > 0)
  112.     {
  113.         return m_lRefCount;
  114.     }
  115.     delete this;
  116.     return 0;
  117. }
  118. /*
  119.  * IHXXMLParser methods
  120.  */
  121. STDMETHODIMP
  122. HXXMLParser::Init(IHXXMLParserResponse* /*IN*/  pResponse,
  123.    const char*     /*IN*/ pEncoding,
  124.    BOOL     /*IN*/ bStrict)
  125. {
  126.     HX_RESULT rc = HXR_OK;
  127.     m_pResponse = pResponse;
  128.     m_pResponse->AddRef(); 
  129.     if(bStrict)
  130.     {
  131. m_pParser = new HXStrictXMLParser();
  132.     }
  133.     else
  134.     {
  135. m_pParser = new HXLooseXMLParser(m_bAllowNonXMLComments);
  136.     }
  137.     rc = m_pParser->Init(pResponse, pEncoding);
  138.     return rc;
  139. }
  140. STDMETHODIMP
  141. HXXMLParser::Close()
  142. {
  143.     HX_RESULT rc = HXR_OK;
  144.     HX_RELEASE(m_pResponse);
  145.     HX_DELETE(m_pParser);
  146.     return rc;
  147. }
  148. STDMETHODIMP
  149. HXXMLParser::Parse(IHXBuffer* /*IN*/     pBuffer,
  150.   BOOL /*IN*/     bIsFinal)
  151. {
  152.     HX_RESULT rc = HXR_OK;
  153.     rc = m_pParser->Parse(pBuffer, bIsFinal);    
  154.     return rc;
  155. }
  156. STDMETHODIMP
  157. HXXMLParser::GetCurrentLineNumber(REF(ULONG32) /*OUT*/ ulLineNumber)
  158. {
  159.     HX_RESULT rc = HXR_OK;
  160.     rc = m_pParser->GetCurrentLineNumber(ulLineNumber);
  161.     return rc;
  162. }
  163. STDMETHODIMP
  164. HXXMLParser::GetCurrentColumnNumber(REF(ULONG32) /*OUT*/ ulColumnNumber)
  165. {
  166.     HX_RESULT rc = HXR_OK;
  167.     rc = m_pParser->GetCurrentColumnNumber(ulColumnNumber);
  168.     return rc;
  169. }
  170. STDMETHODIMP
  171. HXXMLParser::GetCurrentByteIndex(REF(ULONG32) /*OUT*/ ulByteIndex)
  172. {
  173.     HX_RESULT rc = HXR_OK;
  174.     rc = m_pParser->GetCurrentByteIndex(ulByteIndex);
  175.     return rc;
  176. }
  177. STDMETHODIMP
  178. HXXMLParser::GetCurrentErrorText(REF(IHXBuffer*) /*OUT*/ pBuffer)
  179. {
  180.     HX_RESULT rc = HXR_OK;
  181.     rc = m_pParser->GetCurrentErrorText(pBuffer);
  182.     return rc;
  183. }
  184. HX_RESULT
  185. HXXMLParser::InitErrorNotifier(ErrorNotifier* /*OUT*/ pNotifier)
  186. {
  187.     return m_pParser->InitErrorNotifier(pNotifier);
  188. }
  189. /*
  190.  * virtual base class methods
  191.  */
  192. HXActualXMLParser::HXActualXMLParser():
  193.     m_pResponse(NULL)
  194. {
  195. }
  196. HXActualXMLParser::~HXActualXMLParser()
  197. {
  198. }
  199. void HXActualXMLParser::CheckEncoding(XMLParser* pParser, IHXBuffer* pBuffer)
  200. {
  201.     if (pParser && pBuffer)
  202.     {
  203.         // Check if this buffer has any prolog info
  204.         char* pszVersion  = NULL;
  205.         char* pszEncoding = NULL;
  206.         HX_RESULT rv = pParser->GetPrologInfo((const char*) pBuffer->GetBuffer(),
  207.                                               pBuffer->GetSize(),
  208.                                               pszVersion,
  209.                                               pszEncoding);
  210.         if (SUCCEEDED(rv) && pszEncoding && strlen(pszEncoding) > 0)
  211.         {
  212.             // Get the encoding from the parser
  213.             char* pszParserEncoding = NULL;
  214.             HX_RESULT rv = pParser->GetEncoding(pszParserEncoding);
  215.             if (SUCCEEDED(rv) &&
  216.                 strcmp(pszEncoding, pszParserEncoding) != 0)
  217.             {
  218.                 pParser->SetEncoding(pszEncoding);
  219.             }
  220.             HX_VECTOR_DELETE(pszParserEncoding);
  221.         }
  222.         HX_VECTOR_DELETE(pszVersion);
  223.         HX_VECTOR_DELETE(pszEncoding);
  224.     }
  225. }
  226. /* 
  227.  * HXLooseXMLParser methods
  228.  */
  229. HXLooseXMLParser::HXLooseXMLParser(BOOL bAllowNonXMLComments):
  230.     m_pParser(NULL),
  231.     m_pByteQueue(NULL),
  232.     m_bAllowNonXMLComments(bAllowNonXMLComments)
  233. {
  234. }
  235. HXLooseXMLParser::~HXLooseXMLParser()
  236. {
  237.     HX_DELETE(m_pParser);
  238.     HX_DELETE(m_pByteQueue);
  239. }
  240. HX_RESULT
  241. HXLooseXMLParser::Init(IHXXMLParserResponse* pResponse,
  242.        const char* pEncoding)
  243. {
  244.     m_pResponse = pResponse;
  245.     m_pParser = new XMLParser(FALSE, pEncoding, m_bAllowNonXMLComments);
  246.     m_pByteQueue = new CBigByteQueue(BUFSIZE);
  247.     return HXR_OK;
  248. }
  249. HX_RESULT
  250. HXLooseXMLParser::Parse(IHXBuffer* pBuffer,
  251. BOOL bIsFinal)
  252. {
  253.     HX_RESULT rc = HXR_OK;
  254.     // Check the encoding
  255.     CheckEncoding(m_pParser, pBuffer);
  256.     UINT32 ulBufLen = pBuffer->GetSize();
  257.     if(m_pByteQueue->GetAvailableElements() < ulBufLen)
  258.     {
  259. m_pByteQueue->Grow(ulBufLen);
  260.     }
  261.     m_pByteQueue->EnQueue(pBuffer->GetBuffer(), ulBufLen);
  262.     rc = DoParse(bIsFinal);
  263.     return rc;
  264. }
  265. HX_RESULT
  266. HXLooseXMLParser::GetCurrentLineNumber(REF(ULONG32) ulLineNumber)
  267. {
  268.     HX_RESULT rc = HXR_OK;
  269.     ulLineNumber = (UINT32)m_pParser->GetCurrentLineNumber();
  270.     return rc;
  271. }
  272. HX_RESULT
  273. HXLooseXMLParser::GetCurrentColumnNumber(REF(ULONG32) ulColumnNumber)
  274. {
  275.     HX_RESULT rc = HXR_OK;
  276.     ulColumnNumber = (UINT32)m_pParser->GetCurrentColumnNumber();
  277.     return rc;
  278. }
  279. HX_RESULT
  280. HXLooseXMLParser::GetCurrentByteIndex(REF(ULONG32) ulByteIndex)
  281. {
  282.     HX_RESULT rc = HXR_OK;
  283.     return rc;
  284. }
  285. HX_RESULT
  286. HXLooseXMLParser::GetCurrentErrorText(REF(IHXBuffer*) pBuffer)
  287. {
  288.     HX_RESULT rc = HXR_FAIL;
  289.     XMLError* pLastError = m_pParser->GetLastError();
  290.     if(pLastError &&
  291. pLastError->m_pErrorString)
  292.     {
  293. pBuffer = new CHXBuffer;
  294. pBuffer->AddRef();
  295. pBuffer->Set((BYTE*)pLastError->m_pErrorString,
  296.  strlen(pLastError->m_pErrorString) + 1);
  297. rc = HXR_OK;
  298.     }
  299.     return rc;
  300. }
  301. HX_RESULT
  302. HXLooseXMLParser::DoParse(BOOL bIsFinal)
  303. {
  304.     HX_RESULT rc = HXR_OK;
  305.     XMLTag* pTag = NULL;
  306.     BOOL bDone = FALSE;
  307.     while(!bDone && SUCCEEDED(rc))
  308.     {
  309. UINT32 bytesUsed;
  310. UINT32 bytesAvail = m_pByteQueue->GetQueuedItemCount();
  311. if(bytesAvail <= 0)
  312. {
  313.     break;
  314. }
  315. BYTE* pBuf = new BYTE[bytesAvail];
  316. BYTE* p = pBuf;
  317. m_pByteQueue->DeQueue(pBuf, bytesAvail);
  318. bytesUsed = bytesAvail;
  319. if(pTag)
  320. {
  321.     delete pTag;
  322.     pTag = 0;
  323. }
  324. XMLParseResult pResult = 
  325.     m_pParser->Parse((const char*&)p, bytesAvail, pTag, bIsFinal);
  326. m_pByteQueue->EnQueue(p, (UINT32)(bytesAvail - (p - pBuf)));
  327. // pBuf is not needed anymore, so delete
  328. HX_VECTOR_DELETE(pBuf);
  329. p = NULL;
  330. switch(pResult)
  331. {
  332.     case XMLPNotDone:
  333.     {
  334. goto exit;
  335.     }
  336.     case XMLPNoClose:
  337.     {
  338. rc = HXR_XML_NOCLOSE;
  339. goto exit;
  340.     }
  341.     case XMLPBadAttribute:
  342.     {
  343. rc = HXR_XML_NOTAGTYPE;
  344. goto exit;
  345.     }
  346.     case XMLPBadEndTag:
  347.     {
  348. rc = HXR_XML_BADENDTAG;
  349. goto exit;
  350.     }
  351.     
  352.     case XMLPAttributeValueNotQuoted:
  353.     {
  354. rc = HXR_XML_MISSINGQUOTE;
  355. goto exit;
  356.     }
  357.     case XMLPBadDirective:
  358.     {
  359. rc = HXR_XML_GENERALERROR;
  360. goto exit;
  361.     }
  362.     case XMLPDupAttribute:
  363.     {
  364. rc = HXR_XML_DUPATTRIBUTE;
  365. goto exit;
  366.     }
  367.     case XMLPComment:
  368.     {
  369. const char* pValue = pTag->m_cur_attribute->value;
  370. rc = m_pResponse->HandleComment(pValue,0,0);
  371.     }
  372.     break;
  373.     case XMLPPlainText:
  374.     {
  375. const char* pValue = pTag->m_cur_attribute->value;
  376. CHXBuffer* pBuffer = new CHXBuffer;
  377. pBuffer->AddRef();
  378. pBuffer->Set((const BYTE*)pValue, strlen(pValue)+1);
  379. rc = m_pResponse->HandleCharacterData(pBuffer,0,0);
  380. HX_RELEASE(pBuffer);
  381.     }
  382.     break;
  383.     case XMLPDirective:
  384.     {
  385. const char* pValue = pTag->m_name;
  386. if(strcmp(pValue, "DOCTYPE") == 0)
  387. {
  388.     // m_bExternalDoctype = TRUE;
  389. }
  390.     }
  391.     break;
  392.     case XMLPProcInst:
  393.     // handle processing instruction
  394.     {
  395. const char* pTarget = pTag->m_name;
  396. CHXHeader* pValues = new CHXHeader;
  397. pValues->AddRef();
  398. for(UINT32 i=0;i<pTag->m_numAttributes;++i)
  399. {
  400.     XMLAttribute* pAttr = pTag->attribute(i);
  401.     // the XMLParser class supports what it calls attributes
  402.     // without names.  It's used to communicate processing
  403.     // instructions and things like that. We just ignore attributes
  404.     // without names here.
  405.     if (pAttr->name != NULL)
  406.     {
  407. CHXBuffer* pBuf = new CHXBuffer;
  408. pBuf->AddRef();
  409. pBuf->Set((const BYTE*)pAttr->value,
  410.     strlen(pAttr->value)+1);
  411. pValues->SetPropertyCString(
  412.     pAttr->name, pBuf);
  413. pBuf->Release();
  414.     }
  415. }
  416. rc = m_pResponse->HandleProcessingInstruction(pTarget,
  417.       pValues,0,0);
  418. HX_RELEASE(pValues);
  419.     }
  420.     break;
  421.     case XMLPTag:
  422.     {
  423. const char* pName = pTag->m_name;
  424. if(pTag->m_type != XMLEndTag)
  425. {
  426.     CHXHeader* pValues = new CHXHeader;
  427.     pValues->AddRef();
  428.     for(UINT32 i=0;i<pTag->m_numAttributes;++i)
  429.     {
  430. XMLAttribute* pAttr = pTag->attribute(i);
  431. // the XMLParser class supports what it calls attributes
  432. // without names.  It's used to communicate processing
  433. // instructions and things like that. We just ignore attributes
  434. // without names here.
  435. if (pAttr->name != NULL)
  436. {
  437.     CHXBuffer* pBuf = new CHXBuffer;
  438.     pBuf->AddRef();
  439.     pBuf->Set((const BYTE*)pAttr->value,
  440. strlen(pAttr->value)+1);
  441.     pValues->SetPropertyCString(
  442. pAttr->name, pBuf);
  443.     pBuf->Release();
  444. }
  445.     }
  446.     rc = m_pResponse->HandleStartElement(pName, pValues,
  447.                                                          m_pParser->GetTagStartLineNumber(),
  448.                                                          m_pParser->GetTagStartColumnNumber());
  449.     HX_RELEASE(pValues);
  450.     if(!pTag->m_need_close && SUCCEEDED(rc))
  451.     {
  452. rc = m_pResponse->HandleEndElement(pName,0,0);
  453.     }
  454. }
  455. else
  456. {
  457.     rc = m_pResponse->HandleEndElement(pName,0,0);
  458. }
  459.     }
  460.     break;
  461.     default:
  462.     {
  463. bDone = TRUE;
  464.     }
  465.     break;
  466. }
  467.     }
  468. exit:
  469.     HX_DELETE(pTag);
  470.     return rc;
  471. }
  472. /* 
  473.  * HXStrictXMLParser methods
  474.  */
  475. HXStrictXMLParser::HXStrictXMLParser():
  476.     m_pParser(NULL),
  477.     m_pByteQueue(NULL)
  478.     , m_pErrorNotifier(NULL)
  479. {
  480. }
  481. HXStrictXMLParser::~HXStrictXMLParser()
  482. {
  483.     HX_DELETE(m_pParser);
  484.     HX_DELETE(m_pByteQueue);
  485. }
  486. HX_RESULT
  487. HXStrictXMLParser::Init(IHXXMLParserResponse* pResponse,
  488.        const char* pEncoding)
  489. {
  490.     m_pResponse = pResponse;
  491.     m_pResponse = pResponse;
  492.     m_pParser = new XMLParser(TRUE, pEncoding);
  493.     if (m_pErrorNotifier)
  494.     {
  495. m_pParser->StoreErrors();
  496.     }
  497.     m_pByteQueue = new CBigByteQueue(BUFSIZE);
  498.     return HXR_OK;
  499. }
  500. HX_RESULT
  501. HXStrictXMLParser::InitErrorNotifier(ErrorNotifier* /*OUT*/ pNotifier)
  502. {
  503.     m_pErrorNotifier = pNotifier; 
  504.     if (m_pParser)
  505.     {
  506. m_pParser->StoreErrors();
  507.     }
  508.     return HXR_OK; 
  509. }
  510. HX_RESULT
  511. HXStrictXMLParser::Parse(IHXBuffer* pBuffer,
  512. BOOL bIsFinal)
  513. {
  514.     HX_RESULT rc = HXR_OK;
  515.     // See if we have any encoding info
  516.     CheckEncoding(m_pParser, pBuffer);
  517.     UINT32 ulBufLen = pBuffer->GetSize();
  518.     if(m_pByteQueue->GetAvailableElements() < ulBufLen)
  519.     {
  520. m_pByteQueue->Grow(ulBufLen);
  521.     }
  522.     m_pByteQueue->EnQueue(pBuffer->GetBuffer(), ulBufLen);
  523.     rc = DoParse(bIsFinal);
  524.     return rc;
  525. }
  526. HX_RESULT
  527. HXStrictXMLParser::HandleErrors(CHXPtrArray* pErrs)
  528. {
  529.     if (m_pErrorNotifier && pErrs)
  530.     {
  531. int size = pErrs->GetSize();
  532. for(int i=0;i<size;++i)
  533. {
  534.     XMLError* pError = (XMLError*) (*pErrs)[i];
  535.     HX_RESULT code = ConvertToHX_RESULT(pError->m_errorTag);
  536.     m_pErrorNotifier->ErrorInLastTag(code, pError->m_pErrorString, 
  537. pError->m_pFrameString,  pError->m_lLineNumber, 
  538. pError->m_lLinePosition);
  539. }
  540.     }
  541.     return HXR_OK;
  542. }
  543. HX_RESULT
  544. HXStrictXMLParser::ConvertToHX_RESULT(UINT32 err)
  545. {
  546.     HX_RESULT ret = HXR_OK;
  547.     switch (err)
  548.     {
  549.     case XMLUnknownError:
  550. ret = HXR_XML_GENERALERROR;
  551. break;
  552.     case XMLErrorNoClose:
  553. ret = HXR_XML_NOCLOSE;
  554. break;
  555.     case XMLErrorBadAttribute:
  556. ret = HXR_XML_BADATTRIBUTE;
  557. break;
  558.     case XMLErrorNoValue:
  559. ret = HXR_XML_NOVALUE;
  560. break;
  561.     case XMLErrorMissingQuote:
  562. ret = HXR_XML_MISSINGQUOTE;
  563. break;
  564.     case XMLErrorBadEndTag:
  565. ret = HXR_XML_BADENDTAG;
  566. break;
  567.     case XMLErrorNoTagType:
  568. ret = HXR_XML_NOTAGTYPE;
  569. break;
  570.     case XMLErrorDupAttribute:
  571. ret = HXR_XML_DUPATTRIBUTE;
  572. break;
  573.     case XMLErrorCommentBeforeProcInst:
  574. ret = HXR_XML_COMMENT_B4_PROCINST;
  575. break;
  576.     case XMLErrorInvalidName:
  577. ret = HXR_XML_INVALID_NAME;
  578. break;
  579.     case XMLErrorInvalidCharInDoc:
  580. ret = HXR_XML_INVALID_CHAR_IN_DOC;
  581. break;
  582.     case XMLErrorTwoDashNotAllowed:
  583. ret = HXR_XML_TWO_DASHES_NOT_ALLOWED_IN_COMMENT;
  584. break;
  585.     case XMLErrorInvalidDecl:
  586. ret = HXR_XML_INVALID_DECL;
  587. break;
  588.     case XMLErrorInvalidPI:
  589. ret = HXR_XML_INVALID_PI;
  590. break;
  591.     case XMLErrorInvalidPITarget:
  592. ret = HXR_XML_INVALID_PI_TARGET;
  593. break;
  594.     case XMLErrorInvalidCDATA:
  595. ret = HXR_XML_INVALID_CDATA;
  596. break;
  597.     case XMLErrorInvalidRef:
  598. ret = HXR_XML_INVALID_REF;
  599. break;
  600.     case XMLErrorMissingEquals:
  601. ret = HXR_XML_MISSING_EQUALS;
  602. break;
  603.     case XMLErrorMissingReqSpace:
  604. ret = HXR_XML_MISSING_REQ_SPACE;
  605. break;
  606.     case XMLErrorLTnotAllowed:
  607. ret = HXR_XML_LT_NOT_ALLOWED;
  608. break;
  609.     case XMLErrorInvalidGTafter2RSQB:
  610. ret = HXR_XML_INVALID_GT_AFFT_2_RSQB_IN_CONTENT;
  611. break;
  612.     case XMLErrorInvalidComment:
  613. ret = HXR_XML_INVALID_COMMENT;
  614. break;
  615.     }
  616.     return ret;
  617. }
  618. HX_RESULT
  619. HXStrictXMLParser::DoParse(BOOL bIsFinal)
  620. {
  621.     HX_RESULT rc = HXR_OK;
  622.     XMLTag* pTag = NULL;
  623.     BOOL bDone = FALSE;
  624.     while(!bDone &&
  625. HXR_OK == rc)
  626.     {
  627. UINT32 bytesUsed;
  628. UINT32 bytesAvail = m_pByteQueue->GetQueuedItemCount();
  629. if(bytesAvail <= 0)
  630. {
  631.     break;
  632. }
  633. BYTE* pBuf = new BYTE[bytesAvail];
  634. BYTE* p = pBuf;
  635. m_pByteQueue->DeQueue(pBuf, bytesAvail);
  636. bytesUsed = bytesAvail;
  637. if(pTag)
  638. {
  639.     delete pTag;
  640.     pTag = 0;
  641. }
  642. XMLParseResult pResult = 
  643.     m_pParser->Parse((const char*&)p, bytesAvail, pTag, bIsFinal);
  644. m_pByteQueue->EnQueue(p, (UINT32)(bytesAvail - (p - pBuf)));
  645. // pBuf is not used anymore, so delete
  646. HX_VECTOR_DELETE(pBuf);
  647. p = NULL;
  648. UINT32 ulTagStartLine = m_pParser->GetTagStartLineNumber();
  649. UINT32 ulTagStartCol = m_pParser->GetTagStartColumnNumber();
  650. switch(pResult)
  651. {
  652.     case XMLPNotDone:
  653.     {
  654. goto exit;
  655.     }
  656.     case XMLPNoClose:
  657.     {
  658. rc = HXR_XML_NOCLOSE;
  659. goto exit;
  660.     }
  661.     case XMLPBadAttribute:
  662.     {
  663. rc = HXR_XML_NOTAGTYPE;
  664. goto exit;
  665.     }
  666.     case XMLPBadEndTag:
  667.     {
  668. rc = HXR_XML_BADENDTAG;
  669. goto exit;
  670.     }
  671.     
  672.     case XMLPAttributeValueNotQuoted:
  673.     {
  674. rc = HXR_XML_MISSINGQUOTE;
  675. goto exit;
  676.     }
  677.     case XMLPBadDirective:
  678.     {
  679. rc = HXR_XML_GENERALERROR;
  680. goto exit;
  681.     }
  682.     case XMLPDupAttribute:
  683.     {
  684. rc = HXR_XML_DUPATTRIBUTE;
  685. goto exit;
  686.     }
  687.     case XMLPCommentBeforeProcInst:
  688.     {
  689. rc = HXR_XML_COMMENT_B4_PROCINST;
  690. goto exit;
  691.     }
  692.     
  693.     case XMLPComment:
  694.     {
  695. const char* pValue = pTag->m_cur_attribute->value;
  696. rc = m_pResponse->HandleComment(pValue,ulTagStartLine,ulTagStartCol);
  697. HandleErrors(pTag->m_errs);
  698.     }
  699.     break;
  700.     case XMLPPlainText:
  701.     {
  702. const char* pValue = pTag->m_cur_attribute->value;
  703. CHXBuffer* pBuffer = new CHXBuffer;
  704. pBuffer->AddRef();
  705. pBuffer->Set((const BYTE*)pValue, strlen(pValue)+1);
  706. rc = m_pResponse->HandleCharacterData(pBuffer,ulTagStartLine,ulTagStartCol);
  707. HandleErrors(pTag->m_errs);
  708. HX_RELEASE(pBuffer);
  709.     }
  710.     break;
  711.     case XMLPDirective:
  712.     {
  713. const char* pName = NULL;
  714. const char* pPublicID = NULL;
  715. const char* pSystemID = NULL;
  716. CHXBuffer* pBuffer = NULL;
  717. UINT32 ulNumAttributes = pTag->m_numAttributes; 
  718. if(strcmp(pTag->m_name, "DOCTYPE") == 0 &&
  719.     ulNumAttributes > 0)
  720. {
  721.     UINT32 ulCurAttribute = 0;
  722.     while(ulCurAttribute < ulNumAttributes)
  723.     {
  724. XMLAttribute* pAttr = NULL;
  725. if(ulCurAttribute == 0)
  726. {
  727.     pAttr = pTag->attribute(ulCurAttribute);
  728.     if(pAttr)
  729.     {
  730. pName = pAttr->value;
  731.     }
  732. }
  733. else
  734. {
  735.     pAttr = pTag->attribute(ulCurAttribute);
  736.     if(strcmp(pAttr->value, "SYSTEM") == 0)
  737.     {
  738. ulCurAttribute++;
  739. if(ulCurAttribute < ulNumAttributes)
  740. {
  741.     pAttr = pTag->attribute(ulCurAttribute);
  742.     if(pAttr)
  743.     {
  744. pSystemID = pAttr->value;
  745.     }
  746. }
  747.     }
  748.     else if(strcmp(pAttr->value, "PUBLIC") == 0)
  749.     {
  750. ulCurAttribute++;
  751. if(ulCurAttribute < ulNumAttributes)
  752. {
  753.     pAttr = pTag->attribute(ulCurAttribute);
  754.     if(pAttr)
  755.     {
  756. pPublicID = pAttr->value;
  757. ulCurAttribute++;
  758. if(ulCurAttribute < ulNumAttributes)
  759. {
  760.     pAttr = pTag->attribute(ulCurAttribute);
  761.     if(pAttr)
  762.     {
  763. pSystemID = pAttr->value;
  764.     }
  765. }
  766.     }
  767. }
  768.     }
  769. }
  770. ulCurAttribute++;
  771.     }
  772.     rc = m_pResponse->HandleUnparsedDoctypeDecl(pName, pSystemID,
  773. pPublicID, ulTagStartLine,ulTagStartCol);
  774.     HX_RELEASE(pBuffer);
  775. }
  776.     }
  777.     break;
  778.     case XMLPProcInst:
  779.     // handle processing instruction
  780.     {
  781. const char* pTarget = pTag->m_name;
  782. CHXHeader* pValues = new CHXHeader;
  783. pValues->AddRef();
  784. pValues->PreserveCase(TRUE);
  785. for(UINT32 i=0;i<pTag->m_numAttributes;++i)
  786. {
  787.     XMLAttribute* pAttr = pTag->attribute(i);
  788.     // the XMLParser class supports what it calls attributes
  789.     // without names.  It's used to communicate processing
  790.     // instructions and things like that. We just ignore attributes
  791.     // without names here.
  792.     if (pAttr->name != NULL)
  793.     {
  794. CHXBuffer* pBuf = new CHXBuffer;
  795. pBuf->AddRef();
  796. pBuf->Set((const BYTE*)pAttr->value,
  797.     strlen(pAttr->value)+1);
  798. pValues->SetPropertyCString(
  799.     pAttr->name, pBuf);
  800. pBuf->Release();
  801.     }
  802. }
  803. rc = m_pResponse->HandleProcessingInstruction(pTarget,
  804.       pValues,ulTagStartLine,ulTagStartCol);
  805. HandleErrors(pTag->m_errs);
  806. HX_RELEASE(pValues);
  807.     }
  808.     break;
  809.     case XMLPTag:
  810.     {
  811. const char* pName = pTag->m_name;
  812. if(pTag->m_type != XMLEndTag)
  813. {
  814.     CHXHeader* pValues = new CHXHeader;
  815.     pValues->AddRef();
  816.     pValues->PreserveCase(TRUE);
  817.     for(UINT32 i=0;i<pTag->m_numAttributes;++i)
  818.     {
  819. XMLAttribute* pAttr = pTag->attribute(i);
  820. // the XMLParser class supports what it calls attributes
  821. // without names.  It's used to communicate processing
  822. // instructions and things like that. We just ignore attributes
  823. // without names here.
  824. if (pAttr->name != NULL)
  825. {
  826.     CHXBuffer* pBuf = new CHXBuffer;
  827.     pBuf->AddRef();
  828.     pBuf->Set((const BYTE*)pAttr->value,
  829. strlen(pAttr->value)+1);
  830.     pValues->SetPropertyCString(
  831. pAttr->name, pBuf);
  832.     pBuf->Release();
  833. }
  834.     }
  835.     if(HXR_OK == rc)
  836.     {
  837. rc = m_pResponse->HandleStartElement(pName, 
  838.     pValues,ulTagStartLine,ulTagStartCol);
  839. HandleErrors(pTag->m_errs);
  840.     }
  841.     HX_RELEASE(pValues);
  842.     if(HXR_OK == rc &&
  843. !pTag->m_need_close)
  844.     {
  845. rc = m_pResponse->HandleEndElement(pName,ulTagStartLine,ulTagStartCol);
  846.     }
  847. }
  848. else
  849. {
  850.     rc = m_pResponse->HandleEndElement(pName,ulTagStartLine,ulTagStartCol);
  851.     HandleErrors(pTag->m_errs);
  852. }
  853.     }
  854.     break;
  855.     default:
  856.     {
  857. bDone = TRUE;
  858.     }
  859.     break;
  860. }
  861.     }
  862. exit:
  863.     HX_DELETE(pTag);
  864.     return rc;
  865. }
  866. HX_RESULT
  867. HXStrictXMLParser::GetCurrentLineNumber(REF(ULONG32) ulLineNumber)
  868. {
  869.     HX_RESULT rc = HXR_OK;
  870.     ulLineNumber = (UINT32)m_pParser->GetCurrentLineNumber();
  871.     return rc;
  872. }
  873. HX_RESULT
  874. HXStrictXMLParser::GetCurrentColumnNumber(REF(ULONG32) ulColumnNumber)
  875. {
  876.     HX_RESULT rc = HXR_OK;
  877.     ulColumnNumber = (UINT32)m_pParser->GetCurrentColumnNumber();
  878.     return rc;
  879. }
  880. HX_RESULT
  881. HXStrictXMLParser::GetCurrentByteIndex(REF(ULONG32) ulByteIndex)
  882. {
  883.     HX_RESULT rc = HXR_NOTIMPL;
  884.     return rc;
  885. }
  886. HX_RESULT
  887. HXStrictXMLParser::GetCurrentErrorText(REF(IHXBuffer*) pBuffer)
  888. {
  889.     HX_RESULT rc = HXR_FAIL;
  890.     XMLError* pLastError = m_pParser->GetLastError();
  891.     if(pLastError &&
  892. pLastError->m_pErrorString)
  893.     {
  894. pBuffer = new CHXBuffer;
  895. pBuffer->AddRef();
  896. pBuffer->Set((BYTE*)pLastError->m_pErrorString,
  897.  strlen(pLastError->m_pErrorString) + 1);
  898. rc = HXR_OK;
  899.     }
  900.     return rc;
  901. }