From 3cb7fdea950dd2d0377f0d9ad8a88fcb7c48b842 Mon Sep 17 00:00:00 2001 From: Jedidiah Barber Date: Wed, 14 Jul 2021 11:27:03 +1200 Subject: Initial mirror commit --- Main/Xml.cpp | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 Main/Xml.cpp (limited to 'Main/Xml.cpp') diff --git a/Main/Xml.cpp b/Main/Xml.cpp new file mode 100644 index 0000000..d70c0f7 --- /dev/null +++ b/Main/Xml.cpp @@ -0,0 +1,178 @@ +/* + Copyright (c) 2008 TrueCrypt Developers Association. All rights reserved. + + Governed by the TrueCrypt License 3.0 the full text of which is contained in + the file License.txt included in TrueCrypt binary and source code distribution + packages. +*/ + +#include "System.h" +#include +#include "Platform/FileStream.h" +#include "Xml.h" + +namespace TrueCrypt +{ + XmlParser::XmlParser (const FilePath &fileName) + { + make_shared_auto (File, file); + file->Open (fileName); + FileStream stream (file); + + XmlText = wxString::FromUTF8 (stream.ReadToEnd().c_str()); + } + + wxString XmlParser::ConvertEscapedChars (wxString xmlString) const + { + xmlString.Replace (L"<", L"<"); + xmlString.Replace (L">", L">"); + xmlString.Replace (L"&", L"&"); + xmlString.Replace (L""", L"\""); + return xmlString; + } + + XmlNodeList XmlParser::GetNodes (const wxString &nodeName) const + { + XmlNodeList nodeList; + + size_t nodePos = 0; + while ((nodePos = XmlText.find (L"<" + nodeName, nodePos)) != string::npos) + { + XmlNode xmlNode; + xmlNode.Name = nodeName; + + size_t nodeEnd = XmlText.find (L">", nodePos); + if (nodeEnd == string::npos) + throw ParameterIncorrect (SRC_POS); + + wxString nodeTagText = XmlText.substr (nodePos + 1, nodeEnd - nodePos - 1); + nodePos = nodeEnd; + + if (nodeTagText.size() > nodeName.size() && nodeTagText[nodeName.size()] != L' ' && nodeTagText[nodeName.size()] != L'/') + continue; + + nodeTagText = nodeTagText.substr (nodeName.size()); + + + // Attributes + wxStringTokenizer tokenizer (nodeTagText, L"\"", wxTOKEN_RET_EMPTY); + while (tokenizer.HasMoreTokens()) + { + wxString attributeName = tokenizer.GetNextToken(); + attributeName.Replace (L" ", L"", true); + attributeName.Replace (L"=", L""); + + if (!attributeName.empty() && tokenizer.HasMoreTokens()) + { + wxString attributeText = tokenizer.GetNextToken(); + xmlNode.Attributes[attributeName] = ConvertEscapedChars (attributeText); + } + } + + // Inner text + if (!nodeTagText.EndsWith (L"/")) + { + size_t innerTextPos = nodeEnd + 1; + size_t innerTextEnd = XmlText.find (L"", innerTextPos); + if (innerTextEnd == string::npos) + throw ParameterIncorrect (SRC_POS); + + xmlNode.InnerText = ConvertEscapedChars (XmlText.substr (innerTextPos, innerTextEnd - innerTextPos)); + nodePos = innerTextEnd; + } + + nodeList.push_back (xmlNode); + } + + return nodeList; + } + + XmlWriter::XmlWriter (const FilePath &fileName) + { + MemOutStream.reset (new wxMemoryOutputStream); + TextOutStream.reset (new wxTextOutputStream (*MemOutStream)); + OutFile.Open (fileName, File::CreateWrite); + + *TextOutStream << L"" << endl << L"" << endl; + CurrentIndentLevel = 0; + } + + void XmlWriter::Close() + { + if (MemOutStream.get()) + { + *TextOutStream << L"" << endl; + + wxStreamBuffer *buf = MemOutStream->GetOutputStreamBuffer(); + OutFile.Write (ConstBufferPtr (reinterpret_cast (buf->GetBufferStart()), buf->GetBufferSize())); + OutFile.Close(); + + TextOutStream.reset(); + MemOutStream.reset(); + } + } + + wxString XmlWriter::EscapeChars (wxString rawString) const + { + rawString.Replace (L"<", L"<"); + rawString.Replace (L">", L">"); + rawString.Replace (L"&", L"&"); + rawString.Replace (L"\"", L"""); + return rawString; + } + + void XmlWriter::WriteNode (const XmlNode &xmlNode) + { + XmlNodeList nodes; + nodes.push_back (xmlNode); + WriteNodes (nodes); + } + + void XmlWriter::WriteNodes (const XmlNodeList &xmlNodes) + { + CurrentIndentLevel++; + wxString indent; + for (int i = 0; i < CurrentIndentLevel; ++i) + indent += L"\t"; + + foreach (const XmlNode &node, xmlNodes) + { + *TextOutStream << indent << L"<" << node.Name; + + typedef pair AttribPair; + foreach (AttribPair attrib, node.Attributes) + { + *TextOutStream << L" " << attrib.first << L"=\"" << EscapeChars (attrib.second) << L"\""; + } + + if (!node.InnerNodes.empty()) + { + *TextOutStream << L">" << endl; + WriteNodes (node.InnerNodes); + *TextOutStream << indent; + } + else if (!node.InnerText.empty()) + { + *TextOutStream << L">" << EscapeChars (node.InnerText); + } + else + { + *TextOutStream << L"/>" << endl; + continue; + } + + *TextOutStream << L"" << endl; + } + + CurrentIndentLevel--; + } + + XmlWriter::~XmlWriter () + { + try + { + Close(); + } + catch (...) { } + } +} -- cgit