summaryrefslogtreecommitdiff
path: root/xfa/fxfa/parser/cxfa_dataexporter.cpp
blob: 4f10d0ddfeec0ed207d5179c8d89ff41b1975898 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/parser/cxfa_dataexporter.h"

#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/xml/cfx_xmldoc.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "third_party/base/stl_util.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/xfa_utils.h"

CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument)
    : m_pDocument(pDocument) {
  ASSERT(m_pDocument);
}

CXFA_DataExporter::~CXFA_DataExporter() {}

bool CXFA_DataExporter::Export(const RetainPtr<IFX_SeekableStream>& pWrite) {
  return Export(pWrite, m_pDocument->GetRoot(), 0, nullptr);
}

bool CXFA_DataExporter::Export(const RetainPtr<IFX_SeekableStream>& pWrite,
                               CXFA_Node* pNode,
                               uint32_t dwFlag,
                               const char* pChecksum) {
  ASSERT(pWrite);
  if (!pWrite)
    return false;

  auto pStream = pdfium::MakeRetain<CFX_SeekableStreamProxy>(pWrite, true);
  pStream->SetCodePage(FX_CODEPAGE_UTF8);
  return Export(pStream, pNode, dwFlag, pChecksum);
}

bool CXFA_DataExporter::Export(
    const RetainPtr<CFX_SeekableStreamProxy>& pStream,
    CXFA_Node* pNode,
    uint32_t dwFlag,
    const char* pChecksum) {
  if (pNode->IsModelNode()) {
    switch (pNode->GetPacketType()) {
      case XFA_PacketType::Xdp: {
        pStream->WriteString(
            L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">");
        for (CXFA_Node* pChild = pNode->GetFirstChild(); pChild;
             pChild = pChild->GetNextSibling()) {
          Export(pStream, pChild, dwFlag, pChecksum);
        }
        pStream->WriteString(L"</xdp:xdp\n>");
        break;
      }
      case XFA_PacketType::Datasets: {
        CFX_XMLElement* pElement =
            static_cast<CFX_XMLElement*>(pNode->GetXMLMappingNode());
        if (!pElement || pElement->GetType() != FX_XMLNODE_Element)
          return false;

        CXFA_Node* pDataNode = pNode->GetFirstChild();
        ASSERT(pDataNode);
        XFA_DataExporter_DealWithDataGroupNode(pDataNode);
        pElement->Save(pStream);
        break;
      }
      case XFA_PacketType::Form: {
        XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum, false);
        break;
      }
      case XFA_PacketType::Template:
      default: {
        CFX_XMLElement* pElement =
            static_cast<CFX_XMLElement*>(pNode->GetXMLMappingNode());
        if (!pElement || pElement->GetType() != FX_XMLNODE_Element)
          return false;

        pElement->Save(pStream);
        break;
      }
    }
    return true;
  }

  CXFA_Node* pDataNode = pNode->GetParent();
  CXFA_Node* pExportNode = pNode;
  for (CXFA_Node* pChildNode = pDataNode->GetFirstChild(); pChildNode;
       pChildNode = pChildNode->GetNextSibling()) {
    if (pChildNode != pNode) {
      pExportNode = pDataNode;
      break;
    }
  }
  CFX_XMLElement* pElement =
      static_cast<CFX_XMLElement*>(pExportNode->GetXMLMappingNode());
  if (!pElement || pElement->GetType() != FX_XMLNODE_Element)
    return false;

  XFA_DataExporter_DealWithDataGroupNode(pExportNode);
  pElement->SetString(L"xmlns:xfa", L"http://www.xfa.org/schema/xfa-data/1.0/");
  pElement->Save(pStream);
  pElement->RemoveAttribute(L"xmlns:xfa");

  return true;
}