1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
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 | |
75 | using namespace xercesc; |
76 | |
77 | int explicit_repeat_count = 1; |
78 | |
79 | class 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 | |
92 | class 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 | |
122 | class 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 | |
152 | void 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 | |
163 | int 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++) |
| 1 | Assuming 'argInd' is >= 'argC' | |
|
| 2 | | Loop condition is false. Execution continues on line 207 | |
|
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)) |
| 9 | | Loop condition is true. Entering loop body | |
|
| 11 | | Loop condition is true. Entering loop body | |
|
| 13 | | Loop condition is true. Entering loop body | |
|
| 15 | | Loop condition is true. Entering loop body | |
|
274 | { |
275 | ofs << line; |
276 | if (line == "</HDDM>") |
| |
| |
| |
| |
277 | { |
278 | break; |
| 17 | | Execution continues on line 281 | |
|
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) |
| 18 | | Assuming 'document' is not equal to null | |
|
| |
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()) |
| 22 | | Loop condition is true. Entering loop body | |
|
| 32 | | Loop condition is true. Entering loop body | |
|
| 42 | | Loop condition is true. Entering loop body | |
|
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) |
| 24 | | Assuming 'tsize' is > 0 | |
|
| |
| 34 | | Assuming 'tsize' is > 0 | |
|
| |
| 44 | | Assuming 'tsize' is > 0 | |
|
| |
342 | { |
343 | break; |
344 | } |
345 | else if (tsize == 1) { |
| 26 | | Assuming 'tsize' is not equal to 1 | |
|
| |
| 36 | | Assuming 'tsize' is not equal to 1 | |
|
| |
| 46 | | Assuming 'tsize' is equal to 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) { |
| 49 | | Assuming 'compression_flags' is not equal to 'compression_mode' | |
|
| |
360 | fin_sb = ifs->rdbuf(); |
361 | } |
362 | else if (size == 8 && format == 0 && compression_flags == 0x10) { |
| 51 | | Assuming 'size' is not equal to 8 | |
|
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) { |
| 52 | | Potential leak of memory pointed to by 'leftovers' |
|
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++) |
| 30 | | Assuming 'c' is >= 'contLength' | |
|
| 31 | | Loop condition is false. Execution continues on line 324 | |
|
| 40 | | Assuming 'c' is >= 'contLength' | |
|
| 41 | | Loop condition is false. Execution continues on line 324 | |
|
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 | |
512 | |
513 | void 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 | |
526 | |
527 | |
528 | |
529 | void 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 | } |