Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(444)

Side by Side Diff: xfa/fxfa/parser/cxfa_document.cpp

Issue 2163133004: Move xfa_document to cxfa_document (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@xfa_parser_II
Patch Set: Rebase to master Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/fxfa/parser/cxfa_document.h ('k') | xfa/fxfa/parser/cxfa_document_parser.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/fxcrt/include/fx_ext.h" 7 #include "core/fxcrt/include/fx_ext.h"
8 #include "xfa/fxfa/app/xfa_ffnotify.h" 8 #include "xfa/fxfa/app/xfa_ffnotify.h"
9 #include "xfa/fxfa/parser/cscript_datawindow.h" 9 #include "xfa/fxfa/parser/cscript_datawindow.h"
10 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h" 10 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
11 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h" 11 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h"
12 #include "xfa/fxfa/parser/cscript_layoutpseudomodel.h" 12 #include "xfa/fxfa/parser/cscript_layoutpseudomodel.h"
13 #include "xfa/fxfa/parser/cscript_logpseudomodel.h" 13 #include "xfa/fxfa/parser/cscript_logpseudomodel.h"
14 #include "xfa/fxfa/parser/cscript_signaturepseudomodel.h" 14 #include "xfa/fxfa/parser/cscript_signaturepseudomodel.h"
15 #include "xfa/fxfa/parser/cxfa_document.h"
15 #include "xfa/fxfa/parser/cxfa_document_parser.h" 16 #include "xfa/fxfa/parser/cxfa_document_parser.h"
16 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" 17 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
17 #include "xfa/fxfa/parser/cxfa_scriptcontext.h" 18 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
18 #include "xfa/fxfa/parser/xfa_document.h"
19 #include "xfa/fxfa/parser/xfa_localemgr.h" 19 #include "xfa/fxfa/parser/xfa_localemgr.h"
20 #include "xfa/fxfa/parser/xfa_object.h" 20 #include "xfa/fxfa/parser/xfa_object.h"
21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" 21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
22 #include "xfa/fxfa/parser/xfa_utils.h" 22 #include "xfa/fxfa/parser/xfa_utils.h"
23 23
24 namespace {
25
26 void MergeNodeRecurse(CXFA_Document* pDocument,
27 CXFA_Node* pDestNodeParent,
28 CXFA_Node* pProtoNode) {
29 CXFA_Node* pExistingNode = nullptr;
30 for (CXFA_Node* pFormChild =
31 pDestNodeParent->GetNodeItem(XFA_NODEITEM_FirstChild);
32 pFormChild;
33 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
34 if (pFormChild->GetElementType() == pProtoNode->GetElementType() &&
35 pFormChild->GetNameHash() == pProtoNode->GetNameHash() &&
36 pFormChild->IsUnusedNode()) {
37 pFormChild->ClearFlag(XFA_NodeFlag_UnusedNode);
38 pExistingNode = pFormChild;
39 break;
40 }
41 }
42
43 if (pExistingNode) {
44 pExistingNode->SetTemplateNode(pProtoNode);
45 for (CXFA_Node* pTemplateChild =
46 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild);
47 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
48 XFA_NODEITEM_NextSibling)) {
49 MergeNodeRecurse(pDocument, pExistingNode, pTemplateChild);
50 }
51 return;
52 }
53 CXFA_Node* pNewNode = pProtoNode->Clone(TRUE);
54 pNewNode->SetTemplateNode(pProtoNode);
55 pDestNodeParent->InsertChild(pNewNode, nullptr);
56 }
57
58 void MergeNode(CXFA_Document* pDocument,
59 CXFA_Node* pDestNode,
60 CXFA_Node* pProtoNode) {
61 {
62 CXFA_NodeIterator sIterator(pDestNode);
63 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
64 pNode = sIterator.MoveToNext()) {
65 pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
66 }
67 }
68 pDestNode->SetTemplateNode(pProtoNode);
69 for (CXFA_Node* pTemplateChild =
70 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild);
71 pTemplateChild;
72 pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
73 MergeNodeRecurse(pDocument, pDestNode, pTemplateChild);
74 }
75 {
76 CXFA_NodeIterator sIterator(pDestNode);
77 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
78 pNode = sIterator.MoveToNext()) {
79 pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
80 }
81 }
82 }
83
84 } // namespace
85
24 CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser) 86 CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser)
25 : m_pParser(pParser), 87 : m_pParser(pParser),
26 m_pScriptContext(nullptr), 88 m_pScriptContext(nullptr),
27 m_pLayoutProcessor(nullptr), 89 m_pLayoutProcessor(nullptr),
28 m_pRootNode(nullptr), 90 m_pRootNode(nullptr),
29 m_pLocalMgr(nullptr), 91 m_pLocalMgr(nullptr),
30 m_pScriptDataWindow(nullptr), 92 m_pScriptDataWindow(nullptr),
31 m_pScriptEvent(nullptr), 93 m_pScriptEvent(nullptr),
32 m_pScriptHost(nullptr), 94 m_pScriptHost(nullptr),
33 m_pScriptLog(nullptr), 95 m_pScriptLog(nullptr),
34 m_pScriptLayout(nullptr), 96 m_pScriptLayout(nullptr),
35 m_pScriptSignature(nullptr), 97 m_pScriptSignature(nullptr),
36 m_eCurVersionMode(XFA_VERSION_DEFAULT), 98 m_eCurVersionMode(XFA_VERSION_DEFAULT),
37 m_dwDocFlags(0) { 99 m_dwDocFlags(0) {
38 ASSERT(m_pParser); 100 ASSERT(m_pParser);
39 } 101 }
102
40 CXFA_Document::~CXFA_Document() { 103 CXFA_Document::~CXFA_Document() {
41 delete m_pRootNode; 104 delete m_pRootNode;
42 PurgeNodes(); 105 PurgeNodes();
43 } 106 }
44 107
45 void CXFA_Document::ClearLayoutData() { 108 void CXFA_Document::ClearLayoutData() {
46 delete m_pLayoutProcessor; 109 delete m_pLayoutProcessor;
47 m_pLayoutProcessor = nullptr; 110 m_pLayoutProcessor = nullptr;
48 delete m_pScriptContext; 111 delete m_pScriptContext;
49 m_pScriptContext = nullptr; 112 m_pScriptContext = nullptr;
50 delete m_pLocalMgr; 113 delete m_pLocalMgr;
51 m_pLocalMgr = nullptr; 114 m_pLocalMgr = nullptr;
52 delete m_pScriptDataWindow; 115 delete m_pScriptDataWindow;
53 m_pScriptDataWindow = nullptr; 116 m_pScriptDataWindow = nullptr;
54 delete m_pScriptEvent; 117 delete m_pScriptEvent;
55 m_pScriptEvent = nullptr; 118 m_pScriptEvent = nullptr;
56 delete m_pScriptHost; 119 delete m_pScriptHost;
57 m_pScriptHost = nullptr; 120 m_pScriptHost = nullptr;
58 delete m_pScriptLog; 121 delete m_pScriptLog;
59 m_pScriptLog = nullptr; 122 m_pScriptLog = nullptr;
60 delete m_pScriptLayout; 123 delete m_pScriptLayout;
61 m_pScriptLayout = nullptr; 124 m_pScriptLayout = nullptr;
62 delete m_pScriptSignature; 125 delete m_pScriptSignature;
63 m_pScriptSignature = nullptr; 126 m_pScriptSignature = nullptr;
64 } 127 }
65 128
66 void CXFA_Document::SetRoot(CXFA_Node* pNewRoot) { 129 void CXFA_Document::SetRoot(CXFA_Node* pNewRoot) {
67 if (m_pRootNode) { 130 if (m_pRootNode)
68 AddPurgeNode(m_pRootNode); 131 AddPurgeNode(m_pRootNode);
69 } 132
70 m_pRootNode = pNewRoot; 133 m_pRootNode = pNewRoot;
71 RemovePurgeNode(pNewRoot); 134 RemovePurgeNode(pNewRoot);
72 } 135 }
73 136
74 CFDE_XMLDoc* CXFA_Document::GetXMLDoc() const { 137 CFDE_XMLDoc* CXFA_Document::GetXMLDoc() const {
75 return m_pParser->GetXMLDoc(); 138 return m_pParser->GetXMLDoc();
76 } 139 }
77 140
78 CXFA_FFNotify* CXFA_Document::GetNotify() const { 141 CXFA_FFNotify* CXFA_Document::GetNotify() const {
79 return m_pParser->GetNotify(); 142 return m_pParser->GetNotify();
80 } 143 }
81 144
82 CXFA_Object* CXFA_Document::GetXFAObject(XFA_HashCode dwNodeNameHash) { 145 CXFA_Object* CXFA_Document::GetXFAObject(XFA_HashCode dwNodeNameHash) {
83 switch (dwNodeNameHash) { 146 switch (dwNodeNameHash) {
84 case XFA_HASHCODE_Data: { 147 case XFA_HASHCODE_Data: {
85 CXFA_Node* pDatasetsNode = ToNode(GetXFAObject(XFA_HASHCODE_Datasets)); 148 CXFA_Node* pDatasetsNode = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
86 if (!pDatasetsNode) { 149 if (!pDatasetsNode)
87 return nullptr; 150 return nullptr;
88 } 151
89 for (CXFA_Node* pDatasetsChild = 152 for (CXFA_Node* pDatasetsChild =
90 pDatasetsNode->GetFirstChildByClass(XFA_Element::DataGroup); 153 pDatasetsNode->GetFirstChildByClass(XFA_Element::DataGroup);
91 pDatasetsChild; 154 pDatasetsChild;
92 pDatasetsChild = pDatasetsChild->GetNextSameClassSibling( 155 pDatasetsChild = pDatasetsChild->GetNextSameClassSibling(
93 XFA_Element::DataGroup)) { 156 XFA_Element::DataGroup)) {
94 if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data) { 157 if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data)
95 continue; 158 continue;
96 } 159
97 CFX_WideString wsNamespaceURI; 160 CFX_WideString wsNamespaceURI;
98 if (!pDatasetsChild->TryNamespace(wsNamespaceURI)) { 161 if (!pDatasetsChild->TryNamespace(wsNamespaceURI))
99 continue; 162 continue;
100 } 163
101 CFX_WideString wsDatasetsURI; 164 CFX_WideString wsDatasetsURI;
102 if (!pDatasetsNode->TryNamespace(wsDatasetsURI)) { 165 if (!pDatasetsNode->TryNamespace(wsDatasetsURI))
103 continue; 166 continue;
104 } 167 if (wsNamespaceURI == wsDatasetsURI)
105 if (wsNamespaceURI == wsDatasetsURI) {
106 return pDatasetsChild; 168 return pDatasetsChild;
107 }
108 } 169 }
109 return nullptr; 170 return nullptr;
110 } 171 }
111 case XFA_HASHCODE_Record: { 172 case XFA_HASHCODE_Record: {
112 CXFA_Node* pData = ToNode(GetXFAObject(XFA_HASHCODE_Data)); 173 CXFA_Node* pData = ToNode(GetXFAObject(XFA_HASHCODE_Data));
113 return pData ? pData->GetFirstChildByClass(XFA_Element::DataGroup) 174 return pData ? pData->GetFirstChildByClass(XFA_Element::DataGroup)
114 : nullptr; 175 : nullptr;
115 } 176 }
116 case XFA_HASHCODE_DataWindow: { 177 case XFA_HASHCODE_DataWindow: {
117 if (!m_pScriptDataWindow) 178 if (!m_pScriptDataWindow)
(...skipping 22 matching lines...) Expand all
140 } 201 }
141 case XFA_HASHCODE_Layout: { 202 case XFA_HASHCODE_Layout: {
142 if (!m_pScriptLayout) 203 if (!m_pScriptLayout)
143 m_pScriptLayout = new CScript_LayoutPseudoModel(this); 204 m_pScriptLayout = new CScript_LayoutPseudoModel(this);
144 return m_pScriptLayout; 205 return m_pScriptLayout;
145 } 206 }
146 default: 207 default:
147 return m_pRootNode->GetFirstChildByName(dwNodeNameHash); 208 return m_pRootNode->GetFirstChildByName(dwNodeNameHash);
148 } 209 }
149 } 210 }
211
150 CXFA_Node* CXFA_Document::CreateNode(uint32_t dwPacket, XFA_Element eElement) { 212 CXFA_Node* CXFA_Document::CreateNode(uint32_t dwPacket, XFA_Element eElement) {
151 return CreateNode(XFA_GetPacketByID(dwPacket), eElement); 213 return CreateNode(XFA_GetPacketByID(dwPacket), eElement);
152 } 214 }
153 215
154 CXFA_Node* CXFA_Document::CreateNode(const XFA_PACKETINFO* pPacket, 216 CXFA_Node* CXFA_Document::CreateNode(const XFA_PACKETINFO* pPacket,
155 XFA_Element eElement) { 217 XFA_Element eElement) {
156 if (!pPacket) 218 if (!pPacket)
157 return nullptr; 219 return nullptr;
158 220
159 const XFA_ELEMENTINFO* pElement = XFA_GetElementByID(eElement); 221 const XFA_ELEMENTINFO* pElement = XFA_GetElementByID(eElement);
(...skipping 17 matching lines...) Expand all
177 } 239 }
178 240
179 void CXFA_Document::PurgeNodes() { 241 void CXFA_Document::PurgeNodes() {
180 for (CXFA_Node* pNode : m_PurgeNodes) 242 for (CXFA_Node* pNode : m_PurgeNodes)
181 delete pNode; 243 delete pNode;
182 244
183 m_PurgeNodes.clear(); 245 m_PurgeNodes.clear();
184 } 246 }
185 247
186 void CXFA_Document::SetFlag(uint32_t dwFlag, FX_BOOL bOn) { 248 void CXFA_Document::SetFlag(uint32_t dwFlag, FX_BOOL bOn) {
187 if (bOn) { 249 if (bOn)
188 m_dwDocFlags |= dwFlag; 250 m_dwDocFlags |= dwFlag;
189 } else { 251 else
190 m_dwDocFlags &= ~dwFlag; 252 m_dwDocFlags &= ~dwFlag;
191 }
192 } 253 }
254
193 FX_BOOL CXFA_Document::IsInteractive() { 255 FX_BOOL CXFA_Document::IsInteractive() {
194 if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive) { 256 if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive)
195 return !!(m_dwDocFlags & XFA_DOCFLAG_Interactive); 257 return !!(m_dwDocFlags & XFA_DOCFLAG_Interactive);
196 } 258
197 CXFA_Node* pConfig = ToNode(GetXFAObject(XFA_HASHCODE_Config)); 259 CXFA_Node* pConfig = ToNode(GetXFAObject(XFA_HASHCODE_Config));
198 if (!pConfig) { 260 if (!pConfig)
199 return FALSE; 261 return FALSE;
200 } 262
201 CFX_WideString wsInteractive; 263 CFX_WideString wsInteractive;
202 CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_Element::Present); 264 CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_Element::Present);
203 if (!pPresent) { 265 if (!pPresent)
204 return FALSE; 266 return FALSE;
205 } 267
206 CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_Element::Pdf); 268 CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_Element::Pdf);
207 if (!pPDF) { 269 if (!pPDF)
208 return FALSE; 270 return FALSE;
209 } 271
210 CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_Element::Interactive); 272 CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_Element::Interactive);
211 if (pInteractive) { 273 if (pInteractive) {
212 m_dwDocFlags |= XFA_DOCFLAG_HasInteractive; 274 m_dwDocFlags |= XFA_DOCFLAG_HasInteractive;
213 if (pInteractive->TryContent(wsInteractive) && 275 if (pInteractive->TryContent(wsInteractive) &&
214 wsInteractive == FX_WSTRC(L"1")) { 276 wsInteractive == FX_WSTRC(L"1")) {
215 m_dwDocFlags |= XFA_DOCFLAG_Interactive; 277 m_dwDocFlags |= XFA_DOCFLAG_Interactive;
216 return TRUE; 278 return TRUE;
217 } 279 }
218 } 280 }
219 return FALSE; 281 return FALSE;
220 } 282 }
283
221 CXFA_LocaleMgr* CXFA_Document::GetLocalMgr() { 284 CXFA_LocaleMgr* CXFA_Document::GetLocalMgr() {
222 if (!m_pLocalMgr) { 285 if (!m_pLocalMgr) {
223 CFX_WideString wsLanguage; 286 CFX_WideString wsLanguage;
224 GetNotify()->GetAppProvider()->GetLanguage(wsLanguage); 287 GetNotify()->GetAppProvider()->GetLanguage(wsLanguage);
225 m_pLocalMgr = new CXFA_LocaleMgr( 288 m_pLocalMgr = new CXFA_LocaleMgr(
226 ToNode(GetXFAObject(XFA_HASHCODE_LocaleSet)), wsLanguage); 289 ToNode(GetXFAObject(XFA_HASHCODE_LocaleSet)), wsLanguage);
227 } 290 }
228 return m_pLocalMgr; 291 return m_pLocalMgr;
229 } 292 }
293
230 CXFA_ScriptContext* CXFA_Document::InitScriptContext(v8::Isolate* pIsolate) { 294 CXFA_ScriptContext* CXFA_Document::InitScriptContext(v8::Isolate* pIsolate) {
231 if (!m_pScriptContext) 295 if (!m_pScriptContext)
232 m_pScriptContext = new CXFA_ScriptContext(this); 296 m_pScriptContext = new CXFA_ScriptContext(this);
233 m_pScriptContext->Initialize(pIsolate); 297 m_pScriptContext->Initialize(pIsolate);
234 return m_pScriptContext; 298 return m_pScriptContext;
235 } 299 }
300
236 CXFA_ScriptContext* CXFA_Document::GetScriptContext() { 301 CXFA_ScriptContext* CXFA_Document::GetScriptContext() {
237 if (!m_pScriptContext) 302 if (!m_pScriptContext)
238 m_pScriptContext = new CXFA_ScriptContext(this); 303 m_pScriptContext = new CXFA_ScriptContext(this);
239 return m_pScriptContext; 304 return m_pScriptContext;
240 } 305 }
306
241 XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber( 307 XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber(
242 CFX_WideString& wsTemplateNS) { 308 CFX_WideString& wsTemplateNS) {
243 CFX_WideStringC wsTemplateURIPrefix = 309 CFX_WideStringC wsTemplateURIPrefix =
244 XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI; 310 XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI;
245 FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength(); 311 FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength();
246 if (CFX_WideStringC(wsTemplateNS.c_str(), wsTemplateNS.GetLength()) != 312 if (CFX_WideStringC(wsTemplateNS.c_str(), wsTemplateNS.GetLength()) !=
247 wsTemplateURIPrefix) { 313 wsTemplateURIPrefix) {
248 return XFA_VERSION_UNKNOWN; 314 return XFA_VERSION_UNKNOWN;
249 } 315 }
250 FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength); 316 FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength);
251 if (nDotPos == (FX_STRSIZE)-1) { 317 if (nDotPos == (FX_STRSIZE)-1)
252 return XFA_VERSION_UNKNOWN; 318 return XFA_VERSION_UNKNOWN;
253 } 319
254 int8_t iMajor = FXSYS_wtoi( 320 int8_t iMajor = FXSYS_wtoi(
255 wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength).c_str()); 321 wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength).c_str());
256 int8_t iMinor = FXSYS_wtoi( 322 int8_t iMinor = FXSYS_wtoi(
257 wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2) 323 wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2)
258 .c_str()); 324 .c_str());
259 XFA_VERSION eVersion = (XFA_VERSION)((int32_t)iMajor * 100 + iMinor); 325 XFA_VERSION eVersion = (XFA_VERSION)((int32_t)iMajor * 100 + iMinor);
260 if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX) { 326 if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX)
261 return XFA_VERSION_UNKNOWN; 327 return XFA_VERSION_UNKNOWN;
262 } 328
263 m_eCurVersionMode = eVersion; 329 m_eCurVersionMode = eVersion;
264 return eVersion; 330 return eVersion;
265 } 331 }
332
266 CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot, 333 CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot,
267 const CFX_WideStringC& wsID) { 334 const CFX_WideStringC& wsID) {
268 if (!pRoot || wsID.IsEmpty()) { 335 if (!pRoot || wsID.IsEmpty())
269 return nullptr; 336 return nullptr;
270 } 337
271 CXFA_NodeIterator sIterator(pRoot); 338 CXFA_NodeIterator sIterator(pRoot);
272 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; 339 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
273 pNode = sIterator.MoveToNext()) { 340 pNode = sIterator.MoveToNext()) {
274 CFX_WideStringC wsIDVal; 341 CFX_WideStringC wsIDVal;
275 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) { 342 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
276 if (wsIDVal == wsID) { 343 if (wsIDVal == wsID)
277 return pNode; 344 return pNode;
278 }
279 } 345 }
280 } 346 }
281 return nullptr; 347 return nullptr;
282 } 348 }
283 static void XFA_ProtoMerge_MergeNodeRecurse(CXFA_Document* pDocument, 349
284 CXFA_Node* pDestNodeParent,
285 CXFA_Node* pProtoNode) {
286 CXFA_Node* pExistingNode = nullptr;
287 for (CXFA_Node* pFormChild =
288 pDestNodeParent->GetNodeItem(XFA_NODEITEM_FirstChild);
289 pFormChild;
290 pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
291 if (pFormChild->GetElementType() == pProtoNode->GetElementType() &&
292 pFormChild->GetNameHash() == pProtoNode->GetNameHash() &&
293 pFormChild->IsUnusedNode()) {
294 pFormChild->ClearFlag(XFA_NodeFlag_UnusedNode);
295 pExistingNode = pFormChild;
296 break;
297 }
298 }
299 if (pExistingNode) {
300 pExistingNode->SetTemplateNode(pProtoNode);
301 for (CXFA_Node* pTemplateChild =
302 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild);
303 pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(
304 XFA_NODEITEM_NextSibling)) {
305 XFA_ProtoMerge_MergeNodeRecurse(pDocument, pExistingNode, pTemplateChild);
306 }
307 return;
308 }
309 CXFA_Node* pNewNode = pProtoNode->Clone(TRUE);
310 pNewNode->SetTemplateNode(pProtoNode);
311 pDestNodeParent->InsertChild(pNewNode, nullptr);
312 }
313 static void XFA_ProtoMerge_MergeNode(CXFA_Document* pDocument,
314 CXFA_Node* pDestNode,
315 CXFA_Node* pProtoNode) {
316 {
317 CXFA_NodeIterator sIterator(pDestNode);
318 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
319 pNode = sIterator.MoveToNext()) {
320 pNode->SetFlag(XFA_NodeFlag_UnusedNode, true);
321 }
322 }
323 pDestNode->SetTemplateNode(pProtoNode);
324 for (CXFA_Node* pTemplateChild =
325 pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild);
326 pTemplateChild;
327 pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
328 XFA_ProtoMerge_MergeNodeRecurse(pDocument, pDestNode, pTemplateChild);
329 }
330 {
331 CXFA_NodeIterator sIterator(pDestNode);
332 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
333 pNode = sIterator.MoveToNext()) {
334 pNode->ClearFlag(XFA_NodeFlag_UnusedNode);
335 }
336 }
337 }
338 void CXFA_Document::DoProtoMerge() { 350 void CXFA_Document::DoProtoMerge() {
339 CXFA_Node* pTemplateRoot = ToNode(GetXFAObject(XFA_HASHCODE_Template)); 351 CXFA_Node* pTemplateRoot = ToNode(GetXFAObject(XFA_HASHCODE_Template));
340 if (!pTemplateRoot) { 352 if (!pTemplateRoot)
341 return; 353 return;
342 } 354
343 CFX_MapPtrTemplate<uint32_t, CXFA_Node*> mIDMap; 355 CFX_MapPtrTemplate<uint32_t, CXFA_Node*> mIDMap;
344 CXFA_NodeSet sUseNodes; 356 CXFA_NodeSet sUseNodes;
345 CXFA_NodeIterator sIterator(pTemplateRoot); 357 CXFA_NodeIterator sIterator(pTemplateRoot);
346 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode; 358 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
347 pNode = sIterator.MoveToNext()) { 359 pNode = sIterator.MoveToNext()) {
348 CFX_WideStringC wsIDVal; 360 CFX_WideStringC wsIDVal;
349 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) { 361 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
350 mIDMap[FX_HashCode_GetW(wsIDVal, false)] = pNode; 362 mIDMap[FX_HashCode_GetW(wsIDVal, false)] = pNode;
351 } 363 }
352 CFX_WideStringC wsUseVal; 364 CFX_WideStringC wsUseVal;
353 if (pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) { 365 if (pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) {
354 sUseNodes.insert(pNode); 366 sUseNodes.insert(pNode);
355 } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && 367 } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) &&
356 !wsUseVal.IsEmpty()) { 368 !wsUseVal.IsEmpty()) {
357 sUseNodes.insert(pNode); 369 sUseNodes.insert(pNode);
358 } 370 }
359 } 371 }
372
360 for (CXFA_Node* pUseHrefNode : sUseNodes) { 373 for (CXFA_Node* pUseHrefNode : sUseNodes) {
361 CFX_WideString wsUseVal; 374 CFX_WideString wsUseVal;
362 CFX_WideStringC wsURI, wsID, wsSOM; 375 CFX_WideStringC wsURI, wsID, wsSOM;
363 if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && 376 if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) &&
364 !wsUseVal.IsEmpty()) { 377 !wsUseVal.IsEmpty()) {
365 FX_STRSIZE uSharpPos = wsUseVal.Find('#'); 378 FX_STRSIZE uSharpPos = wsUseVal.Find('#');
366 if (uSharpPos < 0) { 379 if (uSharpPos < 0) {
367 wsURI = wsUseVal.AsStringC(); 380 wsURI = wsUseVal.AsStringC();
368 } else { 381 } else {
369 wsURI = CFX_WideStringC(wsUseVal.c_str(), uSharpPos); 382 wsURI = CFX_WideStringC(wsUseVal.c_str(), uSharpPos);
370 FX_STRSIZE uLen = wsUseVal.GetLength(); 383 FX_STRSIZE uLen = wsUseVal.GetLength();
371 if (uLen >= uSharpPos + 5 && 384 if (uLen >= uSharpPos + 5 &&
372 CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) == 385 CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) ==
373 FX_WSTRC(L"#som(") && 386 FX_WSTRC(L"#som(") &&
374 wsUseVal[uLen - 1] == ')') { 387 wsUseVal[uLen - 1] == ')') {
375 wsSOM = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 5, 388 wsSOM = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 5,
376 uLen - 1 - uSharpPos - 5); 389 uLen - 1 - uSharpPos - 5);
377 } else { 390 } else {
378 wsID = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 1, 391 wsID = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 1,
379 uLen - uSharpPos - 1); 392 uLen - uSharpPos - 1);
380 } 393 }
381 } 394 }
382 } else if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && 395 } else if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) &&
383 !wsUseVal.IsEmpty()) { 396 !wsUseVal.IsEmpty()) {
384 if (wsUseVal[0] == '#') { 397 if (wsUseVal[0] == '#')
385 wsID = CFX_WideStringC(wsUseVal.c_str() + 1, wsUseVal.GetLength() - 1); 398 wsID = CFX_WideStringC(wsUseVal.c_str() + 1, wsUseVal.GetLength() - 1);
386 } else { 399 else
387 wsSOM = CFX_WideStringC(wsUseVal.c_str(), wsUseVal.GetLength()); 400 wsSOM = CFX_WideStringC(wsUseVal.c_str(), wsUseVal.GetLength());
388 }
389 } 401 }
390 if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) { 402
403 if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L"."))
391 continue; 404 continue;
392 } 405
393 CXFA_Node* pProtoNode = nullptr; 406 CXFA_Node* pProtoNode = nullptr;
394 if (!wsSOM.IsEmpty()) { 407 if (!wsSOM.IsEmpty()) {
395 uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | 408 uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
396 XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | 409 XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
397 XFA_RESOLVENODE_Siblings; 410 XFA_RESOLVENODE_Siblings;
398 XFA_RESOLVENODE_RS resoveNodeRS; 411 XFA_RESOLVENODE_RS resoveNodeRS;
399 int32_t iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM, 412 int32_t iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM,
400 resoveNodeRS, dwFlag); 413 resoveNodeRS, dwFlag);
401 if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) { 414 if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
402 pProtoNode = resoveNodeRS.nodes[0]->AsNode(); 415 pProtoNode = resoveNodeRS.nodes[0]->AsNode();
403 } 416 }
404 } else if (!wsID.IsEmpty()) { 417 } else if (!wsID.IsEmpty()) {
405 if (!mIDMap.Lookup(FX_HashCode_GetW(wsID, false), pProtoNode)) { 418 if (!mIDMap.Lookup(FX_HashCode_GetW(wsID, false), pProtoNode)) {
406 continue; 419 continue;
407 } 420 }
408 } 421 }
409 if (!pProtoNode) { 422 if (!pProtoNode)
410 continue; 423 continue;
411 } 424
412 XFA_ProtoMerge_MergeNode(this, pUseHrefNode, pProtoNode); 425 MergeNode(this, pUseHrefNode, pProtoNode);
413 } 426 }
414 } 427 }
OLDNEW
« no previous file with comments | « xfa/fxfa/parser/cxfa_document.h ('k') | xfa/fxfa/parser/cxfa_document_parser.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698