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 --- BUILD.gn | 3 ++ 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 ++-- fpdfsdk/fpdf_ext.cpp | 19 ++++----- fpdfsdk/pdfwindow/PWL_Edit.cpp | 34 +++++++-------- xfa/fxfa/parser/cxfa_xmllocale.cpp | 39 +++++++++++------ 11 files changed, 196 insertions(+), 132 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 diff --git a/BUILD.gn b/BUILD.gn index 1abcc8d756..a50a4ea9df 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -803,11 +803,14 @@ static_library("fxcrt") { "core/fxcrt/xml/cxml_attritem.h", "core/fxcrt/xml/cxml_attrmap.cpp", "core/fxcrt/xml/cxml_attrmap.h", + "core/fxcrt/xml/cxml_content.cpp", "core/fxcrt/xml/cxml_content.h", "core/fxcrt/xml/cxml_databufacc.cpp", "core/fxcrt/xml/cxml_databufacc.h", "core/fxcrt/xml/cxml_element.cpp", "core/fxcrt/xml/cxml_element.h", + "core/fxcrt/xml/cxml_object.cpp", + "core/fxcrt/xml/cxml_object.h", "core/fxcrt/xml/cxml_parser.cpp", "core/fxcrt/xml/cxml_parser.h", ] 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)); } diff --git a/fpdfsdk/fpdf_ext.cpp b/fpdfsdk/fpdf_ext.cpp index 8773d680ea..f598835e3c 100644 --- a/fpdfsdk/fpdf_ext.cpp +++ b/fpdfsdk/fpdf_ext.cpp @@ -16,6 +16,7 @@ #include "core/fpdfdoc/cpdf_metadata.h" #include "core/fxcrt/fx_basic.h" #include "core/fxcrt/fx_memory.h" +#include "core/fxcrt/xml/cxml_content.h" #include "core/fxcrt/xml/cxml_element.h" #include "fpdfsdk/fsdk_define.h" #include "third_party/base/ptr_util.h" @@ -86,12 +87,13 @@ bool CheckSharedForm(const CXML_Element* pElement, CFX_ByteString cbName) { if (space == "xmlns" && name == "adhocwf" && value == L"http://ns.adobe.com/AcrobatAdhocWorkflow/1.0/") { CXML_Element* pVersion = - pElement->GetElement("adhocwf", cbName.AsStringC()); + pElement->GetElement("adhocwf", cbName.AsStringC(), 0); if (!pVersion) continue; - CFX_WideString wsContent = pVersion->GetContent(0); - int nType = wsContent.GetInteger(); - switch (nType) { + CXML_Content* pContent = ToContent(pVersion->GetChild(0)); + if (!pContent) + continue; + switch (pContent->m_Content.GetInteger()) { case 1: FPDF_UnSupportError(FPDF_UNSP_DOC_SHAREDFORM_ACROBAT); break; @@ -107,12 +109,9 @@ bool CheckSharedForm(const CXML_Element* pElement, CFX_ByteString cbName) { uint32_t nCount = pElement->CountChildren(); for (i = 0; i < (int)nCount; i++) { - CXML_Element::ChildType childType = pElement->GetChildType(i); - if (childType == CXML_Element::Element) { - CXML_Element* pChild = pElement->GetElement(i); - if (CheckSharedForm(pChild, cbName)) - return true; - } + CXML_Element* pChild = ToElement(pElement->GetChild(i)); + if (pChild && CheckSharedForm(pChild, cbName)) + return true; } return false; } diff --git a/fpdfsdk/pdfwindow/PWL_Edit.cpp b/fpdfsdk/pdfwindow/PWL_Edit.cpp index b1285a8428..90572746da 100644 --- a/fpdfsdk/pdfwindow/PWL_Edit.cpp +++ b/fpdfsdk/pdfwindow/PWL_Edit.cpp @@ -13,6 +13,7 @@ #include "core/fpdfapi/font/cpdf_font.h" #include "core/fpdfdoc/cpvt_word.h" #include "core/fxcrt/fx_safe_types.h" +#include "core/fxcrt/xml/cxml_content.h" #include "core/fxcrt/xml/cxml_element.h" #include "core/fxge/cfx_graphstatedata.h" #include "core/fxge/cfx_pathdata.h" @@ -55,30 +56,27 @@ void CPWL_Edit::SetText(const CFX_WideString& csText) { m_pEdit->SetText(swText); return; } - - int32_t nCount = pXML->CountChildren(); - bool bFirst = true; - swText.clear(); + bool bFirst = true; + int32_t nCount = pXML->CountChildren(); for (int32_t i = 0; i < nCount; i++) { - CXML_Element* pSubElement = pXML->GetElement(i); - if (!pSubElement) + CXML_Element* pSubElement = ToElement(pXML->GetChild(i)); + if (!pSubElement || !pSubElement->GetTagName().EqualNoCase("p")) continue; - CFX_ByteString tag = pSubElement->GetTagName(); - if (tag.EqualNoCase("p")) { - int nChild = pSubElement->CountChildren(); - CFX_WideString swSection; - for (int32_t j = 0; j < nChild; j++) - swSection += pSubElement->GetContent(j); - - if (bFirst) - bFirst = false; - else - swText += FWL_VKEY_Return; - swText += swSection; + CFX_WideString swSection; + int nSubChild = pSubElement->CountChildren(); + for (int32_t j = 0; j < nSubChild; j++) { + CXML_Content* pSubContent = ToContent(pSubElement->GetChild(j)); + if (pSubContent) + swSection += pSubContent->m_Content; } + if (bFirst) + bFirst = false; + else + swText += FWL_VKEY_Return; + swText += swSection; } m_pEdit->SetText(swText); diff --git a/xfa/fxfa/parser/cxfa_xmllocale.cpp b/xfa/fxfa/parser/cxfa_xmllocale.cpp index dd1d7cd1b8..4055c155dd 100644 --- a/xfa/fxfa/parser/cxfa_xmllocale.cpp +++ b/xfa/fxfa/parser/cxfa_xmllocale.cpp @@ -8,6 +8,7 @@ #include +#include "core/fxcrt/xml/cxml_content.h" #include "core/fxcrt/xml/cxml_element.h" #include "xfa/fxfa/parser/cxfa_document.h" #include "xfa/fxfa/parser/cxfa_localemgr.h" @@ -60,7 +61,8 @@ CFX_WideString CXFA_XMLLocale::GetNumbericSymbol( default: return CFX_WideString(); } - CXML_Element* pElement = m_pLocaleData->GetElement("", bsSymbols.AsStringC()); + CXML_Element* pElement = + m_pLocaleData->GetElement("", bsSymbols.AsStringC(), 0); if (!pElement) return CFX_WideString(); @@ -73,10 +75,16 @@ CFX_WideString CXFA_XMLLocale::GetDateTimeSymbols() const { if (!m_pLocaleData) return CFX_WideString(); - CFX_ByteString bsSpace; CXML_Element* pNumberSymbols = - m_pLocaleData->GetElement(bsSpace.AsStringC(), "dateTimeSymbols"); - return pNumberSymbols ? pNumberSymbols->GetContent(0) : CFX_WideString(); + m_pLocaleData->GetElement("", "dateTimeSymbols", 0); + if (!pNumberSymbols) + return CFX_WideString(); + + CXML_Content* pContent = ToContent(pNumberSymbols->GetChild(0)); + if (!pContent) + return CFX_WideString(); + + return pContent->m_Content; } CFX_WideString CXFA_XMLLocale::GetMonthName(int32_t nMonth, bool bAbbr) const { @@ -105,15 +113,16 @@ CFX_WideString CXFA_XMLLocale::GetCalendarSymbol(const CFX_ByteStringC& symbol, if (!m_pLocaleData) return CFX_WideString(); - CXML_Element* pChild = m_pLocaleData->GetElement("", "calendarSymbols"); + CXML_Element* pChild = m_pLocaleData->GetElement("", "calendarSymbols", 0); if (!pChild) return CFX_WideString(); CFX_ByteString pstrSymbolNames = symbol + "Names"; CXML_Element* pSymbolNames = - pChild->GetElement("", pstrSymbolNames.AsStringC()); + pChild->GetElement("", pstrSymbolNames.AsStringC(), 0); if (!pSymbolNames) return CFX_WideString(); + if ((!!pSymbolNames->GetAttrInteger("abbr")) != bAbbr) pSymbolNames = pChild->GetElement("", pstrSymbolNames.AsStringC(), 1); @@ -121,12 +130,16 @@ CFX_WideString CXFA_XMLLocale::GetCalendarSymbol(const CFX_ByteStringC& symbol, return CFX_WideString(); CXML_Element* pSymbolName = pSymbolNames->GetElement("", symbol, index); - return pSymbolName ? pSymbolName->GetContent(0) : CFX_WideString(); + if (!pSymbolName) + return CFX_WideString(); + + CXML_Content* pContent = ToContent(pSymbolName->GetChild(0)); + return pContent ? pContent->m_Content : CFX_WideString(); } CFX_WideString CXFA_XMLLocale::GetDatePattern( FX_LOCALEDATETIMESUBCATEGORY eType) const { - CXML_Element* pElement = m_pLocaleData->GetElement("", "datePatterns"); + CXML_Element* pElement = m_pLocaleData->GetElement("", "datePatterns", 0); if (!pElement) return CFX_WideString(); @@ -151,7 +164,7 @@ CFX_WideString CXFA_XMLLocale::GetDatePattern( CFX_WideString CXFA_XMLLocale::GetTimePattern( FX_LOCALEDATETIMESUBCATEGORY eType) const { - CXML_Element* pElement = m_pLocaleData->GetElement("", "timePatterns"); + CXML_Element* pElement = m_pLocaleData->GetElement("", "timePatterns", 0); if (!pElement) return CFX_WideString(); @@ -176,7 +189,7 @@ CFX_WideString CXFA_XMLLocale::GetTimePattern( CFX_WideString CXFA_XMLLocale::GetNumPattern( FX_LOCALENUMSUBCATEGORY eType) const { - return m_pLocaleData->GetElement("", "numberPatterns") + return m_pLocaleData->GetElement("", "numberPatterns", 0) ? XFA_PatternToString(eType) : CFX_WideString(); } @@ -187,8 +200,10 @@ CFX_WideString CXFA_XMLLocale::GetPattern(CXML_Element* pElement, int32_t iCount = pElement->CountElements("", bsTag); for (int32_t i = 0; i < iCount; i++) { CXML_Element* pChild = pElement->GetElement("", bsTag, i); - if (pChild->GetAttrValue("name") == wsName) - return pChild->GetContent(0); + if (pChild->GetAttrValue("name") == wsName) { + CXML_Content* pContent = ToContent(pChild->GetChild(0)); + return pContent ? pContent->m_Content : CFX_WideString(); + } } return CFX_WideString(); } -- cgit v1.2.3