Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.3 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. sxsxmltree.cpp
  5. Abstract:
  6. Create a XML DOM tree during push-mode parsing
  7. Author:
  8. Xiaoyu Wu (xiaoyuw) Aug 2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include "ole2.h"
  13. #include "sxsxmltree.h"
  14. #include "fusiontrace.h"
  15. #include "fusionheap.h"
  16. #include "simplefp.h"
  17. //////////////////////////////////////////////////////////////////////////////////////
  18. //
  19. // SXS_XMLDOMTree
  20. //
  21. //////////////////////////////////////////////////////////////////////////////////////
  22. VOID SXS_XMLDOMTree::DeleteTreeBranch(SXS_XMLTreeNode * pNode)
  23. {
  24. // SXS_XMLTreeNode * pParent = NULL;
  25. SXS_XMLTreeNode * pChild = NULL;
  26. SXS_XMLTreeNode * pNext = NULL;
  27. if (pNode == NULL)
  28. return;
  29. pChild = pNode->m_pFirstChild;
  30. while(pChild){
  31. pNext = pChild->m_pSiblingNode;
  32. this->DeleteTreeBranch(pChild);
  33. pChild = pNext;
  34. }
  35. pNode->DeleteSelf();
  36. }
  37. //
  38. // CreateNode calls this func to add node into the Tree,
  39. //
  40. HRESULT SXS_XMLDOMTree::AddNode(USHORT cNumRecs, XML_NODE_INFO** apNodeInfo)
  41. {
  42. HRESULT hr = NOERROR;
  43. FN_TRACE_HR(hr);
  44. SXS_XMLTreeNode * pNewTreeNode= NULL ;
  45. if ((apNodeInfo == NULL) || (cNumRecs <= 0)){
  46. hr = E_INVALIDARG;
  47. goto Exit;
  48. }
  49. if (!((apNodeInfo[0]->dwType == XML_ELEMENT) ||(apNodeInfo[0]->dwType == XML_PCDATA))){// ignore nodes other than ELEMENT and PCDATA
  50. hr = NOERROR;
  51. goto Exit;
  52. }
  53. IFALLOCFAILED_EXIT(pNewTreeNode = new SXS_XMLTreeNode);
  54. IFCOMFAILED_EXIT(pNewTreeNode->CreateTreeNode(cNumRecs, apNodeInfo));
  55. if (m_fBeginChildCreation) {
  56. m_pCurrentNode->m_pFirstChild = pNewTreeNode;
  57. pNewTreeNode->m_pParentNode = m_pCurrentNode;
  58. m_pCurrentNode = pNewTreeNode;
  59. m_fBeginChildCreation = FALSE;
  60. }
  61. else{
  62. if (m_pCurrentNode){
  63. m_pCurrentNode->m_pSiblingNode = pNewTreeNode;
  64. pNewTreeNode->m_pParentNode = m_pCurrentNode->m_pParentNode;
  65. }
  66. m_pCurrentNode = pNewTreeNode;
  67. }
  68. if (m_Root == NULL) // root has not been setup
  69. m_Root = m_pCurrentNode;
  70. pNewTreeNode = NULL;
  71. hr = NOERROR;
  72. Exit:
  73. if (pNewTreeNode){
  74. pNewTreeNode->DeleteSelf();
  75. pNewTreeNode = NULL;
  76. }
  77. return hr;
  78. }
  79. //
  80. // EndChildren is called with "fEmpty=FALSE", go to parent node
  81. //
  82. VOID SXS_XMLDOMTree::ReturnToParent()
  83. {
  84. if (m_pCurrentNode)
  85. m_pCurrentNode = m_pCurrentNode->m_pParentNode;
  86. return;
  87. }
  88. // BeginChildren calls this func
  89. VOID SXS_XMLDOMTree::SetChildCreation()
  90. {
  91. m_fBeginChildCreation = TRUE;
  92. }
  93. /*
  94. VOID SXS_XMLDOMTree::TurnOffFirstChildFlag()
  95. {
  96. m_fBeginChildCreation = FALSE;
  97. }
  98. */
  99. //////////////////////////////////////////////////////////////////////////////////////
  100. //
  101. // SXS_XMLTreeNode
  102. //
  103. //////////////////////////////////////////////////////////////////////////////////////
  104. HRESULT SXS_XMLTreeNode::ComputeBlockSize(USHORT cNumRecs, XML_NODE_INFO** apNodeInfo, ULONG * pulBlockSizeInBytes)
  105. {
  106. HRESULT hr = NOERROR;
  107. ULONG ulBlockSizeInBytes = 0;
  108. USHORT i;
  109. USHORT cAttributes;
  110. FN_TRACE_HR(hr);
  111. if (pulBlockSizeInBytes)
  112. *pulBlockSizeInBytes = 0 ;
  113. else {
  114. hr = E_INVALIDARG;
  115. goto Exit;
  116. }
  117. if ((apNodeInfo == NULL) || (cNumRecs <= 0)){
  118. hr = E_INVALIDARG;
  119. goto Exit;
  120. }
  121. ulBlockSizeInBytes = 0;
  122. for ( i = 0; i< cNumRecs; i ++ ) {
  123. ulBlockSizeInBytes += apNodeInfo[i]->ulLen * sizeof(WCHAR);
  124. ulBlockSizeInBytes += sizeof(WCHAR); //trailing '\0'
  125. }
  126. // if attributes present, add size of attribute array
  127. cAttributes = (cNumRecs - 1) >> 1 ; // name:value pair
  128. if (cAttributes > 0)
  129. ulBlockSizeInBytes += cAttributes * sizeof(SXS_XMLATTRIBUTE);
  130. * pulBlockSizeInBytes = ulBlockSizeInBytes;
  131. hr = NOERROR;
  132. Exit:
  133. return hr;
  134. }
  135. //////////////////////////////////////////////////////////////////////////////////////
  136. HRESULT SXS_XMLTreeNode::CreateTreeNode(USHORT cNumRecs, XML_NODE_INFO** apNodeInfo)
  137. {
  138. HRESULT hr = NOERROR;
  139. DWORD dwBlockSizeInBytes;
  140. PBYTE Cursor = NULL;
  141. USHORT i;
  142. FN_TRACE_HR(hr);
  143. PARAMETER_CHECK((apNodeInfo != NULL) || (cNumRecs == 0));
  144. IFCOMFAILED_EXIT(this->ComputeBlockSize(cNumRecs, apNodeInfo, &dwBlockSizeInBytes));
  145. IFALLOCFAILED_EXIT(m_pMemoryPool = FUSION_NEW_ARRAY(BYTE, dwBlockSizeInBytes));
  146. m_AttributeList = (SXS_XMLATTRIBUTE *)m_pMemoryPool;
  147. m_cAttributes = (cNumRecs - 1) >> 1;
  148. Cursor = m_pMemoryPool + m_cAttributes*(sizeof(SXS_XMLATTRIBUTE));
  149. // set Name(Element) or Value(PCData)
  150. m_pwszStr = (PWSTR)Cursor;
  151. wcsncpy((WCHAR*)Cursor, apNodeInfo[0]->pwcText, apNodeInfo[0]->ulLen); //ulLen is # of WCHAR or BYTE?
  152. Cursor += apNodeInfo[0]->ulLen * sizeof(WCHAR);
  153. *(WCHAR *)Cursor = L'\0';
  154. Cursor += sizeof(WCHAR); // '\0'
  155. for ( i=0 ;i<m_cAttributes ;i++) {
  156. // copy name
  157. m_AttributeList[i].m_wszName = (PWSTR)Cursor;
  158. wcsncpy((WCHAR*)Cursor, apNodeInfo[1+2*i]->pwcText, apNodeInfo[1+2*i]->ulLen); //ulLen is # of WCHAR or BYTE?
  159. Cursor += apNodeInfo[1+2*i]->ulLen * sizeof(WCHAR);
  160. *(WCHAR *)Cursor = L'\0';
  161. Cursor += sizeof(WCHAR); // '\0'
  162. //copy value
  163. m_AttributeList[i].m_wszValue = (PWSTR)Cursor;
  164. wcsncpy((PWSTR)Cursor, apNodeInfo[1 + 2*i + 1]->pwcText, apNodeInfo[1 + 2*i + 1]->ulLen); //ulLen is # of WCHAR or BYTE?
  165. Cursor += apNodeInfo[1 + 2*i + 1]->ulLen * sizeof(WCHAR);
  166. *(WCHAR *)Cursor = L'\0';
  167. Cursor += sizeof(WCHAR); // '\0'
  168. m_AttributeList[i].m_ulPrefixLen = apNodeInfo[1+2*i]->ulNsPrefixLen;
  169. }
  170. Exit:
  171. return hr;
  172. }
  173. //////////////////////////////////////////////////////////////////////////////////////
  174. VOID SXS_XMLTreeNode::PrintSelf()
  175. {
  176. FusionpDbgPrint("CreateNode\n");
  177. FusionpDbgPrint("NodeName = %ls\n", m_pwszStr);
  178. if ( m_cAttributes > 0)
  179. {
  180. FusionpDbgPrint("Attributes :\n");
  181. for ( USHORT i = 0; i < m_cAttributes; i++)
  182. {
  183. FusionpDbgPrint("\t%ls = %ls\n", m_AttributeList[i].m_wszName, m_AttributeList[i].m_wszValue);
  184. }
  185. }
  186. }