| // Copyright 2014 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/fxfa/fm2js/xfa_fm2jsapi.h" |
| #include "xfa/fxfa/parser/xfa_docdata.h" |
| #include "xfa/fxfa/parser/xfa_doclayout.h" |
| #include "xfa/fxfa/parser/xfa_document.h" |
| #include "xfa/fxfa/parser/xfa_localemgr.h" |
| #include "xfa/fxfa/parser/xfa_object.h" |
| #include "xfa/fxfa/parser/xfa_parser.h" |
| #include "xfa/fxfa/parser/xfa_script.h" |
| #include "xfa/fxfa/parser/xfa_utils.h" |
| |
| #define XFA_HASHCODE_Group 0xf7f75fcd |
| |
| class CXFA_TraverseStrategy_DDGroup { |
| public: |
| static inline CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) { |
| return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group); |
| } |
| static inline CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) { |
| return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group); |
| } |
| static inline CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) { |
| return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent); |
| } |
| }; |
| void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode, |
| CXFA_Node* pDataDescriptionNode) { |
| FXSYS_assert(pDataDescriptionNode); |
| for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); |
| pDataChild; |
| pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { |
| uint32_t dwNameHash = pDataChild->GetNameHash(); |
| XFA_ELEMENT eType = pDataChild->GetClassID(); |
| if (!dwNameHash) { |
| continue; |
| } |
| CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> |
| sIterator(pDataDescriptionNode); |
| for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; |
| pDDGroupNode = sIterator.MoveToNext()) { |
| if (pDDGroupNode != pDataDescriptionNode) { |
| if (pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) { |
| continue; |
| } |
| CFX_WideString wsNamespace; |
| if (!pDDGroupNode->TryNamespace(wsNamespace) || |
| wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) { |
| continue; |
| } |
| } |
| CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash); |
| if (!pDDNode) { |
| continue; |
| } |
| if (pDDNode->GetClassID() != eType) { |
| break; |
| } |
| pDataChild->SetDataDescriptionNode(pDDNode); |
| XFA_DataDescription_UpdateDataRelation(pDataChild, pDDNode); |
| break; |
| } |
| } |
| } |
| CXFA_Node* XFA_DataDescription_MaybeCreateDataNode( |
| CXFA_Document* pDocument, |
| CXFA_Node* pDataParent, |
| XFA_ELEMENT eNodeType, |
| const CFX_WideStringC& wsName) { |
| if (!pDataParent) { |
| return NULL; |
| } |
| CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode(); |
| if (!pParentDDNode) { |
| CXFA_Node* pDataNode = |
| pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType); |
| FXSYS_assert(pDataNode); |
| pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName); |
| pDataNode->CreateXMLMappingNode(); |
| pDataParent->InsertChild(pDataNode); |
| pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE); |
| return pDataNode; |
| } else { |
| CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> |
| sIterator(pParentDDNode); |
| for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; |
| pDDGroupNode = sIterator.MoveToNext()) { |
| if (pDDGroupNode != pParentDDNode) { |
| if (pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) { |
| continue; |
| } |
| CFX_WideString wsNamespace; |
| if (!pDDGroupNode->TryNamespace(wsNamespace) || |
| wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) { |
| continue; |
| } |
| } |
| CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName); |
| if (!pDDNode) { |
| continue; |
| } |
| if (pDDNode->GetClassID() != eNodeType) { |
| break; |
| } |
| CXFA_Node* pDataNode = |
| pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType); |
| FXSYS_assert(pDataNode); |
| pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName); |
| pDataNode->CreateXMLMappingNode(); |
| if (eNodeType == XFA_ELEMENT_DataValue && |
| pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) == |
| XFA_ATTRIBUTEENUM_MetaData) { |
| pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData); |
| } |
| pDataParent->InsertChild(pDataNode); |
| pDataNode->SetDataDescriptionNode(pDDNode); |
| pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE); |
| return pDataNode; |
| } |
| return NULL; |
| } |
| } |