1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "xfa/src/foxitlib.h" 8 #include "xfa/src/fxfa/src/common/xfa_utils.h" 9 #include "xfa/src/fxfa/src/common/xfa_object.h" 10 #include "xfa/src/fxfa/src/common/xfa_document.h" 11 #include "xfa/src/fxfa/src/common/xfa_parser.h" 12 #include "xfa/src/fxfa/src/common/xfa_script.h" 13 #include "xfa/src/fxfa/src/common/xfa_docdata.h" 14 #include "xfa/src/fxfa/src/common/xfa_doclayout.h" 15 #include "xfa/src/fxfa/src/common/xfa_localemgr.h" 16 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h" 17 #define XFA_HASHCODE_Group 0xf7f75fcd 18 class CXFA_TraverseStrategy_DDGroup { 19 public: 20 static inline CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) { 21 return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group); 22 } 23 static inline CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) { 24 return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group); 25 } 26 static inline CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) { 27 return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent); 28 } 29 }; 30 void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode, 31 CXFA_Node* pDataDescriptionNode) { 32 FXSYS_assert(pDataDescriptionNode); 33 for (CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); 34 pDataChild; 35 pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { 36 FX_DWORD dwNameHash = pDataChild->GetNameHash(); 37 XFA_ELEMENT eType = pDataChild->GetClassID(); 38 if (!dwNameHash) { 39 continue; 40 } 41 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> 42 sIterator(pDataDescriptionNode); 43 for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; 44 pDDGroupNode = sIterator.MoveToNext()) { 45 if (pDDGroupNode != pDataDescriptionNode) { 46 if (pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) { 47 continue; 48 } 49 CFX_WideString wsNamespace; 50 if (!pDDGroupNode->TryNamespace(wsNamespace) || 51 wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) { 52 continue; 53 } 54 } 55 CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash); 56 if (!pDDNode) { 57 continue; 58 } 59 if (pDDNode->GetClassID() != eType) { 60 break; 61 } 62 pDataChild->SetDataDescriptionNode(pDDNode); 63 XFA_DataDescription_UpdateDataRelation(pDataChild, pDDNode); 64 break; 65 } 66 } 67 } 68 CXFA_Node* XFA_DataDescription_MaybeCreateDataNode( 69 CXFA_Document* pDocument, 70 CXFA_Node* pDataParent, 71 XFA_ELEMENT eNodeType, 72 const CFX_WideStringC& wsName) { 73 if (!pDataParent) { 74 return NULL; 75 } 76 CXFA_Node* pParentDDNode = pDataParent->GetDataDescriptionNode(); 77 if (!pParentDDNode) { 78 CXFA_Node* pDataNode = 79 pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType); 80 FXSYS_assert(pDataNode); 81 pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName); 82 pDataNode->CreateXMLMappingNode(); 83 pDataParent->InsertChild(pDataNode); 84 pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE); 85 return pDataNode; 86 } else { 87 CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> 88 sIterator(pParentDDNode); 89 for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; 90 pDDGroupNode = sIterator.MoveToNext()) { 91 if (pDDGroupNode != pParentDDNode) { 92 if (pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) { 93 continue; 94 } 95 CFX_WideString wsNamespace; 96 if (!pDDGroupNode->TryNamespace(wsNamespace) || 97 wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) { 98 continue; 99 } 100 } 101 CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName); 102 if (!pDDNode) { 103 continue; 104 } 105 if (pDDNode->GetClassID() != eNodeType) { 106 break; 107 } 108 CXFA_Node* pDataNode = 109 pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType); 110 FXSYS_assert(pDataNode); 111 pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName); 112 pDataNode->CreateXMLMappingNode(); 113 if (eNodeType == XFA_ELEMENT_DataValue && 114 pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) == 115 XFA_ATTRIBUTEENUM_MetaData) { 116 pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData); 117 } 118 pDataParent->InsertChild(pDataNode); 119 pDataNode->SetDataDescriptionNode(pDDNode); 120 pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE); 121 return pDataNode; 122 } 123 return NULL; 124 } 125 } 126