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