hxxmlprs.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:23k
源码类别:

Symbian

开发平台:

C/C++

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