Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BHepRepWriter.cc
Go to the documentation of this file.
1 // Copyright FreeHEP, 2005.
2 
3 #include "cheprep/config.h"
4 
5 #include <iostream>
6 #include <algorithm>
7 
9 
14 namespace cheprep {
15 
16  // class variables
17  std::map<std::string, unsigned char> BHepRepWriter::tags;
18  std::map<std::string, unsigned char> BHepRepWriter::attributes;
19  std::map<std::string, unsigned char> BHepRepWriter::values;
20 
21  BHepRepWriter::BHepRepWriter( std::ostream& ostrm)
22  : AbstractXMLWriter("heprep"),
23  os(ostrm),
24  singlePrecision(true) {
25 
26  // resolve endiannes
27  union { long l; char c[sizeof (long)]; } u;
28  u.l = 1;
29  isBigEndian = (u.c[sizeof (long) - 1] == 1);
30 
31 // std::cout << "Host is " << (isBigEndian ? "Big-Endian" : "Little-Endian") << "." << std::endl;
32 
33  if (tags.size() <= 0) {
34  // tags
35  tags["heprep"] = 0x05;
36  tags["attdef"] = 0x06;
37  tags["attvalue"] = 0x07;
38  tags["instance"] = 0x08;
39  tags["treeid"] = 0x09;
40  tags["action"] = 0x0a;
41  tags["instancetree"] = 0x0b;
42  tags["type"] = 0x0c;
43  tags["typetree"] = 0x0d;
44  tags["layer"] = 0x0e;
45  tags["point"] = 0x0f;
46  }
47 
48  if (attributes.size() <= 0) {
49  // attribute names
50  attributes["version"] = 0x05;
51  attributes["xmlns"] = 0x06;
52  attributes["xmlns:xsi"] = 0x07;
53  attributes["xsi:schemaLocation"] = 0x08;
54 
55  attributes["valueString"] = 0x10;
56  attributes["valueColor"] = 0x11;
57  attributes["valueLong"] = 0x12;
58  attributes["valueInt"] = 0x13;
59  attributes["valueBoolean"] = 0x14;
60  attributes["valueDouble"] = 0x15;
61 
62  attributes["name"] = 0x20;
63  attributes["type"] = 0x22;
64  attributes["showlabel"] = 0x23;
65  attributes["desc"] = 0x24;
66  attributes["category"] = 0x25;
67  attributes["extra"] = 0x26;
68  attributes["x"] = 0x27;
69  attributes["y"] = 0x28;
70  attributes["z"] = 0x29;
71  attributes["qualifier"] = 0x2a;
72  attributes["expression"] = 0x2b;
73  attributes["typetreename"] = 0x2c;
74  attributes["typetreeversion"] = 0x2d;
75  attributes["order"] = 0x2e;
76 
77  // for PI
78  attributes["eof"] = 0x7f;
79  }
80 
81  if (values.size() <= 0) {
82  // attribute values
83  values["drawas"] = 0x85;
84  values["drawasoptions"] = 0x86;
85  values["visibility"] = 0x87;
86 
87  values["label"] = 0x88;
88 
89  values["fontname"] = 0x89;
90  values["fontstyle"] = 0x8a;
91  values["fontsize"] = 0x8b;
92  values["fontcolor"] = 0x8c;
93  values["fonthasframe"] = 0x8d;
94  values["fontframecolor"] = 0x8e;
95  values["fontframewidth"] = 0x8f;
96  values["fonthasbanner"] = 0x90;
97  values["fontbannercolor"] = 0x91;
98 
99  values["color"] = 0x92;
100  values["framecolor"] = 0x93;
101  values["layer"] = 0x94;
102  values["markname"] = 0x95;
103  values["marksize"] = 0x96;
104  values["marksizemultiplier"] = 0x97;
105  values["marktype"] = 0x98;
106  values["hasframe"] = 0x99;
107  values["framecolor"] = 0x9a;
108  values["framewidth"] = 0x9b;
109 
110  values["linestyle"] = 0x9c;
111  values["linewidth"] = 0x9d;
112  values["linewidthmultiplier"] = 0x9e;
113  values["linehasarrow"] = 0x9f;
114 
115  values["fillcolor"] = 0xa0;
116  values["filltype"] = 0xa1;
117  values["fill"] = 0xa2;
118 
119  values["radius"] = 0xa3;
120  values["phi"] = 0xa4;
121  values["theta"] = 0xa5;
122  values["omega"] = 0xa6;
123  values["radius1"] = 0xa7;
124  values["radius2"] = 0xa8;
125  values["radius3"] = 0xa9;
126  values["curvature"] = 0xaa;
127  values["flylength"] = 0xab;
128  values["faces"] = 0xac;
129 
130  values["text"] = 0xad;
131  values["hpos"] = 0xae;
132  values["vpos"] = 0xaf;
133  values["halign"] = 0xb0;
134  values["valign"] = 0xb1;
135 
136  values["ispickable"] = 0xb2;
137  values["showparentvalues"] = 0xb3;
138  values["pickparent"] = 0xb4;
139 
140  // attvalue values
141  values["false"] = 0xd0;
142  values["true"] = 0xd1;
143 
144  values["point"] = 0xd2;
145  values["line"] = 0xd3;
146  values["helix"] = 0xd4;
147  values["polygon"] = 0xd5;
148  values["circle"] = 0xd6;
149  values["curve"] = 0xd7;
150  values["ellipse"] = 0xd8;
151  values["ellipsoid"] = 0xd9;
152  values["prism"] = 0xda;
153  values["cylinder"] = 0xdb;
154  values["ellipseprism"] = 0xdc;
155  values["text"] = 0xdd;
156 
157  values["nonzero"] = 0xde;
158  values["evenodd"] = 0xdf;
159 
160  values["circle"] = 0xe0;
161  values["box"] = 0xe1;
162  values["uptriangle"] = 0xe2;
163  values["dntriangle"] = 0xe3;
164  values["diamond"] = 0xe4;
165  values["cross"] = 0xe5;
166  values["star"] = 0xe6;
167  values["plus"] = 0xe7;
168  values["hline"] = 0xe8;
169  values["vline"] = 0xe9;
170 
171  values["solid"] = 0xea;
172  values["dotted"] = 0xeb;
173  values["dashed"] = 0xec;
174  values["dotdash"] = 0xed;
175 
176  values["none"] = 0xee;
177  values["start"] = 0xef;
178  values["end"] = 0xf0;
179  values["both"] = 0xf1;
180 
181  values["serif"] = 0xf2;
182  values["sansserif"] = 0xf3;
183  values["monotype"] = 0xf4;
184  values["symbol"] = 0xf5;
185 
186  values["plain"] = 0xf6;
187  values["bold"] = 0xf7;
188  values["italic"] = 0xf8;
189 
190  values["top"] = 0xf9;
191  values["baseline"] = 0xfa;
192  values["center"] = 0xfb;
193  values["bottom"] = 0xfc;
194 
195  values["left"] = 0xfd;
196  values["right"] = 0xfe;
197 
198  values["default"] = 0xff;
199  }
200  }
201 
203  }
204 
206  }
207 
208  void BHepRepWriter::openDoc(std::string version, std::string /* encoding */, bool /* standalone */) {
209  stringValues.clear();
210 
211  // header
212  writeByte(WBXML_VERSION);
213  writeMultiByteInt(UNKNOWN_PID);
214  writeMultiByteInt(UTF8);
215 
216  version = "BinaryHepRep/1.0";
217 
218  // string table
219  writeMultiByteInt(version.length()+1);
220 
221  // BHepRep Header (as part of the string table)
222  writeString(version);
223 
224  }
225 
226  void BHepRepWriter::closeDoc(bool /* force */) {
227  writeByte(PI);
228  writeByte(attributes["eof"]);
229  writeByte(END);
230  }
231 
232  void BHepRepWriter::openTag(std::string name) {
233  writeTag(name, true);
234  }
235 
237  writePoints();
238  writeByte(END);
239  }
240 
241  void BHepRepWriter::printTag(std::string name) {
242  writeTag(name);
243  }
244 
245  void BHepRepWriter::writeTag(std::string tagName, bool hasContent) {
246  std::string s = tagName;
247  std::transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
248 
249  // find tag
250  if (tags.count(s) <= 0) {
251  std::cerr << "Cannot find tag '" << s << "' in tags table." << std::endl;
252  return;
253  }
254 
255  // write tag
256  bool isPoint = (s == "point");
257  bool hasAttributes = (stringAttributes.size() > 0) || (doubleAttributes.size() > (unsigned int)(isPoint ? 3 : 0));
258 
259  if (!hasAttributes && isPoint) {
260  // store the point for the future
261  points.push_back(doubleAttributes["x"]);
262  points.push_back(doubleAttributes["y"]);
263  points.push_back(doubleAttributes["z"]);
264  return;
265  }
266 
267  writePoints();
268  writeByte(tags[s] | ((hasContent || isPoint) ? CONTENT : 0x00) | (hasAttributes ? ATTRIBUTE : 0x00));
269 
270  // write attributes
271  if (hasAttributes) {
272  // write string attributes
273  for (std::map<std::string,std::string>::iterator i = stringAttributes.begin(); i != stringAttributes.end(); i++) {
274  std::string name = i->first;
275  std::string value = i->second;
276 
277  // write ATTRSTART
278  writeByte(attributes[name]);
279  std::string v = value;
280  std::transform(v.begin(), v.end(), v.begin(), (int(*)(int)) tolower);
281  if (values.count(v) > 0) {
282  // write ATTRVALUE
283  writeByte(values[v]);
284  } else {
285  if (stringValues.count(value) <= 0) {
286  // define this new string
287  writeStringDefine(value);
288  int index = stringValues.size();
289  stringValues[value] = index;
290  } else {
291  // write string ref
292  writeByte(STR_R);
293  writeMultiByteInt(stringValues[value]);
294  }
295  }
296  }
297  stringAttributes.clear();
298 
299  // write color attributes
300  for (std::map<std::string,std::vector<double> >::iterator i = colorAttributes.begin(); i != colorAttributes.end(); i++) {
301  std::string name = i->first;
302  std::vector<double> value = i->second;
303  // write ATTRSTART
304  writeByte(attributes[name]);
305  // write OPAQUE
306  writeByte(OPAQUE);
307  writeMultiByteInt(value.size());
308  writeByte((int)(value[0] * 0xff) & 0xff);
309  writeByte((int)(value[1] * 0xff) & 0xff);
310  writeByte((int)(value[2] * 0xff) & 0xff);
311  if (value.size() > 3) writeByte((int)(value[3] * 0xff) & 0xff);
312  }
313  colorAttributes.clear();
314 
315  // write long attributes
316  for (std::map<std::string,int64>::iterator i = longAttributes.begin(); i != longAttributes.end(); i++) {
317  std::string name = i->first;
318  int64 value = i->second;
319  // write ATTRSTART
320  writeByte(attributes[name]);
321  // write OPAQUE
322  writeByte(OPAQUE);
323  writeMultiByteInt(8);
324  writeLong(value);
325  }
326  longAttributes.clear();
327 
328  // write int attributes
329  for (std::map<std::string,int>::iterator i = intAttributes.begin(); i != intAttributes.end(); i++) {
330  std::string name = i->first;
331  int value = i->second;
332  // write ATTRSTART
333  writeByte(attributes[name]);
334  // write OPAQUE
335  writeByte(OPAQUE);
336  writeMultiByteInt(4);
337  writeInt(value);
338  }
339  intAttributes.clear();
340 
341  // write boolean attributes
342  for (std::map<std::string,bool>::iterator i = booleanAttributes.begin(); i != booleanAttributes.end(); i++) {
343  std::string name = i->first;
344  bool value = i->second;
345  // write ATTRSTART
346  writeByte(attributes[name]);
347  // write ATTRVALUE
348  writeByte(value ? values["true"] : values["false"]);
349  }
350  booleanAttributes.clear();
351 
352  // write double attributes
353  for (std::map<std::string,double>::iterator i = doubleAttributes.begin(); i != doubleAttributes.end(); i++) {
354  std::string name = i->first;
355  double value = i->second;
356  if (!isPoint && (name != "x") && (name != "y") && (name != "z")) {
357  // write ATTRSTART
358  writeByte(attributes[name]);
359  // write OPAQUE
360  writeByte(OPAQUE);
361  writeMultiByteInt(singlePrecision ? 4 : 8);
362  writeReal(value);
363  }
364  }
365  doubleAttributes.clear();
366 
367  // end of attributes
368  writeByte(END);
369  }
370 
371  if (s == "point") {
372  writeByte(OPAQUE);
373  writeMultiByteInt(singlePrecision ? 12 : 24);
374  writeReal(doubleAttributes["x"]);
375  writeReal(doubleAttributes["y"]);
376  writeReal(doubleAttributes["z"]);
377  }
378 
379  if (isPoint && !hasContent) {
380  // end this tag
381  writeByte(END);
382  }
383  }
384 
385  void BHepRepWriter::writePoints() {
386  if (points.size() <= 0) return;
387 
388  writeByte(tags["point"] | CONTENT);
389  writeByte(OPAQUE);
390  writeMultiByteInt(points.size()*(singlePrecision ? 4 : 8));
391  for (std::vector<double>::iterator i = points.begin(); i != points.end(); ) {
392  writeReal(*i++);
393  writeReal(*i++);
394  writeReal(*i++);
395  }
396  writeByte(END);
397 
398  points.clear();
399  }
400 
401  void BHepRepWriter::setAttribute(std::string name, char* value) {
402  setAttribute(name, (std::string)value);
403  }
404 
405  void BHepRepWriter::setAttribute(std::string name, std::string value) {
406  if (name == "value") name = name.append("String");
407 
408  // make sure the attribute name is defined
409  if (attributes.count(name) <= 0) {
410  std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
411  return;
412  }
413 
414  stringAttributes[name] = value;
415  }
416 
417  void BHepRepWriter::setAttribute(std::string name, std::vector<double> value) {
418  if (name == "value") name = name.append("Color");
419 
420  // make sure the attribute name is defined
421  if (attributes.count(name) <= 0) {
422  std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
423  return;
424  }
425 
426  colorAttributes[name] = value;
427  }
428 
429  void BHepRepWriter::setAttribute(std::string name, int64 value) {
430  if (name == "value") name = name.append("Long");
431 
432  // make sure the attribute name is defined
433  if (attributes.count(name) <= 0) {
434  std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
435  return;
436  }
437 
438  longAttributes[name] = value;
439  }
440 
441  void BHepRepWriter::setAttribute(std::string name, int value) {
442  if (name == "value") name = name.append("Int");
443 
444  // make sure the attribute name is defined
445  if (attributes.count(name) <= 0) {
446  std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
447  return;
448  }
449 
450  intAttributes[name] = value;
451  }
452 
453  void BHepRepWriter::setAttribute(std::string name, bool value) {
454  if (name == "value") name = name.append("Boolean");
455 
456  // make sure the attribute name is defined
457  if (attributes.count(name) <= 0) {
458  std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
459  return;
460  }
461 
462  booleanAttributes[name] = value;
463  }
464 
465  void BHepRepWriter::setAttribute(std::string name, double value) {
466  if (name == "value") name = name.append("Double");
467 
468  // make sure the attribute name is defined
469  if (attributes.count(name) <= 0) {
470  std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
471  return;
472  }
473 
474  doubleAttributes[name] = value;
475  }
476 
477  void BHepRepWriter::writeStringDefine(std::string s) {
478  writeByte(STR_D);
479  writeString(s);
480  }
481 
482  void BHepRepWriter::writeMultiByteInt(unsigned int ui) {
483  unsigned char buf[5];
484  int idx = 0;
485 
486  do {
487  buf[idx++] = (unsigned char) (ui & 0x7f);
488  ui = ui >> 7;
489  }
490  while (ui != 0);
491 
492  while (idx > 1) {
493  writeByte(buf[--idx] | 0x80);
494  }
495  writeByte(buf[0]);
496  }
497 
498  void BHepRepWriter::writeReal(double d) {
499  if (singlePrecision) {
500  union {
501  int i;
502  float f;
503  } u;
504  u.f = (float)d;
505  writeInt(u.i);
506  } else {
507  union {
508  int64 i;
509  double d;
510  } u;
511  u.d = d;
512 
513  writeLong(u.i);
514  }
515  }
516 
517  void BHepRepWriter::writeLong(int64 i) {
518  // write network-order
519  os.put((i >> 56) & 0xff);
520  os.put((i >> 48) & 0xff);
521  os.put((i >> 40) & 0xff);
522  os.put((i >> 32) & 0xff);
523  os.put((i >> 24) & 0xff);
524  os.put((i >> 16) & 0xff);
525  os.put((i >> 8) & 0xff);
526  os.put((i ) & 0xff);
527  }
528 
529  void BHepRepWriter::writeInt(int i) {
530  // write network-order
531  os.put((i >> 24) & 0xff);
532  os.put((i >> 16) & 0xff);
533  os.put((i >> 8) & 0xff);
534  os.put((i ) & 0xff);
535  }
536 
537  void BHepRepWriter::writeByte(unsigned char b) {
538  os.put((char)b);
539  }
540 
541  void BHepRepWriter::writeString(std::string s) {
542  os << s;
543  os.put(0);
544  }
545 } // cheprep