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