diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2017-01-17 16:35:16 -0500 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2017-01-17 22:04:45 +0000 |
commit | 3285c56b0dd6b83c2fcc8b8f714324185a09c920 (patch) | |
tree | 1da61ece5e7ca7f8a99cdb00ad0f5f41e2020afb /xfa | |
parent | da489976371eb928d8b4d004744667fdf82b90d4 (diff) | |
download | pdfium-3285c56b0dd6b83c2fcc8b8f714324185a09c920.tar.xz |
Start CSS parser unit tests
Start adding unit tests for the css parser. Fixup memory
leaks that are exposed by the tests.
Change-Id: Id863d9cd5f13ab82626bc7b945de925253c88d43
Reviewed-on: https://pdfium-review.googlesource.com/2180
Reviewed-by: Nicolás Peña <npm@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'xfa')
-rw-r--r-- | xfa/fde/css/cfde_cssstylesheet_unittest.cpp | 112 | ||||
-rw-r--r-- | xfa/fde/css/cfde_cssvalue.cpp | 2 | ||||
-rw-r--r-- | xfa/fde/css/cfde_cssvalue.h | 4 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssdatatable.cpp | 35 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssdatatable.h | 24 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssdeclaration.cpp | 333 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssdeclaration.h | 110 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssstyleselector.cpp | 39 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssstylesheet.cpp | 267 | ||||
-rw-r--r-- | xfa/fde/css/fde_cssstylesheet.h | 38 |
10 files changed, 530 insertions, 434 deletions
diff --git a/xfa/fde/css/cfde_cssstylesheet_unittest.cpp b/xfa/fde/css/cfde_cssstylesheet_unittest.cpp new file mode 100644 index 0000000000..1edc4b5f51 --- /dev/null +++ b/xfa/fde/css/cfde_cssstylesheet_unittest.cpp @@ -0,0 +1,112 @@ +// 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 "xfa/fde/css/fde_cssstylesheet.h" + +#include <memory> + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/base/ptr_util.h" + +class CFDE_CSSStyleSheetTest : public testing::Test { + public: + void SetUp() override { + sheet_ = pdfium::MakeUnique<CFDE_CSSStyleSheet>(); + decl_ = nullptr; + } + + void TearDown() override { decl_ = nullptr; } + + void LoadAndVerifyDecl(const FX_WCHAR* buf, size_t decl_count) { + ASSERT(sheet_); + + EXPECT_TRUE(sheet_->LoadFromBuffer(buf, FXSYS_wcslen(buf))); + EXPECT_EQ(1, sheet_->CountRules()); + + CFDE_CSSRule* rule = sheet_->GetRule(0); + EXPECT_EQ(FDE_CSSRuleType::Style, rule->GetType()); + + CFDE_CSSStyleRule* style = static_cast<CFDE_CSSStyleRule*>(rule); + decl_ = style->GetDeclaration(); + EXPECT_EQ(decl_count, decl_->PropertyCountForTesting()); + } + + void VerifyFloat(FDE_CSSProperty prop, float val, FDE_CSSPrimitiveType type) { + ASSERT(decl_); + + bool important; + CFDE_CSSValue* v = decl_->GetProperty(prop, important); + CFDE_CSSPrimitiveValue* pval = static_cast<CFDE_CSSPrimitiveValue*>(v); + EXPECT_EQ(type, pval->GetPrimitiveType()); + EXPECT_EQ(val, pval->GetFloat()); + } + + void VerifyEnum(FDE_CSSProperty prop, FDE_CSSPropertyValue val) { + ASSERT(decl_); + + bool important; + CFDE_CSSValue* v = decl_->GetProperty(prop, important); + CFDE_CSSPrimitiveValue* pval = static_cast<CFDE_CSSPrimitiveValue*>(v); + EXPECT_EQ(FDE_CSSPrimitiveType::Enum, pval->GetPrimitiveType()); + EXPECT_EQ(val, pval->GetEnum()); + } + + std::unique_ptr<CFDE_CSSStyleSheet> sheet_; + CFDE_CSSDeclaration* decl_; +}; + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorder) { + LoadAndVerifyDecl(L"a { border: 5px; }", 4); + VerifyFloat(FDE_CSSProperty::BorderLeftWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderRightWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderTopWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderBottomWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); +} + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorderFull) { + LoadAndVerifyDecl(L"a { border: 5px solid red; }", 4); + VerifyFloat(FDE_CSSProperty::BorderLeftWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderRightWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderTopWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); + VerifyFloat(FDE_CSSProperty::BorderBottomWidth, 5.0, + FDE_CSSPrimitiveType::Pixels); +} + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorderLeft) { + LoadAndVerifyDecl(L"a { border-left: 2.5pc; }", 1); + VerifyFloat(FDE_CSSProperty::BorderLeftWidth, 2.5, + FDE_CSSPrimitiveType::Picas); +} + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorderLeftThick) { + LoadAndVerifyDecl(L"a { border-left: thick; }", 1); + VerifyEnum(FDE_CSSProperty::BorderLeftWidth, FDE_CSSPropertyValue::Thick); +} + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorderRight) { + LoadAndVerifyDecl(L"a { border-right: 2.5pc; }", 1); + VerifyFloat(FDE_CSSProperty::BorderRightWidth, 2.5, + FDE_CSSPrimitiveType::Picas); +} + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorderTop) { + LoadAndVerifyDecl(L"a { border-top: 2.5pc; }", 1); + VerifyFloat(FDE_CSSProperty::BorderTopWidth, 2.5, + FDE_CSSPrimitiveType::Picas); +} + +TEST_F(CFDE_CSSStyleSheetTest, ParseBorderBottom) { + LoadAndVerifyDecl(L"a { border-bottom: 2.5pc; }", 1); + VerifyFloat(FDE_CSSProperty::BorderBottomWidth, 2.5, + FDE_CSSPrimitiveType::Picas); +} diff --git a/xfa/fde/css/cfde_cssvalue.cpp b/xfa/fde/css/cfde_cssvalue.cpp index 84e99353a9..0dc577beb0 100644 --- a/xfa/fde/css/cfde_cssvalue.cpp +++ b/xfa/fde/css/cfde_cssvalue.cpp @@ -7,5 +7,3 @@ #include "xfa/fde/css/cfde_cssvalue.h" CFDE_CSSValue::CFDE_CSSValue(FDE_CSSVALUETYPE type) : m_value(type) {} - -CFDE_CSSValue::~CFDE_CSSValue() {} diff --git a/xfa/fde/css/cfde_cssvalue.h b/xfa/fde/css/cfde_cssvalue.h index 17cc565b5d..a5ac24c38a 100644 --- a/xfa/fde/css/cfde_cssvalue.h +++ b/xfa/fde/css/cfde_cssvalue.h @@ -9,10 +9,8 @@ #include "xfa/fde/css/fde_css.h" -class CFDE_CSSValue { +class CFDE_CSSValue : public CFX_Retainable { public: - virtual ~CFDE_CSSValue(); - FDE_CSSVALUETYPE GetType() const { return m_value; } protected: diff --git a/xfa/fde/css/fde_cssdatatable.cpp b/xfa/fde/css/fde_cssdatatable.cpp index 569a6f2bf9..82a29e2f06 100644 --- a/xfa/fde/css/fde_cssdatatable.cpp +++ b/xfa/fde/css/fde_cssdatatable.cpp @@ -6,6 +6,8 @@ #include "xfa/fde/css/fde_cssdatatable.h" +#include <utility> + #include "core/fxcrt/fx_ext.h" #include "xfa/fde/css/fde_cssstyleselector.h" #include "xfa/fgas/crt/fgas_codepage.h" @@ -535,20 +537,19 @@ bool FDE_ParseCSSColor(const FX_WCHAR* pszValue, } CFDE_CSSValueList::CFDE_CSSValueList( - const CFX_ArrayTemplate<CFDE_CSSValue*>& list) - : CFDE_CSSValue(FDE_CSSVALUETYPE_List) { - m_iCount = list.GetSize(); - m_ppList = FX_Alloc(CFDE_CSSValue*, m_iCount); - FXSYS_memcpy(m_ppList, list.GetData(), m_iCount * sizeof(CFDE_CSSValue*)); -} + std::vector<CFX_RetainPtr<CFDE_CSSValue>>& list) + : CFDE_CSSValue(FDE_CSSVALUETYPE_List), m_ppList(std::move(list)) {} + +CFDE_CSSValueList::~CFDE_CSSValueList() {} int32_t CFDE_CSSValueList::CountValues() const { - return m_iCount; + return m_ppList.size(); } CFDE_CSSValue* CFDE_CSSValueList::GetValue(int32_t index) const { - return m_ppList[index]; + return m_ppList[index].Get(); } + bool CFDE_CSSValueListParser::NextValue(FDE_CSSPrimitiveType& eType, const FX_WCHAR*& pStart, int32_t& iLength) { @@ -651,9 +652,6 @@ int32_t CFDE_CSSValueListParser::SkipTo(FX_WCHAR wch, return m_pCur - pStart; } -CFDE_CSSPrimitiveValue::CFDE_CSSPrimitiveValue( - const CFDE_CSSPrimitiveValue& src) = default; - CFDE_CSSPrimitiveValue::CFDE_CSSPrimitiveValue(FX_ARGB color) : CFDE_CSSValue(FDE_CSSVALUETYPE_Primitive), m_eType(FDE_CSSPrimitiveType::RGB), @@ -678,10 +676,13 @@ CFDE_CSSPrimitiveValue::CFDE_CSSPrimitiveValue(FDE_CSSPrimitiveType eType, ASSERT(m_pString); } -CFDE_CSSPrimitiveValue::CFDE_CSSPrimitiveValue(CFDE_CSSFunction* pFunction) +CFDE_CSSPrimitiveValue::CFDE_CSSPrimitiveValue( + std::unique_ptr<CFDE_CSSFunction> pFunction) : CFDE_CSSValue(FDE_CSSVALUETYPE_Primitive), m_eType(FDE_CSSPrimitiveType::Function), - m_pFunction(pFunction) {} + m_pFunction(std::move(pFunction)) {} + +CFDE_CSSPrimitiveValue::~CFDE_CSSPrimitiveValue() {} FDE_CSSPrimitiveType CFDE_CSSPrimitiveValue::GetPrimitiveType() const { return m_eType; @@ -724,3 +725,11 @@ CFDE_CSSValue* CFDE_CSSPrimitiveValue::GetArgs(int32_t index) const { ASSERT(m_eType == FDE_CSSPrimitiveType::Function); return m_pFunction->GetArgs(index); } + +CFDE_CSSFunction::CFDE_CSSFunction(const FX_WCHAR* pszFuncName, + CFX_RetainPtr<CFDE_CSSValueList> pArgList) + : m_pArgList(pArgList), m_pszFuncName(pszFuncName) { + ASSERT(pArgList); +} + +CFDE_CSSFunction::~CFDE_CSSFunction() {} diff --git a/xfa/fde/css/fde_cssdatatable.h b/xfa/fde/css/fde_cssdatatable.h index 0904b445d9..0b14ffc101 100644 --- a/xfa/fde/css/fde_cssdatatable.h +++ b/xfa/fde/css/fde_cssdatatable.h @@ -7,6 +7,9 @@ #ifndef XFA_FDE_CSS_FDE_CSSDATATABLE_H_ #define XFA_FDE_CSS_FDE_CSSDATATABLE_H_ +#include <memory> +#include <vector> + #include "core/fxcrt/fx_system.h" #include "xfa/fde/css/cfde_cssvalue.h" #include "xfa/fde/css/fde_css.h" @@ -17,10 +20,11 @@ class CFDE_CSSPrimitiveValue : public CFDE_CSSValue { public: explicit CFDE_CSSPrimitiveValue(FX_ARGB color); explicit CFDE_CSSPrimitiveValue(FDE_CSSPropertyValue eValue); - explicit CFDE_CSSPrimitiveValue(CFDE_CSSFunction* pFunction); + explicit CFDE_CSSPrimitiveValue(std::unique_ptr<CFDE_CSSFunction> pFunction); CFDE_CSSPrimitiveValue(FDE_CSSPrimitiveType eType, FX_FLOAT fValue); CFDE_CSSPrimitiveValue(FDE_CSSPrimitiveType eType, const FX_WCHAR* pValue); CFDE_CSSPrimitiveValue(const CFDE_CSSPrimitiveValue& src); + ~CFDE_CSSPrimitiveValue() override; FDE_CSSPrimitiveType GetPrimitiveType() const; FX_ARGB GetRGBColor() const; @@ -37,20 +41,20 @@ class CFDE_CSSPrimitiveValue : public CFDE_CSSValue { FX_FLOAT m_fNumber; const FX_WCHAR* m_pString; FDE_CSSPropertyValue m_eEnum; - CFDE_CSSFunction* m_pFunction; }; + std::unique_ptr<CFDE_CSSFunction> m_pFunction; }; class CFDE_CSSValueList : public CFDE_CSSValue { public: - explicit CFDE_CSSValueList(const CFX_ArrayTemplate<CFDE_CSSValue*>& list); + explicit CFDE_CSSValueList(std::vector<CFX_RetainPtr<CFDE_CSSValue>>& list); + ~CFDE_CSSValueList() override; int32_t CountValues() const; CFDE_CSSValue* GetValue(int32_t index) const; protected: - CFDE_CSSValue** m_ppList; - int32_t m_iCount; + std::vector<CFX_RetainPtr<CFDE_CSSValue>> m_ppList; }; class CFDE_CSSValueListParser { @@ -75,10 +79,10 @@ class CFDE_CSSValueListParser { class CFDE_CSSFunction { public: - CFDE_CSSFunction(const FX_WCHAR* pszFuncName, CFDE_CSSValueList* pArgList) - : m_pArgList(pArgList), m_pszFuncName(pszFuncName) { - ASSERT(pArgList); - } + CFDE_CSSFunction(const FX_WCHAR* pszFuncName, + CFX_RetainPtr<CFDE_CSSValueList> pArgList); + ~CFDE_CSSFunction(); + int32_t CountArgs() const { return m_pArgList->CountValues(); } CFDE_CSSValue* GetArgs(int32_t index) const { return m_pArgList->GetValue(index); @@ -86,7 +90,7 @@ class CFDE_CSSFunction { const FX_WCHAR* GetFuncName() const { return m_pszFuncName; } protected: - CFDE_CSSValueList* m_pArgList; + CFX_RetainPtr<CFDE_CSSValueList> m_pArgList; const FX_WCHAR* m_pszFuncName; }; diff --git a/xfa/fde/css/fde_cssdeclaration.cpp b/xfa/fde/css/fde_cssdeclaration.cpp index b995649e6d..14ed101500 100644 --- a/xfa/fde/css/fde_cssdeclaration.cpp +++ b/xfa/fde/css/fde_cssdeclaration.cpp @@ -7,45 +7,23 @@ #include "xfa/fde/css/fde_cssdeclaration.h" #include "core/fxcrt/fx_ext.h" +#include "third_party/base/ptr_util.h" + +CFDE_CSSDeclaration::CFDE_CSSDeclaration() {} + +CFDE_CSSDeclaration::~CFDE_CSSDeclaration() {} CFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSProperty eProperty, bool& bImportant) const { - for (const FDE_CSSPropertyHolder* pHolder = m_pFirstProperty; pHolder; - pHolder = pHolder->pNext) { - if (pHolder->eProperty == eProperty) { - bImportant = pHolder->bImportant; - return pHolder->pValue; + for (const auto& p : properties_) { + if (p->eProperty == eProperty) { + bImportant = p->bImportant; + return p->pValue.Get(); } } return nullptr; } -FX_POSITION CFDE_CSSDeclaration::GetStartPosition() const { - return (FX_POSITION)m_pFirstProperty; -} -void CFDE_CSSDeclaration::GetNextProperty(FX_POSITION& pos, - FDE_CSSProperty& eProperty, - CFDE_CSSValue*& pValue, - bool& bImportant) const { - const FDE_CSSPropertyHolder* pHolder = (const FDE_CSSPropertyHolder*)pos; - bImportant = pHolder->bImportant; - eProperty = pHolder->eProperty; - pValue = pHolder->pValue; - pos = (FX_POSITION)pHolder->pNext; -} -FX_POSITION CFDE_CSSDeclaration::GetStartCustom() const { - return (FX_POSITION)m_pFirstCustom; -} -void CFDE_CSSDeclaration::GetNextCustom(FX_POSITION& pos, - CFX_WideString& wsName, - CFX_WideString& wsValue) const { - const FDE_CSSCustomProperty* pProperty = (const FDE_CSSCustomProperty*)pos; - if (!pProperty) - return; - wsName = pProperty->pwsName; - wsValue = pProperty->pwsValue; - pos = (FX_POSITION)pProperty->pNext; -} const FX_WCHAR* CFDE_CSSDeclaration::CopyToLocal( const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, @@ -67,43 +45,40 @@ const FX_WCHAR* CFDE_CSSDeclaration::CopyToLocal( return psz; } -CFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewNumberValue( + +CFX_RetainPtr<CFDE_CSSPrimitiveValue> CFDE_CSSDeclaration::NewNumberValue( FDE_CSSPrimitiveType eUnit, FX_FLOAT fValue) const { - static CFDE_CSSPrimitiveValue s_ZeroValue(FDE_CSSPrimitiveType::Number, 0.0f); - if (eUnit == FDE_CSSPrimitiveType::Number && FXSYS_fabs(fValue) < 0.001f) { - return &s_ZeroValue; - } - return new CFDE_CSSPrimitiveValue(eUnit, fValue); + if (eUnit == FDE_CSSPrimitiveType::Number && FXSYS_fabs(fValue) < 0.001f) + fValue = 0.0f; + return pdfium::MakeRetain<CFDE_CSSPrimitiveValue>(eUnit, fValue); } -CFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewEnumValue( + +CFX_RetainPtr<CFDE_CSSPrimitiveValue> CFDE_CSSDeclaration::NewEnumValue( FDE_CSSPropertyValue eValue) const { - return new CFDE_CSSPrimitiveValue(eValue); + return pdfium::MakeRetain<CFDE_CSSPrimitiveValue>(eValue); } + void CFDE_CSSDeclaration::AddPropertyHolder(FDE_CSSProperty eProperty, - CFDE_CSSValue* pValue, + CFX_RetainPtr<CFDE_CSSValue> pValue, bool bImportant) { - FDE_CSSPropertyHolder* pHolder = new FDE_CSSPropertyHolder; + auto pHolder = pdfium::MakeUnique<FDE_CSSPropertyHolder>(); pHolder->bImportant = bImportant; pHolder->eProperty = eProperty; pHolder->pValue = pValue; - pHolder->pNext = nullptr; - if (m_pLastProperty) - m_pLastProperty->pNext = pHolder; - else - m_pFirstProperty = pHolder; - m_pLastProperty = pHolder; + properties_.push_back(std::move(pHolder)); } -bool CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, + +void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { ASSERT(iValueLen > 0); bool bImportant = false; if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!' && FXSYS_wcsnicmp(L"important", pszValue + iValueLen - 9, 9) == 0) { - if ((iValueLen -= 10) == 0) { - return false; - } + if ((iValueLen -= 10) == 0) + return; + bImportant = true; } const uint32_t dwType = pArgs->pProperty->dwType; @@ -121,7 +96,7 @@ bool CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, if (dwMatch == 0) { continue; } - CFDE_CSSValue* pCSSValue = nullptr; + CFX_RetainPtr<CFDE_CSSValue> pCSSValue; switch (dwMatch) { case FDE_CSSVALUETYPE_MaybeFunction: pCSSValue = ParseFunction(pArgs, pszValue, iValueLen); @@ -146,18 +121,19 @@ bool CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, } if (pCSSValue) { AddPropertyHolder(pArgs->pProperty->eName, pCSSValue, bImportant); - return true; - } - if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) { - return false; + return; } + if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) + return; } - } break; + break; + } case FDE_CSSVALUETYPE_Shorthand: { - CFDE_CSSValue* pWidth; + CFX_RetainPtr<CFDE_CSSValue> pWidth; switch (pArgs->pProperty->eName) { case FDE_CSSProperty::Font: - return ParseFontProperty(pArgs, pszValue, iValueLen, bImportant); + ParseFontProperty(pArgs, pszValue, iValueLen, bImportant); + return; case FDE_CSSProperty::Border: if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { AddPropertyHolder(FDE_CSSProperty::BorderLeftWidth, pWidth, @@ -168,35 +144,35 @@ bool CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, bImportant); AddPropertyHolder(FDE_CSSProperty::BorderBottomWidth, pWidth, bImportant); - return true; + return; } break; case FDE_CSSProperty::BorderLeft: if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { AddPropertyHolder(FDE_CSSProperty::BorderLeftWidth, pWidth, bImportant); - return true; + return; } break; case FDE_CSSProperty::BorderTop: if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { AddPropertyHolder(FDE_CSSProperty::BorderTopWidth, pWidth, bImportant); - return true; + return; } break; case FDE_CSSProperty::BorderRight: if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { AddPropertyHolder(FDE_CSSProperty::BorderRightWidth, pWidth, bImportant); - return true; + return; } break; case FDE_CSSProperty::BorderBottom: if (ParseBorderProperty(pszValue, iValueLen, pWidth)) { AddPropertyHolder(FDE_CSSProperty::BorderBottomWidth, pWidth, bImportant); - return true; + return; } break; default: @@ -204,60 +180,59 @@ bool CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, } } break; case FDE_CSSVALUETYPE_List: - return ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant); + ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant); + return; default: ASSERT(false); break; } - return false; } -bool CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, + +void CFDE_CSSDeclaration::AddProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszName, int32_t iNameLen, const FX_WCHAR* pszValue, int32_t iValueLen) { - FDE_CSSCustomProperty* pProperty = new FDE_CSSCustomProperty; + auto pProperty = pdfium::MakeUnique<FDE_CSSCustomProperty>(); pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen); pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen); - pProperty->pNext = nullptr; - if (m_pLastCustom) - m_pLastCustom->pNext = pProperty; - else - m_pFirstCustom = pProperty; - m_pLastCustom = pProperty; - return true; + custom_properties_.push_back(std::move(pProperty)); } -CFDE_CSSValue* CFDE_CSSDeclaration::ParseNumber( + +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseNumber( const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { FX_FLOAT fValue; FDE_CSSPrimitiveType eUnit; - if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) { + if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) return nullptr; - } return NewNumberValue(eUnit, fValue); } -CFDE_CSSValue* CFDE_CSSDeclaration::ParseEnum(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { + +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseEnum( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { const FDE_CSSPropertyValueTable* pValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); return pValue ? NewEnumValue(pValue->eName) : nullptr; } -CFDE_CSSValue* CFDE_CSSDeclaration::ParseColor(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { + +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseColor( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { FX_ARGB dwColor; - if (!FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { + if (!FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) return nullptr; - } - return new CFDE_CSSPrimitiveValue(dwColor); + return pdfium::MakeRetain<CFDE_CSSPrimitiveValue>(dwColor); } -CFDE_CSSValue* CFDE_CSSDeclaration::ParseURI(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen) { +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseURI( + const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen) { int32_t iOffset; if (!FDE_ParseCSSURI(pszValue, &iOffset, &iValueLen)) return nullptr; @@ -266,12 +241,12 @@ CFDE_CSSValue* CFDE_CSSDeclaration::ParseURI(const FDE_CSSPropertyArgs* pArgs, return nullptr; pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); - return pszValue - ? new CFDE_CSSPrimitiveValue(FDE_CSSPrimitiveType::URI, pszValue) - : nullptr; + return pszValue ? pdfium::MakeRetain<CFDE_CSSPrimitiveValue>( + FDE_CSSPrimitiveType::URI, pszValue) + : nullptr; } -CFDE_CSSValue* CFDE_CSSDeclaration::ParseString( +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseString( const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { @@ -283,32 +258,31 @@ CFDE_CSSValue* CFDE_CSSDeclaration::ParseString( return nullptr; pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen); - return pszValue ? new CFDE_CSSPrimitiveValue(FDE_CSSPrimitiveType::String, - pszValue) + return pszValue ? pdfium::MakeRetain<CFDE_CSSPrimitiveValue>( + FDE_CSSPrimitiveType::String, pszValue) : nullptr; } -CFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction( + +CFX_RetainPtr<CFDE_CSSValue> CFDE_CSSDeclaration::ParseFunction( const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen) { - if (pszValue[iValueLen - 1] != ')') { + if (pszValue[iValueLen - 1] != ')') return nullptr; - } + int32_t iStartBracket = 0; while (pszValue[iStartBracket] != '(') { - if (iStartBracket < iValueLen) { - iStartBracket++; - } else { + if (iStartBracket >= iValueLen) return nullptr; - } + iStartBracket++; } - if (iStartBracket == 0) { + if (iStartBracket == 0) return nullptr; - } + const FX_WCHAR* pszFuncName = CopyToLocal(pArgs, pszValue, iStartBracket); pszValue += (iStartBracket + 1); iValueLen -= (iStartBracket + 2); - CFX_ArrayTemplate<CFDE_CSSValue*> argumentArr; + std::vector<CFX_RetainPtr<CFDE_CSSValue>> argumentArr; CFDE_CSSValueListParser parser(pszValue, iValueLen, ','); FDE_CSSPrimitiveType ePrimitiveType; while (parser.NextValue(ePrimitiveType, pszValue, iValueLen)) { @@ -317,17 +291,16 @@ CFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction( const FDE_CSSPropertyValueTable* pPropertyValue = FDE_GetCSSPropertyValueByName(CFX_WideStringC(pszValue, iValueLen)); if (pPropertyValue) { - argumentArr.Add(NewEnumValue(pPropertyValue->eName)); + argumentArr.push_back(NewEnumValue(pPropertyValue->eName)); continue; } - CFDE_CSSValue* pFunctionValue = - ParseFunction(pArgs, pszValue, iValueLen); + auto pFunctionValue = ParseFunction(pArgs, pszValue, iValueLen); if (pFunctionValue) { - argumentArr.Add(pFunctionValue); + argumentArr.push_back(pFunctionValue); continue; } - argumentArr.Add(new CFDE_CSSPrimitiveValue( + argumentArr.push_back(pdfium::MakeRetain<CFDE_CSSPrimitiveValue>( FDE_CSSPrimitiveType::String, CopyToLocal(pArgs, pszValue, iValueLen))); break; @@ -335,23 +308,24 @@ CFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction( case FDE_CSSPrimitiveType::Number: { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, ePrimitiveType)) - argumentArr.Add(NewNumberValue(ePrimitiveType, fValue)); + argumentArr.push_back(NewNumberValue(ePrimitiveType, fValue)); break; } default: - argumentArr.Add(new CFDE_CSSPrimitiveValue( + argumentArr.push_back(pdfium::MakeRetain<CFDE_CSSPrimitiveValue>( FDE_CSSPrimitiveType::String, CopyToLocal(pArgs, pszValue, iValueLen))); break; } } - CFDE_CSSValueList* pArgumentList = new CFDE_CSSValueList(argumentArr); - CFDE_CSSFunction* pFunction = - new CFDE_CSSFunction(pszFuncName, pArgumentList); - return new CFDE_CSSPrimitiveValue(pFunction); + + auto pArgumentList = pdfium::MakeRetain<CFDE_CSSValueList>(argumentArr); + auto pFunction = + pdfium::MakeUnique<CFDE_CSSFunction>(pszFuncName, pArgumentList); + return pdfium::MakeRetain<CFDE_CSSPrimitiveValue>(std::move(pFunction)); } -bool CFDE_CSSDeclaration::ParseValueListProperty( +void CFDE_CSSDeclaration::ParseValueListProperty( const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, @@ -359,23 +333,24 @@ bool CFDE_CSSDeclaration::ParseValueListProperty( FX_WCHAR separator = (pArgs->pProperty->eName == FDE_CSSProperty::FontFamily) ? ',' : ' '; CFDE_CSSValueListParser parser(pszValue, iValueLen, separator); + const uint32_t dwType = pArgs->pProperty->dwType; FDE_CSSPrimitiveType eType; - CFX_ArrayTemplate<CFDE_CSSValue*> list; + std::vector<CFX_RetainPtr<CFDE_CSSValue>> list; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { case FDE_CSSPrimitiveType::Number: if (dwType & FDE_CSSVALUETYPE_MaybeNumber) { FX_FLOAT fValue; if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) - list.Add(NewNumberValue(eType, fValue)); + list.push_back(NewNumberValue(eType, fValue)); } break; case FDE_CSSPrimitiveType::String: if (dwType & FDE_CSSVALUETYPE_MaybeColor) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { - list.Add(new CFDE_CSSPrimitiveValue(dwColor)); + list.push_back(pdfium::MakeRetain<CFDE_CSSPrimitiveValue>(dwColor)); continue; } } @@ -384,21 +359,21 @@ bool CFDE_CSSDeclaration::ParseValueListProperty( FDE_GetCSSPropertyValueByName( CFX_WideStringC(pszValue, iValueLen)); if (pValue) { - list.Add(NewEnumValue(pValue->eName)); + list.push_back(NewEnumValue(pValue->eName)); continue; } } if (dwType & FDE_CSSVALUETYPE_MaybeString) { pszValue = CopyToLocal(pArgs, pszValue, iValueLen); - list.Add(new CFDE_CSSPrimitiveValue(FDE_CSSPrimitiveType::String, - pszValue)); + list.push_back(pdfium::MakeRetain<CFDE_CSSPrimitiveValue>( + FDE_CSSPrimitiveType::String, pszValue)); } break; case FDE_CSSPrimitiveType::RGB: if (dwType & FDE_CSSVALUETYPE_MaybeColor) { FX_ARGB dwColor; if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) { - list.Add(new CFDE_CSSPrimitiveValue(dwColor)); + list.push_back(pdfium::MakeRetain<CFDE_CSSPrimitiveValue>(dwColor)); } } break; @@ -406,75 +381,79 @@ bool CFDE_CSSDeclaration::ParseValueListProperty( break; } } - if (list.GetSize() == 0) { - return false; - } + if (list.empty()) + return; + switch (pArgs->pProperty->eName) { case FDE_CSSProperty::BorderWidth: - return Add4ValuesProperty( - list, bImportant, FDE_CSSProperty::BorderLeftWidth, - FDE_CSSProperty::BorderTopWidth, FDE_CSSProperty::BorderRightWidth, - FDE_CSSProperty::BorderBottomWidth); + Add4ValuesProperty(list, bImportant, FDE_CSSProperty::BorderLeftWidth, + FDE_CSSProperty::BorderTopWidth, + FDE_CSSProperty::BorderRightWidth, + FDE_CSSProperty::BorderBottomWidth); + return; case FDE_CSSProperty::Margin: - return Add4ValuesProperty(list, bImportant, FDE_CSSProperty::MarginLeft, - FDE_CSSProperty::MarginTop, - FDE_CSSProperty::MarginRight, - FDE_CSSProperty::MarginBottom); + Add4ValuesProperty(list, bImportant, FDE_CSSProperty::MarginLeft, + FDE_CSSProperty::MarginTop, + FDE_CSSProperty::MarginRight, + FDE_CSSProperty::MarginBottom); + return; case FDE_CSSProperty::Padding: - return Add4ValuesProperty(list, bImportant, FDE_CSSProperty::PaddingLeft, - FDE_CSSProperty::PaddingTop, - FDE_CSSProperty::PaddingRight, - FDE_CSSProperty::PaddingBottom); + Add4ValuesProperty(list, bImportant, FDE_CSSProperty::PaddingLeft, + FDE_CSSProperty::PaddingTop, + FDE_CSSProperty::PaddingRight, + FDE_CSSProperty::PaddingBottom); + return; default: { - CFDE_CSSValueList* pList = new CFDE_CSSValueList(list); + auto pList = pdfium::MakeRetain<CFDE_CSSValueList>(list); AddPropertyHolder(pArgs->pProperty->eName, pList, bImportant); - return true; - } break; + return; + } } - return false; } -bool CFDE_CSSDeclaration::Add4ValuesProperty( - const CFX_ArrayTemplate<CFDE_CSSValue*>& list, +void CFDE_CSSDeclaration::Add4ValuesProperty( + const std::vector<CFX_RetainPtr<CFDE_CSSValue>>& list, bool bImportant, FDE_CSSProperty eLeft, FDE_CSSProperty eTop, FDE_CSSProperty eRight, FDE_CSSProperty eBottom) { - switch (list.GetSize()) { + switch (list.size()) { case 1: AddPropertyHolder(eLeft, list[0], bImportant); AddPropertyHolder(eTop, list[0], bImportant); AddPropertyHolder(eRight, list[0], bImportant); AddPropertyHolder(eBottom, list[0], bImportant); - return true; + return; case 2: AddPropertyHolder(eLeft, list[1], bImportant); AddPropertyHolder(eTop, list[0], bImportant); AddPropertyHolder(eRight, list[1], bImportant); AddPropertyHolder(eBottom, list[0], bImportant); - return true; + return; case 3: AddPropertyHolder(eLeft, list[1], bImportant); AddPropertyHolder(eTop, list[0], bImportant); AddPropertyHolder(eRight, list[1], bImportant); AddPropertyHolder(eBottom, list[2], bImportant); - return true; + return; case 4: AddPropertyHolder(eLeft, list[3], bImportant); AddPropertyHolder(eTop, list[0], bImportant); AddPropertyHolder(eRight, list[1], bImportant); AddPropertyHolder(eBottom, list[2], bImportant); - return true; + return; default: break; } - return false; } -bool CFDE_CSSDeclaration::ParseBorderProperty(const FX_WCHAR* pszValue, - int32_t iValueLen, - CFDE_CSSValue*& pWidth) const { - pWidth = nullptr; + +bool CFDE_CSSDeclaration::ParseBorderProperty( + const FX_WCHAR* pszValue, + int32_t iValueLen, + CFX_RetainPtr<CFDE_CSSValue>& pWidth) const { + pWidth.Reset(nullptr); + CFDE_CSSValueListParser parser(pszValue, iValueLen, ' '); FDE_CSSPrimitiveType eType; while (parser.NextValue(eType, pszValue, iValueLen)) { @@ -521,17 +500,17 @@ bool CFDE_CSSDeclaration::ParseBorderProperty(const FX_WCHAR* pszValue, return true; } -bool CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, +void CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant) { CFDE_CSSValueListParser parser(pszValue, iValueLen, '/'); - CFDE_CSSPrimitiveValue* pStyle = nullptr; - CFDE_CSSPrimitiveValue* pVariant = nullptr; - CFDE_CSSPrimitiveValue* pWeight = nullptr; - CFDE_CSSPrimitiveValue* pFontSize = nullptr; - CFDE_CSSPrimitiveValue* pLineHeight = nullptr; - CFX_ArrayTemplate<CFDE_CSSValue*> familyList; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> pStyle; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> pVariant; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> pWeight; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> pFontSize; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> pLineHeight; + std::vector<CFX_RetainPtr<CFDE_CSSValue>> familyList; FDE_CSSPrimitiveType eType; while (parser.NextValue(eType, pszValue, iValueLen)) { switch (eType) { @@ -584,16 +563,16 @@ bool CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, } } if (pFontSize) { - familyList.Add(new CFDE_CSSPrimitiveValue( + familyList.push_back(pdfium::MakeRetain<CFDE_CSSPrimitiveValue>( eType, CopyToLocal(pArgs, pszValue, iValueLen))); } parser.m_Separator = ','; - } break; + break; + } case FDE_CSSPrimitiveType::Number: { FX_FLOAT fValue; - if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) { + if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) break; - } if (eType == FDE_CSSPrimitiveType::Number) { switch ((int32_t)fValue) { case 100: @@ -605,9 +584,8 @@ bool CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, case 700: case 800: case 900: - if (!pWeight) { + if (!pWeight) pWeight = NewNumberValue(FDE_CSSPrimitiveType::Number, fValue); - } continue; } } @@ -615,11 +593,13 @@ bool CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, pFontSize = NewNumberValue(eType, fValue); else if (!pLineHeight) pLineHeight = NewNumberValue(eType, fValue); - } break; + break; + } default: break; } } + if (!pStyle) pStyle = NewEnumValue(FDE_CSSPropertyValue::Normal); if (!pVariant) @@ -636,9 +616,16 @@ bool CFDE_CSSDeclaration::ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, AddPropertyHolder(FDE_CSSProperty::FontWeight, pWeight, bImportant); AddPropertyHolder(FDE_CSSProperty::FontSize, pFontSize, bImportant); AddPropertyHolder(FDE_CSSProperty::LineHeight, pLineHeight, bImportant); - if (familyList.GetSize() > 0) { - CFDE_CSSValueList* pList = new CFDE_CSSValueList(familyList); + if (!familyList.empty()) { + auto pList = pdfium::MakeRetain<CFDE_CSSValueList>(familyList); AddPropertyHolder(FDE_CSSProperty::FontFamily, pList, bImportant); } - return true; } + +size_t CFDE_CSSDeclaration::PropertyCountForTesting() const { + return properties_.size(); +} + +FDE_CSSPropertyHolder::FDE_CSSPropertyHolder() {} + +FDE_CSSPropertyHolder::~FDE_CSSPropertyHolder() {} diff --git a/xfa/fde/css/fde_cssdeclaration.h b/xfa/fde/css/fde_cssdeclaration.h index 2dbd7a0622..bb8795c446 100644 --- a/xfa/fde/css/fde_cssdeclaration.h +++ b/xfa/fde/css/fde_cssdeclaration.h @@ -7,23 +7,27 @@ #ifndef XFA_FDE_CSS_FDE_CSSDECLARATION_H_ #define XFA_FDE_CSS_FDE_CSSDECLARATION_H_ +#include <memory> #include <unordered_map> +#include <utility> +#include <vector> #include "xfa/fde/css/fde_cssdatatable.h" class FDE_CSSPropertyHolder { public: + FDE_CSSPropertyHolder(); + ~FDE_CSSPropertyHolder(); + FDE_CSSProperty eProperty; bool bImportant; - CFDE_CSSValue* pValue; - FDE_CSSPropertyHolder* pNext; + CFX_RetainPtr<CFDE_CSSValue> pValue; }; class FDE_CSSCustomProperty { public: const FX_WCHAR* pwsName; const FX_WCHAR* pwsValue; - FDE_CSSCustomProperty* pNext; }; struct FDE_CSSPropertyArgs { @@ -33,81 +37,87 @@ struct FDE_CSSPropertyArgs { class CFDE_CSSDeclaration { public: - CFDE_CSSDeclaration() - : m_pFirstProperty(nullptr), - m_pLastProperty(nullptr), - m_pFirstCustom(nullptr), - m_pLastCustom(nullptr) {} + using const_prop_iterator = + std::vector<std::unique_ptr<FDE_CSSPropertyHolder>>::const_iterator; + using const_custom_iterator = + std::vector<std::unique_ptr<FDE_CSSCustomProperty>>::const_iterator; + + CFDE_CSSDeclaration(); + ~CFDE_CSSDeclaration(); CFDE_CSSValue* GetProperty(FDE_CSSProperty eProperty, bool& bImportant) const; - FX_POSITION GetStartPosition() const; - void GetNextProperty(FX_POSITION& pos, - FDE_CSSProperty& eProperty, - CFDE_CSSValue*& pValue, - bool& bImportant) const; - FX_POSITION GetStartCustom() const; - void GetNextCustom(FX_POSITION& pos, - CFX_WideString& wsName, - CFX_WideString& wsValue) const; - bool AddProperty(const FDE_CSSPropertyArgs* pArgs, + + const_prop_iterator begin() const { return properties_.begin(); } + const_prop_iterator end() const { return properties_.end(); } + + const_custom_iterator custom_begin() const { + return custom_properties_.begin(); + } + const_custom_iterator custom_end() const { return custom_properties_.end(); } + + bool empty() const { return properties_.empty(); } + + void AddProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen); - bool AddProperty(const FDE_CSSPropertyArgs* pArgs, + void AddProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszName, int32_t iNameLen, const FX_WCHAR* pszValue, int32_t iValueLen); + size_t PropertyCountForTesting() const; + protected: - bool ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, + void ParseFontProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant); bool ParseBorderProperty(const FX_WCHAR* pszValue, int32_t iValueLen, - CFDE_CSSValue*& pWidth) const; - bool ParseValueListProperty(const FDE_CSSPropertyArgs* pArgs, + CFX_RetainPtr<CFDE_CSSValue>& pWidth) const; + void ParseValueListProperty(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen, bool bImportant); - bool Add4ValuesProperty(const CFX_ArrayTemplate<CFDE_CSSValue*>& list, + void Add4ValuesProperty(const std::vector<CFX_RetainPtr<CFDE_CSSValue>>& list, bool bImportant, FDE_CSSProperty eLeft, FDE_CSSProperty eTop, FDE_CSSProperty eRight, FDE_CSSProperty eBottom); - CFDE_CSSValue* ParseNumber(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFDE_CSSValue* ParseEnum(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFDE_CSSValue* ParseColor(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFDE_CSSValue* ParseURI(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFDE_CSSValue* ParseString(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); - CFDE_CSSValue* ParseFunction(const FDE_CSSPropertyArgs* pArgs, - const FX_WCHAR* pszValue, - int32_t iValueLen); + CFX_RetainPtr<CFDE_CSSValue> ParseNumber(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr<CFDE_CSSValue> ParseEnum(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr<CFDE_CSSValue> ParseColor(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr<CFDE_CSSValue> ParseURI(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr<CFDE_CSSValue> ParseString(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); + CFX_RetainPtr<CFDE_CSSValue> ParseFunction(const FDE_CSSPropertyArgs* pArgs, + const FX_WCHAR* pszValue, + int32_t iValueLen); const FX_WCHAR* CopyToLocal(const FDE_CSSPropertyArgs* pArgs, const FX_WCHAR* pszValue, int32_t iValueLen); void AddPropertyHolder(FDE_CSSProperty eProperty, - CFDE_CSSValue* pValue, + CFX_RetainPtr<CFDE_CSSValue> pValue, bool bImportant); - CFDE_CSSPrimitiveValue* NewNumberValue(FDE_CSSPrimitiveType eUnit, - FX_FLOAT fValue) const; - CFDE_CSSPrimitiveValue* NewEnumValue(FDE_CSSPropertyValue eValue) const; - - FDE_CSSPropertyHolder* m_pFirstProperty; - FDE_CSSPropertyHolder* m_pLastProperty; - FDE_CSSCustomProperty* m_pFirstCustom; - FDE_CSSCustomProperty* m_pLastCustom; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> NewNumberValue( + FDE_CSSPrimitiveType eUnit, + FX_FLOAT fValue) const; + CFX_RetainPtr<CFDE_CSSPrimitiveValue> NewEnumValue( + FDE_CSSPropertyValue eValue) const; + + std::vector<std::unique_ptr<FDE_CSSPropertyHolder>> properties_; + std::vector<std::unique_ptr<FDE_CSSCustomProperty>> custom_properties_; }; #endif // XFA_FDE_CSS_FDE_CSSDECLARATION_H_ diff --git a/xfa/fde/css/fde_cssstyleselector.cpp b/xfa/fde/css/fde_cssstyleselector.cpp index 5e981d96eb..e6ee18f245 100644 --- a/xfa/fde/css/fde_cssstyleselector.cpp +++ b/xfa/fde/css/fde_cssstyleselector.cpp @@ -280,14 +280,15 @@ void CFDE_CSSStyleSelector::ApplyDeclarations( int32_t iDeclCount, CFDE_CSSComputedStyle* pDestStyle) { CFDE_CSSComputedStyle* pComputedStyle = pDestStyle; - CFDE_CSSValue* pVal; - bool bImportant; + int32_t i; if (bPriority) { CFDE_CSSValue* pLastest = nullptr; CFDE_CSSValue* pImportant = nullptr; for (i = 0; i < iDeclCount; ++i) { - pVal = ppDeclArray[i]->GetProperty(FDE_CSSProperty::FontSize, bImportant); + bool bImportant; + CFDE_CSSValue* pVal = + ppDeclArray[i]->GetProperty(FDE_CSSProperty::FontSize, bImportant); if (!pVal) continue; @@ -304,39 +305,33 @@ void CFDE_CSSStyleSelector::ApplyDeclarations( } else { CFX_ArrayTemplate<CFDE_CSSDeclaration*> importants; const CFDE_CSSDeclaration* pDecl = nullptr; - FDE_CSSProperty eProp; - FX_POSITION pos; + for (i = 0; i < iDeclCount; ++i) { pDecl = ppDeclArray[i]; - pos = pDecl->GetStartPosition(); - while (pos) { - pDecl->GetNextProperty(pos, eProp, pVal, bImportant); - if (eProp == FDE_CSSProperty::FontSize) { + for (auto it = pDecl->begin(); it != pDecl->end(); it++) { + if ((*it)->eProperty == FDE_CSSProperty::FontSize) continue; - } else if (!bImportant) { - ApplyProperty(eProp, pVal, pComputedStyle); + if (!(*it)->bImportant) { + ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); } else if (importants.GetSize() == 0 || importants[importants.GetUpperBound()] != pDecl) { importants.Add(const_cast<CFDE_CSSDeclaration*>(pDecl)); } } } + iDeclCount = importants.GetSize(); for (i = 0; i < iDeclCount; ++i) { pDecl = importants[i]; - pos = pDecl->GetStartPosition(); - while (pos) { - pDecl->GetNextProperty(pos, eProp, pVal, bImportant); - if (bImportant && eProp != FDE_CSSProperty::FontSize) { - ApplyProperty(eProp, pVal, pComputedStyle); - } + + for (auto it = pDecl->begin(); it != pDecl->end(); it++) { + if ((*it)->bImportant && (*it)->eProperty != FDE_CSSProperty::FontSize) + ApplyProperty((*it)->eProperty, (*it)->pValue.Get(), pComputedStyle); } } - CFX_WideString wsName, wsValue; - pos = pDecl->GetStartCustom(); - while (pos) { - pDecl->GetNextCustom(pos, wsName, wsValue); - pComputedStyle->AddCustomStyle(wsName, wsValue); + + for (auto it = pDecl->custom_begin(); it != pDecl->custom_end(); it++) { + pComputedStyle->AddCustomStyle((*it)->pwsName, (*it)->pwsValue); } } } diff --git a/xfa/fde/css/fde_cssstylesheet.cpp b/xfa/fde/css/fde_cssstylesheet.cpp index a5ac0c07cc..a3667b202f 100644 --- a/xfa/fde/css/fde_cssstylesheet.cpp +++ b/xfa/fde/css/fde_cssstylesheet.cpp @@ -9,15 +9,50 @@ #include <memory> #include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" #include "xfa/fde/css/fde_cssdatatable.h" #include "xfa/fde/css/fde_csssyntax.h" #include "xfa/fgas/crt/fgas_codepage.h" +namespace { + +bool IsCSSChar(FX_WCHAR wch) { + return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z'); +} + +int32_t GetCSSPseudoLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { + ASSERT(*psz == ':'); + const FX_WCHAR* pStart = psz; + while (psz < pEnd) { + FX_WCHAR wch = *psz; + if (IsCSSChar(wch) || wch == ':') + ++psz; + else + break; + } + return psz - pStart; +} + +int32_t GetCSSNameLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { + const FX_WCHAR* pStart = psz; + while (psz < pEnd) { + FX_WCHAR wch = *psz; + if (IsCSSChar(wch) || (wch >= '0' && wch <= '9') || wch == '_' || + wch == '-') { + ++psz; + } else { + break; + } + } + return psz - pStart; +} + +} // namespace + CFDE_CSSStyleSheet::CFDE_CSSStyleSheet() : m_wCodePage(FX_CODEPAGE_UTF8), m_wRefCount(1), - m_dwMediaList(FDE_CSSMEDIATYPE_ALL), - m_RuleArray(100) { + m_dwMediaList(FDE_CSSMEDIATYPE_ALL) { ASSERT(m_dwMediaList > 0); } @@ -26,25 +61,8 @@ CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet() { } void CFDE_CSSStyleSheet::Reset() { - for (int32_t i = m_RuleArray.GetSize() - 1; i >= 0; --i) { - CFDE_CSSRule* pRule = m_RuleArray.GetAt(i); - switch (pRule->GetType()) { - case FDE_CSSRuleType::Style: - static_cast<CFDE_CSSStyleRule*>(pRule)->~CFDE_CSSStyleRule(); - break; - case FDE_CSSRuleType::Media: - static_cast<CFDE_CSSMediaRule*>(pRule)->~CFDE_CSSMediaRule(); - break; - case FDE_CSSRuleType::FontFace: - static_cast<CFDE_CSSFontFaceRule*>(pRule)->~CFDE_CSSFontFaceRule(); - break; - default: - ASSERT(false); - break; - } - } - m_RuleArray.RemoveAll(false); - m_Selectors.RemoveAll(); + m_RuleArray.clear(); + m_Selectors.clear(); m_StringCache.clear(); } @@ -73,11 +91,11 @@ uint16_t CFDE_CSSStyleSheet::GetCodePage() const { } int32_t CFDE_CSSStyleSheet::CountRules() const { - return m_RuleArray.GetSize(); + return pdfium::CollectionSize<int32_t>(m_RuleArray); } CFDE_CSSRule* CFDE_CSSStyleSheet::GetRule(int32_t index) { - return m_RuleArray.GetAt(index); + return m_RuleArray[index].get(); } bool CFDE_CSSStyleSheet::LoadFromBuffer(const FX_WCHAR* pBuffer, @@ -97,13 +115,13 @@ bool CFDE_CSSStyleSheet::LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax) { do { switch (eStatus = pSyntax->DoSyntaxParse()) { case FDE_CSSSyntaxStatus::StyleRule: - eStatus = LoadStyleRule(pSyntax, m_RuleArray); + eStatus = LoadStyleRule(pSyntax, &m_RuleArray); break; case FDE_CSSSyntaxStatus::MediaRule: eStatus = LoadMediaRule(pSyntax); break; case FDE_CSSSyntaxStatus::FontFaceRule: - eStatus = LoadFontFaceRule(pSyntax, m_RuleArray); + eStatus = LoadFontFaceRule(pSyntax, &m_RuleArray); break; case FDE_CSSSyntaxStatus::ImportRule: eStatus = LoadImportRule(pSyntax); @@ -115,7 +133,7 @@ bool CFDE_CSSStyleSheet::LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax) { break; } } while (eStatus >= FDE_CSSSyntaxStatus::None); - m_Selectors.RemoveAll(); + m_Selectors.clear(); m_StringCache.clear(); return eStatus != FDE_CSSSyntaxStatus::Error; } @@ -137,7 +155,7 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadMediaRule( case FDE_CSSSyntaxStatus::StyleRule: if (pMediaRule) { FDE_CSSSyntaxStatus eStatus = - LoadStyleRule(pSyntax, pMediaRule->GetArray()); + LoadStyleRule(pSyntax, &pMediaRule->GetArray()); if (eStatus < FDE_CSSSyntaxStatus::None) { return eStatus; } @@ -147,8 +165,10 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadMediaRule( break; case FDE_CSSSyntaxStatus::DeclOpen: if ((dwMediaList & m_dwMediaList) > 0 && !pMediaRule) { - pMediaRule = new CFDE_CSSMediaRule(dwMediaList); - m_RuleArray.Add(pMediaRule); + m_RuleArray.push_back( + pdfium::MakeUnique<CFDE_CSSMediaRule>(dwMediaList)); + pMediaRule = + static_cast<CFDE_CSSMediaRule*>(m_RuleArray.back().get()); } break; case FDE_CSSSyntaxStatus::DeclClose: @@ -164,8 +184,9 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadMediaRule( FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( CFDE_CSSSyntaxParser* pSyntax, - CFX_MassArrayTemplate<CFDE_CSSRule*>& ruleArray) { - m_Selectors.RemoveAt(0, m_Selectors.GetSize()); + std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray) { + m_Selectors.clear(); + CFDE_CSSStyleRule* pStyleRule = nullptr; const FX_WCHAR* pszValue = nullptr; int32_t iValueLen = 0; @@ -177,10 +198,9 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( switch (pSyntax->DoSyntaxParse()) { case FDE_CSSSyntaxStatus::Selector: { pszValue = pSyntax->GetCurrentString(iValueLen); - CFDE_CSSSelector* pSelector = - CFDE_CSSSelector::FromString(pszValue, iValueLen); + auto pSelector = CFDE_CSSSelector::FromString(pszValue, iValueLen); if (pSelector) - m_Selectors.Add(pSelector); + m_Selectors.push_back(std::move(pSelector)); } break; case FDE_CSSSyntaxStatus::PropertyName: pszValue = pSyntax->GetCurrentString(iValueLen); @@ -206,19 +226,20 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( } break; case FDE_CSSSyntaxStatus::DeclOpen: - if (!pStyleRule && m_Selectors.GetSize() > 0) { - pStyleRule = new CFDE_CSSStyleRule; + if (!pStyleRule && !m_Selectors.empty()) { + auto rule = pdfium::MakeUnique<CFDE_CSSStyleRule>(); + pStyleRule = rule.get(); pStyleRule->SetSelector(m_Selectors); - ruleArray.Add(pStyleRule); + ruleArray->push_back(std::move(rule)); } else { SkipRuleSet(pSyntax); return FDE_CSSSyntaxStatus::None; } break; case FDE_CSSSyntaxStatus::DeclClose: - if (pStyleRule && !pStyleRule->GetDeclImp().GetStartPosition()) { - pStyleRule->~CFDE_CSSStyleRule(); - ruleArray.RemoveLast(1); + if (pStyleRule && pStyleRule->GetDeclImp().empty()) { + ruleArray->pop_back(); + pStyleRule = nullptr; } return FDE_CSSSyntaxStatus::None; case FDE_CSSSyntaxStatus::EOS: @@ -232,7 +253,7 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadStyleRule( FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadFontFaceRule( CFDE_CSSSyntaxParser* pSyntax, - CFX_MassArrayTemplate<CFDE_CSSRule*>& ruleArray) { + std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray) { CFDE_CSSFontFaceRule* pFontFaceRule = nullptr; const FX_WCHAR* pszValue = nullptr; int32_t iValueLen = 0; @@ -257,8 +278,9 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::LoadFontFaceRule( break; case FDE_CSSSyntaxStatus::DeclOpen: if (!pFontFaceRule) { - pFontFaceRule = new CFDE_CSSFontFaceRule; - ruleArray.Add(pFontFaceRule); + auto rule = pdfium::MakeUnique<CFDE_CSSFontFaceRule>(); + pFontFaceRule = rule.get(); + ruleArray->push_back(std::move(rule)); } break; case FDE_CSSSyntaxStatus::DeclClose: @@ -316,9 +338,10 @@ FDE_CSSSyntaxStatus CFDE_CSSStyleSheet::SkipRuleSet( CFDE_CSSStyleRule::CFDE_CSSStyleRule() : CFDE_CSSRule(FDE_CSSRuleType::Style), - m_ppSelector(nullptr), m_iSelectors(0) {} +CFDE_CSSStyleRule::~CFDE_CSSStyleRule() {} + int32_t CFDE_CSSStyleRule::CountSelectorLists() const { return m_iSelectors; } @@ -332,77 +355,28 @@ CFDE_CSSDeclaration* CFDE_CSSStyleRule::GetDeclaration() { } void CFDE_CSSStyleRule::SetSelector( - const CFX_ArrayTemplate<CFDE_CSSSelector*>& list) { - ASSERT(!m_ppSelector); - m_iSelectors = list.GetSize(); - m_ppSelector = static_cast<CFDE_CSSSelector**>( - FX_Alloc(CFDE_CSSSelector*, m_iSelectors)); - for (int32_t i = 0; i < m_iSelectors; ++i) { - m_ppSelector[i] = list.GetAt(i); - } + const std::vector<std::unique_ptr<CFDE_CSSSelector>>& list) { + ASSERT(m_ppSelector.empty()); + + for (const auto& item : list) + m_ppSelector.push_back(item.get()); } CFDE_CSSMediaRule::CFDE_CSSMediaRule(uint32_t dwMediaList) - : CFDE_CSSRule(FDE_CSSRuleType::Media), - m_dwMediaList(dwMediaList), - m_RuleArray(100) {} - -CFDE_CSSMediaRule::~CFDE_CSSMediaRule() { - for (int32_t i = m_RuleArray.GetSize() - 1; i >= 0; --i) { - CFDE_CSSRule* pRule = m_RuleArray.GetAt(i); - switch (pRule->GetType()) { - case FDE_CSSRuleType::Style: - static_cast<CFDE_CSSStyleRule*>(pRule)->~CFDE_CSSStyleRule(); - break; - default: - ASSERT(false); - break; - } - } -} + : CFDE_CSSRule(FDE_CSSRuleType::Media), m_dwMediaList(dwMediaList) {} + +CFDE_CSSMediaRule::~CFDE_CSSMediaRule() {} uint32_t CFDE_CSSMediaRule::GetMediaList() const { return m_dwMediaList; } int32_t CFDE_CSSMediaRule::CountRules() const { - return m_RuleArray.GetSize(); + return pdfium::CollectionSize<int32_t>(m_RuleArray); } CFDE_CSSRule* CFDE_CSSMediaRule::GetRule(int32_t index) { - return m_RuleArray.GetAt(index); -} - -bool FDE_IsCSSChar(FX_WCHAR wch) { - return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z'); -} - -int32_t FDE_GetCSSPseudoLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { - ASSERT(*psz == ':'); - const FX_WCHAR* pStart = psz; - while (psz < pEnd) { - FX_WCHAR wch = *psz; - if (FDE_IsCSSChar(wch) || wch == ':') { - ++psz; - } else { - break; - } - } - return psz - pStart; -} - -int32_t FDE_GetCSSNameLen(const FX_WCHAR* psz, const FX_WCHAR* pEnd) { - const FX_WCHAR* pStart = psz; - while (psz < pEnd) { - FX_WCHAR wch = *psz; - if (FDE_IsCSSChar(wch) || (wch >= '0' && wch <= '9') || wch == '_' || - wch == '-') { - ++psz; - } else { - break; - } - } - return psz - pStart; + return m_RuleArray[index].get(); } CFDE_CSSSelector::CFDE_CSSSelector(FDE_CSSSelectorType eType, @@ -410,8 +384,9 @@ CFDE_CSSSelector::CFDE_CSSSelector(FDE_CSSSelectorType eType, int32_t iLen, bool bIgnoreCase) : m_eType(eType), - m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)), - m_pNext(nullptr) {} + m_dwHash(FX_HashCode_GetW(CFX_WideStringC(psz, iLen), bIgnoreCase)) {} + +CFDE_CSSSelector::~CFDE_CSSSelector() {} FDE_CSSSelectorType CFDE_CSSSelector::GetType() const { return m_eType; @@ -422,10 +397,14 @@ uint32_t CFDE_CSSSelector::GetNameHash() const { } CFDE_CSSSelector* CFDE_CSSSelector::GetNextSelector() const { - return m_pNext; + return m_pNext.get(); +} + +std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::ReleaseNextSelector() { + return std::move(m_pNext); } -CFDE_CSSSelector* CFDE_CSSSelector::FromString( +std::unique_ptr<CFDE_CSSSelector> CFDE_CSSSelector::FromString( const FX_WCHAR* psz, int32_t iLen) { ASSERT(psz && iLen > 0); @@ -440,72 +419,68 @@ CFDE_CSSSelector* CFDE_CSSSelector::FromString( return nullptr; } } - CFDE_CSSSelector* pFirst = nullptr; + + std::unique_ptr<CFDE_CSSSelector> pFirst = nullptr; CFDE_CSSSelector* pLast = nullptr; - CFDE_CSSSelector* pPseudoFirst = nullptr; + std::unique_ptr<CFDE_CSSSelector> pPseudoFirst = nullptr; CFDE_CSSSelector* pPseudoLast = nullptr; + for (psz = pStart; psz < pEnd;) { FX_WCHAR wch = *psz; if (wch == '.' || wch == '#') { if (psz == pStart || psz[-1] == ' ') { - CFDE_CSSSelector* p = - new CFDE_CSSSelector(FDE_CSSSelectorType::Element, L"*", 1, true); - if (!p) - return nullptr; + auto p = pdfium::MakeUnique<CFDE_CSSSelector>( + FDE_CSSSelectorType::Element, L"*", 1, true); if (pFirst) { pFirst->SetType(FDE_CSSSelectorType::Descendant); - p->SetNext(pFirst); + p->SetNext(std::move(pFirst)); } - pFirst = pLast = p; + pFirst = std::move(p); + pLast = pFirst.get(); } ASSERT(pLast); - int32_t iNameLen = FDE_GetCSSNameLen(++psz, pEnd); - if (iNameLen == 0) { + + int32_t iNameLen = GetCSSNameLen(++psz, pEnd); + if (iNameLen == 0) return nullptr; - } + FDE_CSSSelectorType eType = wch == '.' ? FDE_CSSSelectorType::Class : FDE_CSSSelectorType::ID; - CFDE_CSSSelector* p = new CFDE_CSSSelector(eType, psz, iNameLen, false); - if (!p) - return nullptr; + auto p = + pdfium::MakeUnique<CFDE_CSSSelector>(eType, psz, iNameLen, false); - p->SetNext(pLast->GetNextSelector()); - pLast->SetNext(p); - pLast = p; + p->SetNext(pLast->ReleaseNextSelector()); + pLast->SetNext(std::move(p)); + pLast = pLast->GetNextSelector(); psz += iNameLen; - } else if (FDE_IsCSSChar(wch) || wch == '*') { - int32_t iNameLen = wch == '*' ? 1 : FDE_GetCSSNameLen(psz, pEnd); - if (iNameLen == 0) { - return nullptr; - } - CFDE_CSSSelector* p = new CFDE_CSSSelector(FDE_CSSSelectorType::Element, - psz, iNameLen, true); - if (!p) + } else if (IsCSSChar(wch) || wch == '*') { + int32_t iNameLen = wch == '*' ? 1 : GetCSSNameLen(psz, pEnd); + if (iNameLen == 0) return nullptr; + auto p = pdfium::MakeUnique<CFDE_CSSSelector>( + FDE_CSSSelectorType::Element, psz, iNameLen, true); if (pFirst) { pFirst->SetType(FDE_CSSSelectorType::Descendant); - p->SetNext(pFirst); + p->SetNext(std::move(pFirst)); } - pFirst = p; - pLast = p; + pFirst = std::move(p); + pLast = pFirst.get(); psz += iNameLen; } else if (wch == ':') { - int32_t iNameLen = FDE_GetCSSPseudoLen(psz, pEnd); - if (iNameLen == 0) { - return nullptr; - } - CFDE_CSSSelector* p = new CFDE_CSSSelector(FDE_CSSSelectorType::Pseudo, - psz, iNameLen, true); - if (!p) + int32_t iNameLen = GetCSSPseudoLen(psz, pEnd); + if (iNameLen == 0) return nullptr; + auto p = pdfium::MakeUnique<CFDE_CSSSelector>(FDE_CSSSelectorType::Pseudo, + psz, iNameLen, true); + CFDE_CSSSelector* ptr = p.get(); if (pPseudoFirst) - pPseudoLast->SetNext(p); + pPseudoLast->SetNext(std::move(p)); else - pPseudoFirst = p; - pPseudoLast = p; + pPseudoFirst = std::move(p); + pPseudoLast = ptr; psz += iNameLen; } else if (wch == ' ') { psz++; @@ -516,7 +491,7 @@ CFDE_CSSSelector* CFDE_CSSSelector::FromString( if (!pPseudoFirst) return pFirst; - pPseudoLast->SetNext(pFirst); + pPseudoLast->SetNext(std::move(pFirst)); return pPseudoFirst; } diff --git a/xfa/fde/css/fde_cssstylesheet.h b/xfa/fde/css/fde_cssstylesheet.h index 8cedb76526..7acccd5776 100644 --- a/xfa/fde/css/fde_cssstylesheet.h +++ b/xfa/fde/css/fde_cssstylesheet.h @@ -9,6 +9,8 @@ #include <memory> #include <unordered_map> +#include <utility> +#include <vector> #include "core/fxcrt/fx_ext.h" #include "xfa/fde/css/cfde_cssrule.h" @@ -18,40 +20,46 @@ class CFDE_CSSSyntaxParser; class CFDE_CSSSelector { public: + static std::unique_ptr<CFDE_CSSSelector> FromString(const FX_WCHAR* psz, + int32_t iLen); + CFDE_CSSSelector(FDE_CSSSelectorType eType, const FX_WCHAR* psz, int32_t iLen, bool bIgnoreCase); + ~CFDE_CSSSelector(); - virtual FDE_CSSSelectorType GetType() const; - virtual uint32_t GetNameHash() const; - virtual CFDE_CSSSelector* GetNextSelector() const; - - static CFDE_CSSSelector* FromString(const FX_WCHAR* psz, int32_t iLen); + FDE_CSSSelectorType GetType() const; + uint32_t GetNameHash() const; + CFDE_CSSSelector* GetNextSelector() const; + std::unique_ptr<CFDE_CSSSelector> ReleaseNextSelector(); - void SetNext(CFDE_CSSSelector* pNext) { m_pNext = pNext; } + void SetNext(std::unique_ptr<CFDE_CSSSelector> pNext) { + m_pNext = std::move(pNext); + } protected: void SetType(FDE_CSSSelectorType eType) { m_eType = eType; } FDE_CSSSelectorType m_eType; uint32_t m_dwHash; - CFDE_CSSSelector* m_pNext; + std::unique_ptr<CFDE_CSSSelector> m_pNext; }; class CFDE_CSSStyleRule : public CFDE_CSSRule { public: CFDE_CSSStyleRule(); + ~CFDE_CSSStyleRule() override; int32_t CountSelectorLists() const; CFDE_CSSSelector* GetSelectorList(int32_t index) const; CFDE_CSSDeclaration* GetDeclaration(); CFDE_CSSDeclaration& GetDeclImp() { return m_Declaration; } - void SetSelector(const CFX_ArrayTemplate<CFDE_CSSSelector*>& list); + void SetSelector(const std::vector<std::unique_ptr<CFDE_CSSSelector>>& list); private: CFDE_CSSDeclaration m_Declaration; - CFDE_CSSSelector** m_ppSelector; + std::vector<CFDE_CSSSelector*> m_ppSelector; // Owned by the stylessheet. int32_t m_iSelectors; }; @@ -64,11 +72,11 @@ class CFDE_CSSMediaRule : public CFDE_CSSRule { int32_t CountRules() const; CFDE_CSSRule* GetRule(int32_t index); - CFX_MassArrayTemplate<CFDE_CSSRule*>& GetArray() { return m_RuleArray; } + std::vector<std::unique_ptr<CFDE_CSSRule>>& GetArray() { return m_RuleArray; } protected: uint32_t m_dwMediaList; - CFX_MassArrayTemplate<CFDE_CSSRule*> m_RuleArray; + std::vector<std::unique_ptr<CFDE_CSSRule>> m_RuleArray; }; class CFDE_CSSFontFaceRule : public CFDE_CSSRule { @@ -104,21 +112,21 @@ class CFDE_CSSStyleSheet : public IFX_Retainable { bool LoadFromSyntax(CFDE_CSSSyntaxParser* pSyntax); FDE_CSSSyntaxStatus LoadStyleRule( CFDE_CSSSyntaxParser* pSyntax, - CFX_MassArrayTemplate<CFDE_CSSRule*>& ruleArray); + std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray); FDE_CSSSyntaxStatus LoadImportRule(CFDE_CSSSyntaxParser* pSyntax); FDE_CSSSyntaxStatus LoadPageRule(CFDE_CSSSyntaxParser* pSyntax); FDE_CSSSyntaxStatus LoadMediaRule(CFDE_CSSSyntaxParser* pSyntax); FDE_CSSSyntaxStatus LoadFontFaceRule( CFDE_CSSSyntaxParser* pSyntax, - CFX_MassArrayTemplate<CFDE_CSSRule*>& ruleArray); + std::vector<std::unique_ptr<CFDE_CSSRule>>* ruleArray); FDE_CSSSyntaxStatus SkipRuleSet(CFDE_CSSSyntaxParser* pSyntax); uint16_t m_wCodePage; uint16_t m_wRefCount; uint32_t m_dwMediaList; - CFX_MassArrayTemplate<CFDE_CSSRule*> m_RuleArray; + std::vector<std::unique_ptr<CFDE_CSSRule>> m_RuleArray; CFX_WideString m_szUrl; - CFX_ArrayTemplate<CFDE_CSSSelector*> m_Selectors; + std::vector<std::unique_ptr<CFDE_CSSSelector>> m_Selectors; std::unordered_map<uint32_t, FX_WCHAR*> m_StringCache; }; |