|
|
1.1 root 1: /*
2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved.
3:
4: Governed by the TrueCrypt License 2.4 the full text of which is contained
5: in the file License.txt included in TrueCrypt binary and source code
6: distribution packages.
7: */
8:
9: #include "System.h"
10: #include <wx/tokenzr.h>
11: #include "Platform/FileStream.h"
12: #include "Xml.h"
13:
14: namespace TrueCrypt
15: {
16: XmlParser::XmlParser (const FilePath &fileName)
17: {
18: make_shared_auto (File, file);
19: file->Open (fileName);
20: FileStream stream (file);
21:
22: XmlText = wxString::FromUTF8 (stream.ReadToEnd().c_str());
23: }
24:
25: wxString XmlParser::ConvertEscapedChars (wxString xmlString) const
26: {
27: xmlString.Replace (L"<", L"<");
28: xmlString.Replace (L">", L">");
29: xmlString.Replace (L"&", L"&");
30: xmlString.Replace (L""", L"\"");
31: return xmlString;
32: }
33:
34: XmlNodeList XmlParser::GetNodes (const wxString &nodeName) const
35: {
36: XmlNodeList nodeList;
37:
38: size_t nodePos = 0;
39: while ((nodePos = XmlText.find (L"<" + nodeName, nodePos)) != string::npos)
40: {
41: XmlNode xmlNode;
42: xmlNode.Name = nodeName;
43:
44: size_t nodeEnd = XmlText.find (L">", nodePos);
45: if (nodeEnd == string::npos)
46: throw ParameterIncorrect (SRC_POS);
47:
48: wxString nodeTagText = XmlText.substr (nodePos + 1, nodeEnd - nodePos - 1);
49: nodePos = nodeEnd;
50:
51: if (nodeTagText.size() > nodeName.size() && nodeTagText[nodeName.size()] != L' ' && nodeTagText[nodeName.size()] != L'/')
52: continue;
53:
54: nodeTagText = nodeTagText.substr (nodeName.size());
55:
56:
57: // Attributes
58: wxStringTokenizer tokenizer (nodeTagText, L"\"", wxTOKEN_RET_EMPTY);
59: while (tokenizer.HasMoreTokens())
60: {
61: wxString attributeName = tokenizer.GetNextToken();
62: attributeName.Replace (L" ", L"", true);
63: attributeName.Replace (L"=", L"");
64:
65: if (!attributeName.empty() && tokenizer.HasMoreTokens())
66: {
67: wxString attributeText = tokenizer.GetNextToken();
68: xmlNode.Attributes[attributeName] = ConvertEscapedChars (attributeText);
69: }
70: }
71:
72: // Inner text
73: if (!nodeTagText.EndsWith (L"/"))
74: {
75: size_t innerTextPos = nodeEnd + 1;
76: size_t innerTextEnd = XmlText.find (L"</" + nodeName + L">", innerTextPos);
77: if (innerTextEnd == string::npos)
78: throw ParameterIncorrect (SRC_POS);
79:
80: xmlNode.InnerText = ConvertEscapedChars (XmlText.substr (innerTextPos, innerTextEnd - innerTextPos));
81: nodePos = innerTextEnd;
82: }
83:
84: nodeList.push_back (xmlNode);
85: }
86:
87: return nodeList;
88: }
89:
90: XmlWriter::XmlWriter (const FilePath &fileName)
91: {
92: MemOutStream.reset (new wxMemoryOutputStream);
93: TextOutStream.reset (new wxTextOutputStream (*MemOutStream));
94: OutFile.Open (fileName, File::CreateWrite);
95:
96: *TextOutStream << L"<?xml version=\"1.0\" encoding=\"utf-8\"?>" << endl << L"<TrueCrypt>" << endl;
97: CurrentIndentLevel = 0;
98: }
99:
100: void XmlWriter::Close()
101: {
102: if (MemOutStream.get())
103: {
104: *TextOutStream << L"</TrueCrypt>" << endl;
105:
106: wxStreamBuffer *buf = MemOutStream->GetOutputStreamBuffer();
107: OutFile.Write (ConstBufferPtr (reinterpret_cast <byte *> (buf->GetBufferStart()), buf->GetBufferSize()));
108: OutFile.Close();
109:
110: TextOutStream.reset();
111: MemOutStream.reset();
112: }
113: }
114:
115: wxString XmlWriter::EscapeChars (wxString rawString) const
116: {
117: rawString.Replace (L"<", L"<");
118: rawString.Replace (L">", L">");
119: rawString.Replace (L"&", L"&");
120: rawString.Replace (L"\"", L""");
121: return rawString;
122: }
123:
124: void XmlWriter::WriteNode (const XmlNode &xmlNode)
125: {
126: XmlNodeList nodes;
127: nodes.push_back (xmlNode);
128: WriteNodes (nodes);
129: }
130:
131: void XmlWriter::WriteNodes (const XmlNodeList &xmlNodes)
132: {
133: CurrentIndentLevel++;
134: wxString indent;
135: for (int i = 0; i < CurrentIndentLevel; ++i)
136: indent += L"\t";
137:
138: foreach (const XmlNode &node, xmlNodes)
139: {
140: *TextOutStream << indent << L"<" << node.Name;
141:
142: typedef pair <wxString, wxString> AttribPair;
143: foreach (AttribPair attrib, node.Attributes)
144: {
145: *TextOutStream << L" " << attrib.first << L"=\"" << EscapeChars (attrib.second) << L"\"";
146: }
147:
148: if (!node.InnerNodes.empty())
149: {
150: *TextOutStream << L">" << endl;
151: WriteNodes (node.InnerNodes);
152: *TextOutStream << indent;
153: }
154: else if (!node.InnerText.empty())
155: {
156: *TextOutStream << L">" << EscapeChars (node.InnerText);
157: }
158: else
159: {
160: *TextOutStream << L"/>" << endl;
161: continue;
162: }
163:
164: *TextOutStream << L"</" << node.Name << L">" << endl;
165: }
166:
167: CurrentIndentLevel--;
168: }
169:
170: XmlWriter::~XmlWriter ()
171: {
172: Close();
173: }
174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.