BHepRepWriter.cc

Go to the documentation of this file.
00001 // Copyright FreeHEP, 2005.
00002 
00003 #include "cheprep/config.h"
00004 
00005 #include <iostream>
00006 #include <algorithm>
00007 
00008 #include "cheprep/BHepRepWriter.h"
00009                         
00014 namespace cheprep {
00015 
00016     // class variables
00017     std::map<std::string, unsigned char> BHepRepWriter::tags; 
00018     std::map<std::string, unsigned char> BHepRepWriter::attributes;           
00019     std::map<std::string, unsigned char> BHepRepWriter::values;
00020 
00021     BHepRepWriter::BHepRepWriter( std::ostream& ostrm) 
00022             : AbstractXMLWriter("heprep"), 
00023             os(ostrm), 
00024             singlePrecision(true) {        
00025 
00026         // resolve endiannes        
00027         union { long l; char c[sizeof (long)]; } u;
00028         u.l = 1;
00029         isBigEndian = (u.c[sizeof (long) - 1] == 1);
00030                
00031 //        std::cout << "Host is " << (isBigEndian ? "Big-Endian" : "Little-Endian") << "." << std::endl;
00032        
00033         if (tags.size() <= 0) { 
00034             // tags
00035             tags["heprep"]              = 0x05;
00036             tags["attdef"]              = 0x06;
00037             tags["attvalue"]            = 0x07;
00038             tags["instance"]            = 0x08;
00039             tags["treeid"]              = 0x09;
00040             tags["action"]              = 0x0a;
00041             tags["instancetree"]        = 0x0b;
00042             tags["type"]                = 0x0c;
00043             tags["typetree"]            = 0x0d;
00044             tags["layer"]               = 0x0e;
00045             tags["point"]               = 0x0f;
00046         }
00047 
00048         if (attributes.size() <= 0) {
00049             // attribute names
00050             attributes["version"]               = 0x05;
00051             attributes["xmlns"]                 = 0x06;
00052             attributes["xmlns:xsi"]             = 0x07;
00053             attributes["xsi:schemaLocation"]    = 0x08;
00054     
00055             attributes["valueString"]           = 0x10;
00056             attributes["valueColor"]            = 0x11;
00057             attributes["valueLong"]             = 0x12;
00058             attributes["valueInt"]              = 0x13;
00059             attributes["valueBoolean"]          = 0x14;
00060             attributes["valueDouble"]           = 0x15;
00061     
00062             attributes["name"]                  = 0x20;
00063             attributes["type"]                  = 0x22;
00064             attributes["showlabel"]             = 0x23;
00065             attributes["desc"]                  = 0x24;
00066             attributes["category"]              = 0x25;
00067             attributes["extra"]                 = 0x26;
00068             attributes["x"]                     = 0x27;
00069             attributes["y"]                     = 0x28;
00070             attributes["z"]                     = 0x29;
00071             attributes["qualifier"]             = 0x2a;
00072             attributes["expression"]            = 0x2b;
00073             attributes["typetreename"]          = 0x2c;
00074             attributes["typetreeversion"]       = 0x2d;
00075             attributes["order"]                 = 0x2e;
00076             
00077             // for PI
00078             attributes["eof"]                   = 0x7f;
00079         }
00080         
00081         if (values.size() <= 0) { 
00082             // attribute values
00083             values["drawas"]                     = 0x85;
00084             values["drawasoptions"]              = 0x86;
00085             values["visibility"]                 = 0x87;
00086     
00087             values["label"]                      = 0x88;
00088     
00089             values["fontname"]                   = 0x89;
00090             values["fontstyle"]                  = 0x8a;
00091             values["fontsize"]                   = 0x8b;
00092             values["fontcolor"]                  = 0x8c;
00093             values["fonthasframe"]               = 0x8d;
00094             values["fontframecolor"]             = 0x8e;
00095             values["fontframewidth"]             = 0x8f;
00096             values["fonthasbanner"]              = 0x90;
00097             values["fontbannercolor"]            = 0x91;
00098     
00099             values["color"]                      = 0x92;
00100             values["framecolor"]                 = 0x93;
00101             values["layer"]                      = 0x94;
00102             values["markname"]                   = 0x95;
00103             values["marksize"]                   = 0x96;
00104             values["marksizemultiplier"]         = 0x97;
00105             values["marktype"]                   = 0x98;
00106             values["hasframe"]                   = 0x99;
00107             values["framecolor"]                 = 0x9a;
00108             values["framewidth"]                 = 0x9b;
00109     
00110             values["linestyle"]                  = 0x9c;
00111             values["linewidth"]                  = 0x9d;
00112             values["linewidthmultiplier"]        = 0x9e;
00113             values["linehasarrow"]               = 0x9f;
00114             
00115             values["fillcolor"]                  = 0xa0;
00116             values["filltype"]                   = 0xa1;
00117             values["fill"]                       = 0xa2;
00118     
00119             values["radius"]                     = 0xa3;
00120             values["phi"]                        = 0xa4;
00121             values["theta"]                      = 0xa5;
00122             values["omega"]                      = 0xa6;
00123             values["radius1"]                    = 0xa7;
00124             values["radius2"]                    = 0xa8;
00125             values["radius3"]                    = 0xa9;
00126             values["curvature"]                  = 0xaa;
00127             values["flylength"]                  = 0xab;
00128             values["faces"]                      = 0xac;
00129     
00130             values["text"]                       = 0xad;
00131             values["hpos"]                       = 0xae;
00132             values["vpos"]                       = 0xaf;
00133             values["halign"]                     = 0xb0;
00134             values["valign"]                     = 0xb1;
00135     
00136             values["ispickable"]                 = 0xb2;
00137             values["showparentvalues"]           = 0xb3;
00138             values["pickparent"]                 = 0xb4;
00139             
00140             // attvalue values
00141             values["false"]         = 0xd0;
00142             values["true"]          = 0xd1;
00143             
00144             values["point"]         = 0xd2;
00145             values["line"]          = 0xd3;
00146             values["helix"]         = 0xd4;
00147             values["polygon"]       = 0xd5;
00148             values["circle"]        = 0xd6;
00149             values["curve"]         = 0xd7;
00150             values["ellipse"]       = 0xd8;
00151             values["ellipsoid"]     = 0xd9;
00152             values["prism"]         = 0xda;
00153             values["cylinder"]      = 0xdb;
00154             values["ellipseprism"]  = 0xdc;
00155             values["text"]          = 0xdd;
00156     
00157             values["nonzero"]       = 0xde;
00158             values["evenodd"]       = 0xdf;
00159             
00160             values["circle"]        = 0xe0;
00161             values["box"]           = 0xe1;
00162             values["uptriangle"]    = 0xe2;
00163             values["dntriangle"]    = 0xe3;
00164             values["diamond"]       = 0xe4;
00165             values["cross"]         = 0xe5;
00166             values["star"]          = 0xe6;
00167             values["plus"]          = 0xe7;
00168             values["hline"]         = 0xe8;
00169             values["vline"]         = 0xe9;
00170     
00171             values["solid"]         = 0xea;
00172             values["dotted"]        = 0xeb;
00173             values["dashed"]        = 0xec;
00174             values["dotdash"]       = 0xed;
00175             
00176             values["none"]          = 0xee;
00177             values["start"]         = 0xef;
00178             values["end"]           = 0xf0;
00179             values["both"]          = 0xf1;
00180     
00181             values["serif"]         = 0xf2;
00182             values["sansserif"]     = 0xf3;
00183             values["monotype"]      = 0xf4;
00184             values["symbol"]        = 0xf5;
00185     
00186             values["plain"]         = 0xf6;
00187             values["bold"]          = 0xf7;
00188             values["italic"]        = 0xf8;
00189     
00190             values["top"]           = 0xf9;
00191             values["baseline"]      = 0xfa;
00192             values["center"]        = 0xfb;
00193             values["bottom"]        = 0xfc;
00194     
00195             values["left"]          = 0xfd;
00196             values["right"]         = 0xfe;
00197     
00198             values["default"]       = 0xff;
00199         }        
00200     }
00201     
00202     BHepRepWriter::~BHepRepWriter() {
00203     }
00204 
00205     void BHepRepWriter::close() {
00206     }
00207     
00208     void BHepRepWriter::openDoc(std::string version, std::string /* encoding */, bool /* standalone */) {
00209         stringValues.clear();
00210         
00211         // header
00212         writeByte(WBXML_VERSION);
00213         writeMultiByteInt(UNKNOWN_PID);
00214         writeMultiByteInt(UTF8);        
00215         
00216         version = "BinaryHepRep/1.0"; 
00217        
00218         // string table
00219         writeMultiByteInt(version.length()+1);
00220         
00221         // BHepRep Header (as part of the string table)
00222         writeString(version);
00223         
00224     }
00225     
00226     void BHepRepWriter::closeDoc(bool /* force */) {
00227         writeByte(PI);
00228         writeByte(attributes["eof"]);
00229         writeByte(END);
00230     }
00231 
00232     void BHepRepWriter::openTag(std::string name) {
00233         writeTag(name, true);
00234     }
00235     
00236     void BHepRepWriter::closeTag() {
00237         writePoints();
00238         writeByte(END);
00239     }
00240     
00241     void BHepRepWriter::printTag(std::string name) {
00242         writeTag(name);
00243     }
00244     
00245     void BHepRepWriter::writeTag(std::string tagName, bool hasContent) {
00246         std::string s = tagName;
00247         std::transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower);
00248         
00249         // find tag
00250         if (tags.count(s) <= 0) {
00251             std::cerr << "Cannot find tag '" << s << "' in tags table." << std::endl;
00252             return;
00253         }
00254         
00255         // write tag
00256         bool isPoint = (s == "point");
00257         bool hasAttributes = (stringAttributes.size() > 0) || (doubleAttributes.size() > (unsigned int)(isPoint ? 3 : 0));
00258         
00259         if (!hasAttributes && isPoint) {
00260             // store the point for the future
00261             points.push_back(doubleAttributes["x"]);
00262             points.push_back(doubleAttributes["y"]);
00263             points.push_back(doubleAttributes["z"]);
00264             return;
00265         }
00266 
00267         writePoints();
00268         writeByte(tags[s] | ((hasContent || isPoint) ? CONTENT : 0x00) | (hasAttributes ? ATTRIBUTE : 0x00));        
00269             
00270         // write attributes
00271         if (hasAttributes) {
00272             // write string attributes
00273                 for (std::map<std::string,std::string>::iterator i = stringAttributes.begin(); i != stringAttributes.end(); i++) {
00274                     std::string name = i->first;
00275                     std::string value = i->second;
00276 
00277                 // write ATTRSTART
00278                 writeByte(attributes[name]);
00279                 std::string v = value;
00280                 std::transform(v.begin(), v.end(), v.begin(), (int(*)(int)) tolower);
00281                 if (values.count(v) > 0) {
00282                     // write ATTRVALUE
00283                     writeByte(values[v]);
00284                 } else {
00285                     if (stringValues.count(value) <= 0) {
00286                         // define this new string
00287                         writeStringDefine(value);
00288                         int index = stringValues.size();
00289                         stringValues[value] = index;
00290                     } else {
00291                         // write string ref
00292                         writeByte(STR_R);
00293                         writeMultiByteInt(stringValues[value]);    
00294                     }
00295                 }
00296             }
00297             stringAttributes.clear();                
00298 
00299             // write color attributes
00300                 for (std::map<std::string,std::vector<double> >::iterator i = colorAttributes.begin(); i != colorAttributes.end(); i++) {
00301                     std::string name = i->first;
00302                     std::vector<double> value = i->second;
00303                 // write ATTRSTART
00304                 writeByte(attributes[name]);
00305                 // write OPAQUE
00306                 writeByte(OPAQUE);
00307                 writeMultiByteInt(value.size());
00308                 writeByte((int)(value[0] * 0xff) & 0xff);
00309                 writeByte((int)(value[1] * 0xff) & 0xff);
00310                 writeByte((int)(value[2] * 0xff) & 0xff);
00311                 if (value.size() > 3) writeByte((int)(value[3] * 0xff) & 0xff);
00312             }
00313             colorAttributes.clear();
00314             
00315             // write long attributes
00316                 for (std::map<std::string,int64>::iterator i = longAttributes.begin(); i != longAttributes.end(); i++) {
00317                     std::string name = i->first;
00318                     int64 value = i->second;
00319                  // write ATTRSTART
00320                 writeByte(attributes[name]);
00321                 // write OPAQUE
00322                 writeByte(OPAQUE);
00323                 writeMultiByteInt(8);
00324                 writeLong(value);
00325             }
00326             longAttributes.clear();
00327             
00328             // write int attributes
00329                 for (std::map<std::string,int>::iterator i = intAttributes.begin(); i != intAttributes.end(); i++) {
00330                     std::string name = i->first;
00331                     int value = i->second;
00332                 // write ATTRSTART
00333                 writeByte(attributes[name]);
00334                 // write OPAQUE
00335                 writeByte(OPAQUE);
00336                 writeMultiByteInt(4);
00337                 writeInt(value);
00338             }
00339             intAttributes.clear();
00340             
00341             // write boolean attributes
00342                 for (std::map<std::string,bool>::iterator i = booleanAttributes.begin(); i != booleanAttributes.end(); i++) {
00343                     std::string name = i->first;
00344                     bool value = i->second;
00345                 // write ATTRSTART
00346                 writeByte(attributes[name]);
00347                 // write ATTRVALUE
00348                 writeByte(value ? values["true"] : values["false"]);
00349             }
00350             booleanAttributes.clear();
00351             
00352             // write double attributes
00353                 for (std::map<std::string,double>::iterator i = doubleAttributes.begin(); i != doubleAttributes.end(); i++) {
00354                     std::string name = i->first;
00355                     double value = i->second;
00356                     if (!isPoint && (name != "x") && (name != "y") && (name != "z")) {
00357                     // write ATTRSTART
00358                     writeByte(attributes[name]);
00359                     // write OPAQUE
00360                     writeByte(OPAQUE);
00361                     writeMultiByteInt(singlePrecision ? 4 : 8);
00362                     writeReal(value);
00363                 }        
00364             }
00365             doubleAttributes.clear();
00366             
00367             // end of attributes
00368             writeByte(END);          
00369             }
00370         
00371         if (s == "point") {
00372             writeByte(OPAQUE);
00373             writeMultiByteInt(singlePrecision ?  12 : 24);
00374             writeReal(doubleAttributes["x"]);
00375             writeReal(doubleAttributes["y"]);
00376             writeReal(doubleAttributes["z"]);
00377         }
00378         
00379         if (isPoint && !hasContent) {
00380             // end this tag
00381             writeByte(END);
00382         }    
00383     }
00384     
00385     void BHepRepWriter::writePoints() {
00386         if (points.size() <= 0) return;
00387         
00388         writeByte(tags["point"] | CONTENT);                
00389         writeByte(OPAQUE);
00390         writeMultiByteInt(points.size()*(singlePrecision ? 4 : 8));
00391         for (std::vector<double>::iterator i = points.begin(); i != points.end(); ) {
00392             writeReal(*i++);
00393             writeReal(*i++);
00394             writeReal(*i++);
00395         }
00396         writeByte(END);
00397         
00398         points.clear();
00399     }
00400         
00401     void BHepRepWriter::setAttribute(std::string name, char* value) {
00402         setAttribute(name, (std::string)value);
00403     }
00404 
00405     void BHepRepWriter::setAttribute(std::string name, std::string value) {
00406         if (name == "value") name = name.append("String");
00407                 
00408         // make sure the attribute name is defined
00409         if (attributes.count(name) <= 0) {
00410             std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
00411             return;
00412         }
00413                     
00414         stringAttributes[name] = value;
00415     }
00416 
00417     void BHepRepWriter::setAttribute(std::string name, std::vector<double> value) {
00418         if (name == "value") name = name.append("Color");
00419 
00420         // make sure the attribute name is defined
00421         if (attributes.count(name) <= 0) {
00422             std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
00423             return;
00424         }
00425                     
00426         colorAttributes[name] = value;
00427     }
00428     
00429     void BHepRepWriter::setAttribute(std::string name, int64 value) {
00430         if (name == "value") name = name.append("Long");
00431 
00432         // make sure the attribute name is defined
00433         if (attributes.count(name) <= 0) {
00434             std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
00435             return;
00436         }
00437                     
00438         longAttributes[name] = value;
00439     }
00440     
00441     void BHepRepWriter::setAttribute(std::string name, int value) {
00442         if (name == "value") name = name.append("Int");
00443 
00444         // make sure the attribute name is defined
00445         if (attributes.count(name) <= 0) {
00446             std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
00447             return;
00448         }
00449                     
00450         intAttributes[name] = value;
00451     }
00452     
00453     void BHepRepWriter::setAttribute(std::string name, bool value) {
00454         if (name == "value") name = name.append("Boolean");
00455 
00456         // make sure the attribute name is defined
00457         if (attributes.count(name) <= 0) {
00458             std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
00459             return;
00460         }
00461                     
00462         booleanAttributes[name] = value;
00463     }
00464     
00465     void BHepRepWriter::setAttribute(std::string name, double value) {
00466         if (name == "value") name = name.append("Double");
00467 
00468         // make sure the attribute name is defined
00469         if (attributes.count(name) <= 0) {
00470             std::cerr << "Cannot find attribute name '" << name << "' in attributes table, skipped." << std::endl;
00471             return;
00472         }
00473                     
00474         doubleAttributes[name] = value;
00475     }
00476 
00477     void BHepRepWriter::writeStringDefine(std::string s) {
00478         writeByte(STR_D);
00479         writeString(s);
00480     }
00481 
00482     void BHepRepWriter::writeMultiByteInt(unsigned int ui) {
00483         unsigned char buf[5];
00484         int idx = 0;
00485         
00486         do {
00487             buf[idx++] = (unsigned char) (ui & 0x7f);
00488             ui = ui >> 7;
00489         }
00490         while (ui != 0);
00491 
00492         while (idx > 1) {
00493             writeByte(buf[--idx] | 0x80);
00494         }
00495         writeByte(buf[0]);
00496     }
00497 
00498     void BHepRepWriter::writeReal(double d) {
00499         if (singlePrecision) {
00500             union {
00501                 int i;
00502                 float f;
00503             } u;
00504             u.f = (float)d;
00505             writeInt(u.i);
00506         } else {
00507             union {
00508                 int64 i;
00509                 double d;
00510             } u;
00511             u.d = d;
00512      
00513             writeLong(u.i);
00514         }
00515     }
00516 
00517     void BHepRepWriter::writeLong(int64 i) {        
00518         // write network-order
00519         os.put((i >> 56) & 0xff);
00520         os.put((i >> 48) & 0xff);
00521         os.put((i >> 40) & 0xff);
00522         os.put((i >> 32) & 0xff);
00523         os.put((i >> 24) & 0xff);
00524         os.put((i >> 16) & 0xff);
00525         os.put((i >>  8) & 0xff);
00526         os.put((i      ) & 0xff);
00527     }    
00528     
00529     void BHepRepWriter::writeInt(int i) {
00530         // write network-order
00531         os.put((i >> 24) & 0xff);
00532         os.put((i >> 16) & 0xff);
00533         os.put((i >>  8) & 0xff);
00534         os.put((i      ) & 0xff);
00535     }
00536     
00537     void BHepRepWriter::writeByte(unsigned char b) {
00538         os.put((char)b);
00539     }
00540     
00541     void BHepRepWriter::writeString(std::string s) {
00542         os << s;
00543         os.put(0);
00544     }
00545 } // cheprep

Generated on Mon May 27 17:47:34 2013 for Geant4 by  doxygen 1.4.7