Home | History | Annotate | Download | only in parser
      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