source: trunk/source/visualization/HepRep/src/BHepRepWriter.cc @ 1098

Last change on this file since 1098 was 834, checked in by garnier, 16 years ago

import all except CVS

  • Property svn:executable set to *
File size: 19.8 KB
Line 
1// Copyright FreeHEP, 2005.
2
3#include "cheprep/config.h"
4
5#include <iostream>
6#include <algorithm>
7
8#include "cheprep/BHepRepWriter.h"
9                       
10/**
11 * @author Mark Donszelmann
12 * @version $Id: BHepRepWriter.cc,v 1.9 2005/06/02 21:28:45 duns Exp $
13 */
14namespace 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& os) 
22            : AbstractXMLWriter("heprep"), 
23            os(os), 
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   
202    BHepRepWriter::~BHepRepWriter() {
203    }
204
205    void BHepRepWriter::close() {
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   
236    void BHepRepWriter::closeTag() {
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 name, bool hasContent) {
246        std::string s = name;
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
Note: See TracBrowser for help on using the repository browser.