00001
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
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
00027 union { long l; char c[sizeof (long)]; } u;
00028 u.l = 1;
00029 isBigEndian = (u.c[sizeof (long) - 1] == 1);
00030
00031
00032
00033 if (tags.size() <= 0) {
00034
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
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
00078 attributes["eof"] = 0x7f;
00079 }
00080
00081 if (values.size() <= 0) {
00082
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
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 , bool ) {
00209 stringValues.clear();
00210
00211
00212 writeByte(WBXML_VERSION);
00213 writeMultiByteInt(UNKNOWN_PID);
00214 writeMultiByteInt(UTF8);
00215
00216 version = "BinaryHepRep/1.0";
00217
00218
00219 writeMultiByteInt(version.length()+1);
00220
00221
00222 writeString(version);
00223
00224 }
00225
00226 void BHepRepWriter::closeDoc(bool ) {
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
00250 if (tags.count(s) <= 0) {
00251 std::cerr << "Cannot find tag '" << s << "' in tags table." << std::endl;
00252 return;
00253 }
00254
00255
00256 bool isPoint = (s == "point");
00257 bool hasAttributes = (stringAttributes.size() > 0) || (doubleAttributes.size() > (unsigned int)(isPoint ? 3 : 0));
00258
00259 if (!hasAttributes && isPoint) {
00260
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
00271 if (hasAttributes) {
00272
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
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
00283 writeByte(values[v]);
00284 } else {
00285 if (stringValues.count(value) <= 0) {
00286
00287 writeStringDefine(value);
00288 int index = stringValues.size();
00289 stringValues[value] = index;
00290 } else {
00291
00292 writeByte(STR_R);
00293 writeMultiByteInt(stringValues[value]);
00294 }
00295 }
00296 }
00297 stringAttributes.clear();
00298
00299
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
00304 writeByte(attributes[name]);
00305
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
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
00320 writeByte(attributes[name]);
00321
00322 writeByte(OPAQUE);
00323 writeMultiByteInt(8);
00324 writeLong(value);
00325 }
00326 longAttributes.clear();
00327
00328
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
00333 writeByte(attributes[name]);
00334
00335 writeByte(OPAQUE);
00336 writeMultiByteInt(4);
00337 writeInt(value);
00338 }
00339 intAttributes.clear();
00340
00341
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
00346 writeByte(attributes[name]);
00347
00348 writeByte(value ? values["true"] : values["false"]);
00349 }
00350 booleanAttributes.clear();
00351
00352
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
00358 writeByte(attributes[name]);
00359
00360 writeByte(OPAQUE);
00361 writeMultiByteInt(singlePrecision ? 4 : 8);
00362 writeReal(value);
00363 }
00364 }
00365 doubleAttributes.clear();
00366
00367
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
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
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
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
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
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
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
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
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
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 }