From 68c77592f25f9173d2166fa01fb34b4155f4cfcb Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Mon, 20 Nov 2017 20:27:43 +0000 Subject: Remove {Set|Get|Try}Object methods The CJX_Node::{Set|Get|Try}Object methods are used to set CXFA_WidgetData and CXFA_Node objects into the CJX_Node. This is stored in the node as void* data and custom delete methods are passed when needed. Instead, this CL just stores the two types of things we need on the CJX_Node and returns the correct types. This uses a bit more space on the CJX_Node, but it makes the code a lot clearer and simpler. Change-Id: I8546ea6456a1c1f5f8b602a6a420a0e85f3fac29 Reviewed-on: https://pdfium-review.googlesource.com/18570 Reviewed-by: Tom Sepez Commit-Queue: dsinclair --- xfa/fxfa/cxfa_ffnotify.cpp | 15 ++-- xfa/fxfa/cxfa_widgetacc.h | 2 +- xfa/fxfa/parser/cxfa_datadata.cpp | 4 + xfa/fxfa/parser/cxfa_datadata.h | 3 +- xfa/fxfa/parser/cxfa_document.cpp | 4 + xfa/fxfa/parser/cxfa_filldata.h | 2 +- xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp | 3 +- xfa/fxfa/parser/cxfa_layoutpagemgr.cpp | 3 +- xfa/fxfa/parser/cxfa_node.cpp | 113 +++++++++++------------- xfa/fxfa/parser/cxfa_node.h | 3 +- xfa/fxfa/parser/xfa_document_datamerger_imp.cpp | 8 +- 11 files changed, 79 insertions(+), 81 deletions(-) (limited to 'xfa/fxfa') diff --git a/xfa/fxfa/cxfa_ffnotify.cpp b/xfa/fxfa/cxfa_ffnotify.cpp index 068cf70591..7e66e4e888 100644 --- a/xfa/fxfa/cxfa_ffnotify.cpp +++ b/xfa/fxfa/cxfa_ffnotify.cpp @@ -6,6 +6,9 @@ #include "xfa/fxfa/cxfa_ffnotify.h" +#include +#include + #include "xfa/fxfa/cxfa_ffapp.h" #include "xfa/fxfa/cxfa_ffarc.h" #include "xfa/fxfa/cxfa_ffbarcode.h" @@ -52,13 +55,6 @@ CXFA_FFComboBox* ToComboBox(CXFA_FFWidget* widget) { } // namespace -static void XFA_FFDeleteWidgetAcc(void* pData) { - delete ToWidgetAcc(pData); -} - -static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = { - XFA_FFDeleteWidgetAcc, nullptr}; - CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc) : m_pDoc(pDoc) {} CXFA_FFNotify::~CXFA_FFNotify() {} @@ -345,9 +341,8 @@ void CXFA_FFNotify::OnNodeReady(CXFA_Node* pNode) { XFA_Element eType = pNode->GetElementType(); if (XFA_IsCreateWidget(eType)) { - CXFA_WidgetAcc* pAcc = new CXFA_WidgetAcc(pDocView, pNode); - pNode->JSNode()->SetObject(XFA_Attribute::WidgetData, pAcc, - &gs_XFADeleteWidgetAcc); + pNode->JSNode()->SetWidgetData( + pdfium::MakeUnique(pDocView, pNode)); return; } switch (eType) { diff --git a/xfa/fxfa/cxfa_widgetacc.h b/xfa/fxfa/cxfa_widgetacc.h index 600cc1afed..6cb2e7f01d 100644 --- a/xfa/fxfa/cxfa_widgetacc.h +++ b/xfa/fxfa/cxfa_widgetacc.h @@ -36,7 +36,7 @@ class IXFA_AppProvider; class CXFA_WidgetAcc : public CXFA_WidgetData { public: CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode); - ~CXFA_WidgetAcc(); + ~CXFA_WidgetAcc() override; void ResetData(); diff --git a/xfa/fxfa/parser/cxfa_datadata.cpp b/xfa/fxfa/parser/cxfa_datadata.cpp index cf813fc017..b08801a386 100644 --- a/xfa/fxfa/parser/cxfa_datadata.cpp +++ b/xfa/fxfa/parser/cxfa_datadata.cpp @@ -61,6 +61,10 @@ FX_ARGB CXFA_DataData::ToColor(const WideStringView& wsValue) { return (0xff << 24) | (r << 16) | (g << 8) | b; } +CXFA_DataData::CXFA_DataData(CXFA_Node* pNode) : m_pNode(pNode) {} + +CXFA_DataData::~CXFA_DataData() {} + XFA_Element CXFA_DataData::GetElementType() const { return m_pNode ? m_pNode->GetElementType() : XFA_Element::Unknown; } diff --git a/xfa/fxfa/parser/cxfa_datadata.h b/xfa/fxfa/parser/cxfa_datadata.h index 5be86c28ab..a05b5024fe 100644 --- a/xfa/fxfa/parser/cxfa_datadata.h +++ b/xfa/fxfa/parser/cxfa_datadata.h @@ -17,7 +17,8 @@ class CXFA_DataData { public: static FX_ARGB ToColor(const WideStringView& wsValue); - explicit CXFA_DataData(CXFA_Node* pNode) : m_pNode(pNode) {} + explicit CXFA_DataData(CXFA_Node* pNode); + virtual ~CXFA_DataData(); explicit operator bool() const { return !!m_pNode; } CXFA_Node* GetNode() const { return m_pNode; } diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp index 44fc9089c1..edae6c3837 100644 --- a/xfa/fxfa/parser/cxfa_document.cpp +++ b/xfa/fxfa/parser/cxfa_document.cpp @@ -94,6 +94,10 @@ CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser) } CXFA_Document::~CXFA_Document() { + // Remove all the bindings before freeing the node as the ownership is wonky. + if (m_pRootNode) + m_pRootNode->ReleaseBindingNodes(); + delete m_pRootNode; PurgeNodes(); } diff --git a/xfa/fxfa/parser/cxfa_filldata.h b/xfa/fxfa/parser/cxfa_filldata.h index 290e0b72e1..7faca4a95a 100644 --- a/xfa/fxfa/parser/cxfa_filldata.h +++ b/xfa/fxfa/parser/cxfa_filldata.h @@ -16,7 +16,7 @@ class CXFA_Node; class CXFA_FillData : public CXFA_DataData { public: explicit CXFA_FillData(CXFA_Node* pNode); - ~CXFA_FillData(); + ~CXFA_FillData() override; int32_t GetPresence(); FX_ARGB GetColor(bool bText = false); diff --git a/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp b/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp index cd6e57ce02..bf63a2a56c 100644 --- a/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp +++ b/xfa/fxfa/parser/cxfa_itemlayoutprocessor.cpp @@ -2106,8 +2106,7 @@ void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode) { CXFA_Node* pBindNode = pNode->GetBindData(); if (pBindNode) { pBindNode->RemoveBindItem(pNode); - pNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, - nullptr); + pNode->JSNode()->SetBindingNode(nullptr); } } pNode->SetFlag(XFA_NodeFlag_UnusedNode, true); diff --git a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp index 72f5594982..7a013a9a9b 100644 --- a/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp +++ b/xfa/fxfa/parser/cxfa_layoutpagemgr.cpp @@ -1698,8 +1698,7 @@ void CXFA_LayoutPageMgr::MergePageSetContents() { CXFA_Node* pBindNode = pNode->GetBindData(); if (pBindNode) { pBindNode->RemoveBindItem(pNode); - pNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, - nullptr); + pNode->JSNode()->SetBindingNode(nullptr); } } pNode->SetFlag(XFA_NodeFlag_UnusedNode, true); diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp index 6ec3b98f7b..c667c08d10 100644 --- a/xfa/fxfa/parser/cxfa_node.cpp +++ b/xfa/fxfa/parser/cxfa_node.cpp @@ -41,13 +41,6 @@ namespace { -void XFA_DataNodeDeleteBindItem(void* pData) { - delete static_cast*>(pData); -} - -XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = { - XFA_DataNodeDeleteBindItem, nullptr}; - std::vector NodesSortedByDocumentIdx( const std::set& rgNodeSet) { if (rgNodeSet.empty()) @@ -177,6 +170,7 @@ CXFA_Node::CXFA_Node(CXFA_Document* pDoc, CXFA_Node::~CXFA_Node() { ASSERT(!m_pParent); + CXFA_Node* pNode = m_pChild; while (pNode) { CXFA_Node* pNext = pNode->m_pNext; @@ -222,7 +216,7 @@ CXFA_Node* CXFA_Node::Clone(bool bRecursive) { } } pClone->SetFlag(XFA_NodeFlag_Initialized, true); - pClone->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, nullptr); + pClone->JSNode()->SetBindingNode(nullptr); return pClone; } @@ -384,86 +378,79 @@ void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode) { CXFA_Node* CXFA_Node::GetBindData() { ASSERT(GetPacketID() == XFA_XDPPACKET_Form); - return static_cast( - JSNode()->GetObject(XFA_Attribute::BindingNode)); + return JSNode()->GetBindingNode(); } -std::vector CXFA_Node::GetBindItems() { - if (BindsFormItems()) { - void* pBinding = nullptr; - JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding); - return *static_cast*>(pBinding); - } - std::vector result; - CXFA_Node* pFormNode = - static_cast(JSNode()->GetObject(XFA_Attribute::BindingNode)); - if (pFormNode) - result.push_back(pFormNode); - return result; +std::vector>* CXFA_Node::GetBindItems() { + return JSNode()->GetBindingNodes(); } int32_t CXFA_Node::AddBindItem(CXFA_Node* pFormNode) { ASSERT(pFormNode); + if (BindsFormItems()) { - void* pBinding = nullptr; - JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding); - auto* pItems = static_cast*>(pBinding); - if (!pdfium::ContainsValue(*pItems, pFormNode)) - pItems->push_back(pFormNode); - return pdfium::CollectionSize(*pItems); + std::vector>* nodes = JSNode()->GetBindingNodes(); + bool found = false; + for (auto& v : *nodes) { + if (v.Get() == pFormNode) { + found = true; + break; + } + } + if (!found) + nodes->emplace_back(pFormNode); + return pdfium::CollectionSize(*nodes); } - CXFA_Node* pOldFormItem = - static_cast(JSNode()->GetObject(XFA_Attribute::BindingNode)); + + CXFA_Node* pOldFormItem = JSNode()->GetBindingNode(); if (!pOldFormItem) { - JSNode()->SetObject(XFA_Attribute::BindingNode, pFormNode, nullptr); + JSNode()->SetBindingNode(pFormNode); return 1; } if (pOldFormItem == pFormNode) return 1; - std::vector* pItems = new std::vector; - JSNode()->SetObject(XFA_Attribute::BindingNode, pItems, - &deleteBindItemCallBack); - pItems->push_back(pOldFormItem); - pItems->push_back(pFormNode); + std::vector> items; + items.emplace_back(pOldFormItem); + items.emplace_back(pFormNode); + JSNode()->SetBindingNodes(std::move(items)); + m_uNodeFlags |= XFA_NodeFlag_BindFormItems; return 2; } int32_t CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode) { if (BindsFormItems()) { - void* pBinding = nullptr; - JSNode()->TryObject(XFA_Attribute::BindingNode, pBinding); - auto* pItems = static_cast*>(pBinding); - auto iter = std::find(pItems->begin(), pItems->end(), pFormNode); - if (iter != pItems->end()) { - *iter = pItems->back(); - pItems->pop_back(); - if (pItems->size() == 1) { - JSNode()->SetObject(XFA_Attribute::BindingNode, (*pItems)[0], - nullptr); // Invalidates pItems. - m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems; - return 1; - } + std::vector>* nodes = JSNode()->GetBindingNodes(); + + auto it = std::find_if(nodes->begin(), nodes->end(), + [&pFormNode](const UnownedPtr& node) { + return node.Get() == pFormNode; + }); + if (it != nodes->end()) + nodes->erase(it); + + if (nodes->size() == 1) { + m_uNodeFlags &= ~XFA_NodeFlag_BindFormItems; + return 1; } - return pdfium::CollectionSize(*pItems); + return pdfium::CollectionSize(*nodes); } - CXFA_Node* pOldFormItem = - static_cast(JSNode()->GetObject(XFA_Attribute::BindingNode)); + + CXFA_Node* pOldFormItem = JSNode()->GetBindingNode(); if (pOldFormItem != pFormNode) return pOldFormItem ? 1 : 0; - JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, nullptr); + JSNode()->SetBindingNode(nullptr); return 0; } bool CXFA_Node::HasBindItem() { - return GetPacketID() == XFA_XDPPACKET_Datasets && - JSNode()->GetObject(XFA_Attribute::BindingNode); + return GetPacketID() == XFA_XDPPACKET_Datasets && JSNode()->GetBindingNode(); } CXFA_WidgetData* CXFA_Node::GetWidgetData() { - return (CXFA_WidgetData*)JSNode()->GetObject(XFA_Attribute::WidgetData); + return JSNode()->GetWidgetData(); } CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() { @@ -494,7 +481,7 @@ CXFA_WidgetData* CXFA_Node::GetContainerWidgetData() { if (!pDataNode) return nullptr; pFieldWidgetData = nullptr; - for (CXFA_Node* pFormNode : pDataNode->GetBindItems()) { + for (const auto& pFormNode : *(pDataNode->GetBindItems())) { if (!pFormNode || pFormNode->HasRemovedChildren()) continue; pFieldWidgetData = pFormNode->GetWidgetData(); @@ -1016,6 +1003,15 @@ void CXFA_Node::ClearFlag(uint32_t dwFlag) { m_uNodeFlags &= ~dwFlag; } +void CXFA_Node::ReleaseBindingNodes() { + // Clear any binding nodes set on our JS node as we don't necessarily destruct + // in an order that makes sense. + JSNode()->ReleaseBindingNodes(); + + for (CXFA_Node* pNode = m_pChild; pNode; pNode = pNode->m_pNext) + pNode->ReleaseBindingNodes(); +} + bool CXFA_Node::IsAttributeInXML() { return JSNode()->GetEnum(XFA_Attribute::Contains) == XFA_ATTRIBUTEENUM_MetaData; @@ -1212,8 +1208,7 @@ void CXFA_Node::RemoveItem(CXFA_Node* pRemoveInstance, pDataParent->RemoveChild(pDataNode, true); } } - pFormNode->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, - nullptr); + pFormNode->JSNode()->SetBindingNode(nullptr); } } diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h index 66a3174901..dc4710a9c6 100644 --- a/xfa/fxfa/parser/cxfa_node.h +++ b/xfa/fxfa/parser/cxfa_node.h @@ -82,6 +82,7 @@ class CXFA_Node : public CXFA_Object { bool IsLayoutGeneratedNode() const { return HasFlag(XFA_NodeFlag_LayoutGeneratedNode); } + void ReleaseBindingNodes(); bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); } bool HasRemovedChildren() const { return HasFlag(XFA_NodeFlag_HasRemovedChildren); @@ -119,7 +120,7 @@ class CXFA_Node : public CXFA_Object { CXFA_Node* GetDataDescriptionNode(); void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode); CXFA_Node* GetBindData(); - std::vector GetBindItems(); + std::vector>* GetBindItems(); int32_t AddBindItem(CXFA_Node* pFormNode); int32_t RemoveBindItem(CXFA_Node* pFormNode); bool HasBindItem(); diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp index 89a6500fa6..3a70135aea 100644 --- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp +++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp @@ -122,8 +122,7 @@ bool FormValueNode_SetChildContent(CXFA_Node* pValueNode, void CreateDataBinding(CXFA_Node* pFormNode, CXFA_Node* pDataNode, bool bDataToForm) { - pFormNode->JSNode()->SetObject(XFA_Attribute::BindingNode, pDataNode, - nullptr); + pFormNode->JSNode()->SetBindingNode(pDataNode); pDataNode->AddBindItem(pFormNode); XFA_Element eType = pFormNode->GetElementType(); if (eType != XFA_Element::Field && eType != XFA_Element::ExclGroup) @@ -1544,10 +1543,11 @@ void CXFA_Document::DoDataRemerge(bool bDoDataMerge) { if (pFormRoot) { while (CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) pFormRoot->RemoveChild(pNode, true); - pFormRoot->JSNode()->SetObject(XFA_Attribute::BindingNode, nullptr, - nullptr); + + pFormRoot->JSNode()->SetBindingNode(nullptr); } m_rgGlobalBinding.clear(); + if (bDoDataMerge) DoDataMerge(); -- cgit v1.2.3