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

Side by Side Diff: xfa/fxfa/parser/xfa_document_imp.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
OLDNEW
(Empty)
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 "core/fxcrt/include/fx_ext.h"
8 #include "xfa/fxfa/app/xfa_ffnotify.h"
9 #include "xfa/fxfa/parser/cscript_datawindow.h"
10 #include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
11 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h"
12 #include "xfa/fxfa/parser/cscript_layoutpseudomodel.h"
13 #include "xfa/fxfa/parser/cscript_logpseudomodel.h"
14 #include "xfa/fxfa/parser/cscript_signaturepseudomodel.h"
15 #include "xfa/fxfa/parser/cxfa_document_parser.h"
16 #include "xfa/fxfa/parser/cxfa_layoutprocessor.h"
17 #include "xfa/fxfa/parser/cxfa_scriptcontext.h"
18 #include "xfa/fxfa/parser/xfa_document.h"
19 #include "xfa/fxfa/parser/xfa_localemgr.h"
20 #include "xfa/fxfa/parser/xfa_object.h"
21 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
22 #include "xfa/fxfa/parser/xfa_utils.h"
23
24 CXFA_Document::CXFA_Document(CXFA_DocumentParser* pParser)
25 : m_pParser(pParser),
26 m_pScriptContext(nullptr),
27 m_pLayoutProcessor(nullptr),
28 m_pRootNode(nullptr),
29 m_pLocalMgr(nullptr),
30 m_pScriptDataWindow(nullptr),
31 m_pScriptEvent(nullptr),
32 m_pScriptHost(nullptr),
33 m_pScriptLog(nullptr),
34 m_pScriptLayout(nullptr),
35 m_pScriptSignature(nullptr),
36 m_eCurVersionMode(XFA_VERSION_DEFAULT),
37 m_dwDocFlags(0) {
38 ASSERT(m_pParser);
39 }
40 CXFA_Document::~CXFA_Document() {
41 delete m_pRootNode;
42 PurgeNodes();
43 }
44
45 void CXFA_Document::ClearLayoutData() {
46 delete m_pLayoutProcessor;
47 m_pLayoutProcessor = nullptr;
48 delete m_pScriptContext;
49 m_pScriptContext = nullptr;
50 delete m_pLocalMgr;
51 m_pLocalMgr = nullptr;
52 delete m_pScriptDataWindow;
53 m_pScriptDataWindow = nullptr;
54 delete m_pScriptEvent;
55 m_pScriptEvent = nullptr;
56 delete m_pScriptHost;
57 m_pScriptHost = nullptr;
58 delete m_pScriptLog;
59 m_pScriptLog = nullptr;
60 delete m_pScriptLayout;
61 m_pScriptLayout = nullptr;
62 delete m_pScriptSignature;
63 m_pScriptSignature = nullptr;
64 }
65
66 void CXFA_Document::SetRoot(CXFA_Node* pNewRoot) {
67 if (m_pRootNode) {
68 AddPurgeNode(m_pRootNode);
69 }
70 m_pRootNode = pNewRoot;
71 RemovePurgeNode(pNewRoot);
72 }
73
74 CFDE_XMLDoc* CXFA_Document::GetXMLDoc() const {
75 return m_pParser->GetXMLDoc();
76 }
77
78 CXFA_FFNotify* CXFA_Document::GetNotify() const {
79 return m_pParser->GetNotify();
80 }
81
82 CXFA_Object* CXFA_Document::GetXFAObject(XFA_HashCode dwNodeNameHash) {
83 switch (dwNodeNameHash) {
84 case XFA_HASHCODE_Data: {
85 CXFA_Node* pDatasetsNode = ToNode(GetXFAObject(XFA_HASHCODE_Datasets));
86 if (!pDatasetsNode) {
87 return nullptr;
88 }
89 for (CXFA_Node* pDatasetsChild =
90 pDatasetsNode->GetFirstChildByClass(XFA_Element::DataGroup);
91 pDatasetsChild;
92 pDatasetsChild = pDatasetsChild->GetNextSameClassSibling(
93 XFA_Element::DataGroup)) {
94 if (pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data) {
95 continue;
96 }
97 CFX_WideString wsNamespaceURI;
98 if (!pDatasetsChild->TryNamespace(wsNamespaceURI)) {
99 continue;
100 }
101 CFX_WideString wsDatasetsURI;
102 if (!pDatasetsNode->TryNamespace(wsDatasetsURI)) {
103 continue;
104 }
105 if (wsNamespaceURI == wsDatasetsURI) {
106 return pDatasetsChild;
107 }
108 }
109 return nullptr;
110 }
111 case XFA_HASHCODE_Record: {
112 CXFA_Node* pData = ToNode(GetXFAObject(XFA_HASHCODE_Data));
113 return pData ? pData->GetFirstChildByClass(XFA_Element::DataGroup)
114 : nullptr;
115 }
116 case XFA_HASHCODE_DataWindow: {
117 if (!m_pScriptDataWindow)
118 m_pScriptDataWindow = new CScript_DataWindow(this);
119 return m_pScriptDataWindow;
120 }
121 case XFA_HASHCODE_Event: {
122 if (!m_pScriptEvent)
123 m_pScriptEvent = new CScript_EventPseudoModel(this);
124 return m_pScriptEvent;
125 }
126 case XFA_HASHCODE_Host: {
127 if (!m_pScriptHost)
128 m_pScriptHost = new CScript_HostPseudoModel(this);
129 return m_pScriptHost;
130 }
131 case XFA_HASHCODE_Log: {
132 if (!m_pScriptLog)
133 m_pScriptLog = new CScript_LogPseudoModel(this);
134 return m_pScriptLog;
135 }
136 case XFA_HASHCODE_Signature: {
137 if (!m_pScriptSignature)
138 m_pScriptSignature = new CScript_SignaturePseudoModel(this);
139 return m_pScriptSignature;
140 }
141 case XFA_HASHCODE_Layout: {
142 if (!m_pScriptLayout)
143 m_pScriptLayout = new CScript_LayoutPseudoModel(this);
144 return m_pScriptLayout;
145 }
146 default:
147 return m_pRootNode->GetFirstChildByName(dwNodeNameHash);
148 }
149 }
150 CXFA_Node* CXFA_Document::CreateNode(uint32_t dwPacket, XFA_Element eElement) {
151 return CreateNode(XFA_GetPacketByID(dwPacket), eElement);
152 }
153
154 CXFA_Node* CXFA_Document::CreateNode(const XFA_PACKETINFO* pPacket,
155 XFA_Element eElement) {
156 if (!pPacket)
157 return nullptr;
158
159 const XFA_ELEMENTINFO* pElement = XFA_GetElementByID(eElement);
160 if (pElement && (pElement->dwPackets & pPacket->eName)) {
161 CXFA_Node* pNode =
162 new CXFA_Node(this, pPacket->eName, pElement->eObjectType,
163 pElement->eName, pElement->pName);
164 AddPurgeNode(pNode);
165 return pNode;
166 }
167
168 return nullptr;
169 }
170
171 void CXFA_Document::AddPurgeNode(CXFA_Node* pNode) {
172 m_PurgeNodes.insert(pNode);
173 }
174
175 FX_BOOL CXFA_Document::RemovePurgeNode(CXFA_Node* pNode) {
176 return !!m_PurgeNodes.erase(pNode);
177 }
178
179 void CXFA_Document::PurgeNodes() {
180 for (CXFA_Node* pNode : m_PurgeNodes)
181 delete pNode;
182
183 m_PurgeNodes.clear();
184 }
185
186 void CXFA_Document::SetFlag(uint32_t dwFlag, FX_BOOL bOn) {
187 if (bOn) {
188 m_dwDocFlags |= dwFlag;
189 } else {
190 m_dwDocFlags &= ~dwFlag;
191 }
192 }
193 FX_BOOL CXFA_Document::IsInteractive() {
194 if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive) {
195 return !!(m_dwDocFlags & XFA_DOCFLAG_Interactive);
196 }
197 CXFA_Node* pConfig = ToNode(GetXFAObject(XFA_HASHCODE_Config));
198 if (!pConfig) {
199 return FALSE;
200 }
201 CFX_WideString wsInteractive;
202 CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_Element::Present);
203 if (!pPresent) {
204 return FALSE;
205 }
206 CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_Element::Pdf);
207 if (!pPDF) {
208 return FALSE;
209 }
210 CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_Element::Interactive);
211 if (pInteractive) {
212 m_dwDocFlags |= XFA_DOCFLAG_HasInteractive;
213 if (pInteractive->TryContent(wsInteractive) &&
214 wsInteractive == FX_WSTRC(L"1")) {
215 m_dwDocFlags |= XFA_DOCFLAG_Interactive;
216 return TRUE;
217 }
218 }
219 return FALSE;
220 }
221 CXFA_LocaleMgr* CXFA_Document::GetLocalMgr() {
222 if (!m_pLocalMgr) {
223 CFX_WideString wsLanguage;
224 GetNotify()->GetAppProvider()->GetLanguage(wsLanguage);
225 m_pLocalMgr = new CXFA_LocaleMgr(
226 ToNode(GetXFAObject(XFA_HASHCODE_LocaleSet)), wsLanguage);
227 }
228 return m_pLocalMgr;
229 }
230 CXFA_ScriptContext* CXFA_Document::InitScriptContext(v8::Isolate* pIsolate) {
231 if (!m_pScriptContext)
232 m_pScriptContext = new CXFA_ScriptContext(this);
233 m_pScriptContext->Initialize(pIsolate);
234 return m_pScriptContext;
235 }
236 CXFA_ScriptContext* CXFA_Document::GetScriptContext() {
237 if (!m_pScriptContext)
238 m_pScriptContext = new CXFA_ScriptContext(this);
239 return m_pScriptContext;
240 }
241 XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber(
242 CFX_WideString& wsTemplateNS) {
243 CFX_WideStringC wsTemplateURIPrefix =
244 XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI;
245 FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength();
246 if (CFX_WideStringC(wsTemplateNS.c_str(), wsTemplateNS.GetLength()) !=
247 wsTemplateURIPrefix) {
248 return XFA_VERSION_UNKNOWN;
249 }
250 FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength);
251 if (nDotPos == (FX_STRSIZE)-1) {
252 return XFA_VERSION_UNKNOWN;
253 }
254 int8_t iMajor = FXSYS_wtoi(
255 wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength).c_str());
256 int8_t iMinor = FXSYS_wtoi(
257 wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2)
258 .c_str());
259 XFA_VERSION eVersion = (XFA_VERSION)((int32_t)iMajor * 100 + iMinor);
260 if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX) {
261 return XFA_VERSION_UNKNOWN;
262 }
263 m_eCurVersionMode = eVersion;
264 return eVersion;
265 }
266 CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot,
267 const CFX_WideStringC& wsID) {
268 if (!pRoot || wsID.IsEmpty()) {
269 return nullptr;
270 }
271 CXFA_NodeIterator sIterator(pRoot);
272 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
273 pNode = sIterator.MoveToNext()) {
274 CFX_WideStringC wsIDVal;
275 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
276 if (wsIDVal == wsID) {
277 return pNode;
278 }
279 }
280 }
281 return nullptr;
282 }
283 static void XFA_ProtoMerge_MergeNodeRecurse(CXFA_Document* pDocument,
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() {
339 CXFA_Node* pTemplateRoot = ToNode(GetXFAObject(XFA_HASHCODE_Template));
340 if (!pTemplateRoot) {
341 return;
342 }
343 CFX_MapPtrTemplate<uint32_t, CXFA_Node*> mIDMap;
344 CXFA_NodeSet sUseNodes;
345 CXFA_NodeIterator sIterator(pTemplateRoot);
346 for (CXFA_Node* pNode = sIterator.GetCurrent(); pNode;
347 pNode = sIterator.MoveToNext()) {
348 CFX_WideStringC wsIDVal;
349 if (pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
350 mIDMap[FX_HashCode_GetW(wsIDVal, false)] = pNode;
351 }
352 CFX_WideStringC wsUseVal;
353 if (pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) {
354 sUseNodes.insert(pNode);
355 } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) &&
356 !wsUseVal.IsEmpty()) {
357 sUseNodes.insert(pNode);
358 }
359 }
360 for (CXFA_Node* pUseHrefNode : sUseNodes) {
361 CFX_WideString wsUseVal;
362 CFX_WideStringC wsURI, wsID, wsSOM;
363 if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) &&
364 !wsUseVal.IsEmpty()) {
365 FX_STRSIZE uSharpPos = wsUseVal.Find('#');
366 if (uSharpPos < 0) {
367 wsURI = wsUseVal.AsStringC();
368 } else {
369 wsURI = CFX_WideStringC(wsUseVal.c_str(), uSharpPos);
370 FX_STRSIZE uLen = wsUseVal.GetLength();
371 if (uLen >= uSharpPos + 5 &&
372 CFX_WideStringC(wsUseVal.c_str() + uSharpPos, 5) ==
373 FX_WSTRC(L"#som(") &&
374 wsUseVal[uLen - 1] == ')') {
375 wsSOM = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 5,
376 uLen - 1 - uSharpPos - 5);
377 } else {
378 wsID = CFX_WideStringC(wsUseVal.c_str() + uSharpPos + 1,
379 uLen - uSharpPos - 1);
380 }
381 }
382 } else if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) &&
383 !wsUseVal.IsEmpty()) {
384 if (wsUseVal[0] == '#') {
385 wsID = CFX_WideStringC(wsUseVal.c_str() + 1, wsUseVal.GetLength() - 1);
386 } else {
387 wsSOM = CFX_WideStringC(wsUseVal.c_str(), wsUseVal.GetLength());
388 }
389 }
390 if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) {
391 continue;
392 }
393 CXFA_Node* pProtoNode = nullptr;
394 if (!wsSOM.IsEmpty()) {
395 uint32_t dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
396 XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
397 XFA_RESOLVENODE_Siblings;
398 XFA_RESOLVENODE_RS resoveNodeRS;
399 int32_t iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM,
400 resoveNodeRS, dwFlag);
401 if (iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
402 pProtoNode = resoveNodeRS.nodes[0]->AsNode();
403 }
404 } else if (!wsID.IsEmpty()) {
405 if (!mIDMap.Lookup(FX_HashCode_GetW(wsID, false), pProtoNode)) {
406 continue;
407 }
408 }
409 if (!pProtoNode) {
410 continue;
411 }
412 XFA_ProtoMerge_MergeNode(this, pUseHrefNode, pProtoNode);
413 }
414 }
OLDNEW
« no previous file with comments | « xfa/fxfa/parser/xfa_document_datamerger_imp.cpp ('k') | xfa/fxfa/parser/xfa_document_serialize.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698