Geant4  10.01.p03
XMLWriter.cc
Go to the documentation of this file.
1 // Copyright FreeHEP, 2005.
2 
3 #include "cheprep/config.h"
4 
5 #include <cstdio>
6 
7 #include "cheprep/DefaultHepRepAttValue.h"
8 #include "cheprep/XMLWriter.h"
9 
10 using namespace std;
11 
16 namespace cheprep {
17 
18 XMLWriter::XMLWriter(ostream* out, string indentString, string aDefaultNameSpace)
19  : AbstractXMLWriter(aDefaultNameSpace) {
20  writer = new IndentPrintWriter(out);
21  writer->setIndentString(indentString);
22  closed = false;
23  dtdName = "";
24 }
25 
26 XMLWriter::~XMLWriter() {
27  writer->close();
28  delete writer;
29 }
30 
31 void XMLWriter::close() {
32  closeDoc();
33  writer->close();
34 }
35 
36 void XMLWriter::openDoc(string version, string encoding, bool standalone) {
37  string indentString = writer->getIndentString();
38  writer->setIndentString(indentString);
39 
40 // if (!XMLCharacterProperties.validVersionNum(version)) throw new RuntimeException("Invalid version number: "+version);
41  *writer << "<?xml version=\"" << version.c_str() << "\" ";
42  if (encoding.compare("") != 0) {
43 // if (!XMLCharacterProperties.validEncName(encoding)) throw new RuntimeException("Invalid encoding name: "+encoding);
44  *writer << "encoding=\"" << encoding.c_str() << "\" ";
45  }
46  if (standalone) {
47  *writer << "standalone=\"yes\" ";
48  }
49  *writer << "?>";
50  *writer << endl;
51  writer->setIndentString(indentString);
52 }
53 
54 void XMLWriter::referToDTD(string name, string pid, string ref) {
55  if (dtdName != "") {
56  cerr << "XMLWriter::ReferToDTD cannot be called twice" << endl;
57  }
58  dtdName = name;
59  *writer << "<!DOCTYPE " << name.c_str() << " PUBLIC \"" << pid.c_str() << "\" \"" << ref.c_str() << "\">" << endl;
60 }
61 
62 void XMLWriter::referToDTD(string name, string system) {
63  if (dtdName != "") {
64  cerr << "XMLWriter::ReferToDTD cannot be called twice";
65  }
66  dtdName = name;
67  *writer << "<!DOCTYPE " << name.c_str() << " SYSTEM \"" << system.c_str() << "\">" << endl;
68 }
69 
70 void XMLWriter::closeDoc(bool force) {
71  if (!closed) {
72  if (!openTags.empty()) {
73  if (!force) cerr << "Not all tags were closed before closing XML document:" << endl;
74  while (!openTags.empty()) {
75  if (force) {
76  closeTag();
77  } else {
78  cerr << " </" << openTags.top().c_str() << ">" << endl;
79  openTags.pop();
80  }
81  }
82  }
83  closed = true;
84  }
85 }
86 
87 void XMLWriter::printComment(string comment) {
88  if (comment.find("--") != string::npos) {
89  cerr << "XMLWriter::printComment '--' sequence not allowed in comment" << endl;
90  }
91  *writer << "<!--" << normalizeText(comment).c_str() << "-->" << endl;
92 }
93 
94 void XMLWriter::printPlain(string text) {
95  *writer << text.c_str();
96 }
97 
98 void XMLWriter::print(string text) {
99  *writer << normalizeText(text).c_str();
100 }
101 
102 void XMLWriter::println(string text) {
103  print(text);
104  *writer << endl;
105 }
106 
107 void XMLWriter::openTag(string name) {
108  checkNameValid(name);
109  if (openTags.empty() && dtdName.compare("") && dtdName.compare(name)) {
110  cerr << "XMLWriter::openTag(), First tag: '" << name << "' not equal to DTD id: '" << dtdName << "'" << endl;
111  }
112  *writer << "<" << name.c_str();
113  printAttributes(name.length());
114  *writer << ">" << endl;
115  writer->indent();
116  openTags.push(name);
117 }
118 
119 void XMLWriter::closeTag() {
120  if (openTags.empty()) {
121  writer->close();
122  cerr << "XMLWriter::closeTag(), No open tags" << endl;
123  }
124  string name = openTags.top();
125  openTags.pop();
126  writer->outdent();
127  *writer << "</" << name.c_str() << ">" << endl;
128 }
129 
130 void XMLWriter::printTag(string name) {
131  checkNameValid(name);
132  *writer << "<" << name.c_str();
133  printAttributes(name.length());
134  *writer << "/>" << endl;
135 }
136 
137 void XMLWriter::setAttribute(string name, char* value) {
138  setAttribute(name, (string)value);
139 }
140 
141 void XMLWriter::setAttribute(string name, string value) {
142  attributes[name] = value;
143  // NOTE: never set type here
144 }
145 
146 void XMLWriter::setAttribute(std::string name, std::vector<double> value) {
147  if (name == "value") setAttribute("type", (std::string)"Color");
148  setAttribute(name, DefaultHepRepAttValue::getAsString(value));
149 }
150 
151 void XMLWriter::setAttribute(std::string name, int64 value) {
152  if (name == "value") setAttribute("type", (std::string)"long");
153  setAttribute(name, DefaultHepRepAttValue::getAsString(value));
154 }
155 
156 void XMLWriter::setAttribute(std::string name, int value) {
157  if (name == "showlabel") {
158  string label = DefaultHepRepAttValue::toShowLabel(value);
159  setAttribute("showlabel", label);
160  } else {
161  if (name == "value") setAttribute("type", (std::string)"int");
162  setAttribute(name, DefaultHepRepAttValue::getAsString(value));
163  }
164 }
165 
166 void XMLWriter::setAttribute(std::string name, bool value) {
167  if (name == "value") setAttribute("type", (std::string)"boolean");
168  setAttribute(name, DefaultHepRepAttValue::getAsString(value));
169 }
170 
171 void XMLWriter::setAttribute(string name, double value) {
172  if (name == "value") setAttribute("type", (std::string)"double");
173  setAttribute(name, DefaultHepRepAttValue::getAsString(value));
174 }
175 
176 void XMLWriter::printAttributes(int tagLength) {
177  int width = tagLength + 1;
178  bool extraIndent = false;
179  for (map<string,string>::iterator i = attributes.begin(); i != attributes.end(); i++) {
180  string key = i->first;
181  checkNameValid(key);
182  string value = normalize(i->second);
183  int length = key.length() + value.length() + 3;
184  if (width > 0 && width + length + 2*writer->getIndent() > 60) {
185  width = 0;
186  *writer << endl;
187  if (!extraIndent) {
188  writer->indent();
189  extraIndent = true;
190  }
191  } else {
192  width += length;
193  *writer << " ";
194  }
195  *writer << key.c_str() << "=\"" << value.c_str() << "\"";
196  }
197  attributes.clear();
198  if (extraIndent) writer->outdent();
199 }
200 
201 string XMLWriter::normalize(string s) {
202  string str = "";
203  char buffer[20];
204 
205  int len = s.length();
206  for (int i = 0; i < len; i++) {
207  char ch = s[i];
208  switch (ch) {
209  case '<': {
210  str.append("&lt;");
211  break;
212  }
213  case '>': {
214  str.append("&gt;");
215  break;
216  }
217  case '&': {
218  str.append("&amp;");
219  break;
220  }
221  case '"': {
222  str.append("&quot;");
223  break;
224  }
225  case '\r':
226  case '\n': {
227  sprintf(buffer, "&#%ud", ch);
228  str.append(buffer);
229  str.append(";");
230  break;
231  }
232  default: {
233 // if (ch > 0x00FF) {
234 // sprintf(buffer, "&#x%4.4x", ch);
235 // str.append(buffer);
236 // str.append(";");
237 // } else {
238  str.append(&ch, 1);
239 // }
240  }
241  }
242  }
243 
244  return str;
245 }
246 
247 string XMLWriter::normalizeText(string s) {
248  string str = "";
249 
250  int len = s.length();
251  for (int i = 0; i < len; i++) {
252  char ch = s[i];
253  switch (ch) {
254  case '<': {
255  str.append("&lt;");
256  break;
257  }
258  case '>': {
259  str.append("&gt;");
260  break;
261  }
262  case '&': {
263  str.append("&amp;");
264  break;
265  }
266  default: {
267 // if (ch > 0x00FF) {
268 // sprintf(buffer, "&#x%4.4x", ch);
269 // str.append(buffer);
270 // str.append(";");
271 // } else {
272  str.append(&ch, 1);
273 // }
274  }
275  }
276  }
277  return str;
278 }
279 
280 void XMLWriter::checkNameValid(string) {
281 // Could be added.
282 // if (!XMLCharacterProperties.validName(s)) throw new RuntimeException("Invalid name: "+s);
283 }
284 
285 
286 } // cheprep
G4String name
Definition: TRTMaterials.hh:40
#define width
#define buffer
Definition: xmlparse.cc:611
static const double s
Definition: G4SIunits.hh:150
#define encoding
Definition: xmlparse.cc:588
void print(const std::vector< T > &data)
Definition: DicomRun.hh:109