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 18 CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument) 19 : m_pDocument(pDocument) { 20 ASSERT(m_pDocument); 21 } 22 23 CXFA_DataExporter::~CXFA_DataExporter() {} 24 25 bool CXFA_DataExporter::Export(const RetainPtr<IFX_SeekableStream>& pWrite) { 26 return Export(pWrite, m_pDocument->GetRoot(), 0, nullptr); 27 } 28 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 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