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/fxfa/parser/cxfa_dataexporter.h"
8
9 #include "core/fxcrt/fx_codepage.h"
10 #include "core/fxcrt/xml/cfx_xmldoc.h"
11 #include "core/fxcrt/xml/cfx_xmlelement.h"
12 #include "core/fxcrt/xml/cfx_xmlnode.h"
13 #include "third_party/base/stl_util.h"
14 #include "xfa/fxfa/parser/cxfa_document.h"
15 #include "xfa/fxfa/parser/cxfa_node.h"
16 #include "xfa/fxfa/parser/xfa_utils.h"
17
CXFA_DataExporter(CXFA_Document * pDocument)18 CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument)
19 : m_pDocument(pDocument) {
20 ASSERT(m_pDocument);
21 }
22
~CXFA_DataExporter()23 CXFA_DataExporter::~CXFA_DataExporter() {}
24
Export(const RetainPtr<IFX_SeekableStream> & pWrite)25 bool CXFA_DataExporter::Export(const RetainPtr<IFX_SeekableStream>& pWrite) {
26 return Export(pWrite, m_pDocument->GetRoot(), 0, nullptr);
27 }
28
Export(const RetainPtr<IFX_SeekableStream> & pWrite,CXFA_Node * pNode,uint32_t dwFlag,const char * pChecksum)29 bool CXFA_DataExporter::Export(const RetainPtr<IFX_SeekableStream>& pWrite,
30 CXFA_Node* pNode,
31 uint32_t dwFlag,
32 const char* pChecksum) {
33 ASSERT(pWrite);
34 if (!pWrite)
35 return false;
36
37 auto pStream = pdfium::MakeRetain<CFX_SeekableStreamProxy>(pWrite, true);
38 pStream->SetCodePage(FX_CODEPAGE_UTF8);
39 return Export(pStream, pNode, dwFlag, pChecksum);
40 }
41
Export(const RetainPtr<CFX_SeekableStreamProxy> & pStream,CXFA_Node * pNode,uint32_t dwFlag,const char * pChecksum)42 bool CXFA_DataExporter::Export(
43 const RetainPtr<CFX_SeekableStreamProxy>& pStream,
44 CXFA_Node* pNode,
45 uint32_t dwFlag,
46 const char* pChecksum) {
47 CFX_XMLDoc* pXMLDoc = m_pDocument->GetXMLDoc();
48 if (pNode->IsModelNode()) {
49 switch (pNode->GetPacketType()) {
50 case XFA_PacketType::Xdp: {
51 pStream->WriteString(
52 L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">");
53 for (CXFA_Node* pChild = pNode->GetFirstChild(); pChild;
54 pChild = pChild->GetNextSibling()) {
55 Export(pStream, pChild, dwFlag, pChecksum);
56 }
57 pStream->WriteString(L"</xdp:xdp\n>");
58 break;
59 }
60 case XFA_PacketType::Datasets: {
61 CFX_XMLElement* pElement =
62 static_cast<CFX_XMLElement*>(pNode->GetXMLMappingNode());
63 if (!pElement || pElement->GetType() != FX_XMLNODE_Element)
64 return false;
65
66 CXFA_Node* pDataNode = pNode->GetFirstChild();
67 ASSERT(pDataNode);
68 XFA_DataExporter_DealWithDataGroupNode(pDataNode);
69 pXMLDoc->SaveXMLNode(pStream, pElement);
70 break;
71 }
72 case XFA_PacketType::Form: {
73 XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum, false);
74 break;
75 }
76 case XFA_PacketType::Template:
77 default: {
78 CFX_XMLElement* pElement =
79 static_cast<CFX_XMLElement*>(pNode->GetXMLMappingNode());
80 if (!pElement || pElement->GetType() != FX_XMLNODE_Element)
81 return false;
82
83 pXMLDoc->SaveXMLNode(pStream, pElement);
84 break;
85 }
86 }
87 return true;
88 }
89
90 CXFA_Node* pDataNode = pNode->GetParent();
91 CXFA_Node* pExportNode = pNode;
92 for (CXFA_Node* pChildNode = pDataNode->GetFirstChild(); pChildNode;
93 pChildNode = pChildNode->GetNextSibling()) {
94 if (pChildNode != pNode) {
95 pExportNode = pDataNode;
96 break;
97 }
98 }
99 CFX_XMLElement* pElement =
100 static_cast<CFX_XMLElement*>(pExportNode->GetXMLMappingNode());
101 if (!pElement || pElement->GetType() != FX_XMLNODE_Element)
102 return false;
103
104 XFA_DataExporter_DealWithDataGroupNode(pExportNode);
105 pElement->SetString(L"xmlns:xfa", L"http://www.xfa.org/schema/xfa-data/1.0/");
106 pXMLDoc->SaveXMLNode(pStream, pElement);
107 pElement->RemoveAttribute(L"xmlns:xfa");
108
109 return true;
110 }
111