diff options
Diffstat (limited to 'core/fxcrt/xml/cfx_xmldoc.cpp')
-rw-r--r-- | core/fxcrt/xml/cfx_xmldoc.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/core/fxcrt/xml/cfx_xmldoc.cpp b/core/fxcrt/xml/cfx_xmldoc.cpp new file mode 100644 index 0000000000..4f58da91f2 --- /dev/null +++ b/core/fxcrt/xml/cfx_xmldoc.cpp @@ -0,0 +1,160 @@ +// Copyright 2017 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 "core/fxcrt/xml/cfx_xmldoc.h" + +#include <utility> +#include <vector> + +#include "core/fxcrt/fx_codepage.h" +#include "core/fxcrt/xml/cfx_xmlchardata.h" +#include "core/fxcrt/xml/cfx_xmlelement.h" +#include "core/fxcrt/xml/cfx_xmlinstruction.h" +#include "core/fxcrt/xml/cfx_xmlnode.h" +#include "core/fxcrt/xml/cfx_xmltext.h" +#include "third_party/base/ptr_util.h" +#include "third_party/base/stl_util.h" + +CFX_XMLDoc::CFX_XMLDoc() + : m_iStatus(0), m_pRoot(pdfium::MakeUnique<CFX_XMLNode>()) { + m_pRoot->InsertChildNode(new CFX_XMLInstruction(L"xml")); +} + +CFX_XMLDoc::~CFX_XMLDoc() {} + +bool CFX_XMLDoc::LoadXML(std::unique_ptr<CFX_XMLParser> pXMLParser) { + if (!pXMLParser) + return false; + + m_iStatus = 0; + m_pStream.Reset(); + m_pRoot->DeleteChildren(); + m_pXMLParser = std::move(pXMLParser); + return true; +} + +int32_t CFX_XMLDoc::DoLoad(IFX_Pause* pPause) { + if (m_iStatus < 100) + m_iStatus = m_pXMLParser->DoParser(pPause); + + return m_iStatus; +} + +void CFX_XMLDoc::CloseXML() { + m_pXMLParser.reset(); +} + +void CFX_XMLDoc::SaveXMLNode( + const CFX_RetainPtr<CFX_SeekableStreamProxy>& pXMLStream, + CFX_XMLNode* pINode) { + CFX_XMLNode* pNode = (CFX_XMLNode*)pINode; + switch (pNode->GetType()) { + case FX_XMLNODE_Instruction: { + CFX_WideString ws; + CFX_XMLInstruction* pInstruction = (CFX_XMLInstruction*)pNode; + if (pInstruction->GetName().CompareNoCase(L"xml") == 0) { + ws = L"<?xml version=\"1.0\" encoding=\""; + uint16_t wCodePage = pXMLStream->GetCodePage(); + if (wCodePage == FX_CODEPAGE_UTF16LE) { + ws += L"UTF-16"; + } else if (wCodePage == FX_CODEPAGE_UTF16BE) { + ws += L"UTF-16be"; + } else { + ws += L"UTF-8"; + } + ws += L"\"?>"; + pXMLStream->WriteString(ws.AsStringC()); + } else { + ws.Format(L"<?%s", pInstruction->GetName().c_str()); + pXMLStream->WriteString(ws.AsStringC()); + + for (auto it : pInstruction->GetAttributes()) { + CFX_WideString wsValue = it.second; + wsValue.Replace(L"&", L"&"); + wsValue.Replace(L"<", L"<"); + wsValue.Replace(L">", L">"); + wsValue.Replace(L"\'", L"'"); + wsValue.Replace(L"\"", L"""); + + ws = L" "; + ws += it.first; + ws += L"=\""; + ws += wsValue; + ws += L"\""; + pXMLStream->WriteString(ws.AsStringC()); + } + + for (auto target : pInstruction->GetTargetData()) { + ws = L" \""; + ws += target; + ws += L"\""; + pXMLStream->WriteString(ws.AsStringC()); + } + ws = L"?>"; + pXMLStream->WriteString(ws.AsStringC()); + } + break; + } + case FX_XMLNODE_Element: { + CFX_WideString ws; + ws = L"<"; + ws += static_cast<CFX_XMLElement*>(pNode)->GetName(); + pXMLStream->WriteString(ws.AsStringC()); + + for (auto it : static_cast<CFX_XMLElement*>(pNode)->GetAttributes()) { + CFX_WideString wsValue = it.second; + wsValue.Replace(L"&", L"&"); + wsValue.Replace(L"<", L"<"); + wsValue.Replace(L">", L">"); + wsValue.Replace(L"\'", L"'"); + wsValue.Replace(L"\"", L"""); + + ws = L" "; + ws += it.first; + ws += L"=\""; + ws += wsValue; + ws += L"\""; + pXMLStream->WriteString(ws.AsStringC()); + } + if (pNode->m_pChild) { + ws = L"\n>"; + pXMLStream->WriteString(ws.AsStringC()); + CFX_XMLNode* pChild = pNode->m_pChild; + while (pChild) { + SaveXMLNode(pXMLStream, static_cast<CFX_XMLNode*>(pChild)); + pChild = pChild->m_pNext; + } + ws = L"</"; + ws += static_cast<CFX_XMLElement*>(pNode)->GetName(); + ws += L"\n>"; + } else { + ws = L"\n/>"; + } + pXMLStream->WriteString(ws.AsStringC()); + break; + } + case FX_XMLNODE_Text: { + CFX_WideString ws = static_cast<CFX_XMLText*>(pNode)->GetText(); + ws.Replace(L"&", L"&"); + ws.Replace(L"<", L"<"); + ws.Replace(L">", L">"); + ws.Replace(L"\'", L"'"); + ws.Replace(L"\"", L"""); + pXMLStream->WriteString(ws.AsStringC()); + break; + } + case FX_XMLNODE_CharData: { + CFX_WideString ws = L"<![CDATA["; + ws += static_cast<CFX_XMLCharData*>(pNode)->GetText(); + ws += L"]]>"; + pXMLStream->WriteString(ws.AsStringC()); + break; + } + case FX_XMLNODE_Unknown: + default: + break; + } +} |