Bug Summary

File:programs/Utilities/hddm/hddm-xml.cpp
Location:line 360, column 13
Description:Value stored to 'fin_sb' is never read

Annotated Source Code

1/*
2 * hddm-xml : tool that reads in a HDDM document (Hall D Data Model)
3 * and translates it into plain-text xml.
4 *
5 * Version 1.3 - Richard Jones, July 2014.
6 * - Added support for input hddm streams with additional features
7 * provided through the c++ API, including on-the-fly compression with
8 * zlib and bzlib2, and per-record crc32 integrity checks.
9 *
10 * Version 1.2 - Richard Jones, December 2005.
11 * - Updated code to use STL strings and vectors instead of old c-style
12 * pre-allocated arrays and strXXX functions.
13 * - Moved functions into classes grouped by function for better clarity.
14 * - Introduced the XStream class library instead of the direct interface
15 * to the rpc/xdr c-library function. This also gives access to a nice
16 * integrated set of compression/decompression streambuf classes.
17 *
18 * Version 1.1 - Richard Jones, September 2003.
19 * - Updated code to work with the new DOM-2 implementation Xerces-c
20 * from apache.org. Significant changes have taken place in the API
21 * since DOM-1.
22 * - Added support for new types "long" (int64), "string" (char arrays of
23 * arbitrary length), and "anyURI" (special case of string).
24 * - Switched from native encoding to the use of the XDR library to make
25 * hddm files machine-independent.
26 *
27 * Original version - Richard Jones, June 4 2001.
28 *
29 *
30 * Programmer's Notes:
31 * -------------------
32 * 1. The output from hddm-xml is a well-formed xml document.
33 *
34 * 2. The hddm stream contains a xml header that functions as a prototype
35 * of the xml output.
36 *
37 * 3. This tool can read any hddm stream. No recompilation is required.
38 *
39 * 4. The code has been tested with the xerces-c DOM implementation from
40 * Apache, and is intended to be used with the xerces-c library.
41 *
42 * 5. Output is sent by default to stdout and can be changed with the
43 * -o option.
44 */
45
46// #define VERBOSE_HDDM_LOGGING 1
47#define BAD_CRC_IS_ONLY_WARNING1 1
48
49#include <xercesc/util/PlatformUtils.hpp>
50#include <xercesc/dom/DOMNamedNodeMap.hpp>
51
52#include "XParsers.hpp"
53#include "XString.hpp"
54
55#include <assert.h>
56#include <stdlib.h>
57#include <stdio.h>
58#include <rpc/rpc.h>
59#include <unistd.h>
60#include <xstream/z.h>
61#include <xstream/bz.h>
62#include <xstream/xdr.h>
63#include <xstream/digest.h>
64
65#include <iostream>
66#include <fstream>
67#include <sstream>
68
69#include "particleType.h"
70
71
72#define X(str)XString(str).unicode_str() XString(str).unicode_str()
73#define S(str)str.c_str() str.c_str()
74
75using namespace xercesc;
76
77int explicit_repeat_count = 1;
78
79class XMLmaker
80{
81 public:
82 std::ofstream xout;
83
84 XMLmaker() {};
85 ~XMLmaker() {};
86
87 void writeXML(const XString& s);
88 void constructXML(xstream::xdr::istream *ifx, DOMElement* el,
89 int size, int depth);
90};
91
92class istreambuffer : public std::streambuf {
93 public:
94 istreambuffer(char* buffer, std::streamsize bufferLength) {
95 setg(buffer, buffer, buffer + bufferLength);
96 }
97
98 std::streampos tellg() {
99 return gptr() - eback();
100 }
101
102 void seekg(std::streampos pos) {
103 reset();
104 gbump(pos);
105 }
106
107 int size() {
108 return egptr() - gptr();
109 }
110
111 void reset() {
112 char *gbegin = eback();
113 char *gend = egptr();
114 setg(gbegin, gbegin, gend);
115 }
116
117 char *getbuf() {
118 return eback();
119 }
120};
121
122class ostreambuffer : public std::streambuf {
123 public:
124 ostreambuffer(char* buffer, std::streamsize bufferLength) {
125 setp(buffer, buffer + bufferLength);
126 }
127
128 std::streampos tellp() {
129 return pptr() - pbase();
130 }
131
132 void seekp(std::streampos pos) {
133 reset();
134 pbump(pos);
135 }
136
137 int size() {
138 return pptr() - pbase();
139 }
140
141 void reset() {
142 char *pbegin = pbase();
143 char *pend = epptr();
144 setp(pbegin, pend);
145 }
146
147 char *getbuf() {
148 return pbase();
149 }
150};
151
152void usage()
153{
154 std::cerr
155 << "\nUsage:\n"
156 << " hddm-xml [-n count] [-o <filename>] [HDDM file]\n\n"
157 << "Options:\n"
158 << " -o <filename> write to <filename>.xml"
159 << std::endl;
160}
161
162
163int main(int argC, char* argV[])
164{
165 XString xFilename;
166
167 try
168 {
169 XMLPlatformUtils::Initialize();
170 }
171 catch (const XMLException* toCatch)
172 {
173 XString msg(toCatch->getMessage());
174 std::cerr
175 << "hddm-xml: Error during initialization! :\n"
176 << S(msg)msg.c_str() << std::endl;
177 return 1;
178 }
179
180 int reqcount=-1;
181 int argInd;
182 for (argInd = 1; argInd < argC; argInd++)
183 {
184 if (argV[argInd][0] != '-')
185 {
186 break;
187 }
188 else if (strcmp(argV[argInd],"-o") == 0)
189 {
190 xFilename = argV[++argInd];
191 }
192 else if (strcmp(argV[argInd],"-n") == 0)
193 {
194 if (!sscanf(argV[++argInd],"%d",&reqcount))
195 {
196 usage();
197 return 1;
198 }
199 }
200 else
201 {
202 usage();
203 return 1;
204 }
205 }
206
207 XString hddmFile;
208 std::istream* ifs;
209 if (argInd == argC)
210 {
211 ifs = &std::cin;
212 }
213 else if (argInd == argC - 1)
214 {
215 hddmFile = XString(argV[argInd]);
216 ifs = new std::ifstream(hddmFile.c_str());
217 }
218 else
219 {
220 usage();
221 return 1;
222 }
223 if (!ifs->good())
224 {
225 std::cerr
226 << "hddm-xml: Error opening input stream " << hddmFile << std::endl;
227 exit(1);
228 }
229 std::ostringstream tmpFileStr;
230 tmpFileStr << "tmp" << getpid();
231 std::ofstream ofs(tmpFileStr.str().c_str());
232 if (! ofs.is_open())
233 {
234 std::cerr
235 << "hddm-xml: Error opening temp file " << tmpFileStr.str() << std::endl;
236 exit(2);
237 }
238
239 ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
240 XString xmlHeader;
241 XString line;
242 if (getline(*ifs,line))
243 {
244 if (line.substr(0,5) == "<?xml")
245 {
246 std::cerr
247 << "hddm-xml: Error reading input stream " << hddmFile
248 << std::endl;
249 std::cerr
250 << "Input file appears to be an xml document!" << std::endl;
251 exit(1);
252 }
253 else if (line.substr(0,5) == "<HDDM")
254 {
255 xmlHeader = line + "\n";
256 ofs << line;
257 }
258 else
259 {
260 std::cerr
261 << "hddm-xml: Input stream does not contain valid hddm header"
262 << std::endl;
263 exit(1);
264 }
265 }
266 else
267 {
268 std::cerr
269 << "hddm-xml: Error reading from input stream " << hddmFile
270 << std::endl;
271 exit(1);
272 }
273 while (getline(*ifs,line))
274 {
275 ofs << line;
276 if (line == "</HDDM>")
277 {
278 break;
279 }
280 }
281 ofs.close();
282
283#if defined OLD_STYLE_XERCES_PARSER
284 DOMDocument* document = parseInputDocument(tmpFileStr.str().c_str(),false);
285#else
286 DOMDocument* document = buildDOMDocument(tmpFileStr.str().c_str(),false);
287#endif
288 if (document == 0)
289 {
290 std::cerr
291 << "hddm-xml : Error parsing HDDM document, "
292 << "cannot continue" << std::endl;
293 return 1;
294 }
295 unlink(tmpFileStr.str().c_str());
296
297 DOMElement* rootEl = document->getDocumentElement();
298 XString rootS(rootEl->getTagName());
299 if (rootS != "HDDM")
300 {
301 std::cerr
302 << "hddm-xml error: root element of input document is "
303 << "\"" << S(rootS)rootS.c_str() << "\", expected \"HDDM\""
304 << std::endl;
305 return 1;
306 }
307
308 XMLmaker builder;
309 if (xFilename.size())
310 {
311 XString fname(xFilename + ".xml");
312 builder.xout.open(fname.c_str());
313 }
314
315 builder.writeXML("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
316 builder.writeXML(xmlHeader);
317
318 int event_buffer_size;
319 char *event_buffer = new char[event_buffer_size = 1000000];
320 istreambuffer *isbuf = new istreambuffer(event_buffer,event_buffer_size);
321 xstream::xdr::istream *ifx = new xstream::xdr::istream(isbuf);
322 int integrity_check_mode = 0;
323 int compression_mode = 0;
324 while (reqcount && ifs->good())
325 {
326 DOMNodeList* contList = rootEl->getChildNodes();
327 int contLength = contList->getLength();
328 int tsize;
329 ifs->read(event_buffer,4);
330 if (ifs->eof()) {
331 break;
332 }
333 isbuf->reset();
334 *ifx >> tsize;
335#ifdef VERBOSE_HDDM_LOGGING
336 XString tnameS(rootEl->getTagName());
337 std::cerr << "hddm-xml : tag " << S(tnameS)tnameS.c_str()
338 << " found with size " << tsize
339 << std::endl;
340#endif
341 if (tsize <= 0)
342 {
343 break;
344 }
345 else if (tsize == 1) {
346 int size, format, flags;
347 ifs->read(event_buffer+4,4);
348 *ifx >> size;
349 ifs->read(event_buffer+8,size);
350 *ifx >> format >> flags;
351 int compression_flags = flags & 0xf0;
352 int integrity_flags = flags & 0x0f;
353 std::streambuf *fin_sb = 0;
354 xstream::z::istreambuf *zin_sb = 0;
355 xstream::bz::istreambuf *bzin_sb = 0;
356 int *leftovers = new int[100];
357 int sizeof_leftovers = sizeof(int[100]);
358 leftovers[0] = 0;
359 if (compression_flags == compression_mode) {
360 fin_sb = ifs->rdbuf();
Value stored to 'fin_sb' is never read
361 }
362 else if (size == 8 && format == 0 && compression_flags == 0x10) {
363 if (compression_mode == 0x20) {
364 bzin_sb = (xstream::bz::istreambuf*)ifs->rdbuf();
365 }
366 compression_mode = compression_flags;
367 zin_sb = new xstream::z::istreambuf(ifs->rdbuf(),
368 leftovers, sizeof_leftovers);
369 ifs->rdbuf(zin_sb);
370 if (bzin_sb != 0)
371 delete bzin_sb;
372 }
373 else if (size == 8 && format == 0 && compression_flags == 0x20) {
374 if (compression_mode == 0x10) {
375 zin_sb = (xstream::z::istreambuf*)ifs->rdbuf();
376 }
377 compression_mode = compression_flags;
378 bzin_sb = new xstream::bz::istreambuf(ifs->rdbuf(),
379 leftovers, sizeof_leftovers);
380 ifs->rdbuf(bzin_sb);
381 if (zin_sb != 0)
382 delete zin_sb;
383 }
384 else {
385 if (compression_mode == 0x20) {
386 bzin_sb = (xstream::bz::istreambuf*)ifs->rdbuf();
387 fin_sb = bzin_sb->get_streambuf();
388 }
389 else if (compression_mode == 0x10) {
390 zin_sb = (xstream::z::istreambuf*)ifs->rdbuf();
391 fin_sb = zin_sb->get_streambuf();
392 }
393 compression_mode = compression_flags;
394 ifs->rdbuf(fin_sb);
395 if (zin_sb != 0)
396 delete zin_sb;
397 if (bzin_sb != 0)
398 delete bzin_sb;
399 }
400 if (size == 8 && format == 0 && integrity_flags == 0x0) {
401 integrity_check_mode = 0;
402 }
403 else if (size == 8 && format == 0 && integrity_flags == 0x1) {
404 integrity_check_mode = 1;
405 }
406 else {
407 std::cerr << "hddm-xml error: unrecognized stream modifier"
408 " encountered, this stream is no longer readable."
409 << std::endl;
410 break;
411 }
412 continue;
413 }
414 else if (tsize+4 > event_buffer_size) {
415 delete ifx;
416 delete isbuf;
417 char *new_buffer = new char[event_buffer_size = tsize+1000];
418 isbuf = new istreambuffer(new_buffer,event_buffer_size);
419 ifx = new xstream::xdr::istream(isbuf);
420 memcpy(new_buffer,event_buffer,4);
421 *ifx >> tsize;
422 delete[] event_buffer;
423 event_buffer = new_buffer;
424 }
425 ifs->read(event_buffer+4,tsize);
426 --reqcount;
427
428 if (integrity_check_mode == 1) {
429 char crcbuf[10];
430 istreambuffer sbuf(crcbuf,10);
431 xstream::xdr::istream xstr(&sbuf);
432 unsigned int recorded_crc;
433 ifs->read(crcbuf,4);
434 xstr >> recorded_crc;
435 xstream::digest::crc32 crc;
436 std::ostream out(&crc);
437 out.write(event_buffer,tsize+4);
438 out.flush();
439 if (crc.digest() != recorded_crc) {
440#if BAD_CRC_IS_ONLY_WARNING1
441 static int bad_crc_warning_needed = true;
442 char errmsg[] =
443 "WARNING: data integrity crc check failed on input.\n"
444 "This may be the result of a bug in the xstream library\n"
445 "if you are analyzing a data file that was generated by\n"
446 "code prior to svn rev 18530. If this concerns you, \n"
447 "regenerate the file using a newer build of the sim-recon\n"
448 "tools and it should go away.\n";
449 if (bad_crc_warning_needed) {
450 std::cerr << errmsg << std::endl;
451 bad_crc_warning_needed = false;
452 }
453#else
454 std::cerr << "hddm-xml error: crc32 check error on input stream"
455 " encountered, this stream is no longer readable."
456 << std::endl;
457 break;
458#endif
459 }
460 }
461
462 for (int c = 0; c < contLength; c++)
463 {
464 DOMNode* cont = contList->item(c);
465 short type = cont->getNodeType();
466 if (type == DOMNode::ELEMENT_NODE)
467 {
468 DOMElement* contEl = (DOMElement*) cont;
469 int size;
470 *ifx >> size;
471#ifdef VERBOSE_HDDM_LOGGING
472 XString cnameS(contEl->getTagName());
473 std::cerr << "hddm-xml : top-level tag " << S(cnameS)cnameS.c_str()
474 << " found with size " << size
475 << std::endl;
476#endif
477 if (size > 0)
478 {
479 builder.constructXML(ifx,contEl,size,1);
480 }
481 else {
482 XString repS(contEl->getAttribute(X("minOccurs")XString("minOccurs").unicode_str()));
483 int rep = (repS == "")? 1 : atoi(S(repS)repS.c_str());
484 if (rep != 0) {
485 XString conameS(contEl->getTagName());
486 std::cerr << "hddm-xml warning: top-level tag " << S(conameS)conameS.c_str()
487 << " found with zero size "
488 << "inside an event with size " << tsize
489 << " continue? [y/n] ";
490 std::string ans;
491 std::cin >> ans;
492 if (ans[0] != 'y' && ans[0] != 'Y') {
493 exit(5);
494 }
495 }
496 }
497 }
498 }
499 }
500
501 builder.writeXML("</HDDM>\n");
502
503 if (ifs != &std::cin)
504 {
505 ((std::ifstream*)ifs)->close();
506 }
507 XMLPlatformUtils::Terminate();
508 return 0;
509}
510
511/* write a string to xml output stream, either stdout or a file */
512
513void XMLmaker::writeXML(const XString& s)
514{
515 if (xout.is_open())
516 {
517 xout << s;
518 }
519 else
520 {
521 std::cout << s;
522 }
523}
524
525/* Generate the output xml document according the DOM;
526 * at entry the buffer pointer bp points the the word after the word count
527 */
528
529void XMLmaker::constructXML(xstream::xdr::istream *ifx,
530 DOMElement* el, int size, int depth)
531{
532 XString tagS(el->getTagName());
533 XString repS(el->getAttribute(X("maxOccurs")XString("maxOccurs").unicode_str()));
534 int rep = (repS == "unbounded")? INT_MAX2147483647 :
535 (repS == "")? 1 :
536 atoi(S(repS)repS.c_str());
537 if (explicit_repeat_count && rep > 1)
538 {
539 *ifx >> rep;
540 size -= 4;
541 }
542
543 int r;
544 for (r = 0; r < rep && size > 0; r++)
545 {
546 for (int d = 0; d < depth; d++)
547 {
548 writeXML(" ");
549 }
550 writeXML("<");
551 writeXML(S(tagS)tagS.c_str());
552 DOMNamedNodeMap* attrList = el->getAttributes();
553 int listLength = attrList->getLength();
554 for (int a = 0; a < listLength; a++)
555 {
556 XString nameS(attrList->item(a)->getNodeName());
557 XString typeS(attrList->item(a)->getNodeValue());
558 std::ostringstream attrStr;
559 if (typeS == "int")
560 {
561 int32_t value;
562 *ifx >> value;
563 size -= 4;
564 attrStr << " " << nameS << "=\"" << value << "\"";
565 }
566 else if (typeS == "long")
567 {
568 int64_t value;
569 *ifx >> value;
570 size -= 8;
571 attrStr << " " << nameS << "=\"" << value << "\"";
572 }
573 else if (typeS == "float")
574 {
575 float value;
576 *ifx >> value;
577 size -= 4;
578 attrStr << " " << nameS << "=\"" << value << "\"";
579 }
580 else if (typeS == "double")
581 {
582 double value;
583 *ifx >> value;
584 size -= 8;
585 attrStr << " " << nameS << "=\"" << value << "\"";
586 }
587 else if (typeS == "boolean")
588 {
589 bool_t value;
590 *ifx >> value;
591 size -= 4;
592 attrStr << " " << nameS << "=\"" << value << "\"";
593 }
594 else if (typeS == "Particle_t")
595 {
596 int32_t value;
597 *ifx >> value;
598 size -= 4;
599 attrStr << " " << nameS << "=\"" << ParticleType((Particle_t)value) << "\"";
600 }
601 else if (typeS == "string" || typeS == "anyURI")
602 {
603 std::string value;
604 *ifx >> value;
605 int strsize = value.size();
606 size -= strsize + 4 + ((strsize % 4)? 4-(strsize % 4) : 0);
607 attrStr << " " << nameS << "=\"" << value << "\"";
608 }
609 else if (nameS == "minOccurs" || nameS == "maxOccurs")
610 {
611 ;
612 }
613 else
614 {
615 attrStr << " " << nameS << "=\"" << typeS << "\"";
616 }
617 writeXML(attrStr.str());
618 }
619
620 DOMNodeList* contList = el->getChildNodes();
621 int contLength = contList->getLength();
622 if (contLength > 1)
623 {
624 writeXML(">\n");
625 }
626 else
627 {
628 writeXML(" />\n");
629 }
630
631 for (int c = 0; c < contLength; c++)
632 {
633 DOMNode* cont = contList->item(c);
634 short type = cont->getNodeType();
635 if (type == DOMNode::ELEMENT_NODE)
636 {
637 DOMElement* contEl = (DOMElement*) cont;
638 int csize;
639 *ifx >> csize;
640 size -= 4;
641#ifdef VERBOSE_HDDM_LOGGING
642 XString cnameS(contEl->getTagName());
643 std::cerr << "hddm-xml : tag " << S(cnameS)cnameS.c_str()
644 << " found with size " << csize
645 << std::endl;
646#endif
647 if (csize > 0) {
648 constructXML(ifx,contEl,csize,depth +1);
649 size -= csize;
650 }
651#ifdef VERBOSE_HDDM_LOGGING
652 else {
653 XString irepS(contEl->getAttribute(X("minOccurs")XString("minOccurs").unicode_str()));
654 int irep = (irepS == "")? 1 : atoi(S(irepS)irepS.c_str());
655 if (irep != 0) {
656 XString conameS(contEl->getTagName());
657 std::cerr << "hddm-xml warning: tag " << S(conameS)conameS.c_str()
658 << " found with zero size, "
659 << "continue? [y/n] ";
660 std::string ans;
661 std::cin >> ans;
662 if (ans[0] != 'y' && ans[0] != 'Y') {
663 exit(5);
664 }
665 }
666 }
667#endif
668 }
669 }
670
671 if (contLength > 1)
672 {
673 for (int d = 0; d < depth; d++)
674 {
675 writeXML(" ");
676 }
677 XString endTag("</"+tagS+">\n");
678 writeXML(endTag);
679 }
680 }
681 if (size != 0) {
682 std::cerr << "hddm-xml : size mismatch in tag " << S(tagS)tagS.c_str()
683 << ", remainder is " << size
684 << ", cannot continue." << std::endl;
685 exit(5);
686 }
687 else if (explicit_repeat_count && r != rep) {
688 std::cerr << "hddm-xml : repeat count mismatch in tag " << S(tagS)tagS.c_str()
689 << ", expected " << rep << " but saw " << r
690 << ", cannot continue." << std::endl;
691 exit(5);
692 }
693}