OLD | NEW |
| (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 "xfa/src/fxfa/parser/xfa_document_serialize.h" | |
8 | |
9 #include "xfa/src/fgas/crt/fgas_codepage.h" | |
10 #include "xfa/src/fxfa/fm2js/xfa_fm2jsapi.h" | |
11 #include "xfa/src/fxfa/parser/xfa_docdata.h" | |
12 #include "xfa/src/fxfa/parser/xfa_doclayout.h" | |
13 #include "xfa/src/fxfa/parser/xfa_document.h" | |
14 #include "xfa/src/fxfa/parser/xfa_localemgr.h" | |
15 #include "xfa/src/fxfa/parser/xfa_object.h" | |
16 #include "xfa/src/fxfa/parser/xfa_parser.h" | |
17 #include "xfa/src/fxfa/parser/xfa_script.h" | |
18 #include "xfa/src/fxfa/parser/xfa_utils.h" | |
19 | |
20 IXFA_PacketImport* IXFA_PacketImport::Create(CXFA_Document* pDocument) { | |
21 return new CXFA_DataImporter(pDocument); | |
22 } | |
23 CXFA_DataImporter::CXFA_DataImporter(CXFA_Document* pDocument) | |
24 : m_pDocument(pDocument) { | |
25 ASSERT(m_pDocument); | |
26 } | |
27 FX_BOOL CXFA_DataImporter::ImportData(IFX_FileRead* pDataDocument) { | |
28 IXFA_Parser* pDataDocumentParser = IXFA_Parser::Create(m_pDocument); | |
29 if (!pDataDocumentParser) { | |
30 return FALSE; | |
31 } | |
32 if (pDataDocumentParser->StartParse(pDataDocument, XFA_XDPPACKET_Datasets) != | |
33 XFA_PARSESTATUS_Ready) { | |
34 pDataDocumentParser->Release(); | |
35 return FALSE; | |
36 } | |
37 if (pDataDocumentParser->DoParse(NULL) < XFA_PARSESTATUS_Done) { | |
38 pDataDocumentParser->Release(); | |
39 return FALSE; | |
40 } | |
41 CXFA_Node* pImportDataRoot = pDataDocumentParser->GetRootNode(); | |
42 if (!pImportDataRoot) { | |
43 pDataDocumentParser->Release(); | |
44 return FALSE; | |
45 } | |
46 CXFA_Node* pDataModel = | |
47 ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets)); | |
48 if (!pDataModel) { | |
49 pDataDocumentParser->Release(); | |
50 return FALSE; | |
51 } | |
52 CXFA_Node* pDataNode = ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Data)); | |
53 if (pDataNode) { | |
54 pDataModel->RemoveChild(pDataNode); | |
55 } | |
56 if (pImportDataRoot->GetClassID() == XFA_ELEMENT_DataModel) { | |
57 while (CXFA_Node* pChildNode = | |
58 pImportDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) { | |
59 pImportDataRoot->RemoveChild(pChildNode); | |
60 pDataModel->InsertChild(pChildNode); | |
61 } | |
62 } else { | |
63 IFDE_XMLNode* pXMLNode = pImportDataRoot->GetXMLMappingNode(); | |
64 IFDE_XMLNode* pParentXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent); | |
65 if (pParentXMLNode) { | |
66 pParentXMLNode->RemoveChildNode(pXMLNode); | |
67 } | |
68 pDataModel->InsertChild(pImportDataRoot); | |
69 } | |
70 m_pDocument->DoDataRemerge(FALSE); | |
71 pDataDocumentParser->Release(); | |
72 return TRUE; | |
73 } | |
74 CFX_WideString XFA_ExportEncodeAttribute(const CFX_WideString& str) { | |
75 CFX_WideTextBuf textBuf; | |
76 int32_t iLen = str.GetLength(); | |
77 for (int32_t i = 0; i < iLen; i++) { | |
78 switch (str[i]) { | |
79 case '&': | |
80 textBuf << FX_WSTRC(L"&"); | |
81 break; | |
82 case '<': | |
83 textBuf << FX_WSTRC(L"<"); | |
84 break; | |
85 case '>': | |
86 textBuf << FX_WSTRC(L">"); | |
87 break; | |
88 case '\'': | |
89 textBuf << FX_WSTRC(L"'"); | |
90 break; | |
91 case '\"': | |
92 textBuf << FX_WSTRC(L"""); | |
93 break; | |
94 default: | |
95 textBuf.AppendChar(str[i]); | |
96 } | |
97 } | |
98 return textBuf.GetWideString(); | |
99 } | |
100 CFX_WideString XFA_ExportEncodeContent(const CFX_WideStringC& str) { | |
101 CFX_WideTextBuf textBuf; | |
102 int32_t iLen = str.GetLength(); | |
103 for (int32_t i = 0; i < iLen; i++) { | |
104 FX_WCHAR ch = str.GetAt(i); | |
105 if (!FDE_IsXMLValidChar(ch)) { | |
106 continue; | |
107 } | |
108 if (ch == '&') { | |
109 textBuf << FX_WSTRC(L"&"); | |
110 } else if (ch == '<') { | |
111 textBuf << FX_WSTRC(L"<"); | |
112 } else if (ch == '>') { | |
113 textBuf << FX_WSTRC(L">"); | |
114 } else if (ch == '\'') { | |
115 textBuf << FX_WSTRC(L"'"); | |
116 } else if (ch == '\"') { | |
117 textBuf << FX_WSTRC(L"""); | |
118 } else if (ch == ' ') { | |
119 if (i && str.GetAt(i - 1) != ' ') { | |
120 textBuf.AppendChar(' '); | |
121 } else { | |
122 textBuf << FX_WSTRC(L" "); | |
123 } | |
124 } else { | |
125 textBuf.AppendChar(str.GetAt(i)); | |
126 } | |
127 } | |
128 return textBuf.GetWideString(); | |
129 } | |
130 static void XFA_SaveAttribute(CXFA_Node* pNode, | |
131 XFA_ATTRIBUTE eName, | |
132 const CFX_WideStringC& wsName, | |
133 FX_BOOL bProto, | |
134 CFX_WideString& wsOutput) { | |
135 CFX_WideString wsValue; | |
136 if ((!bProto && !pNode->HasAttribute((XFA_ATTRIBUTE)eName, bProto)) || | |
137 !pNode->GetAttribute((XFA_ATTRIBUTE)eName, wsValue, FALSE)) { | |
138 return; | |
139 } | |
140 wsValue = XFA_ExportEncodeAttribute(wsValue); | |
141 wsOutput += FX_WSTRC(L" "); | |
142 wsOutput += wsName; | |
143 wsOutput += FX_WSTRC(L"=\""); | |
144 wsOutput += wsValue; | |
145 wsOutput += FX_WSTRC(L"\""); | |
146 } | |
147 static FX_BOOL XFA_DataExporter_AttributeSaveInDataModel( | |
148 CXFA_Node* pNode, | |
149 XFA_ATTRIBUTE eAttribute) { | |
150 FX_BOOL bSaveInDataModel = FALSE; | |
151 if (pNode->GetClassID() != XFA_ELEMENT_Image) { | |
152 return bSaveInDataModel; | |
153 } | |
154 CXFA_Node* pValueNode = pNode->GetNodeItem(XFA_NODEITEM_Parent); | |
155 if (!pValueNode || pValueNode->GetClassID() != XFA_ELEMENT_Value) { | |
156 return bSaveInDataModel; | |
157 } | |
158 CXFA_Node* pFieldNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent); | |
159 if (pFieldNode && pFieldNode->GetBindData() && | |
160 eAttribute == XFA_ATTRIBUTE_Href) { | |
161 bSaveInDataModel = TRUE; | |
162 } | |
163 return bSaveInDataModel; | |
164 } | |
165 FX_BOOL XFA_DataExporter_ContentNodeNeedtoExport(CXFA_Node* pContentNode) { | |
166 CFX_WideString wsContent; | |
167 if (!pContentNode->TryContent(wsContent, FALSE, FALSE)) { | |
168 return FALSE; | |
169 } | |
170 FXSYS_assert(pContentNode->GetObjectType() == XFA_OBJECTTYPE_ContentNode); | |
171 CXFA_Node* pParentNode = pContentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
172 if (!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Value) { | |
173 return TRUE; | |
174 } | |
175 CXFA_Node* pGrandParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
176 if (!pGrandParentNode || | |
177 pGrandParentNode->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) { | |
178 return TRUE; | |
179 } | |
180 if (pGrandParentNode->GetBindData()) { | |
181 return FALSE; | |
182 } | |
183 CXFA_WidgetData* pWidgetData = pGrandParentNode->GetWidgetData(); | |
184 XFA_ELEMENT eUIType = pWidgetData->GetUIType(); | |
185 if (eUIType == XFA_ELEMENT_PasswordEdit) { | |
186 return FALSE; | |
187 } | |
188 return TRUE; | |
189 } | |
190 static void XFA_DataExporter_RecognizeXFAVersionNumber( | |
191 CXFA_Node* pTemplateRoot, | |
192 CFX_WideString& wsVersionNumber) { | |
193 wsVersionNumber.Empty(); | |
194 if (!pTemplateRoot) { | |
195 return; | |
196 } | |
197 CFX_WideString wsTemplateNS; | |
198 if (!pTemplateRoot->TryNamespace(wsTemplateNS)) { | |
199 return; | |
200 } | |
201 XFA_VERSION eVersion = | |
202 pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(wsTemplateNS); | |
203 if (eVersion == XFA_VERSION_UNKNOWN) { | |
204 eVersion = XFA_VERSION_DEFAULT; | |
205 } | |
206 wsVersionNumber.Format(L"%i.%i", eVersion / 100, eVersion % 100); | |
207 } | |
208 static void XFA_DataExporter_RegenerateFormFile_Changed( | |
209 CXFA_Node* pNode, | |
210 CFX_WideTextBuf& buf, | |
211 FX_BOOL bSaveXML = FALSE) { | |
212 CFX_WideString wsAttrs; | |
213 int32_t iAttrs = 0; | |
214 const uint8_t* pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs); | |
215 while (iAttrs--) { | |
216 const XFA_ATTRIBUTEINFO* pAttr = | |
217 XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]); | |
218 if (pAttr->eName == XFA_ATTRIBUTE_Name || | |
219 (XFA_DataExporter_AttributeSaveInDataModel(pNode, pAttr->eName) && | |
220 !bSaveXML)) { | |
221 continue; | |
222 } | |
223 CFX_WideString wsAttr; | |
224 XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, bSaveXML, wsAttr); | |
225 wsAttrs += wsAttr; | |
226 } | |
227 CFX_WideString wsChildren; | |
228 switch (pNode->GetObjectType()) { | |
229 case XFA_OBJECTTYPE_ContentNode: { | |
230 if (!bSaveXML && !XFA_DataExporter_ContentNodeNeedtoExport(pNode)) { | |
231 break; | |
232 } | |
233 CXFA_Node* pRawValueNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
234 while (pRawValueNode && | |
235 pRawValueNode->GetClassID() != XFA_ELEMENT_SharpxHTML && | |
236 pRawValueNode->GetClassID() != XFA_ELEMENT_Sharptext && | |
237 pRawValueNode->GetClassID() != XFA_ELEMENT_Sharpxml) { | |
238 pRawValueNode = pRawValueNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
239 } | |
240 if (!pRawValueNode) { | |
241 break; | |
242 } | |
243 CFX_WideString wsContentType; | |
244 pNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE); | |
245 if (pRawValueNode->GetClassID() == XFA_ELEMENT_SharpxHTML && | |
246 wsContentType.Equal(FX_WSTRC(L"text/html"))) { | |
247 IFDE_XMLNode* pExDataXML = pNode->GetXMLMappingNode(); | |
248 if (!pExDataXML) { | |
249 break; | |
250 } | |
251 IFDE_XMLNode* pRichTextXML = | |
252 pExDataXML->GetNodeItem(IFDE_XMLNode::FirstChild); | |
253 if (!pRichTextXML) { | |
254 break; | |
255 } | |
256 IFX_MemoryStream* pMemStream = FX_CreateMemoryStream(TRUE); | |
257 IFX_Stream* pTempStream = IFX_Stream::CreateStream( | |
258 (IFX_FileWrite*)pMemStream, FX_STREAMACCESS_Text | | |
259 FX_STREAMACCESS_Write | | |
260 FX_STREAMACCESS_Append); | |
261 pTempStream->SetCodePage(FX_CODEPAGE_UTF8); | |
262 pRichTextXML->SaveXMLNode(pTempStream); | |
263 wsChildren += CFX_WideString::FromUTF8( | |
264 (const FX_CHAR*)pMemStream->GetBuffer(), pMemStream->GetSize()); | |
265 pTempStream->Release(); | |
266 pMemStream->Release(); | |
267 } else if (pRawValueNode->GetClassID() == XFA_ELEMENT_Sharpxml && | |
268 wsContentType.Equal(FX_WSTRC(L"text/xml"))) { | |
269 CFX_WideString wsRawValue; | |
270 pRawValueNode->GetAttribute(XFA_ATTRIBUTE_Value, wsRawValue, FALSE); | |
271 if (wsRawValue.IsEmpty()) { | |
272 break; | |
273 } | |
274 CFX_WideStringArray wsSelTextArray; | |
275 int32_t iStart = 0; | |
276 int32_t iEnd = wsRawValue.Find(L'\n', iStart); | |
277 iEnd = (iEnd == -1) ? wsRawValue.GetLength() : iEnd; | |
278 while (iEnd >= iStart) { | |
279 wsSelTextArray.Add(wsRawValue.Mid(iStart, iEnd - iStart)); | |
280 iStart = iEnd + 1; | |
281 if (iStart >= wsRawValue.GetLength()) { | |
282 break; | |
283 } | |
284 iEnd = wsRawValue.Find(L'\n', iStart); | |
285 } | |
286 CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent); | |
287 FXSYS_assert(pParentNode); | |
288 CXFA_Node* pGrandparentNode = | |
289 pParentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
290 FXSYS_assert(pGrandparentNode); | |
291 CFX_WideString bodyTagName; | |
292 bodyTagName = pGrandparentNode->GetCData(XFA_ATTRIBUTE_Name); | |
293 if (bodyTagName.IsEmpty()) { | |
294 bodyTagName = FX_WSTRC(L"ListBox1"); | |
295 } | |
296 buf << FX_WSTRC(L"<"); | |
297 buf << bodyTagName; | |
298 buf << FX_WSTRC(L" xmlns=\"\"\n>"); | |
299 for (int32_t i = 0; i < wsSelTextArray.GetSize(); i++) { | |
300 buf << FX_WSTRC(L"<value\n>"); | |
301 buf << XFA_ExportEncodeContent(wsSelTextArray[i]); | |
302 buf << FX_WSTRC(L"</value\n>"); | |
303 } | |
304 buf << FX_WSTRC(L"</"); | |
305 buf << bodyTagName; | |
306 buf << FX_WSTRC(L"\n>"); | |
307 wsChildren += buf.GetWideString(); | |
308 buf.Clear(); | |
309 } else { | |
310 CFX_WideStringC wsValue = pRawValueNode->GetCData(XFA_ATTRIBUTE_Value); | |
311 wsChildren += XFA_ExportEncodeContent(wsValue); | |
312 } | |
313 } break; | |
314 case XFA_OBJECTTYPE_TextNode: | |
315 case XFA_OBJECTTYPE_NodeC: | |
316 case XFA_OBJECTTYPE_NodeV: { | |
317 CFX_WideStringC wsValue = pNode->GetCData(XFA_ATTRIBUTE_Value); | |
318 wsChildren += XFA_ExportEncodeContent(wsValue); | |
319 } break; | |
320 default: | |
321 if (pNode->GetClassID() == XFA_ELEMENT_Items) { | |
322 CXFA_Node* pTemplateNode = pNode->GetTemplateNode(); | |
323 if (!pTemplateNode || | |
324 pTemplateNode->CountChildren(XFA_ELEMENT_UNKNOWN) != | |
325 pNode->CountChildren(XFA_ELEMENT_UNKNOWN)) { | |
326 bSaveXML = TRUE; | |
327 } | |
328 } | |
329 CFX_WideTextBuf newBuf; | |
330 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
331 while (pChildNode) { | |
332 XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf, | |
333 bSaveXML); | |
334 wsChildren += newBuf.GetWideString(); | |
335 newBuf.Clear(); | |
336 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
337 } | |
338 if (!bSaveXML && !wsChildren.IsEmpty() && | |
339 pNode->GetClassID() == XFA_ELEMENT_Items) { | |
340 wsChildren.Empty(); | |
341 bSaveXML = TRUE; | |
342 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
343 while (pChildNode) { | |
344 XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf, | |
345 bSaveXML); | |
346 wsChildren += newBuf.GetWideString(); | |
347 newBuf.Clear(); | |
348 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
349 } | |
350 } | |
351 break; | |
352 } | |
353 if (!wsChildren.IsEmpty() || !wsAttrs.IsEmpty() || | |
354 pNode->HasAttribute(XFA_ATTRIBUTE_Name)) { | |
355 CFX_WideStringC wsElement; | |
356 pNode->GetClassName(wsElement); | |
357 CFX_WideString wsName; | |
358 XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE, | |
359 wsName); | |
360 buf << FX_WSTRC(L"<"); | |
361 buf << wsElement; | |
362 buf << wsName; | |
363 buf << wsAttrs; | |
364 if (wsChildren.IsEmpty()) { | |
365 buf << FX_WSTRC(L"\n/>"); | |
366 } else { | |
367 buf << FX_WSTRC(L"\n>"); | |
368 buf << wsChildren; | |
369 buf << FX_WSTRC(L"</"); | |
370 buf << wsElement; | |
371 buf << FX_WSTRC(L"\n>"); | |
372 } | |
373 } | |
374 } | |
375 static void XFA_DataExporter_RegenerateFormFile_Container( | |
376 CXFA_Node* pNode, | |
377 IFX_Stream* pStream, | |
378 FX_BOOL bSaveXML = FALSE) { | |
379 XFA_ELEMENT eElement = pNode->GetClassID(); | |
380 if (eElement == XFA_ELEMENT_Field || eElement == XFA_ELEMENT_Draw || | |
381 !pNode->IsContainerNode()) { | |
382 CFX_WideTextBuf buf; | |
383 XFA_DataExporter_RegenerateFormFile_Changed(pNode, buf, bSaveXML); | |
384 FX_STRSIZE nLen = buf.GetLength(); | |
385 if (nLen > 0) { | |
386 pStream->WriteString((const FX_WCHAR*)buf.GetBuffer(), nLen); | |
387 } | |
388 return; | |
389 } | |
390 CFX_WideStringC wsElement; | |
391 pNode->GetClassName(wsElement); | |
392 pStream->WriteString(L"<", 1); | |
393 pStream->WriteString(wsElement.GetPtr(), wsElement.GetLength()); | |
394 CFX_WideString wsOutput; | |
395 XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE, | |
396 wsOutput); | |
397 CFX_WideString wsAttrs; | |
398 int32_t iAttrs = 0; | |
399 const uint8_t* pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs); | |
400 while (iAttrs--) { | |
401 const XFA_ATTRIBUTEINFO* pAttr = | |
402 XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]); | |
403 if (pAttr->eName == XFA_ATTRIBUTE_Name) { | |
404 continue; | |
405 } | |
406 CFX_WideString wsAttr; | |
407 XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, FALSE, wsAttr); | |
408 wsOutput += wsAttr; | |
409 } | |
410 if (!wsOutput.IsEmpty()) { | |
411 pStream->WriteString((const FX_WCHAR*)wsOutput, wsOutput.GetLength()); | |
412 } | |
413 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
414 if (pChildNode) { | |
415 pStream->WriteString(L"\n>", 2); | |
416 while (pChildNode) { | |
417 XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream, | |
418 bSaveXML); | |
419 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
420 } | |
421 pStream->WriteString(L"</", 2); | |
422 pStream->WriteString(wsElement.GetPtr(), wsElement.GetLength()); | |
423 pStream->WriteString(L"\n>", 2); | |
424 } else { | |
425 pStream->WriteString(L"\n/>", 3); | |
426 } | |
427 } | |
428 void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, | |
429 IFX_Stream* pStream, | |
430 const FX_CHAR* pChecksum, | |
431 FX_BOOL bSaveXML) { | |
432 if (pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) { | |
433 static const FX_WCHAR* s_pwsTagName = L"<form"; | |
434 static const FX_WCHAR* s_pwsClose = L"</form\n>"; | |
435 pStream->WriteString(s_pwsTagName, FXSYS_wcslen(s_pwsTagName)); | |
436 if (pChecksum) { | |
437 static const FX_WCHAR* s_pwChecksum = L" checksum=\""; | |
438 CFX_WideString wsChecksum = | |
439 CFX_WideString::FromUTF8(pChecksum, FXSYS_strlen(pChecksum)); | |
440 pStream->WriteString(s_pwChecksum, FXSYS_wcslen(s_pwChecksum)); | |
441 pStream->WriteString((const FX_WCHAR*)wsChecksum, wsChecksum.GetLength()); | |
442 pStream->WriteString(L"\"", 1); | |
443 } | |
444 pStream->WriteString(L" xmlns=\"", FXSYS_wcslen(L" xmlns=\"")); | |
445 const FX_WCHAR* pURI = XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI; | |
446 pStream->WriteString(pURI, FXSYS_wcslen(pURI)); | |
447 CFX_WideString wsVersionNumber; | |
448 XFA_DataExporter_RecognizeXFAVersionNumber( | |
449 ToNode(pNode->GetDocument()->GetXFAObject(XFA_XDPPACKET_Template)), | |
450 wsVersionNumber); | |
451 if (wsVersionNumber.IsEmpty()) { | |
452 wsVersionNumber = FX_WSTRC(L"2.8"); | |
453 } | |
454 wsVersionNumber += FX_WSTRC(L"/\"\n>"); | |
455 pStream->WriteString((const FX_WCHAR*)wsVersionNumber, | |
456 wsVersionNumber.GetLength()); | |
457 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
458 while (pChildNode) { | |
459 XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream); | |
460 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
461 } | |
462 pStream->WriteString(s_pwsClose, FXSYS_wcslen(s_pwsClose)); | |
463 } else { | |
464 XFA_DataExporter_RegenerateFormFile_Container(pNode, pStream, bSaveXML); | |
465 } | |
466 } | |
467 IXFA_PacketExport* IXFA_PacketExport::Create(CXFA_Document* pDocument, | |
468 XFA_DATAFORMAT eFormat) { | |
469 return new CXFA_DataExporter(pDocument); | |
470 } | |
471 CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument) | |
472 : m_pDocument(pDocument) { | |
473 ASSERT(m_pDocument); | |
474 } | |
475 FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite) { | |
476 return Export(pWrite, m_pDocument->GetRoot()); | |
477 } | |
478 FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite, | |
479 CXFA_Node* pNode, | |
480 FX_DWORD dwFlag, | |
481 const FX_CHAR* pChecksum) { | |
482 if (!pWrite) { | |
483 ASSERT(false); | |
484 return FALSE; | |
485 } | |
486 IFX_Stream* pStream = IFX_Stream::CreateStream( | |
487 pWrite, | |
488 FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append); | |
489 if (pStream == NULL) { | |
490 return FALSE; | |
491 } | |
492 pStream->SetCodePage(FX_CODEPAGE_UTF8); | |
493 FX_BOOL bRet = Export(pStream, pNode, dwFlag, pChecksum); | |
494 pStream->Release(); | |
495 return bRet; | |
496 } | |
497 FX_BOOL CXFA_DataExporter::Export(IFX_Stream* pStream, | |
498 CXFA_Node* pNode, | |
499 FX_DWORD dwFlag, | |
500 const FX_CHAR* pChecksum) { | |
501 IFDE_XMLDoc* pXMLDoc = m_pDocument->GetParser()->GetXMLDoc(); | |
502 if (pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) { | |
503 switch (pNode->GetPacketID()) { | |
504 case XFA_XDPPACKET_XDP: { | |
505 static const FX_WCHAR* s_pwsPreamble = | |
506 L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">"; | |
507 pStream->WriteString(s_pwsPreamble, FXSYS_wcslen(s_pwsPreamble)); | |
508 for (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
509 pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
510 Export(pStream, pChild, dwFlag, pChecksum); | |
511 } | |
512 static const FX_WCHAR* s_pwsPostamble = L"</xdp:xdp\n>"; | |
513 pStream->WriteString(s_pwsPostamble, FXSYS_wcslen(s_pwsPostamble)); | |
514 } break; | |
515 case XFA_XDPPACKET_Datasets: { | |
516 IFDE_XMLElement* pElement = | |
517 (IFDE_XMLElement*)pNode->GetXMLMappingNode(); | |
518 if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) { | |
519 return FALSE; | |
520 } | |
521 CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
522 FXSYS_assert(pDataNode); | |
523 XFA_DataExporter_DealWithDataGroupNode(pDataNode); | |
524 pXMLDoc->SaveXMLNode(pStream, pElement); | |
525 } break; | |
526 case XFA_XDPPACKET_Form: { | |
527 XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum); | |
528 } break; | |
529 case XFA_XDPPACKET_Template: | |
530 default: { | |
531 IFDE_XMLElement* pElement = | |
532 (IFDE_XMLElement*)pNode->GetXMLMappingNode(); | |
533 if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) { | |
534 return FALSE; | |
535 } | |
536 pXMLDoc->SaveXMLNode(pStream, pElement); | |
537 } break; | |
538 } | |
539 } else { | |
540 CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_Parent); | |
541 CXFA_Node* pExportNode = pNode; | |
542 for (CXFA_Node* pChildNode = | |
543 pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
544 pChildNode; | |
545 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
546 if (pChildNode != pNode) { | |
547 pExportNode = pDataNode; | |
548 break; | |
549 } | |
550 } | |
551 IFDE_XMLElement* pElement = | |
552 (IFDE_XMLElement*)pExportNode->GetXMLMappingNode(); | |
553 if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) { | |
554 return FALSE; | |
555 } | |
556 XFA_DataExporter_DealWithDataGroupNode(pExportNode); | |
557 pElement->SetString(FX_WSTRC(L"xmlns:xfa"), | |
558 FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/")); | |
559 pXMLDoc->SaveXMLNode(pStream, pElement); | |
560 pElement->RemoveAttribute(L"xmlns:xfa"); | |
561 } | |
562 return TRUE; | |
563 } | |
564 void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode) { | |
565 if (!pDataNode || pDataNode->GetClassID() == XFA_ELEMENT_DataValue) { | |
566 return; | |
567 } | |
568 int32_t iChildNum = 0; | |
569 for (CXFA_Node* pChildNode = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
570 pChildNode; | |
571 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
572 iChildNum++; | |
573 XFA_DataExporter_DealWithDataGroupNode(pChildNode); | |
574 } | |
575 if (pDataNode->GetClassID() == XFA_ELEMENT_DataGroup) { | |
576 if (iChildNum > 0) { | |
577 IFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode(); | |
578 FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element); | |
579 IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode; | |
580 if (pXMLElement->HasAttribute(L"xfa:dataNode")) { | |
581 pXMLElement->RemoveAttribute(L"xfa:dataNode"); | |
582 } | |
583 } else { | |
584 IFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode(); | |
585 FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element); | |
586 ((IFDE_XMLElement*)pXMLNode) | |
587 ->SetString(FX_WSTRC(L"xfa:dataNode"), FX_WSTRC(L"dataGroup")); | |
588 } | |
589 } | |
590 } | |
OLD | NEW |