forked from mgmarino/OrcaROOT
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathORXmlPlist.cc
228 lines (208 loc) · 8.37 KB
/
ORXmlPlist.cc
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
// ORXmlPlist.cc
#include "ORXmlPlist.hh"
#include "TXMLNode.h"
#include <fstream>
#include <cstdlib>
#include "ORLogger.hh"
#include "TDOMParser.h"
#include "TSocket.h"
ORXmlPlist::ORXmlPlist(const char* fullHeaderAsString, size_t lengthOfBuffer)
{
fDictionary = NULL;
fDoValidate = false;
if (fullHeaderAsString) LoadXmlPlist(fullHeaderAsString, lengthOfBuffer);
}
ORXmlPlist::~ORXmlPlist()
{
if (fDictionary != NULL) delete fDictionary;
}
bool ORXmlPlist::LoadXmlPlistFromFile(const char* fileName)
{
// We must use a local buffer but then we must handle the memory of the
// buffer.
// We assume that we get JUST the header.
std::ifstream headerFile(fileName);
if(!headerFile.good()) {
ORLog(kError) << "Error opening file: " << fileName << std::endl;
return false;
}
fRawXML.ReadFile(headerFile);
return LoadXmlPlist(fRawXML.Data(), fRawXML.Length());
}
bool ORXmlPlist::LoadXmlPlist(const char* fullHeaderAsString, size_t lengthOfBuffer)
{
if(ORLogger::GetSeverity() <= ORLogger::kDebug)
{
// dump the header out for debugging purposes.
std::ofstream headerFile("tmp_header.xml");
if (!headerFile.good()) {
ORLog(kError) << "LoadXmlPlist(): You are running in debug mode. "
<< "Problem opening file tmp_header.xml. "
<< "Do you have write permissions to the directory from "
<< "which you are running your application?" << std::endl;
return false;
}
headerFile.write(fullHeaderAsString, lengthOfBuffer);
headerFile.close();
}
ORLog(kDebug) << "LoadXmlPlist(): Parsing..." << std::endl;
TDOMParser domParser;
if(!fDoValidate) {
ORLog(kWarning) << "LoadXmlPlist(): xml plist validation is disabled. "
<< "If you are concerned about the integrity of your "
<< "data and wish to turn on validation, call "
<< "ORXmlPlist::ValidateXML() before loading your "
<< "data file. Typical applications may activate this "
<< "option via ORDataProcManager::ValidateHeaderXML(). "
<< "To use this option, you must be connected to the "
<< "internet." << std::endl;
}
domParser.SetValidate(fDoValidate);
domParser.ParseBuffer(fullHeaderAsString, lengthOfBuffer);
TXMLDocument* doc = domParser.GetXMLDocument();
if (doc == NULL) {
ORLog(kError) << "LoadXmlPlist(): couldn't parse buffer. Parse code was "
<< domParser.GetParseCode() << std::endl;
return false;
}
if(((size_t)fRawXML.Length()) != lengthOfBuffer) {
//we have to copy to fRawXML. Making sure we're not copying again.
fRawXML.Resize(lengthOfBuffer);
}
fRawXML.Replace(0, lengthOfBuffer, fullHeaderAsString, lengthOfBuffer);
ORLog(kDebug) << "LoadXmlPlist(): Getting root node..." << std::endl;
TXMLNode* rootNode = doc->GetRootNode();
if (rootNode == NULL) {
ORLog(kError) << "LoadXmlPlist(): root node was NULL in buffer "
<< std::endl;
return false;
}
if(std::string(rootNode->GetNodeName()) != "plist") {
ORLog(kError) << "LoadXmlPlist(): root node was not a plist in buffer"
<< std::endl;
return false;
}
ORLog(kDebug) << "LoadXmlPlist(): Getting root dictionary..." << std::endl;
TXMLNode* rootDict = FindChildByName("dict", rootNode);
if (rootDict == NULL) {
ORLog(kError) << "LoadXmlPlist(): couldn't find root dictionary in buffer"
<< std::endl;
return false;
}
ORLog(kDebug) << "LoadXmlPlist(): Loading root dictionary..." << std::endl;
if (fDictionary != NULL) delete fDictionary;
fDictionary = new ORDictionary("rootDict"); // deleted in deconstructor
return LoadDictionary(rootDict, fDictionary);
}
const ORVDictValue* ORXmlPlist::LookUp(std::string key, char delimiter) const
{
if(fDictionary == NULL) {
ORLog(kError) << "LookUp(): dictionary not loaded" << std::endl;
return 0;
}
return fDictionary->LookUp(key, delimiter);
}
bool ORXmlPlist::LoadDictionary(TXMLNode* dictNode, ORDictionary* dictionary)
{
ORLog(kDebug) << "LoadDictionary(): Loading dictionary "
<< dictionary->GetName() << "..." << std::endl;
TXMLNode* child = dictNode->GetChildren();
while (child != NULL && child->HasNextNode()) {
while (child->HasNextNode() && std::string(child->GetNodeName()) != "key") {
child = child->GetNextNode();
}
if (!child->HasNextNode()) break;
std::string keyname = child->GetText();
child = child->GetNextNode();
if (!child->HasNextNode()) break;
while (child->HasNextNode() && std::string(child->GetNodeName()) == "text") {
child = child->GetNextNode();
}
std::string valtype = child->GetNodeName();
if(ORLogger::GetSeverity() <= ORLogger::kDebug) {
ORLog(kDebug) << "LoadDictionary(): Handling " << valtype << " " << keyname << std::endl;
}
ORVDictValue* dictValue = NULL;
if (valtype == "dict") {
dictValue = new ORDictionary(keyname);
LoadDictionary(child, (ORDictionary*) dictValue);
} else if (valtype == "string") {
const char* str = child->GetText();
if(str == NULL) dictValue = new ORDictValueS("");
else dictValue = new ORDictValueS(str);
} else if (valtype == "real") {
dictValue = new ORDictValueR(atof(child->GetText()));
} else if (valtype == "integer") {
dictValue = new ORDictValueI(atoi(child->GetText()));
} else if (valtype == "false") {
dictValue = new ORDictValueB(false);
} else if (valtype == "true") {
dictValue = new ORDictValueB(true);
} else if (valtype == "array") {
dictValue = new ORDictValueA(keyname);
LoadArray(child, (ORDictValueA*) dictValue);
} else {
ORLog(kWarning) << "LoadDictionary(): unsupported value type " << valtype << " with name " << keyname << std::endl;
}
dictionary->LoadEntry(keyname, dictValue);
ORLog(kDebug) << "LoadDictionary(): loaded entry " << keyname << std::endl;
if (keyname == "dataId") {
ORLog(kDebug) << dictionary->GetName() + "::LoadDictionary(): dataId = "
<< ((ORDictValueI*) dictValue)->GetI() << std::endl;
}
child = child->GetNextNode();
}
ORLog(kDebug) << "LoadDictionary(): Finished loading dictionary "
<< dictionary->GetName() << "..." << std::endl;
return true;
}
bool ORXmlPlist::LoadArray(TXMLNode* arrayNode, ORDictValueA* dictValueA)
{
ORLog(kDebug) << "LoadArray(): Loading an array " << std::endl;
TXMLNode* child = arrayNode->GetChildren();
while (child != NULL && child->HasNextNode()) {
while (child->HasNextNode() && std::string(child->GetNodeName()) == "text") {
child = child->GetNextNode();
}
if (!child->HasNextNode()) break;
std::string valtype = child->GetNodeName();
ORLog(kDebug) << "LoadArray(): Handling " << valtype << std::endl;
ORVDictValue* dictValue = NULL;
if (valtype == "dict") {
dictValue = new ORDictionary;
LoadDictionary(child, (ORDictionary*) dictValue);
}
else if (valtype == "string") {
const char* str = child->GetText();
if(str == NULL) dictValue = new ORDictValueS("");
else dictValue = new ORDictValueS(str);
} else if (valtype == "real") {
dictValue = new ORDictValueR(atof(child->GetText()));
} else if (valtype == "integer") {
dictValue = new ORDictValueI(atoi(child->GetText()));
} else if (valtype == "false") {
dictValue = new ORDictValueB(false);
} else if (valtype == "true") {
dictValue = new ORDictValueB(true);
} else {
ORLog(kWarning) << "LoadArray(): unsupported value type " << valtype << std::endl;
}
dictValueA->LoadValue(dictValue);
child = child->GetNextNode();
}
ORLog(kDebug) << "LoadArray(): Finished loading array " << std::endl;
return true;
}
TXMLNode* ORXmlPlist::FindChildByName(const char* name, TXMLNode* parent)
{
if (name == NULL || parent == NULL) return NULL;
TXMLNode* child = parent->GetChildren();
while (child != NULL && child->HasNextNode()) {
ORLog(kDebug) << "FindChildByName(): examining child " << child->GetNodeName() << std::endl;
if (std::string(child->GetNodeName()) == name) return child;
child = child->GetNextNode();
}
ORLog(kWarning) << "FindChildByName(): couldn't find child '" << name
<< "' under parent '" << parent->GetNodeName() << "'." << std::endl;
return NULL;
}