From 8a6fdadccd2eedf332ae3a72f0149c1b40cb5bd9 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Tue, 9 May 2017 15:03:33 -0700 Subject: Create common CXML_Object base class for CXML_Content and CXML_Element. They should each know what they are rather than having an external ChildRecord struct to track the type. Change-Id: Ic647ba45569764073e944d30af1a96dccdc29eb3 Reviewed-on: https://pdfium-review.googlesource.com/5210 Reviewed-by: Lei Zhang Commit-Queue: Tom Sepez --- core/fxcrt/xml/cxml_content.cpp | 20 ++++++++++ core/fxcrt/xml/cxml_content.h | 15 +++++--- core/fxcrt/xml/cxml_element.cpp | 85 +++++++++++++---------------------------- core/fxcrt/xml/cxml_element.h | 34 ++++++----------- core/fxcrt/xml/cxml_object.cpp | 25 ++++++++++++ core/fxcrt/xml/cxml_object.h | 45 ++++++++++++++++++++++ core/fxcrt/xml/cxml_parser.cpp | 9 ++--- 7 files changed, 141 insertions(+), 92 deletions(-) create mode 100644 core/fxcrt/xml/cxml_content.cpp create mode 100644 core/fxcrt/xml/cxml_object.cpp create mode 100644 core/fxcrt/xml/cxml_object.h (limited to 'core') diff --git a/core/fxcrt/xml/cxml_content.cpp b/core/fxcrt/xml/cxml_content.cpp new file mode 100644 index 0000000000..fe0c185bb7 --- /dev/null +++ b/core/fxcrt/xml/cxml_content.cpp @@ -0,0 +1,20 @@ +// 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/cxml_content.h" + +CXML_Content::CXML_Content(bool bCDATA, const CFX_WideStringC& content) + : m_bCDATA(bCDATA), m_Content(content) {} + +CXML_Content::~CXML_Content() {} + +CXML_Content* CXML_Content::AsContent() { + return this; +} + +const CXML_Content* CXML_Content::AsContent() const { + return this; +} diff --git a/core/fxcrt/xml/cxml_content.h b/core/fxcrt/xml/cxml_content.h index 261c622eca..641efe6720 100644 --- a/core/fxcrt/xml/cxml_content.h +++ b/core/fxcrt/xml/cxml_content.h @@ -7,14 +7,17 @@ #ifndef CORE_FXCRT_XML_CXML_CONTENT_H_ #define CORE_FXCRT_XML_CXML_CONTENT_H_ -class CXML_Content { +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/xml/cxml_object.h" + +class CXML_Content : public CXML_Object { public: - CXML_Content() : m_bCDATA(false), m_Content() {} + CXML_Content(bool bCDATA, const CFX_WideStringC& content); + ~CXML_Content() override; - void Set(bool bCDATA, const CFX_WideStringC& content) { - m_bCDATA = bCDATA; - m_Content = content; - } + // CXML_Object: + CXML_Content* AsContent() override; + const CXML_Content* AsContent() const override; bool m_bCDATA; CFX_WideString m_Content; diff --git a/core/fxcrt/xml/cxml_element.cpp b/core/fxcrt/xml/cxml_element.cpp index 95a6dba147..ec0a73b00d 100644 --- a/core/fxcrt/xml/cxml_element.cpp +++ b/core/fxcrt/xml/cxml_element.cpp @@ -23,25 +23,16 @@ CXML_Element::CXML_Element(const CXML_Element* pParent, const CFX_ByteStringC& tagname) : m_pParent(pParent), m_QSpaceName(qSpace), m_TagName(tagname) {} -CXML_Element::~CXML_Element() { - Empty(); -} +CXML_Element::~CXML_Element() {} -void CXML_Element::Empty() { - RemoveChildren(); +CXML_Element* CXML_Element::AsElement() { + return this; } -void CXML_Element::RemoveChildren() { - for (const ChildRecord& record : m_Children) { - if (record.type == Content) { - delete static_cast(record.child); - } else if (record.type == Element) { - CXML_Element* child = static_cast(record.child); - child->RemoveChildren(); - delete child; - } - } - m_Children.clear(); + +const CXML_Element* CXML_Element::AsElement() const { + return this; } + CFX_ByteString CXML_Element::GetTagName(bool bQualified) const { if (!bQualified || m_QSpaceName.IsEmpty()) { return m_TagName; @@ -159,69 +150,47 @@ bool CXML_Element::GetAttrFloat(const CFX_ByteStringC& space, return true; } -CXML_Element::ChildType CXML_Element::GetChildType(uint32_t index) const { - return index < m_Children.size() ? m_Children[index].type : Invalid; -} - -CFX_WideString CXML_Element::GetContent(uint32_t index) const { - if (index < m_Children.size() && m_Children[index].type == Content) { - CXML_Content* pContent = - static_cast(m_Children[index].child); - if (pContent) - return pContent->m_Content; - } - return CFX_WideString(); -} - -CXML_Element* CXML_Element::GetElement(uint32_t index) const { - if (index < m_Children.size() && m_Children[index].type == Element) - return static_cast(m_Children[index].child); - return nullptr; -} - uint32_t CXML_Element::CountElements(const CFX_ByteStringC& space, const CFX_ByteStringC& tag) const { int count = 0; - for (const ChildRecord& record : m_Children) { - if (record.type != Element) - continue; - - CXML_Element* pKid = static_cast(record.child); - if ((space.IsEmpty() || pKid->m_QSpaceName == space) && - pKid->m_TagName == tag) { + for (const auto& pChild : m_Children) { + const CXML_Element* pKid = pChild->AsElement(); + if (pKid && pKid->m_TagName == tag && + (space.IsEmpty() || pKid->m_QSpaceName == space)) { count++; } } return count; } +CXML_Object* CXML_Element::GetChild(uint32_t index) const { + return index < m_Children.size() ? m_Children[index].get() : nullptr; +} + CXML_Element* CXML_Element::GetElement(const CFX_ByteStringC& space, const CFX_ByteStringC& tag, - int index) const { - if (index < 0) + int nth) const { + if (nth < 0) return nullptr; - for (const ChildRecord& record : m_Children) { - if (record.type != Element) - continue; - - CXML_Element* pKid = static_cast(record.child); - if ((space.IsEmpty() || pKid->m_QSpaceName == space) && - pKid->m_TagName == tag) { - if (index-- == 0) + for (const auto& pChild : m_Children) { + CXML_Element* pKid = pChild->AsElement(); + if (pKid && pKid->m_TagName == tag && + (space.IsEmpty() || pKid->m_QSpaceName == space)) { + if (nth-- == 0) return pKid; } } return nullptr; } -uint32_t CXML_Element::FindElement(CXML_Element* pChild) const { +uint32_t CXML_Element::FindElement(CXML_Element* pElement) const { int index = 0; - for (const ChildRecord& record : m_Children) { - if (record.type == Element && - static_cast(record.child) == pChild) { + for (const auto& pChild : m_Children) { + CXML_Element* pKid = pChild->AsElement(); + if (pKid && pKid == pElement) return index; - } + ++index; } return 0xFFFFFFFF; diff --git a/core/fxcrt/xml/cxml_element.h b/core/fxcrt/xml/cxml_element.h index 349deba2c8..2eb6caf74c 100644 --- a/core/fxcrt/xml/cxml_element.h +++ b/core/fxcrt/xml/cxml_element.h @@ -12,19 +12,21 @@ #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/xml/cxml_attrmap.h" +#include "core/fxcrt/xml/cxml_object.h" -class CXML_Element { +class CXML_Element : public CXML_Object { public: - enum ChildType { Invalid, Element, Content }; - static std::unique_ptr Parse(const void* pBuffer, size_t size); CXML_Element(const CXML_Element* pParent, const CFX_ByteStringC& qSpace, const CFX_ByteStringC& tagname); - ~CXML_Element(); + ~CXML_Element() override; + + // CXML_Object: + CXML_Element* AsElement() override; + const CXML_Element* AsElement() const override; - void Empty(); CFX_ByteString GetTagName(bool bQualified = false) const; CFX_ByteString GetNamespace(bool bQualified = false) const; CFX_ByteString GetNamespaceURI(const CFX_ByteString& qName) const; @@ -88,39 +90,25 @@ class CXML_Element { } uint32_t CountChildren() const { return m_Children.size(); } - ChildType GetChildType(uint32_t index) const; - CFX_WideString GetContent(uint32_t index) const; - CXML_Element* GetElement(uint32_t index) const; - CXML_Element* GetElement(const CFX_ByteStringC& space, - const CFX_ByteStringC& tag) const { - return GetElement(space, tag, 0); - } - uint32_t CountElements(const CFX_ByteStringC& space, const CFX_ByteStringC& tag) const; + CXML_Object* GetChild(uint32_t index) const; CXML_Element* GetElement(const CFX_ByteStringC& space, const CFX_ByteStringC& tag, - int index) const; - - uint32_t FindElement(CXML_Element* pChild) const; + int nth) const; + uint32_t FindElement(CXML_Element* pElement) const; void SetTag(const CFX_ByteStringC& qTagName); - void RemoveChildren(); void RemoveChild(uint32_t index); private: friend class CXML_Parser; friend class CXML_Composer; - struct ChildRecord { - ChildType type; - void* child; // CXML_Element and CXML_Content lack a common ancestor. - }; - const CXML_Element* const m_pParent; CFX_ByteString m_QSpaceName; CFX_ByteString m_TagName; CXML_AttrMap m_AttrMap; - std::vector m_Children; + std::vector> m_Children; }; #endif // CORE_FXCRT_XML_CXML_ELEMENT_H_ diff --git a/core/fxcrt/xml/cxml_object.cpp b/core/fxcrt/xml/cxml_object.cpp new file mode 100644 index 0000000000..61e88cb407 --- /dev/null +++ b/core/fxcrt/xml/cxml_object.cpp @@ -0,0 +1,25 @@ +// 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/cxml_object.h" + +CXML_Object::~CXML_Object() {} + +CXML_Content* CXML_Object::AsContent() { + return nullptr; +} + +CXML_Element* CXML_Object::AsElement() { + return nullptr; +} + +const CXML_Content* CXML_Object::AsContent() const { + return nullptr; +} + +const CXML_Element* CXML_Object::AsElement() const { + return nullptr; +} diff --git a/core/fxcrt/xml/cxml_object.h b/core/fxcrt/xml/cxml_object.h new file mode 100644 index 0000000000..e7f23aa988 --- /dev/null +++ b/core/fxcrt/xml/cxml_object.h @@ -0,0 +1,45 @@ +// 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 + +#ifndef CORE_FXCRT_XML_CXML_OBJECT_H_ +#define CORE_FXCRT_XML_CXML_OBJECT_H_ + +#include "core/fxcrt/fx_basic.h" + +class CXML_Content; +class CXML_Element; + +class CXML_Object { + public: + virtual ~CXML_Object(); + + virtual CXML_Content* AsContent(); + virtual const CXML_Content* AsContent() const; + + virtual CXML_Element* AsElement(); + virtual const CXML_Element* AsElement() const; + + protected: + CXML_Object() {} +}; + +inline CXML_Content* ToContent(CXML_Object* pObj) { + return pObj ? pObj->AsContent() : nullptr; +} + +inline const CXML_Content* ToContent(const CXML_Object* pObj) { + return pObj ? pObj->AsContent() : nullptr; +} + +inline CXML_Element* ToElement(CXML_Object* pObj) { + return pObj ? pObj->AsElement() : nullptr; +} + +inline const CXML_Element* ToElement(const CXML_Object* pObj) { + return pObj ? pObj->AsElement() : nullptr; +} + +#endif // CORE_FXCRT_XML_CXML_OBJECT_H_ diff --git a/core/fxcrt/xml/cxml_parser.cpp b/core/fxcrt/xml/cxml_parser.cpp index 3c91d744ec..d43fbd6581 100644 --- a/core/fxcrt/xml/cxml_parser.cpp +++ b/core/fxcrt/xml/cxml_parser.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "core/fxcrt/fx_extension.h" @@ -493,8 +494,7 @@ std::unique_ptr CXML_Parser::ParseElementInternal( if (!pSubElement) break; - pElement->m_Children.push_back( - {CXML_Element::Element, pSubElement.release()}); + pElement->m_Children.push_back(std::move(pSubElement)); SkipWhiteSpaces(); } break; @@ -537,7 +537,6 @@ void CXML_Parser::InsertContentSegment(bool bCDATA, if (content.IsEmpty()) return; - CXML_Content* pContent = new CXML_Content; - pContent->Set(bCDATA, content); - pElement->m_Children.push_back({CXML_Element::Content, pContent}); + pElement->m_Children.push_back( + pdfium::MakeUnique(bCDATA, content)); } -- cgit v1.2.3