/opencascade-6.5.1/ros/src/LDOM/LDOM_BasicElement.cxx

https://github.com/jehc/MondocosmOS · C++ · 458 lines · 329 code · 36 blank · 93 comment · 71 complexity · 50fe0926b977c3e10e855fe25eef4ba7 MD5 · raw file

  1. // File: LDOM_BasicElement.cxx
  2. // Created: 26.06.01 21:22:14
  3. // Author: Alexander GRIGORIEV
  4. // Copyright: OpenCascade 2001
  5. // History: AGV 140202: Replace(const char *) for (LDOMBasicString)=>myTagName
  6. #include <LDOM_BasicElement.hxx>
  7. #include <LDOM_BasicAttribute.hxx>
  8. #include <LDOM_BasicText.hxx>
  9. #include <LDOM_MemManager.hxx>
  10. #ifdef WNT
  11. // Disable the warning: "operator new unmatched by delete"
  12. #pragma warning (disable:4291)
  13. #endif
  14. //=======================================================================
  15. //function : Create
  16. //purpose : construction in the Document's data pool
  17. //=======================================================================
  18. LDOM_BasicElement& LDOM_BasicElement::Create
  19. (const char * aName,
  20. const Standard_Integer aLen,
  21. const Handle(LDOM_MemManager)& aDoc)
  22. {
  23. if (aName == NULL) {
  24. static LDOM_BasicElement aVoidElement;
  25. aVoidElement = LDOM_BasicElement();
  26. return aVoidElement;
  27. }
  28. void * aMem = aDoc -> Allocate (sizeof(LDOM_BasicElement));
  29. LDOM_BasicElement * aNewElem = new (aMem) LDOM_BasicElement;
  30. Standard_Integer aHash;
  31. // aDoc -> HashedAllocate (aString, strlen(aString), aNewElem -> myTagName);
  32. aNewElem -> myTagName = aDoc -> HashedAllocate (aName, aLen, aHash);
  33. aNewElem -> myNodeType = LDOM_Node::ELEMENT_NODE;
  34. return * aNewElem;
  35. }
  36. //=======================================================================
  37. //function : RemoveNodes
  38. //purpose :
  39. //=======================================================================
  40. void LDOM_BasicElement::RemoveNodes ()
  41. {
  42. const LDOM_BasicNode * aNode = (const LDOM_BasicNode *) myFirstChild;
  43. while (aNode) {
  44. const LDOM_BasicNode * aNext = aNode -> GetSibling();
  45. switch (aNode -> getNodeType ()) {
  46. case LDOM_Node::ELEMENT_NODE:
  47. {
  48. LDOM_BasicElement& anElement = * (LDOM_BasicElement *) aNode;
  49. anElement = NULL;
  50. break;
  51. }
  52. case LDOM_Node::ATTRIBUTE_NODE:
  53. {
  54. LDOM_BasicAttribute& anAttr = * (LDOM_BasicAttribute *) aNode;
  55. anAttr = NULL;
  56. break;
  57. }
  58. case LDOM_Node::TEXT_NODE:
  59. case LDOM_Node::COMMENT_NODE:
  60. case LDOM_Node::CDATA_SECTION_NODE:
  61. {
  62. LDOM_BasicText& aTxt = * (LDOM_BasicText *) aNode;
  63. aTxt = NULL;
  64. break;
  65. }
  66. default: ;
  67. }
  68. aNode = aNext;
  69. }
  70. myFirstChild = NULL;
  71. }
  72. //=======================================================================
  73. //function : operator =
  74. //purpose : Nullify
  75. //=======================================================================
  76. LDOM_BasicElement& LDOM_BasicElement:: operator = (const LDOM_NullPtr * aNull)
  77. {
  78. myTagName = NULL;
  79. RemoveNodes ();
  80. LDOM_BasicNode::operator= (aNull);
  81. return * this;
  82. }
  83. //=======================================================================
  84. //function : LDOM_BasicElement
  85. //purpose : Constructor
  86. //=======================================================================
  87. /*
  88. LDOM_BasicElement::LDOM_BasicElement (const LDOM_Element& anElement)
  89. : LDOM_BasicNode (LDOM_Node::ELEMENT_NODE),
  90. myAttributeMask (0),
  91. myFirstChild (NULL)
  92. {
  93. // LDOMString aNewTagName (anElement.getTagName(), anElement.myDocument);
  94. // myTagName = aNewTagName;
  95. const LDOM_BasicElement& anOther =
  96. (const LDOM_BasicElement&) anElement.Origin();
  97. myTagName = anOther.GetTagName();
  98. }
  99. */
  100. //=======================================================================
  101. //function : ~LDOM_BasicElement
  102. //purpose : Destructor
  103. //=======================================================================
  104. LDOM_BasicElement::~LDOM_BasicElement ()
  105. {
  106. myTagName = NULL;
  107. RemoveNodes ();
  108. }
  109. //=======================================================================
  110. //function : GetLastChild
  111. //purpose :
  112. //=======================================================================
  113. const LDOM_BasicNode * LDOM_BasicElement::GetLastChild () const
  114. {
  115. const LDOM_BasicNode * aNode = myFirstChild;
  116. if (aNode) {
  117. if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
  118. aNode = NULL;
  119. else
  120. while (aNode -> mySibling) {
  121. if (aNode -> mySibling -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
  122. break;
  123. aNode = aNode -> mySibling;
  124. }
  125. }
  126. return aNode;
  127. }
  128. //=======================================================================
  129. //function : GetAttribute
  130. //purpose :
  131. //=======================================================================
  132. const LDOM_BasicAttribute& LDOM_BasicElement::GetAttribute
  133. (const LDOMBasicString& aName,
  134. const LDOM_BasicNode * aLastCh) const
  135. {
  136. const LDOM_BasicNode * aNode;
  137. if (aLastCh)
  138. aNode = aLastCh -> GetSibling ();
  139. else
  140. aNode = myFirstChild;
  141. const char * aNameStr = aName.GetString();
  142. while (aNode) {
  143. if (aNode -> getNodeType () == LDOM_Node::ATTRIBUTE_NODE) {
  144. const LDOM_BasicAttribute * anAttr = (const LDOM_BasicAttribute *) aNode;
  145. if (!strcmp (aNameStr, anAttr -> GetName()))
  146. return * anAttr;
  147. }
  148. aNode = aNode -> mySibling;
  149. }
  150. static const LDOM_BasicAttribute aNullAttribute;
  151. return aNullAttribute;
  152. }
  153. //=======================================================================
  154. //function : GetFirstAttribute
  155. //purpose : private method
  156. //=======================================================================
  157. const LDOM_BasicAttribute * LDOM_BasicElement::GetFirstAttribute
  158. (const LDOM_BasicNode *& theLastCh,
  159. const LDOM_BasicNode **& thePrevNode) const
  160. {
  161. // Find the First Attribute as well as the Last Child among siblings
  162. const LDOM_BasicNode * aFirstAttr;
  163. const LDOM_BasicNode ** aPrevNode;
  164. if (theLastCh) {
  165. aFirstAttr = theLastCh -> mySibling;
  166. aPrevNode = (const LDOM_BasicNode **) &(theLastCh -> mySibling);
  167. while (aFirstAttr) {
  168. if (aFirstAttr -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE) break;
  169. aPrevNode = (const LDOM_BasicNode **) & (aFirstAttr -> mySibling);
  170. aFirstAttr = aFirstAttr -> mySibling;
  171. }
  172. } else {
  173. aFirstAttr = myFirstChild;
  174. aPrevNode = (const LDOM_BasicNode **) &myFirstChild;
  175. while (aFirstAttr) {
  176. if (aFirstAttr -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE) break;
  177. if (aFirstAttr -> isNull() == Standard_False) theLastCh = aFirstAttr;
  178. aPrevNode = (const LDOM_BasicNode **) & (aFirstAttr -> mySibling);
  179. aFirstAttr = aFirstAttr -> mySibling;
  180. }
  181. }
  182. thePrevNode = aPrevNode;
  183. return (LDOM_BasicAttribute *) aFirstAttr;
  184. }
  185. //=======================================================================
  186. //function : AddAttribute
  187. //purpose : Add or replace an attribute
  188. //=======================================================================
  189. const LDOM_BasicNode * LDOM_BasicElement::AddAttribute
  190. (const LDOMBasicString& anAttrName,
  191. const LDOMBasicString& anAttrValue,
  192. const Handle(LDOM_MemManager)& aDocument,
  193. const LDOM_BasicNode * aLastCh)
  194. {
  195. // Create attribute
  196. Standard_Integer aHash;
  197. LDOM_BasicAttribute& anAttr =
  198. LDOM_BasicAttribute::Create (anAttrName, aDocument, aHash);
  199. anAttr.myValue = anAttrValue;
  200. // Initialize the loop of attribute name search
  201. const LDOM_BasicNode ** aPrNode;
  202. const LDOM_BasicAttribute * aFirstAttr = GetFirstAttribute (aLastCh, aPrNode);
  203. const char * aNameStr = anAttrName.GetString();
  204. // Check attribute hash value against the current mask
  205. const unsigned int anAttrMaskValue = aHash & (8*sizeof(myAttributeMask) - 1);
  206. const unsigned long anAttributeMask = (1 << anAttrMaskValue);
  207. #ifdef DEBUG_MASK
  208. anAttributeMask = 0xffffffff;
  209. #endif
  210. if ((myAttributeMask & anAttributeMask) == 0) {
  211. // this is new attribute, OK
  212. myAttributeMask |= anAttributeMask;
  213. * aPrNode = &anAttr;
  214. anAttr.SetSibling (aFirstAttr);
  215. } else {
  216. // this attribute may have already been installed
  217. LDOM_BasicAttribute * aCurrentAttr = (LDOM_BasicAttribute *) aFirstAttr;
  218. while (aCurrentAttr) {
  219. if (aCurrentAttr -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
  220. if (LDOM_MemManager::CompareStrings (aNameStr, aHash,
  221. aCurrentAttr -> GetName())) {
  222. aCurrentAttr -> SetValue (anAttrValue, aDocument);
  223. break;
  224. }
  225. aCurrentAttr = (LDOM_BasicAttribute *) aCurrentAttr -> mySibling;
  226. }
  227. if (aCurrentAttr == NULL) {
  228. // this is new attribute, OK
  229. * aPrNode = &anAttr;
  230. anAttr.SetSibling (aFirstAttr);
  231. }
  232. }
  233. return aLastCh;
  234. }
  235. //=======================================================================
  236. //function : RemoveAttribute
  237. //purpose : Find and delete an attribute from list
  238. //=======================================================================
  239. const LDOM_BasicNode * LDOM_BasicElement::RemoveAttribute
  240. (const LDOMBasicString& aName,
  241. const LDOM_BasicNode * aLastCh) const
  242. {
  243. // Check attribute hash value against the current mask
  244. const char * const aNameStr = aName.GetString();
  245. const Standard_Integer aHash =
  246. LDOM_MemManager::Hash (aNameStr, strlen(aNameStr));
  247. const unsigned int anAttrMaskValue = aHash & (8*sizeof(myAttributeMask) - 1);
  248. const unsigned long anAttributeMask = (1 << anAttrMaskValue);
  249. #ifdef DEBUG_MASK
  250. anAttributeMask = 0xffffffff;
  251. #endif
  252. if ((myAttributeMask & anAttributeMask) == 0) {
  253. ; // maybe cause for exception
  254. } else {
  255. const LDOM_BasicNode ** aPrevNode; // dummy
  256. const LDOM_BasicAttribute * anAttr = GetFirstAttribute (aLastCh, aPrevNode);
  257. while (anAttr) {
  258. if (anAttr -> getNodeType () == LDOM_Node::ATTRIBUTE_NODE)
  259. if (LDOM_MemManager::CompareStrings(aNameStr,aHash,anAttr->GetName())) {
  260. anAttr = NULL;
  261. break;
  262. }
  263. anAttr = (const LDOM_BasicAttribute *) anAttr -> mySibling;
  264. }
  265. }
  266. return aLastCh;
  267. }
  268. //=======================================================================
  269. //function : RemoveChild
  270. //purpose :
  271. //=======================================================================
  272. void LDOM_BasicElement::RemoveChild (const LDOM_BasicNode * aChild) const
  273. {
  274. const LDOM_BasicNode * aNode = myFirstChild;
  275. const LDOM_BasicNode ** aPrevNode = (const LDOM_BasicNode **) &myFirstChild;
  276. while (aNode) {
  277. if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
  278. break;
  279. if (aNode == aChild) {
  280. * aPrevNode = aNode -> GetSibling();
  281. * (LDOM_BasicNode *) aChild = NULL;
  282. break;
  283. }
  284. aPrevNode = (const LDOM_BasicNode **) & (aNode -> mySibling);
  285. aNode = aNode -> GetSibling();
  286. }
  287. // here may be the cause to throw an exception
  288. }
  289. //=======================================================================
  290. //function : AppendChild
  291. //purpose :
  292. //=======================================================================
  293. void LDOM_BasicElement::AppendChild (const LDOM_BasicNode * aChild,
  294. const LDOM_BasicNode *& aLastChild) const
  295. {
  296. if (aLastChild) {
  297. (const LDOM_BasicNode *&) aChild -> mySibling = aLastChild -> mySibling;
  298. (const LDOM_BasicNode *&) aLastChild -> mySibling = aChild;
  299. } else {
  300. const LDOM_BasicNode * aNode = myFirstChild;
  301. const LDOM_BasicNode ** aPrevNode = (const LDOM_BasicNode **) &myFirstChild;
  302. while (aNode) {
  303. if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE) {
  304. (const LDOM_BasicNode *&) aChild -> mySibling = aNode;
  305. break;
  306. }
  307. aPrevNode = (const LDOM_BasicNode **) & (aNode -> mySibling);
  308. aNode = aNode -> mySibling;
  309. }
  310. * aPrevNode = aChild;
  311. }
  312. aLastChild = aChild;
  313. }
  314. //=======================================================================
  315. //function : AddElementsByTagName
  316. //purpose : Add to the List all sub-elements with the given name (recursive)
  317. //=======================================================================
  318. void LDOM_BasicElement::AddElementsByTagName
  319. (LDOM_NodeList& aList, const LDOMBasicString& aTagName) const
  320. {
  321. const LDOM_BasicNode * aNode = myFirstChild;
  322. const char * aTagString = aTagName.GetString();
  323. while (aNode) {
  324. if (aNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
  325. break;
  326. if (aNode -> getNodeType() == LDOM_Node::ELEMENT_NODE) {
  327. LDOM_BasicElement& anElement = * (LDOM_BasicElement *) aNode;
  328. // if (anElement.GetTagName().equals(aTagName))
  329. if (strcmp (anElement.GetTagName(), aTagString) == 0)
  330. aList.Append (anElement);
  331. anElement.AddElementsByTagName (aList, aTagName);
  332. }
  333. aNode = aNode -> GetSibling();
  334. }
  335. }
  336. //=======================================================================
  337. //function : AddAttributes
  338. //purpose :
  339. //=======================================================================
  340. void LDOM_BasicElement::AddAttributes (LDOM_NodeList& aList,
  341. const LDOM_BasicNode * aLastChild) const
  342. {
  343. const LDOM_BasicNode * aBNode;
  344. if (aLastChild)
  345. aBNode = aLastChild -> GetSibling();
  346. else
  347. aBNode = GetFirstChild();
  348. while (aBNode) {
  349. if (aBNode -> getNodeType() == LDOM_Node::ATTRIBUTE_NODE)
  350. aList.Append (* aBNode);
  351. aBNode = aBNode -> GetSibling();
  352. }
  353. }
  354. //=======================================================================
  355. //function : ReplaceElement
  356. //purpose : Copy data and children into this node from another one
  357. // The only preserved data is mySibling
  358. //=======================================================================
  359. void LDOM_BasicElement::ReplaceElement
  360. (const LDOM_BasicElement& anOtherElem,
  361. const Handle(LDOM_MemManager)& aDocument)
  362. {
  363. myTagName = anOtherElem.GetTagName();
  364. myAttributeMask = anOtherElem.myAttributeMask;
  365. myFirstChild = NULL;
  366. const LDOM_BasicNode * aBNode = anOtherElem.GetFirstChild ();
  367. const LDOM_BasicNode * aLastChild = NULL;
  368. // Loop on children (non-attributes)
  369. for (; aBNode != NULL; aBNode = aBNode -> GetSibling()) {
  370. if (aBNode -> isNull())
  371. continue;
  372. LDOM_BasicNode * aNewBNode;
  373. const LDOM_Node::NodeType aNewNodeType = aBNode -> getNodeType();
  374. switch (aNewNodeType) {
  375. case LDOM_Node::ELEMENT_NODE:
  376. {
  377. const LDOM_BasicElement& aBNodeElem = *(const LDOM_BasicElement*)aBNode;
  378. const char * aTagString = aBNodeElem.GetTagName();
  379. LDOM_BasicElement& aNewBNodeElem =
  380. LDOM_BasicElement::Create (aTagString, strlen(aTagString), aDocument);
  381. aNewBNodeElem.ReplaceElement (aBNodeElem, aDocument); //reccur
  382. aNewBNode = &aNewBNodeElem;
  383. break;
  384. }
  385. case LDOM_Node::ATTRIBUTE_NODE:
  386. goto loop_attr;
  387. case LDOM_Node::TEXT_NODE:
  388. case LDOM_Node::COMMENT_NODE:
  389. case LDOM_Node::CDATA_SECTION_NODE:
  390. {
  391. const LDOM_BasicText& aBNodeText = * (const LDOM_BasicText *) aBNode;
  392. aNewBNode = &LDOM_BasicText::Create (aNewNodeType,
  393. LDOMString(aBNodeText.GetData(),
  394. aDocument),
  395. aDocument);
  396. break;
  397. }
  398. default: continue;
  399. }
  400. if (GetFirstChild())
  401. (const LDOM_BasicNode *&) aLastChild -> mySibling = aNewBNode;
  402. else
  403. (const LDOM_BasicNode *&) myFirstChild = aNewBNode;
  404. (const LDOM_BasicNode *&) aLastChild = aNewBNode;
  405. }
  406. // Loop on attributes (in the end of the list of children)
  407. loop_attr:
  408. LDOM_BasicNode * aLastAttr = (LDOM_BasicNode *) aLastChild;
  409. for (; aBNode != NULL; aBNode = aBNode -> GetSibling()) {
  410. Standard_Integer aHash;
  411. if (aBNode -> isNull()) continue;
  412. const LDOM_BasicAttribute * aBNodeAtt= (const LDOM_BasicAttribute *) aBNode;
  413. LDOM_BasicAttribute * aNewAtt =
  414. &LDOM_BasicAttribute::Create (aBNodeAtt -> GetName(), aDocument, aHash);
  415. aNewAtt -> SetValue (aBNodeAtt->myValue, aDocument);
  416. if (aLastAttr)
  417. aLastAttr -> SetSibling (aNewAtt);
  418. else
  419. myFirstChild = aNewAtt;
  420. aLastAttr = aNewAtt;
  421. }
  422. }