summaryrefslogtreecommitdiff
path: root/core/fxcrt
diff options
context:
space:
mode:
authorTom Sepez <tsepez@chromium.org>2017-05-09 15:03:33 -0700
committerChromium commit bot <commit-bot@chromium.org>2017-05-09 22:24:52 +0000
commit8a6fdadccd2eedf332ae3a72f0149c1b40cb5bd9 (patch)
tree307288716efc81c5b3d5d0e05c380cdd10add95a /core/fxcrt
parent392cfd62f6fd6fc505b644b67938ea30131eb837 (diff)
downloadpdfium-8a6fdadccd2eedf332ae3a72f0149c1b40cb5bd9.tar.xz
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 <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
Diffstat (limited to 'core/fxcrt')
-rw-r--r--core/fxcrt/xml/cxml_content.cpp20
-rw-r--r--core/fxcrt/xml/cxml_content.h15
-rw-r--r--core/fxcrt/xml/cxml_element.cpp85
-rw-r--r--core/fxcrt/xml/cxml_element.h34
-rw-r--r--core/fxcrt/xml/cxml_object.cpp25
-rw-r--r--core/fxcrt/xml/cxml_object.h45
-rw-r--r--core/fxcrt/xml/cxml_parser.cpp9
7 files changed, 141 insertions, 92 deletions
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<CXML_Content*>(record.child);
- } else if (record.type == Element) {
- CXML_Element* child = static_cast<CXML_Element*>(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<CXML_Content*>(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<CXML_Element*>(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<CXML_Element*>(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<CXML_Element*>(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<CXML_Element*>(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<CXML_Element> 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<ChildRecord> m_Children;
+ std::vector<std::unique_ptr<CXML_Object>> 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 <algorithm>
#include <memory>
+#include <utility>
#include <vector>
#include "core/fxcrt/fx_extension.h"
@@ -493,8 +494,7 @@ std::unique_ptr<CXML_Element> 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<CXML_Content>(bCDATA, content));
}