summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser/cxfa_node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/fxfa/parser/cxfa_node.cpp')
-rw-r--r--xfa/fxfa/parser/cxfa_node.cpp220
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;
}