// Copyright 2017 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/fxcrt/xml/cfx_xmlnode.h" #include #include #include "core/fxcrt/xml/cfx_xmlchardata.h" #include "core/fxcrt/xml/cfx_xmlelement.h" #include "core/fxcrt/xml/cfx_xmlinstruction.h" #include "core/fxcrt/xml/cfx_xmltext.h" CFX_XMLNode::CFX_XMLNode() = default; CFX_XMLNode::~CFX_XMLNode() = default; void CFX_XMLNode::DeleteChildren() { while (first_child_) { first_child_->parent_ = nullptr; first_child_->prev_sibling_ = nullptr; CFX_XMLNode* child = first_child_; first_child_ = child->next_sibling_; child->next_sibling_ = nullptr; } last_child_ = nullptr; } void CFX_XMLNode::AppendChild(CFX_XMLNode* pNode) { InsertChildNode(pNode, -1); } void CFX_XMLNode::InsertChildNode(CFX_XMLNode* pNode, int32_t index) { ASSERT(!pNode->parent_); pNode->parent_ = this; // No existing children, add node as first child. if (!first_child_) { ASSERT(!last_child_); first_child_ = pNode; last_child_ = first_child_; first_child_->prev_sibling_ = nullptr; first_child_->next_sibling_ = nullptr; return; } if (index == 0) { first_child_->prev_sibling_ = pNode; pNode->next_sibling_ = first_child_; pNode->prev_sibling_ = nullptr; first_child_ = pNode; return; } int32_t iCount = 0; CFX_XMLNode* pFind = first_child_; // Note, negative indexes, and indexes after the end of the list will result // in appending to the list. while (++iCount != index && pFind->next_sibling_) pFind = pFind->next_sibling_; pNode->prev_sibling_ = pFind; if (pFind->next_sibling_) pFind->next_sibling_->prev_sibling_ = pNode; pNode->next_sibling_ = pFind->next_sibling_; pFind->next_sibling_ = pNode; if (pFind == last_child_) last_child_ = pFind->next_sibling_; } void CFX_XMLNode::RemoveChildNode(CFX_XMLNode* pNode) { ASSERT(first_child_); ASSERT(pNode); if (pNode->GetParent() != this) return; if (first_child_ == pNode) first_child_ = pNode->next_sibling_; if (last_child_ == pNode) last_child_ = pNode->prev_sibling_; if (pNode->prev_sibling_) pNode->prev_sibling_->next_sibling_ = pNode->next_sibling_; if (pNode->next_sibling_) pNode->next_sibling_->prev_sibling_ = pNode->prev_sibling_; pNode->parent_ = nullptr; pNode->prev_sibling_ = nullptr; pNode->next_sibling_ = nullptr; } CFX_XMLNode* CFX_XMLNode::GetRoot() { CFX_XMLNode* pParent = this; while (pParent->parent_) pParent = pParent->parent_; return pParent; } WideString CFX_XMLNode::EncodeEntities(const WideString& value) { WideString ret = value; ret.Replace(L"&", L"&"); ret.Replace(L"<", L"<"); ret.Replace(L">", L">"); ret.Replace(L"\'", L"'"); ret.Replace(L"\"", L"""); return ret; }