File: | /home/sdobbs/work/clang/halld_recon/src/programs/Utilities/hddm/hddm-root.cpp |
Warning: | line 776, column 13 Value stored to 'fin_sb' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * hddm-root : tool that reads in a HDDM document (Hall D Data Model) |
3 | * and copies the contents into root trees for easy browsing. |
4 | * |
5 | * author: richard.t.jones at uconn.edu |
6 | * version: january 2, 2017 |
7 | * |
8 | */ |
9 | |
10 | #include <xercesc/util/PlatformUtils.hpp> |
11 | #include <xercesc/dom/DOMNamedNodeMap.hpp> |
12 | |
13 | #include "XParsers.hpp" |
14 | #include "XString.hpp" |
15 | |
16 | #include <assert.h> |
17 | #include <stdlib.h> |
18 | #include <stdio.h> |
19 | #include <rpc/rpc.h> |
20 | #include <unistd.h> |
21 | #include <xstream/z.h> |
22 | #include <xstream/bz.h> |
23 | #include <xstream/xdr.h> |
24 | #include <xstream/digest.h> |
25 | |
26 | #include <string.h> |
27 | #include <iostream> |
28 | #include <fstream> |
29 | #include <sstream> |
30 | #include <map> |
31 | |
32 | #include <TTree.h> |
33 | #include <TFile.h> |
34 | |
35 | #include "particleType.h" |
36 | |
37 | |
38 | #define X(str)XString(str).unicode_str() XString(str).unicode_str() |
39 | #define S(str)str.c_str() str.c_str() |
40 | |
41 | using namespace xercesc; |
42 | |
43 | int explicit_repeat_count = 1; |
44 | int write_xml_output_to_stdout = 0; |
45 | |
46 | void usage() |
47 | { |
48 | std::cerr |
49 | << "\nUsage:\n" |
50 | << " hddm-root [-x] [-n <count>] [-o <filename>] [HDDM file]\n\n" |
51 | << "Options:\n" |
52 | << " -o <filename> write to output root file <filename>\n" |
53 | << " -n <count> limit output to <count> rows\n" |
54 | << " -x write xml to stdout" |
55 | << " (in addition to root file output)\n" |
56 | << std::endl; |
57 | } |
58 | |
59 | typedef xstream::xdr::istream ixstream; |
60 | |
61 | class attribute_t { |
62 | protected: |
63 | attribute_t() : fName(""), fType("") {} |
64 | attribute_t(XString name) : fName(name), fType("") {} |
65 | attribute_t(XString name, XString type) : fName(name), fType(type) {} |
66 | virtual ~attribute_t() {} |
67 | |
68 | public: |
69 | virtual void reset() = 0; |
70 | virtual void *address() = 0; |
71 | virtual std::string toString() = 0; |
72 | virtual int read(ixstream *ifx) = 0; |
73 | virtual XString get_name() { return fName; } |
74 | virtual XString get_type() { return fType; } |
75 | |
76 | private: |
77 | attribute_t(const attribute_t &src); |
78 | attribute_t &operator=(const attribute_t &src); |
79 | |
80 | protected: |
81 | XString fName; |
82 | XString fType; |
83 | }; |
84 | |
85 | class int_attribute_t : public attribute_t { |
86 | public: |
87 | int_attribute_t() : attribute_t("", "int"), value(0) {} |
88 | int_attribute_t(XString name) : attribute_t(name, "int"), value(0) {} |
89 | virtual ~int_attribute_t() {} |
90 | |
91 | int_attribute_t &operator=(const int_attribute_t &src) { |
92 | fName = src.fName; |
93 | value = src.value; |
94 | return *this; |
95 | } |
96 | |
97 | virtual void reset() { |
98 | value = 0; |
99 | } |
100 | virtual void set(int val) { |
101 | value = val; |
102 | } |
103 | virtual void *address() { |
104 | return &value; |
105 | } |
106 | virtual std::string toString() { |
107 | std::stringstream str; |
108 | str << value; |
109 | return str.str(); |
110 | } |
111 | virtual int read(ixstream *ifx) { |
112 | *ifx >> value; |
113 | return 4; |
114 | } |
115 | |
116 | int value; |
117 | }; |
118 | |
119 | class boolean_attribute_t : public attribute_t { |
120 | public: |
121 | boolean_attribute_t() : attribute_t("", "boolean"), value(0) {} |
122 | boolean_attribute_t(XString name) : attribute_t(name, "boolean"), value(0) {} |
123 | virtual ~boolean_attribute_t() {} |
124 | |
125 | boolean_attribute_t &operator=(const boolean_attribute_t &src) { |
126 | fName = src.fName; |
127 | value = src.value; |
128 | return *this; |
129 | } |
130 | |
131 | virtual void reset() { |
132 | value = 0; |
133 | } |
134 | virtual void set(int val) { |
135 | value = val; |
136 | } |
137 | virtual void *address() { |
138 | return &value; |
139 | } |
140 | virtual std::string toString() { |
141 | std::stringstream str; |
142 | str << value; |
143 | return str.str(); |
144 | } |
145 | virtual int read(ixstream *ifx) { |
146 | *ifx >> value; |
147 | return 4; |
148 | } |
149 | |
150 | int value; |
151 | }; |
152 | |
153 | class Particle_attribute_t : public attribute_t { |
154 | public: |
155 | Particle_attribute_t() : attribute_t("", "Particle_t"), value(Unknown) {} |
156 | Particle_attribute_t(XString name) : attribute_t(name, "Particle_t"), |
157 | value(Unknown) {} |
158 | virtual ~Particle_attribute_t() {} |
159 | |
160 | Particle_attribute_t &operator=(const Particle_attribute_t &src) { |
161 | fName = src.fName; |
162 | value = src.value; |
163 | return *this; |
164 | } |
165 | |
166 | virtual void reset() { |
167 | value = Unknown; |
168 | } |
169 | virtual void set(Particle_t val) { |
170 | value = val; |
171 | } |
172 | virtual void *address() { |
173 | return &value; |
174 | } |
175 | virtual std::string toString() { |
176 | std::stringstream str; |
177 | str << ParticleType(value); |
178 | return str.str(); |
179 | } |
180 | virtual int read(ixstream *ifx) { |
181 | int val; |
182 | *ifx >> val; |
183 | value = (Particle_t)val; |
184 | return 4; |
185 | } |
186 | |
187 | Particle_t value; |
188 | }; |
189 | |
190 | class long_attribute_t : public attribute_t { |
191 | public: |
192 | long_attribute_t() : attribute_t("", "long"), value(0) {} |
193 | long_attribute_t(XString name) : attribute_t(name, "long"), value(0) {} |
194 | virtual ~long_attribute_t() {} |
195 | |
196 | long_attribute_t &operator=(const long_attribute_t &src) { |
197 | fName = src.fName; |
198 | value = src.value; |
199 | return *this; |
200 | } |
201 | |
202 | virtual void reset() { |
203 | value = 0; |
204 | } |
205 | virtual void set(long int val) { |
206 | value = val; |
207 | } |
208 | virtual void *address() { |
209 | return &value; |
210 | } |
211 | virtual std::string toString() { |
212 | std::stringstream str; |
213 | str << value; |
214 | return str.str(); |
215 | } |
216 | virtual int read(ixstream *ifx) { |
217 | *ifx >> value; |
218 | return 8; |
219 | } |
220 | |
221 | #if __APPLE__ |
222 | int64_t value; |
223 | #else |
224 | long int value; |
225 | #endif |
226 | }; |
227 | |
228 | class float_attribute_t : public attribute_t { |
229 | public: |
230 | float_attribute_t() : attribute_t("", "float"), value(0) {} |
231 | float_attribute_t(XString name) : attribute_t(name, "float"), value(0) {} |
232 | virtual ~float_attribute_t() {} |
233 | |
234 | float_attribute_t &operator=(const float_attribute_t &src) { |
235 | fName = src.fName; |
236 | value = src.value; |
237 | return *this; |
238 | } |
239 | |
240 | virtual void reset() { |
241 | value = 0; |
242 | } |
243 | virtual void set(float val) { |
244 | value = val; |
245 | } |
246 | virtual void *address() { |
247 | return &value; |
248 | } |
249 | virtual std::string toString() { |
250 | std::stringstream str; |
251 | str << value; |
252 | return str.str(); |
253 | } |
254 | virtual int read(ixstream *ifx) { |
255 | *ifx >> value; |
256 | return 4; |
257 | } |
258 | |
259 | float value; |
260 | }; |
261 | |
262 | class double_attribute_t : public attribute_t { |
263 | public: |
264 | double_attribute_t() : attribute_t("", "double"), value(0) {} |
265 | double_attribute_t(XString name) : attribute_t(name, "double"), value(0) {} |
266 | ~double_attribute_t() {} |
267 | |
268 | double_attribute_t &operator=(const double_attribute_t &src) { |
269 | fName = src.fName; |
270 | value = src.value; |
271 | return *this; |
272 | } |
273 | |
274 | virtual void reset() { |
275 | value = 0; |
276 | } |
277 | virtual void set(double val) { |
278 | value = val; |
279 | } |
280 | virtual void *address() { |
281 | return &value; |
282 | } |
283 | virtual std::string toString() { |
284 | std::stringstream str; |
285 | str << value; |
286 | return str.str(); |
287 | } |
288 | virtual int read(ixstream *ifx) { |
289 | *ifx >> value; |
290 | return 8; |
291 | } |
292 | |
293 | double value; |
294 | }; |
295 | |
296 | class string_attribute_t : public attribute_t { |
297 | public: |
298 | string_attribute_t() : attribute_t("", "string") { reset(); } |
299 | string_attribute_t(XString name) : attribute_t(name, "string") { reset(); } |
300 | ~string_attribute_t() {} |
301 | |
302 | string_attribute_t &operator=(const string_attribute_t &src) { |
303 | fName = src.fName; |
304 | strncpy(value, src.value, 80); |
305 | return *this; |
306 | } |
307 | |
308 | virtual void reset() { |
309 | strncpy(value, "", 80); |
310 | } |
311 | virtual void set(char *val) { |
312 | strncpy(value, val, 80); |
313 | } |
314 | virtual void *address() { |
315 | return &value; |
316 | } |
317 | virtual std::string toString() { |
318 | return std::string(value); |
319 | } |
320 | virtual int read(ixstream *ifx) { |
321 | std::string val; |
322 | *ifx >> val; |
323 | strncpy(value, val.c_str(), 80); |
324 | return (val.size() + 7) / 4 * 4; |
325 | } |
326 | |
327 | char value[80]; |
328 | }; |
329 | |
330 | class anyURI_attribute_t : public attribute_t { |
331 | public: |
332 | anyURI_attribute_t() : attribute_t("", "anyURI") { reset(); } |
333 | anyURI_attribute_t(XString name) : attribute_t(name, "anyURI") { reset(); } |
334 | ~anyURI_attribute_t() {} |
335 | |
336 | anyURI_attribute_t &operator=(const anyURI_attribute_t &src) { |
337 | fName = src.fName; |
338 | strncpy(value, src.value, 80); |
339 | return *this; |
340 | } |
341 | |
342 | virtual void reset() { |
343 | strncpy(value, "", 80); |
344 | } |
345 | virtual void set(char *val) { |
346 | strncpy(value, val, 80); |
347 | } |
348 | virtual void *address() { |
349 | return &value; |
350 | } |
351 | virtual std::string toString() { |
352 | return std::string(value); |
353 | } |
354 | virtual int read(ixstream *ifx) { |
355 | std::string val; |
356 | *ifx >> val; |
357 | strncpy(value, val.c_str(), 80); |
358 | return (val.size() + 7) / 4 * 4; |
359 | } |
360 | |
361 | char value[80]; |
362 | }; |
363 | |
364 | class constant_attribute_t : public attribute_t { |
365 | public: |
366 | constant_attribute_t() : attribute_t("", "constant"), value(0) |
367 | { reset(); } |
368 | constant_attribute_t(XString name) : attribute_t(name, "constant"), value(0) |
369 | { reset(); } |
370 | ~constant_attribute_t() {} |
371 | |
372 | void reset() { |
373 | if (value) |
374 | delete value; |
375 | value = new char[4]; |
376 | strncpy(value, "", 4); |
377 | } |
378 | void set(const char *str) { |
379 | if (value) |
380 | delete value; |
381 | if (!str) |
382 | return; |
383 | int size = (strlen(str) + 7) / 4 * 4; |
384 | value = new char[size]; |
385 | strncpy(value, str, size); |
386 | } |
387 | |
388 | constant_attribute_t &operator=(const constant_attribute_t &src) { |
389 | fName = src.fName; |
390 | set(src.value); |
391 | return *this; |
392 | } |
393 | |
394 | virtual void *address() { |
395 | return value; |
396 | } |
397 | virtual std::string toString() { |
398 | return std::string(value); |
399 | } |
400 | virtual int read(ixstream *ifx) { |
401 | return 0; |
402 | } |
403 | |
404 | char *value; |
405 | }; |
406 | |
407 | class element_t { |
408 | public: |
409 | element_t(TTree *tree) |
410 | : fKey(0), fTree(tree), fRepeats(0) {} |
411 | element_t(TTree *tree, XString name) |
412 | : fKey(0), fTree(tree), fName(name), fRepeats(0) {} |
413 | ~element_t() {} |
414 | |
415 | void add_attribute(attribute_t *attr) { |
416 | fAttributes.push_back(attr); |
417 | } |
418 | void add_element(element_t *elem) { |
419 | fElements.push_back(elem); |
420 | } |
421 | void add_key(int_attribute_t *attr) { |
422 | fKey = attr; |
423 | } |
424 | void set_repeating() { |
425 | fRepeats = 1; |
426 | } |
427 | |
428 | int read(ixstream *ifx) { |
429 | int size; |
430 | *ifx >> size; |
431 | if (size == 0) |
432 | return 4; |
433 | int seen; |
434 | int reps=1; |
435 | if (fRepeats) { |
436 | *ifx >> reps; |
437 | seen = 4; |
438 | } |
439 | else { |
440 | seen = 0; |
441 | } |
442 | |
443 | static int indent = 0; |
444 | if (write_xml_output_to_stdout) { |
445 | if (indent == 0) { |
446 | std::cout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
447 | << std::endl |
448 | << "<HDDM class=\"s\" version=\"1.0\" " |
449 | << "xmlns=\"http://www.gluex.org/hddm\">" |
450 | << std::endl; |
451 | ++indent; |
452 | } |
453 | } |
454 | while (seen < size) { |
455 | if (write_xml_output_to_stdout) { |
456 | for (int i=0; i < indent; ++i) |
457 | std::cout << " "; |
458 | std::cout << "<" << fName; |
459 | } |
460 | std::list<attribute_t*>::iterator ater; |
461 | for (ater = fAttributes.begin(); ater != fAttributes.end(); ++ater) { |
462 | seen += (*ater)->read(ifx); |
463 | if (write_xml_output_to_stdout) { |
464 | std::cout << " " << (*ater)->get_name() << "=\"" |
465 | << (*ater)->toString() << "\""; |
466 | } |
467 | } |
468 | if (fElements.size() == 0) { |
469 | if (write_xml_output_to_stdout) { |
470 | std::cout << " />" << std::endl; |
471 | } |
472 | if (fTree) |
473 | fTree->Fill(); |
474 | if (fKey) |
475 | ++fKey->value; |
476 | } |
477 | else { |
478 | if (write_xml_output_to_stdout) { |
479 | std::cout << ">" << std::endl; |
480 | ++indent; |
481 | } |
482 | std::list<element_t*>::iterator eter; |
483 | for (eter = fElements.begin(); eter != fElements.end(); ++eter) { |
484 | seen += (*eter)->read(ifx); |
485 | } |
486 | if (write_xml_output_to_stdout) { |
487 | --indent; |
488 | for (int i=0; i < indent; ++i) { |
489 | std::cout << " "; |
490 | } |
491 | std::cout << "</" << fName << ">" << std::endl; |
492 | } |
493 | if (fTree) |
494 | fTree->Fill(); |
495 | } |
496 | --reps; |
497 | } |
498 | assert (seen == size)((seen == size) ? static_cast<void> (0) : __assert_fail ("seen == size", "programs/Utilities/hddm/hddm-root.cpp", 498 , __PRETTY_FUNCTION__)); |
499 | if (fRepeats) |
500 | assert (reps == 0)((reps == 0) ? static_cast<void> (0) : __assert_fail ("reps == 0" , "programs/Utilities/hddm/hddm-root.cpp", 500, __PRETTY_FUNCTION__ )); |
501 | return size + 4; |
502 | } |
503 | |
504 | std::list<attribute_t*> fAttributes; |
505 | std::list<element_t*> fElements; |
506 | int_attribute_t *fKey; |
507 | TTree *fTree; |
508 | XString fName; |
509 | int fRepeats; |
510 | |
511 | private: |
512 | element_t(const element_t &src); |
513 | element_t &operator=(const element_t &src); |
514 | }; |
515 | |
516 | typedef std::map<XString,XString> attribute_list; |
517 | typedef std::map<XString,attribute_t*> attribute_table; |
518 | |
519 | class TreeMaker |
520 | { |
521 | public: |
522 | TreeMaker(XString filename) { |
523 | fRootFile = new TFile(S(filename)filename.c_str(), "recreate"); |
524 | } |
525 | ~TreeMaker() { |
526 | delete fRootFile; |
527 | } |
528 | |
529 | void build(const DOMElement* elem, element_t *parent_element, |
530 | attribute_list columns); |
531 | int filltrees(ixstream *ifx, element_t *parent_element); |
532 | int savetrees(element_t *parent_element); |
533 | |
534 | private: |
535 | TreeMaker(const TreeMaker &src) {} |
536 | TreeMaker operator=(const TreeMaker &src) { |
537 | TreeMaker copy(*this); |
538 | return copy; |
539 | } |
540 | |
541 | protected: |
542 | TFile *fRootFile; |
543 | std::list<element_t*> fElements; |
544 | attribute_table fColumns; |
545 | }; |
546 | |
547 | class istreambuffer : public std::streambuf { |
548 | public: |
549 | istreambuffer(char* buffer, std::streamsize bufferLength) { |
550 | setg(buffer, buffer, buffer + bufferLength); |
551 | } |
552 | |
553 | std::streampos tellg() { |
554 | return gptr() - eback(); |
555 | } |
556 | |
557 | void seekg(std::streampos pos) { |
558 | reset(); |
559 | gbump(pos); |
560 | } |
561 | |
562 | int size() { |
563 | return egptr() - gptr(); |
564 | } |
565 | |
566 | void reset() { |
567 | char *gbegin = eback(); |
568 | char *gend = egptr(); |
569 | setg(gbegin, gbegin, gend); |
570 | } |
571 | |
572 | char *getbuf() { |
573 | return eback(); |
574 | } |
575 | }; |
576 | |
577 | int main(int argC, char* argV[]) |
578 | { |
579 | XString rootFilename; |
580 | |
581 | try |
582 | { |
583 | XMLPlatformUtils::Initialize(); |
584 | } |
585 | catch (const XMLException* toCatch) |
586 | { |
587 | XString msg(toCatch->getMessage()); |
588 | std::cerr |
589 | << "hddm-root: Error during initialization! :\n" |
590 | << S(msg)msg.c_str() << std::endl; |
591 | return 1; |
592 | } |
593 | |
594 | int reqcount=-1; |
595 | int argInd; |
596 | for (argInd = 1; argInd < argC; argInd++) |
597 | { |
598 | if (argV[argInd][0] != '-') |
599 | { |
600 | break; |
601 | } |
602 | else if (strcmp(argV[argInd],"-x") == 0) |
603 | { |
604 | write_xml_output_to_stdout = 1; |
605 | } |
606 | else if (strcmp(argV[argInd],"-o") == 0) |
607 | { |
608 | rootFilename = argV[++argInd]; |
609 | } |
610 | else if (strcmp(argV[argInd],"-n") == 0) |
611 | { |
612 | if (!sscanf(argV[++argInd],"%d",&reqcount)) |
613 | { |
614 | usage(); |
615 | return 1; |
616 | } |
617 | } |
618 | else |
619 | { |
620 | usage(); |
621 | return 1; |
622 | } |
623 | } |
624 | |
625 | XString hddmFile; |
626 | std::istream* ifs; |
627 | if (argInd == argC) |
628 | { |
629 | ifs = &std::cin; |
630 | } |
631 | else if (argInd == argC - 1) |
632 | { |
633 | hddmFile = XString(argV[argInd]); |
634 | ifs = new std::ifstream(hddmFile.c_str()); |
635 | } |
636 | else |
637 | { |
638 | usage(); |
639 | return 1; |
640 | } |
641 | if (!ifs->good()) |
642 | { |
643 | std::cerr |
644 | << "hddm-root: Error opening input stream " << hddmFile << std::endl; |
645 | exit(1); |
646 | } |
647 | std::ostringstream doc; |
648 | std::ostringstream tmpFileStr; |
649 | tmpFileStr << "tmp" << getpid(); |
650 | std::ofstream ofs(tmpFileStr.str().c_str()); |
651 | if (! ofs.is_open()) |
652 | { |
653 | std::cerr |
654 | << "hddm-root: Error opening temp file " << tmpFileStr.str() << std::endl; |
655 | exit(2); |
656 | } |
657 | |
658 | ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; |
659 | doc << std::endl; |
660 | XString xmlHeader; |
661 | XString line; |
662 | if (getline(*ifs,line)) |
663 | { |
664 | if (line.substr(0,5) == "<?xml") |
665 | { |
666 | std::cerr |
667 | << "hddm-root: Error reading input stream " << hddmFile |
668 | << std::endl; |
669 | std::cerr |
670 | << "Input file appears to be an xml document!" << std::endl; |
671 | exit(1); |
672 | } |
673 | else if (line.substr(0,5) == "<HDDM") |
674 | { |
675 | xmlHeader = line + "\n"; |
676 | ofs << line << std::endl; |
677 | doc << line << std::endl; |
678 | } |
679 | else |
680 | { |
681 | std::cerr |
682 | << "hddm-root: Input stream does not contain valid hddm header" |
683 | << std::endl; |
684 | exit(1); |
685 | } |
686 | } |
687 | else |
688 | { |
689 | std::cerr |
690 | << "hddm-root: Error reading from input stream " << hddmFile |
691 | << std::endl; |
692 | exit(1); |
693 | } |
694 | while (getline(*ifs,line)) |
695 | { |
696 | ofs << line << std::endl; |
697 | doc << line << std::endl; |
698 | if (line == "</HDDM>") |
699 | { |
700 | break; |
701 | } |
702 | } |
703 | ofs.close(); |
704 | |
705 | #if defined OLD_STYLE_XERCES_PARSER |
706 | DOMDocument* document = parseInputDocument(tmpFileStr.str().c_str(),false); |
707 | #else |
708 | DOMDocument* document = buildDOMDocument(tmpFileStr.str().c_str(),false); |
709 | #endif |
710 | if (document == 0) |
711 | { |
712 | std::cerr |
713 | << "hddm-root : Error parsing HDDM document, " |
714 | << "cannot continue" << std::endl; |
715 | return 1; |
716 | } |
717 | unlink(tmpFileStr.str().c_str()); |
718 | |
719 | DOMElement* rootEl = document->getDocumentElement(); |
720 | XString rootS(rootEl->getTagName()); |
721 | if (rootS != "HDDM") |
722 | { |
723 | std::cerr |
724 | << "hddm-root error: root element of input document is " |
725 | << "\"" << S(rootS)rootS.c_str() << "\", expected \"HDDM\"" |
726 | << std::endl; |
727 | return 1; |
728 | } |
729 | |
730 | // open root file for output and initialize the trees for writing |
731 | TreeMaker builder(rootFilename); |
732 | attribute_list columns; |
733 | element_t root_element(0); |
734 | builder.build(rootEl, &root_element, columns); |
735 | |
736 | int event_buffer_size; |
737 | char *event_buffer = new char[event_buffer_size = 1000000]; |
738 | istreambuffer *isbuf = new istreambuffer(event_buffer,event_buffer_size); |
739 | ixstream *ifx = new ixstream(isbuf); |
740 | int integrity_check_mode = 0; |
741 | int compression_mode = 0; |
742 | while (reqcount && ifs->good()) |
743 | { |
744 | int tsize; |
745 | ifs->read(event_buffer,4); |
746 | if (ifs->eof()) { |
747 | break; |
748 | } |
749 | isbuf->reset(); |
750 | *ifx >> tsize; |
751 | #ifdef VERBOSE_HDDM_LOGGING |
752 | XString tnameS(rootEl->getTagName()); |
753 | std::cerr << "hddm-root : tag " << S(tnameS)tnameS.c_str() |
754 | << " found with size " << tsize |
755 | << std::endl; |
756 | #endif |
757 | if (tsize <= 0) |
758 | { |
759 | break; |
760 | } |
761 | else if (tsize == 1) { |
762 | int size, format, flags; |
763 | ifs->read(event_buffer+4,4); |
764 | *ifx >> size; |
765 | ifs->read(event_buffer+8,size); |
766 | *ifx >> format >> flags; |
767 | int compression_flags = flags & 0xf0; |
768 | int integrity_flags = flags & 0x0f; |
769 | std::streambuf *fin_sb = 0; |
770 | xstream::z::istreambuf *zin_sb = 0; |
771 | xstream::bz::istreambuf *bzin_sb = 0; |
772 | int *leftovers = new int[100]; |
773 | int sizeof_leftovers = sizeof(int[100]); |
774 | leftovers[0] = 0; |
775 | if (compression_flags == compression_mode) { |
776 | fin_sb = ifs->rdbuf(); |
Value stored to 'fin_sb' is never read | |
777 | } |
778 | else if (size == 8 && format == 0 && compression_flags == 0x10) { |
779 | if (compression_mode == 0x20) { |
780 | bzin_sb = (xstream::bz::istreambuf*)ifs->rdbuf(); |
781 | } |
782 | compression_mode = compression_flags; |
783 | zin_sb = new xstream::z::istreambuf(ifs->rdbuf(), |
784 | leftovers, sizeof_leftovers); |
785 | ifs->rdbuf(zin_sb); |
786 | if (bzin_sb != 0) |
787 | delete bzin_sb; |
788 | } |
789 | else if (size == 8 && format == 0 && compression_flags == 0x20) { |
790 | if (compression_mode == 0x10) { |
791 | zin_sb = (xstream::z::istreambuf*)ifs->rdbuf(); |
792 | } |
793 | compression_mode = compression_flags; |
794 | bzin_sb = new xstream::bz::istreambuf(ifs->rdbuf(), |
795 | leftovers, sizeof_leftovers); |
796 | ifs->rdbuf(bzin_sb); |
797 | if (zin_sb != 0) |
798 | delete zin_sb; |
799 | } |
800 | else { |
801 | if (compression_mode == 0x20) { |
802 | bzin_sb = (xstream::bz::istreambuf*)ifs->rdbuf(); |
803 | fin_sb = bzin_sb->get_streambuf(); |
804 | } |
805 | else if (compression_mode == 0x10) { |
806 | zin_sb = (xstream::z::istreambuf*)ifs->rdbuf(); |
807 | fin_sb = zin_sb->get_streambuf(); |
808 | } |
809 | compression_mode = compression_flags; |
810 | ifs->rdbuf(fin_sb); |
811 | if (zin_sb != 0) |
812 | delete zin_sb; |
813 | if (bzin_sb != 0) |
814 | delete bzin_sb; |
815 | } |
816 | if (size == 8 && format == 0 && integrity_flags == 0x0) { |
817 | integrity_check_mode = 0; |
818 | } |
819 | else if (size == 8 && format == 0 && integrity_flags == 0x1) { |
820 | integrity_check_mode = 1; |
821 | } |
822 | else { |
823 | std::cerr << "hddm-root error: unrecognized stream modifier" |
824 | " encountered, this stream is no longer readable." |
825 | << std::endl; |
826 | break; |
827 | } |
828 | continue; |
829 | } |
830 | else if (tsize+4 > event_buffer_size) { |
831 | delete ifx; |
832 | delete isbuf; |
833 | char *new_buffer = new char[event_buffer_size = tsize+1000]; |
834 | isbuf = new istreambuffer(new_buffer,event_buffer_size); |
835 | ifx = new ixstream(isbuf); |
836 | memcpy(new_buffer,event_buffer,4); |
837 | *ifx >> tsize; |
838 | delete[] event_buffer; |
839 | event_buffer = new_buffer; |
840 | } |
841 | ifs->read(event_buffer+4,tsize); |
842 | --reqcount; |
843 | |
844 | if (integrity_check_mode == 1) { |
845 | char crcbuf[10]; |
846 | istreambuffer sbuf(crcbuf,10); |
847 | ixstream xstr(&sbuf); |
848 | unsigned int recorded_crc; |
849 | ifs->read(crcbuf,4); |
850 | xstr >> recorded_crc; |
851 | xstream::digest::crc32 crc; |
852 | std::ostream out(&crc); |
853 | out.write(event_buffer,tsize+4); |
854 | out.flush(); |
855 | if (crc.digest() != recorded_crc) { |
856 | #if BAD_CRC_IS_ONLY_WARNING |
857 | static int bad_crc_warning_needed = true; |
858 | char errmsg[] = |
859 | "WARNING: data integrity crc check failed on input.\n" |
860 | "This may be the result of a bug in the xstream library\n" |
861 | "if you are analyzing a data file that was generated by\n" |
862 | "code prior to svn rev 18530. If this concerns you, \n" |
863 | "regenerate the file using a newer build of the sim-recon\n" |
864 | "tools and it should go away.\n"; |
865 | if (bad_crc_warning_needed) { |
866 | std::cerr << errmsg << std::endl; |
867 | bad_crc_warning_needed = false; |
868 | } |
869 | #else |
870 | std::cerr << "hddm-root error: crc32 check error on input stream" |
871 | " encountered, this stream is no longer readable." |
872 | << std::endl; |
873 | break; |
874 | #endif |
875 | } |
876 | } |
877 | builder.filltrees(ifx, &root_element); |
878 | } |
879 | if (write_xml_output_to_stdout) { |
880 | std::cout << "</HDDM>" << std::endl; |
881 | } |
882 | builder.savetrees(&root_element); |
883 | TNamed docString("document_metadata_XML", doc.str().c_str()); |
884 | docString.Write(); |
885 | |
886 | if (ifs != &std::cin) |
887 | { |
888 | ((std::ifstream*)ifs)->close(); |
889 | } |
890 | |
891 | XMLPlatformUtils::Terminate(); |
892 | return 0; |
893 | } |
894 | |
895 | void TreeMaker::build(const DOMElement* elem, element_t *parent_element, |
896 | attribute_list columns) |
897 | { |
898 | // Recursively create TTree objects to hold the contents of the hddm model |
899 | // in the form of a row/column table, like a relational database model. |
900 | |
901 | XString elemS(elem->getTagName()); |
902 | std::list<element_t*>::iterator eter; |
903 | for (eter = fElements.begin(); eter != fElements.end(); ++eter) { |
904 | if (elemS == (*eter)->fName) { |
905 | elemS = parent_element->fName + "_" + elemS; |
906 | } |
907 | } |
908 | TTree *tree = new TTree(S(elemS)elemS.c_str(), S(XString(elemS + " tree"))XString(elemS + " tree").c_str()); |
909 | element_t *this_element = new element_t(tree, elemS); |
910 | fElements.push_back(this_element); |
911 | |
912 | XString repS(elem->getAttribute(X("maxOccurs")XString("maxOccurs").unicode_str())); |
913 | int rep = (repS == "unbounded")? INT_MAX2147483647 : |
914 | (repS == "")? 1 : |
915 | atoi(S(repS)repS.c_str()); |
916 | if (explicit_repeat_count && rep > 1) |
917 | this_element->set_repeating(); |
918 | |
919 | // Create a new column called "key" to hold synchronization |
920 | // information between rows in different trees, similar to |
921 | // the way keys are used in relational databases (eg. JOIN). |
922 | |
923 | XString keyS("HDDM_MASTER_ORDERING_KEY"); |
924 | if (fColumns.find(keyS) == fColumns.end()) { |
925 | int_attribute_t *key = new int_attribute_t("key"); |
926 | fColumns[keyS] = key; |
927 | } |
928 | tree->Branch("key", fColumns[keyS]->address(), "key/I"); |
929 | this_element->add_key((int_attribute_t*)fColumns[keyS]); |
930 | |
931 | // Add branches for attributes inherited from parent elements |
932 | |
933 | attribute_list::iterator iter; |
934 | for (iter = columns.begin(); iter != columns.end(); ++iter) { |
935 | XString colS = iter->first; |
936 | XString nameS = iter->second; |
937 | XString typeS = fColumns[colS]->get_type(); |
938 | if (typeS == "int" || typeS == "boolean" || typeS == "Particle_t") |
939 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
940 | S(XString(nameS + "/I"))XString(nameS + "/I").c_str()); |
941 | else if (typeS == "long") |
942 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
943 | S(XString(nameS + "/L"))XString(nameS + "/L").c_str()); |
944 | else if (typeS == "float") |
945 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
946 | S(XString(nameS + "/F"))XString(nameS + "/F").c_str()); |
947 | else if (typeS == "double") |
948 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
949 | S(XString(nameS + "/D"))XString(nameS + "/D").c_str()); |
950 | else if (typeS == "string" || typeS == "anyURI") |
951 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
952 | S(XString(nameS + "/C"))XString(nameS + "/C").c_str()); |
953 | else { |
954 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
955 | S(XString(nameS + "/C"))XString(nameS + "/C").c_str()); |
956 | } |
957 | } |
958 | |
959 | // Add branches for the element's own attributes |
960 | |
961 | DOMNamedNodeMap* attrList = elem->getAttributes(); |
962 | int attrListLength = attrList->getLength(); |
963 | for (int a = 0; a < attrListLength; a++) { |
964 | DOMNode* node = attrList->item(a); |
965 | XString nameS(node->getNodeName()); |
966 | XString typeS(node->getNodeValue()); |
967 | XString colS(elemS + "_" + nameS); |
968 | if (columns.find(nameS) != columns.end()) |
969 | nameS = colS; |
970 | if (typeS == "int") { |
971 | fColumns[colS] = new int_attribute_t(nameS); |
972 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
973 | S(XString(nameS + "/I"))XString(nameS + "/I").c_str()); |
974 | } |
975 | else if (typeS == "boolean") { |
976 | fColumns[colS] = new boolean_attribute_t(nameS); |
977 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
978 | S(XString(nameS + "/I"))XString(nameS + "/I").c_str()); |
979 | } |
980 | else if (typeS == "Particle_t") { |
981 | fColumns[colS] = new Particle_attribute_t(nameS); |
982 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
983 | S(XString(nameS + "/I"))XString(nameS + "/I").c_str()); |
984 | } |
985 | else if (typeS == "long") { |
986 | fColumns[colS] = new long_attribute_t(nameS); |
987 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
988 | S(XString(nameS + "/L"))XString(nameS + "/L").c_str()); |
989 | } |
990 | else if (typeS == "float") { |
991 | fColumns[colS] = new float_attribute_t(nameS); |
992 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
993 | S(XString(nameS + "/F"))XString(nameS + "/F").c_str()); |
994 | } |
995 | else if (typeS == "double") { |
996 | fColumns[colS] = new double_attribute_t(nameS); |
997 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
998 | S(XString(nameS + "/D"))XString(nameS + "/D").c_str()); |
999 | } |
1000 | else if (typeS == "string") { |
1001 | fColumns[colS] = new string_attribute_t(nameS); |
1002 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
1003 | S(XString(nameS + "/C"))XString(nameS + "/C").c_str()); |
1004 | } |
1005 | else if (typeS == "anyURI") { |
1006 | fColumns[colS] = new anyURI_attribute_t(nameS); |
1007 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
1008 | S(XString(nameS + "/C"))XString(nameS + "/C").c_str()); |
1009 | } |
1010 | else if (nameS == "minOccurs" || nameS == "maxOccurs") { |
1011 | continue; |
1012 | } |
1013 | else { |
1014 | fColumns[colS] = new constant_attribute_t(nameS); |
1015 | tree->Branch(S(nameS)nameS.c_str(), fColumns[colS]->address(), |
1016 | S(XString(nameS + "/C"))XString(nameS + "/C").c_str()); |
1017 | ((constant_attribute_t*)fColumns[colS])->set(S(typeS)typeS.c_str()); |
1018 | } |
1019 | columns[colS] = nameS; |
1020 | this_element->add_attribute(fColumns[colS]); |
1021 | } |
1022 | |
1023 | parent_element->add_element(this_element); |
1024 | |
1025 | // Recursively build any elements contained within this one |
1026 | |
1027 | DOMNodeList* contList = elem->getChildNodes(); |
1028 | int contLength = contList->getLength(); |
1029 | for (int c = 0; c < contLength; c++) { |
1030 | DOMNode* cont = contList->item(c); |
1031 | short type = cont->getNodeType(); |
1032 | if (type == DOMNode::ELEMENT_NODE) { |
1033 | DOMElement* contEl = (DOMElement*) cont; |
1034 | build(contEl, this_element, columns); |
1035 | } |
1036 | } |
1037 | } |
1038 | |
1039 | int TreeMaker::filltrees(ixstream *ifx, element_t *parent_element) |
1040 | { |
1041 | element_t *HDDMelement = *parent_element->fElements.begin(); |
1042 | std::list<element_t*>::iterator iter; |
1043 | int size = 0; |
1044 | for (iter = HDDMelement->fElements.begin(); |
1045 | iter != HDDMelement->fElements.end(); |
1046 | ++iter) |
1047 | { |
1048 | size += (*iter)->read(ifx); |
1049 | #ifdef VERBOSE_HDDM_LOGGING |
1050 | XString cnameS((*iter)->fName); |
1051 | std::cerr << "hddm-root : top-level tag " << S(cnameS)cnameS.c_str() |
1052 | << " found with size " << size |
1053 | << std::endl; |
1054 | #endif |
1055 | } |
1056 | return size; |
1057 | } |
1058 | |
1059 | int TreeMaker::savetrees(element_t *parent_element) |
1060 | { |
1061 | int count = 0; |
1062 | std::list<element_t*>::iterator iter; |
1063 | for (iter = parent_element->fElements.begin(); |
1064 | iter != parent_element->fElements.end(); |
1065 | ++iter) |
1066 | { |
1067 | if ((*iter)->fTree) { |
1068 | (*iter)->fTree->Write(); |
1069 | ++count; |
1070 | } |
1071 | count += savetrees(*iter); |
1072 | } |
1073 | return count; |
1074 | } |