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:
GetFirstChild(CXFA_Node * pDDGroupNode)20   static inline CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode) {
21     return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group);
22   }
GetNextSibling(CXFA_Node * pDDGroupNode)23   static inline CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode) {
24     return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group);
25   }
GetParent(CXFA_Node * pDDGroupNode)26   static inline CXFA_Node* GetParent(CXFA_Node* pDDGroupNode) {
27     return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent);
28   }
29 };
XFA_DataDescription_UpdateDataRelation(CXFA_Node * pDataNode,CXFA_Node * pDataDescriptionNode)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 }
XFA_DataDescription_MaybeCreateDataNode(CXFA_Document * pDocument,CXFA_Node * pDataParent,XFA_ELEMENT eNodeType,const CFX_WideStringC & wsName)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