diff options
Diffstat (limited to 'xfa/fxfa/parser/cxfa_node.cpp')
-rw-r--r-- | xfa/fxfa/parser/cxfa_node.cpp | 220 |
1 files changed, 140 insertions, 80 deletions
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp index a947374814..ccbf31048d 100644 --- a/xfa/fxfa/parser/cxfa_node.cpp +++ b/xfa/fxfa/parser/cxfa_node.cpp @@ -138,24 +138,22 @@ const XFA_ATTRIBUTEENUMINFO* GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName) { return g_XFAEnumData + eName; } -// static -std::unique_ptr<CXFA_Node> CXFA_Node::Create(CXFA_Document* doc, - XFA_XDPPACKET packet, - const XFA_ELEMENTINFO* pElement) { - return std::unique_ptr<CXFA_Node>(new CXFA_Node( - doc, packet, pElement->eObjectType, pElement->eName, pElement->pName)); -} - CXFA_Node::CXFA_Node(CXFA_Document* pDoc, uint16_t ePacket, + uint32_t validPackets, XFA_ObjectType oType, XFA_Element eType, + const PropertyData* properties, + const XFA_Attribute* attributes, const WideStringView& elementName) : CXFA_Object(pDoc, oType, eType, elementName, pdfium::MakeUnique<CJX_Node>(this)), + m_Properties(properties), + m_Attributes(attributes), + m_ValidPackets(validPackets), m_pNext(nullptr), m_pChild(nullptr), m_pLastChild(nullptr), @@ -245,6 +243,75 @@ CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem) const { return nullptr; } +bool CXFA_Node::IsValidInPacket(XFA_XDPPACKET packet) const { + return !!(m_ValidPackets & packet); +} + +const CXFA_Node::PropertyData* CXFA_Node::GetPropertyData( + XFA_Element property) const { + if (m_Properties == nullptr) + return nullptr; + + for (size_t i = 0;; ++i) { + const PropertyData* data = m_Properties + i; + if (data->property == XFA_Element::Unknown) + break; + if (data->property == property) + return data; + } + return nullptr; +} + +bool CXFA_Node::HasProperty(XFA_Element property) const { + return !!GetPropertyData(property); +} + +bool CXFA_Node::HasPropertyFlags(XFA_Element property, uint8_t flags) const { + const PropertyData* data = GetPropertyData(property); + return data && !!(data->flags & flags); +} + +uint8_t CXFA_Node::PropertyOccuranceCount(XFA_Element property) const { + const PropertyData* data = GetPropertyData(property); + return data ? data->occurance_count : 0; +} + +pdfium::Optional<XFA_Element> CXFA_Node::GetFirstPropertyWithFlag( + uint8_t flag) { + if (m_Properties == nullptr) + return {}; + + for (size_t i = 0;; ++i) { + const PropertyData* data = m_Properties + i; + if (data->property == XFA_Element::Unknown) + break; + if (data->flags & flag) + return {data->property}; + } + return {}; +} + +bool CXFA_Node::HasAttribute(XFA_Attribute attr) const { + if (m_Attributes == nullptr) + return false; + + for (size_t i = 0;; ++i) { + XFA_Attribute cur_attr = *(m_Attributes + i); + if (cur_attr == XFA_Attribute::Unknown) + break; + if (cur_attr == attr) + return true; + } + return false; +} + +// Note: This Method assumes that i is a valid index .... +XFA_Attribute CXFA_Node::GetAttribute(size_t i) const { + if (m_Attributes == nullptr) + return XFA_Attribute::Unknown; + return *(m_Attributes + i); +} + CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem, XFA_ObjectType eType) const { CXFA_Node* pNode = nullptr; @@ -283,62 +350,64 @@ CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem, std::vector<CXFA_Node*> CXFA_Node::GetNodeList(uint32_t dwTypeFilter, XFA_Element eTypeFilter) { - std::vector<CXFA_Node*> nodes; if (eTypeFilter != XFA_Element::Unknown) { + std::vector<CXFA_Node*> nodes; for (CXFA_Node* pChild = m_pChild; pChild; pChild = pChild->m_pNext) { if (pChild->GetElementType() == eTypeFilter) nodes.push_back(pChild); } - } else if (dwTypeFilter == - (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) { + return nodes; + } + + if (dwTypeFilter == (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) { + std::vector<CXFA_Node*> nodes; for (CXFA_Node* pChild = m_pChild; pChild; pChild = pChild->m_pNext) nodes.push_back(pChild); - } else if (dwTypeFilter != 0) { - bool bFilterChildren = !!(dwTypeFilter & XFA_NODEFILTER_Children); - bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties); - bool bFilterOneOfProperties = - !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty); - CXFA_Node* pChild = m_pChild; - while (pChild) { - const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement( - GetElementType(), pChild->GetElementType(), XFA_XDPPACKET_UNKNOWN); - if (pProperty) { - if (bFilterProperties) { - nodes.push_back(pChild); - } else if (bFilterOneOfProperties && - (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) { - nodes.push_back(pChild); - } else if (bFilterChildren && - (pChild->GetElementType() == XFA_Element::Variables || - pChild->GetElementType() == XFA_Element::PageSet)) { - nodes.push_back(pChild); - } - } else if (bFilterChildren) { + return nodes; + } + + if (dwTypeFilter == 0) + return std::vector<CXFA_Node*>(); + + bool bFilterChildren = !!(dwTypeFilter & XFA_NODEFILTER_Children); + bool bFilterProperties = !!(dwTypeFilter & XFA_NODEFILTER_Properties); + bool bFilterOneOfProperties = !!(dwTypeFilter & XFA_NODEFILTER_OneOfProperty); + std::vector<CXFA_Node*> nodes; + for (CXFA_Node* pChild = m_pChild; pChild; pChild = pChild->m_pNext) { + if (!HasProperty(pChild->GetElementType())) { + if (bFilterProperties) { + nodes.push_back(pChild); + } else if (bFilterOneOfProperties && + HasPropertyFlags(pChild->GetElementType(), + XFA_PROPERTYFLAG_OneOf)) { + nodes.push_back(pChild); + } else if (bFilterChildren && + (pChild->GetElementType() == XFA_Element::Variables || + pChild->GetElementType() == XFA_Element::PageSet)) { nodes.push_back(pChild); } - pChild = pChild->m_pNext; - } - if (bFilterOneOfProperties && nodes.empty()) { - int32_t iProperties = 0; - const XFA_PROPERTY* pProperty = - XFA_GetElementProperties(GetElementType(), iProperties); - if (!pProperty || iProperties < 1) - return nodes; - for (int32_t i = 0; i < iProperties; i++) { - if (pProperty[i].uFlags & XFA_PROPERTYFLAG_DefaultOneOf) { - const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(GetPacketID()); - CXFA_Node* pNewNode = - m_pDocument->CreateNode(pPacket, pProperty[i].eName); - if (!pNewNode) - break; - InsertChild(pNewNode, nullptr); - pNewNode->SetFlag(XFA_NodeFlag_Initialized, true); - nodes.push_back(pNewNode); - break; - } - } + } else if (bFilterChildren) { + nodes.push_back(pChild); } } + + if (!bFilterOneOfProperties || !nodes.empty()) + return nodes; + if (m_Properties == nullptr) + return nodes; + + pdfium::Optional<XFA_Element> property = + GetFirstPropertyWithFlag(XFA_PROPERTYFLAG_DefaultOneOf); + if (!property) + return nodes; + + const XFA_PACKETINFO* pPacket = XFA_GetPacketByID(GetPacketID()); + CXFA_Node* pNewNode = m_pDocument->CreateNode(pPacket, *property); + if (pNewNode) { + InsertChild(pNewNode, nullptr); + pNewNode->SetFlag(XFA_NodeFlag_Initialized, true); + nodes.push_back(pNewNode); + } return nodes; } @@ -671,19 +740,14 @@ CXFA_Node* CXFA_Node::GetModelNode() { } int32_t CXFA_Node::CountChildren(XFA_Element eType, bool bOnlyChild) { - CXFA_Node* pNode = m_pChild; int32_t iCount = 0; - for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { - if (pNode->GetElementType() == eType || eType == XFA_Element::Unknown) { - if (bOnlyChild) { - const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement( - GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN); - if (pProperty) { - continue; - } - } - iCount++; - } + for (CXFA_Node* pNode = m_pChild; pNode; + pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { + if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown) + continue; + if (bOnlyChild && HasProperty(pNode->GetElementType())) + continue; + ++iCount; } return iCount; } @@ -692,22 +756,18 @@ CXFA_Node* CXFA_Node::GetChild(int32_t index, XFA_Element eType, bool bOnlyChild) { ASSERT(index > -1); - CXFA_Node* pNode = m_pChild; + int32_t iCount = 0; - for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { - if (pNode->GetElementType() == eType || eType == XFA_Element::Unknown) { - if (bOnlyChild) { - const XFA_PROPERTY* pProperty = XFA_GetPropertyOfElement( - GetElementType(), pNode->GetElementType(), XFA_XDPPACKET_UNKNOWN); - if (pProperty) { - continue; - } - } - iCount++; - if (iCount > index) { - return pNode; - } - } + for (CXFA_Node* pNode = m_pChild; pNode; + pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { + if (pNode->GetElementType() != eType && eType != XFA_Element::Unknown) + continue; + if (bOnlyChild && HasProperty(pNode->GetElementType())) + continue; + if (iCount == index) + return pNode; + + ++iCount; } return nullptr; } |