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