Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
hddm-cpp.cpp
Go to the documentation of this file.
1 /*
2  * hddm-cpp : tool that reads in a HDDM document (Hall D Data Model)
3  * and writes a c++ class library that expresses the model
4  * in c++ classes. It also generates input/output methods
5  * for serializing/deserializing these classes in a form
6  * suitable for passing over a network or storing on disk.
7  *
8  * author: richard.t.jones at uconn.edu
9  * version: January 25, 2006 - original release.
10  * January 13, 2012 - added support for compression through
11  * the xstream zip and bzip2 facilities.
12  * June 4, 2016 - added reposition support for random
13  * access to hddm streams, including
14  * compressed streams.
15  *
16  *
17  * Programmer's Notes:
18  * -------------------
19  * 1. The HDDM specification describes data files using xml. For
20  * information about the contents and structure of HDDM documents
21  * see the web page that describes the data model.
22  *
23  * 2. Access by hddm-cpp to the xml source is through the industry-
24  * standard Document Object Model (DOM) interface.
25  *
26  * 3. The code has been tested with the xerces-c DOM implementation from
27  * Apache, and is intended to be used with the xerces-c library.
28  *
29  * 4. Output is sent to <filename>.hpp and <filename>.cpp where <filename>
30  * is by default "hddm_X" and can be changed with the -o option, where
31  * X is the user-defined HDDM class string defined in the HDDM tag.
32  *
33  * 5. As a by-product of using the DOM parser to access the xml source,
34  * hddm-cpp verifies the source for well-formedness. Therefore it may
35  * also be used to check the xml data model document.
36  *
37  *
38  * Implementation Notes:
39  * ---------------------
40  * 1. The binary stream consists of the hddm data model in the form
41  * of a well-formed xml header, followed by binary data.
42  *
43  * 2. The binary data consist of a sequence of event records, which are
44  * repetitions of the basic data model in a serial representation.
45  *
46  * 3. Each element is output to the stream in the order it appears in
47  * the data model, prefixed by an exclusive byte count.
48  *
49  * 4. Any c++ application compiled with the hddm header file that is
50  * generated by hddm-cpp is able to read any hddm binary file that
51  * was written using the same hddm class, ie. the <HDDM class="x">
52  * document tags must be a non-colliding set (see matching rules).
53  *
54  * 5. The input/output features of the class library produced by hddm-cpp
55  * are implemented on top of the "xstream" binary i/o class by Claudio
56  * Valente which provides serialization/deserialization of binary data
57  * using network byte-ordering (RFC-1832), compression/decompression,
58  * and error checking capability used to make the hddm i/o facility
59  * flexible and robust.
60  *
61  * 6. The matching rules between the built-in data model and the data
62  * found in an arbitrary input file are as follows:
63  * a) The attribute list for any given tag must be identical in content
64  * and order wherever it appears, otherwise there is a collision.
65  * b) The content list for any given tag must be internally consistent
66  * within each model, but there are no requirements for agreement
67  * between the classes and the binary stream models. Only the
68  * contents which appear in both models will be unpacked, however.
69  */
70 
71 #include "XString.hpp"
72 #include "XParsers.hpp"
73 #include <xercesc/util/XMLUri.hpp>
74 
75 #include <particleType.h>
76 #include <errno.h>
77 
78 #include <string>
79 #include <vector>
80 #include <map>
81 #include <fstream>
82 
83 #define X(str) XString(str).unicode_str()
84 #define S(str) str.c_str()
85 
86 using namespace xercesc;
87 
89 
90 void usage()
91 {
92  std::cerr
93  << "\nUsage:\n"
94  << " hddm-cpp [-v | -o <filename>] {HDDM file}\n\n"
95  << "Options:\n"
96  << " -v validate only\n"
97  << " -o <filename> write to <filename>.hpp, <filename>.cpp"
98  << std::endl;
99 }
100 
101 std::string guessType(const std::string &literal);
103 
104 class XtString : public XString
105 {
106 /* XString class with a few extra methods for creating type
107  * strings that are useful in creating class names
108  */
109  public:
110  XtString() {};
111  XtString(const char* s): XString(s) {};
112  XtString(const XMLCh* p): XString(p) {};
113  XtString(const std::string& s): XString(s) {};
114  XtString(const XString& x): XString(x) {};
115  XtString(const XtString& t): XString((XString&)t) {};
116  ~XtString() {};
117 
118  XtString plural();
119  XtString simpleType();
120  XtString listType();
121  XtString linkType();
122 };
123 
124 class CodeBuilder
125 {
126 /* The methods in this class are used to write the c++ code
127  * that implements the hddm class library.
128  */
129  public:
130  std::ofstream hFile;
131  std::ofstream cFile;
132 
135 
136  void checkConsistency(DOMElement* el, DOMElement* elref);
137  void writeClassdef(DOMElement* el);
138  void writeClassimp(DOMElement* el);
139  void constructDocument(DOMElement* el);
140  void constructGroup(DOMElement* el);
141  void constructIOstreams(DOMElement* el);
142  void constructMethods(DOMElement* el);
143  void constructStreamers(DOMElement* el);
144  void writeStreamers(DOMElement* el);
145 
146  private:
147  std::vector<DOMElement*> tagList;
148  typedef std::vector<DOMNode*> parentList_t;
149  typedef std::map<const XtString,parentList_t> parentTable_t;
153  int element_in_list(XtString &name, parentList_t list);
154 };
155 
156 
157 int main(int argC, char* argV[])
158 {
159  try
160  {
161  XMLPlatformUtils::Initialize();
162  }
163  catch (const XMLException* toCatch)
164  {
165  XtString msg(toCatch->getMessage());
166  std::cerr
167  << "hddm-cpp: Error during initialization! :\n"
168  << msg << std::endl;
169  return 1;
170  }
171 
172  if (argC < 2)
173  {
174  usage();
175  return 1;
176  }
177  else if ((argC == 2) && (strcmp(argV[1], "-?") == 0))
178  {
179  usage();
180  return 2;
181  }
182 
183  XtString xmlFile;
184  XtString hFilename;
185  bool verifyOnly = false;
186  int argInd;
187  for (argInd = 1; argInd < argC; argInd++)
188  {
189  if (argV[argInd][0] != '-')
190  {
191  break;
192  }
193  if (strcmp(argV[argInd],"-v") == 0)
194  {
195  verifyOnly = true;
196  }
197  else if (strcmp(argV[argInd],"-o") == 0)
198  {
199  hFilename = XtString(argV[++argInd]);
200  }
201  else
202  {
203  std::cerr
204  << "Unknown option \'" << argV[argInd]
205  << "\', ignoring it\n" << std::endl;
206  }
207  }
208 
209  if (argInd != argC - 1)
210  {
211  usage();
212  return 1;
213  }
214  xmlFile = XtString(argV[argInd]);
215 
216 #if defined OLD_STYLE_XERCES_PARSER
217  DOMDocument* document = parseInputDocument(xmlFile.c_str(),false);
218 #else
219  DOMDocument* document = buildDOMDocument(xmlFile.c_str(),false);
220 #endif
221  if (document == 0)
222  {
223  std::cerr
224  << "hddm-cpp : Error parsing HDDM document, "
225  << "cannot continue" << std::endl;
226  return 1;
227  }
228 
229  DOMElement* rootEl = document->getDocumentElement();
230  XtString rootS(rootEl->getTagName());
231  if (rootS != "HDDM")
232  {
233  std::cerr
234  << "hddm-cpp error: root element of input document is "
235  << "\"" << rootS << "\", expected \"HDDM\""
236  << std::endl;
237  return 1;
238  }
239 
240  XtString classS(rootEl->getAttribute(X("class")));
241  classPrefix = classS;
242 
243  XtString hname;
244  if (verifyOnly)
245  {
246  hname = "/dev/null";
247  }
248  else if (hFilename.size())
249  {
250  hname = hFilename + ".hpp";
251  }
252  else
253  {
254  hname = "hddm_" + classPrefix + ".hpp";
255  }
256 
257  CodeBuilder builder;
258  builder.hFile.open(hname.c_str());
259  if (! builder.hFile.is_open())
260  {
261  std::cerr
262  << "hddm-cpp error: unable to open output file "
263  << hname << std::endl;
264  return 1;
265  }
266 
267  XtString cname;
268  if (verifyOnly)
269  {
270  cname = "/dev/null";
271  }
272  else if (hFilename.size())
273  {
274  cname = hFilename + ".cpp";
275  }
276  else
277  {
278  cname = "hddm_" + classPrefix + ".cpp";
279  }
280 
281  builder.cFile.open(cname.c_str());
282  if (! builder.cFile.is_open())
283  {
284  std::cerr
285  << "hddm-cpp error: unable to open output file "
286  << cname << std::endl;
287  return 1;
288  }
289 
290  builder.hFile <<
291  "/*\n"
292  " * hddm_" << classPrefix << ".hpp - DO NOT EDIT THIS FILE\n"
293  " *\n"
294  " * This file was generated automatically by hddm-cpp from the file\n"
295  << " * " << xmlFile << std::endl <<
296  "\n"
297  " * This header file defines the c++ classes that hold the data\n"
298  " * described in the data model (from " << xmlFile << "). \n"
299  " *\n"
300  " * The hddm data model tool set was written by\n"
301  " * Richard Jones, University of Connecticut.\n"
302  " *\n"
303  " * For more information see the following web site\n"
304  " *\n"
305  " * http://zeus.phys.uconn.edu/halld/datamodel/doc\n"
306  " *\n"
307  " */\n"
308  "\n"
309  "#ifndef SAW_" << classPrefix << "_HDDM\n"
310  "#define SAW_" << classPrefix << "_HDDM\n"
311  "\n"
312  "#include <list>\n"
313  "#include <deque>\n"
314  "#include <vector>\n"
315  "#include <string>\n"
316  "#include <atomic>\n"
317  "#include <sstream>\n"
318  "#include <stdexcept>\n"
319  "#include <streambuf>\n"
320  "#include <xstream/z.h>\n"
321  "#include <xstream/bz.h>\n"
322  "#include <xstream/xdr.h>\n"
323  "#include <xstream/digest.h>\n"
324  "#include <particleType.h>\n"
325  "#include <pthread.h>\n"
326  "\n"
327  "#define MY_SETUP thread_private_data *my_private = lookup_private_data();\n"
328  "#define MY(VAR) my_private->m_ ## VAR\n"
329  "\n"
330  "namespace hddm_" << classPrefix << " {\n"
331  "\n"
332  "const int k_default_status = 0x0;\n"
333  "const int k_bits_compression = 0xf0;\n"
334  "const int k_no_compression = 0x00;\n"
335  "const int k_z_compression = 0x10;\n"
336  "const int k_bz2_compression = 0x20;\n"
337  "const int k_bits_integrity = 0x0f;\n"
338  "const int k_no_integrity = 0x00;\n"
339  "const int k_crc32_integrity = 0x01;\n"
340  "const int k_bits_randomaccess = 0xf00;\n"
341  "const int k_can_reposition = 0x100;\n"
342  "\n"
343  "enum hddm_type {\n"
344  " k_hddm_unknown,\n"
345  " k_hddm_int,\n"
346  " k_hddm_long,\n"
347  " k_hddm_float,\n"
348  " k_hddm_double,\n"
349  " k_hddm_boolean,\n"
350  " k_hddm_string,\n"
351  " k_hddm_anyURI,\n"
352  " k_hddm_Particle_t\n"
353  "};\n"
354  "\n"
355  "class HDDM;\n"
356  "class istream;\n"
357  "class ostream;\n"
358  "\n"
359  "class streamable {\n"
360  " public:\n"
361  " virtual ~streamable() {}\n"
362  " virtual void streamer(istream &istr) {}\n"
363  " virtual void streamer(ostream &ostr) {}\n"
364  "};\n"
365  "\n"
366  "class streamposition {\n"
367  " public:\n"
368  " uint64_t block_start;\n"
369  " uint32_t block_offset;\n"
370  " uint32_t block_status;\n"
371  " streamposition();\n"
372  " streamposition(uint64_t start, uint32_t offset, uint32_t status);\n"
373  " bool operator==(const streamposition src) const {\n"
374  " return (block_start == src.block_start &&\n"
375  " block_offset == src.block_offset &&\n"
376  " block_status == src.block_status);\n"
377  " }\n"
378  " bool operator!=(const streamposition src) const {\n"
379  " return !(*this == src);\n"
380  " }\n"
381  " bool operator>(const streamposition src) const {\n"
382  " return (block_start > src.block_start ||\n"
383  " (block_start == src.block_start &&\n"
384  " block_offset > src.block_offset));\n"
385  " }\n"
386  " bool operator>=(const streamposition src) const {\n"
387  " return (*this > src || *this == src);\n"
388  " }\n"
389  " bool operator<(const streamposition src) const {\n"
390  " return !(*this >= src);\n"
391  " }\n"
392  " bool operator<=(const streamposition src) const {\n"
393  " return !(*this > src);\n"
394  " }\n"
395  "};\n"
396  "\n"
397  "class threads {\n"
398  " public:\n"
399  " static thread_local int ID;\n"
400  " static int getID() {\n"
401  " // protected access to the ID tls data member\n"
402  " if (ID == 0) {\n"
403  " if (ID >= max_threads) {\n"
404  " throw std::runtime_error(\"hddm_"
405  << classPrefix << "::threads::getID - \"\n"
406  " \"thread count exceeds max_threads\");\n"
407  " }\n"
408  " ID = ++next_unique_ID;\n"
409  " }\n"
410  " return ID;\n"
411  " }\n"
412  " static const int max_threads = 999;\n"
413  " protected:\n"
414  " static std::atomic<int> next_unique_ID;\n"
415  "};\n"
416  "\n"
417  "class istreambuffer : public std::streambuf {\n"
418  " public:\n"
419  " istreambuffer(char* buffer, std::streamsize bufferLength) {\n"
420  " setg(buffer, buffer, buffer + bufferLength);\n"
421  " }\n"
422  "\n"
423  " std::streampos tellg() {\n"
424  " return gptr() - eback();\n"
425  " }\n"
426  "\n"
427  " void seekg(std::streampos pos) {\n"
428  " reset();\n"
429  " gbump(pos);\n"
430  " }\n"
431  "\n"
432  " int size() {\n"
433  " return egptr() - gptr();\n"
434  " }\n"
435  "\n"
436  " void reset() {\n"
437  " char *gbegin = eback();\n"
438  " char *gend = egptr();\n"
439  " setg(gbegin, gbegin, gend);\n"
440  " }\n"
441  "\n"
442  " char *getbuf() {\n"
443  " return eback();\n"
444  " }\n"
445  "};\n"
446  "\n"
447  "class ostreambuffer : public std::streambuf {\n"
448  " public:\n"
449  " ostreambuffer(char* buffer, std::streamsize bufferLength) {\n"
450  " setp(buffer, buffer + bufferLength);\n"
451  " }\n"
452  "\n"
453  " std::streampos tellp() {\n"
454  " return pptr() - pbase();\n"
455  " }\n"
456  "\n"
457  " void seekp(std::streampos pos) {\n"
458  " reset();\n"
459  " pbump(pos);\n"
460  " }\n"
461  "\n"
462  " int size() {\n"
463  " return pptr() - pbase();\n"
464  " }\n"
465  "\n"
466  " void reset() {\n"
467  " char *pbegin = pbase();\n"
468  " char *pend = epptr();\n"
469  " setp(pbegin, pend);\n"
470  " }\n"
471  "\n"
472  " char *getbuf() {\n"
473  " return pbase();\n"
474  " }\n"
475  "};\n"
476  "\n"
477  "class ostream {\n"
478  " public:\n"
479  " ostream(std::ostream &src);\n"
480  " ~ostream();\n"
481  " ostream &operator<<(HDDM &record);\n"
482  " int getCompression() const;\n"
483  " void setCompression(int flags);\n"
484  " int getIntegrityChecks() const;\n"
485  " void setIntegrityChecks(int flags);\n"
486  " streamposition getPosition();\n"
487  " int getBytesWritten() const;\n"
488  " int getRecordsWritten() const;\n"
489  " //protected:\n"
490  " xstream::xdr::ostream *getXDRostream() {\n"
491  " return my_thread_private[threads::ID]->m_xstr;\n"
492  " }\n"
493  " ostream &operator<<(streamable &object);\n"
494  " private:\n"
495  " void configure_streambufs();\n"
496  " void update_streambufs();\n"
497  " void lock_streambufs();\n"
498  " void unlock_streambufs();\n"
499  " std::ostream &m_ostr;\n"
500  " std::atomic<int> m_status_bits;\n"
501  " pthread_mutex_t m_streambuf_mutex;\n"
502  "\n"
503  " typedef struct {\n"
504  " xstream::xdr::ostream *m_xstr;\n"
505  " std::ostream *m_ostr;\n"
506  " ostreambuffer *m_sbuf;\n"
507  " std::streambuf *m_xcmp;\n"
508  " char *m_event_buffer;\n"
509  " int m_event_buffer_size;\n"
510  " std::streampos m_last_start;\n"
511  " std::streamoff m_last_offset;\n"
512  " int m_status_bits;\n"
513  " int m_mutex_lock;\n"
514  " int m_bytes_written;\n"
515  " int m_records_written;\n"
516  " } thread_private_data;\n"
517  "\n"
518  " thread_private_data *my_thread_private[threads::max_threads];\n"
519  " thread_private_data *lookup_private_data();\n"
520  " void init_private_data();\n"
521  "};\n"
522  "\n"
523  "class codon {\n"
524  " public:\n"
525  " codon(): m_order(0) {}\n"
526  " int m_order;\n"
527  " std::string m_tagname;\n"
528  " std::vector<codon> m_sequence;\n"
529  " std::deque<streamable*> m_target;\n"
530  "};\n"
531  "\n"
532  "typedef std::vector<codon> chromosome;\n"
533  "\n"
534  "class istream {\n"
535  " public:\n"
536  " istream(std::istream &src);\n"
537  " ~istream();\n"
538  " istream &operator>>(HDDM &record);\n"
539  " void skip(int count);\n"
540  " int getCompression() const;\n"
541  " int getIntegrityChecks() const;\n"
542  " streamposition getPosition();\n"
543  " void setPosition(const streamposition &pos);\n"
544  " int getBytesRead() const;\n"
545  " int getRecordsRead() const;\n"
546  " bool eof();\n"
547  " bool operator!();\n"
548  " operator void*();\n"
549  " //protected:\n"
550  " void reset_sequencer();\n"
551  " void sequencer(streamable &object);\n"
552  " istream &operator>>(streamable &object);\n"
553  " xstream::xdr::istream *getXDRistream() {\n"
554  " return my_thread_private[threads::ID]->m_xstr;\n"
555  " }\n"
556  "\n"
557  " private:\n"
558  " std::string m_documentString;\n"
559  " chromosome synthesize(const std::string &src, int p_src,\n"
560  " const std::string &ref, int p_ref);\n"
561  " int getTag(const std::string &src, int p_src, std::string &tag, int &level);\n"
562  " int getEndTag(const std::string &src, int p_src, const std::string &tag);\n"
563  " void collide(const std::string &itag, const std::string &rtag);\n"
564  " void configure_streambufs();\n"
565  " void update_streambufs();\n"
566  " void lock_streambufs();\n"
567  " void unlock_streambufs();\n"
568  " std::istream &m_istr;\n"
569  " std::atomic<int> m_status_bits;\n"
570  " pthread_mutex_t m_streambuf_mutex;\n"
571  " int m_leftovers[100];\n"
572  "\n"
573  " typedef struct {\n"
574  " codon m_genome;\n"
575  " codon *m_codon;\n"
576  " int m_sequencing;\n"
577  " xstream::xdr::istream *m_xstr;\n"
578  " std::istream *m_istr;\n"
579  " istreambuffer *m_sbuf;\n"
580  " std::streambuf *m_xcmp;\n"
581  " int m_events_to_skip;\n"
582  " char *m_event_buffer;\n"
583  " int m_event_buffer_size;\n"
584  " int m_event_size;\n"
585  " std::streampos m_last_start;\n"
586  " std::streamoff m_last_offset;\n"
587  " std::streamoff m_next_start;\n"
588  " int m_status_bits;\n"
589  " int m_mutex_lock;\n"
590  " int m_bytes_read;\n"
591  " int m_records_read;\n"
592  " bool m_hit_eof;\n"
593  " } thread_private_data;\n"
594  "\n"
595  " thread_private_data *my_thread_private[threads::max_threads];\n"
596  " thread_private_data *lookup_private_data();\n"
597  " void init_private_data();\n"
598  "};\n"
599  "\n"
600  "template <class T> class HDDM_ElementList;\n"
601  "\n"
602  "class HDDM_Element: public streamable {\n"
603  " public:\n"
604  " ~HDDM_Element() {}\n"
605  " virtual const void *getAttribute(const std::string &name,\n"
606  " hddm_type *atype=0) const {\n"
607  " return 0;\n"
608  " }\n"
609  " virtual std::string toString(int indent=0) {\n"
610  " return \"bad apple\";\n"
611  " }\n"
612  " virtual std::string toXML(int indent=0) {\n"
613  " return \"<!--bad apple-->\";\n"
614  " }\n"
615  " friend class HDDM_ElementList<HDDM_Element>;\n"
616  " protected:\n"
617  " HDDM_Element() : m_parent(0), m_host(0) {}\n"
618  " HDDM_Element(HDDM_Element *parent)\n"
619  " : m_parent(parent),\n"
620  " m_host(parent->m_host)\n"
621  " {}\n"
622  " HDDM_Element(HDDM_Element &src)\n"
623  " : m_parent(src.m_parent),\n"
624  " m_host(src.m_host)\n"
625  " {}\n"
626  " HDDM_Element *m_parent;\n"
627  " HDDM *m_host;\n"
628  "};\n"
629  "\n"
630  "template <class T>\n"
631  "class HDDM_ElementList: public streamable {\n"
632  " public:\n"
633  " HDDM_ElementList(typename std::list<T*> *plist,\n"
634  " typename std::list<T*>::iterator begin,\n"
635  " typename std::list<T*>::iterator end,\n"
636  " HDDM_Element *parent=0)\n"
637  " : m_host_plist(plist),\n"
638  " m_first_iter(begin),\n"
639  " m_last_iter(end),\n"
640  " m_parent(parent)\n"
641  " {\n"
642  " for (m_size = 0; begin != end; ++m_size, ++begin) {}\n"
643  " if (m_size) {\n"
644  " --m_last_iter;\n"
645  " }\n"
646  " }\n"
647  "\n"
648  " HDDM_ElementList(const HDDM_ElementList<T> &src)\n"
649  " : m_host_plist(src.m_host_plist),\n"
650  " m_first_iter(src.m_first_iter),\n"
651  " m_last_iter(src.m_last_iter),\n"
652  " m_parent(0),\n"
653  " m_size(src.m_size)\n"
654  " {}\n"
655  "\n"
656  " bool empty() const { return (m_size == 0); }\n"
657  " int size() const { return m_size; }\n"
658  " T &front() const { return *m_first_iter; }\n"
659  " T &back() const { return *m_last_iter; }\n"
660  " T &operator()() { return *m_first_iter; }\n"
661  " T &operator()(int index) {\n"
662  " if (index == 0) {\n"
663  " return *m_first_iter;\n"
664  " }\n"
665  " else if (index == -1) {\n"
666  " return *m_last_iter;\n"
667  " }\n"
668  " else if (index > 0) {\n"
669  " return *(m_first_iter + index);\n"
670  " }\n"
671  " else {\n"
672  " return *(m_last_iter + (++index));\n"
673  " }\n"
674  " }\n"
675  "\n"
676  " class iterator: public std::list<T*>::iterator {\n"
677  " public:\n"
678  " iterator() {}\n"
679  " iterator(typename std::list<T*>::iterator src)\n"
680  " : std::list<T*>::iterator(src) {}\n"
681  "\n"
682  " T *operator->() const { \n"
683  " return *(typename std::list<T*>::iterator)(*this);\n"
684  " }\n"
685  "\n"
686  " T &operator*() const {\n"
687  " return **(typename std::list<T*>::iterator)(*this);\n"
688  " }\n"
689  "\n"
690  " iterator operator+=(int offset) {\n"
691  " if (offset > 0) {\n"
692  " for (int i=0; i<offset; ++i, ++(*this)) {}\n"
693  " }\n"
694  " else if (offset < 0) {\n"
695  " for (int i=0; i>offset; --i, --(*this)) {}\n"
696  " }\n"
697  " return *this;\n"
698  " }\n"
699  "\n"
700  " iterator operator-=(int offset) {\n"
701  " if (offset > 0) {\n"
702  " for (int i=0; i<offset; ++i, --(*this)) {}\n"
703  " }\n"
704  " else if (offset < 0) {\n"
705  " for (int i=0; i>offset; --i, ++(*this)) {}\n"
706  " }\n"
707  " return *this;\n"
708  " }\n"
709  "\n"
710  " iterator operator+(int offset) const {\n"
711  " iterator iter(*this);\n"
712  " return iter += offset;\n"
713  " }\n"
714  "\n"
715  " iterator operator-(int offset) const {\n"
716  " iterator iter(*this);\n"
717  " return iter -= offset;\n"
718  " }\n"
719  "\n"
720  " int operator-(iterator iter) const {\n"
721  " if (*this == iter) {\n"
722  " return 0;\n"
723  " }\n"
724  " iterator iter2(iter);\n"
725  " for (int n=1; n < m_size; ++n) {\n"
726  " if (++iter == *this) {\n"
727  " return n;\n"
728  " }\n"
729  " else if (--iter2 == *this) {\n"
730  " return -n;\n"
731  " }\n"
732  " }\n"
733  " return m_size;\n"
734  " }\n"
735  " };\n"
736  "\n"
737  " class const_iterator: public std::list<T*>::const_iterator {\n"
738  " public:\n"
739  " const_iterator() {}\n"
740  " const_iterator(const typename std::list<T*>::const_iterator src)\n"
741  " : std::list<T*>::const_iterator(src) {}\n"
742  "\n"
743  " const_iterator(const typename std::list<T*>::iterator src)\n"
744  " : std::list<T*>::const_iterator(src) {}\n"
745  "\n"
746  " const T *operator->() const { \n"
747  " return *(typename std::list<T*>::const_iterator)(*this);\n"
748  " }\n"
749  "\n"
750  " const T &operator*() const { \n"
751  " return **(typename std::list<T*>::const_iterator)(*this);\n"
752  " }\n"
753  "\n"
754  " const const_iterator operator+=(int offset) {\n"
755  " if (offset > 0) {\n"
756  " for (int i=0; i<offset; ++i, ++(*this)) {}\n"
757  " }\n"
758  " else if (offset < 0) {\n"
759  " for (int i=0; i>offset; --i, --(*this)) {}\n"
760  " }\n"
761  " return *this;\n"
762  " }\n"
763  "\n"
764  " const const_iterator operator-=(int offset) {\n"
765  " if (offset > 0) {\n"
766  " for (int i=0; i<offset; ++i, --(*this)) {}\n"
767  " }\n"
768  " else if (offset > 0) {\n"
769  " for (int i=0; i>offset; --i, ++(*this)) {}\n"
770  " }\n"
771  " return *this;\n"
772  " }\n"
773  "\n"
774  " const const_iterator operator+(int offset) const {\n"
775  " const_iterator iter(*this);\n"
776  " return iter += offset;\n"
777  " }\n"
778  "\n"
779  " const const_iterator operator-(int offset) const {\n"
780  " const_iterator iter(*this);\n"
781  " return iter -= offset;\n"
782  " }\n"
783  "\n"
784  " int operator-(const_iterator iter) const {\n"
785  " if (*this == iter) {\n"
786  " return 0;\n"
787  " }\n"
788  " const_iterator iter2(iter);\n"
789  " for (int n=1; n < m_size; ++n) {\n"
790  " if (++iter == *this) {\n"
791  " return n;\n"
792  " }\n"
793  " else if (--iter2 == *this) {\n"
794  " return -n;\n"
795  " }\n"
796  " }\n"
797  " return m_size;\n"
798  " }\n"
799  " };\n"
800  "\n"
801  " iterator begin() const { return m_first_iter; }\n"
802  " iterator end() const { return (m_size)? m_last_iter + 1 : m_last_iter; }\n"
803  " void clear() { del(); }\n"
804  "\n"
805  " HDDM_ElementList add(int count=1, int start=-1) {\n"
806  " if (m_parent == 0) {\n"
807  " throw std::runtime_error(\"HDDM_ElementList error - \"\n"
808  " \"attempt to add to immutable list\");\n"
809  " }\n"
810  " iterator it = insert(start, count);\n"
811  " typename std::list<T*>::iterator iter(it);\n"
812  " for (int n=0; n<count; ++n, ++iter) {\n"
813  " *iter = new T(m_parent);\n"
814  " }\n"
815  " return HDDM_ElementList(m_host_plist, it, it+count, m_parent);\n"
816  " }\n"
817  "\n"
818  " void del(int count=-1, int start=0) {\n"
819  " if (m_parent == 0) {\n"
820  " throw std::runtime_error(\"HDDM_ElementList error - \"\n"
821  " \"attempt to delete from immutable list\");\n"
822  " }\n"
823  " iterator iter_begin(begin());\n"
824  " iterator iter_end(end());\n"
825  " if (start < 0) {\n"
826  " if (count >= 0) {\n"
827  " iter_begin = iter_end - count;\n"
828  " }\n"
829  " }\n"
830  " else {\n"
831  " iter_begin += start;\n"
832  " if (count >= 0) {\n"
833  " iter_end = iter_begin + count;\n"
834  " }\n"
835  " }\n"
836  " typename std::list<T*>::iterator iter;\n"
837  " for (iter = iter_begin; iter != iter_end; ++iter) {\n"
838  " delete *iter;\n"
839  " }\n"
840  " erase(start, count);\n"
841  " }\n"
842  "\n"
843  " HDDM_ElementList slice(int first=0, int last=-1) {\n"
844  " int n1 = (first < 0)? first + m_size : first;\n"
845  " int n2 = (last < 0)? last + m_size + 1 : last + 1;\n"
846  " int count = n2 - n1;\n"
847  " iterator iter_begin;\n"
848  " if (first > 0)\n"
849  " iter_begin = begin() + first;\n"
850  " else if (first < 0)\n"
851  " iter_begin = end() + first;\n"
852  " iterator iter_end(iter_begin + count);\n"
853  " return HDDM_ElementList(m_host_plist, iter_begin, iter_end);\n"
854  " }\n"
855  "\n"
856  " void streamer(istream &istr) {\n"
857  " clear();\n"
858  " int size;\n"
859  " *istr.getXDRistream() >> size;\n"
860  " if (size) {\n"
861  " iterator iter = add(size).begin();\n"
862  " for (int n=0; n < size; ++n, ++iter) {\n"
863  " istr.sequencer(*iter);\n"
864  " }\n"
865  " }\n"
866  " istr.reset_sequencer();\n"
867  " }\n"
868  "\n"
869  " void streamer(ostream &ostr) {\n"
870  " if (m_size) {\n"
871  " *ostr.getXDRostream() << m_size;\n"
872  " for (iterator iter = begin(); iter != end(); ++iter) {\n"
873  " iter->streamer(ostr);\n"
874  " }\n"
875  " }\n"
876  " }\n"
877  " std::string toString(int indent=0) {\n"
878  " std::string result;\n"
879  " if (m_size) {\n"
880  " for (iterator iter = begin(); iter != end(); ++iter) {\n"
881  " result += iter->toString(indent);\n"
882  " }\n"
883  " }\n"
884  " return result;\n"
885  " }\n"
886  " std::string toXML(int indent=0) {\n"
887  " std::string result;\n"
888  " if (m_size) {\n"
889  " for (iterator iter = begin(); iter != end(); ++iter) {\n"
890  " result += iter->toXML(indent);\n"
891  " }\n"
892  " }\n"
893  " return result;\n"
894  " }\n"
895  "\n"
896  " private:\n"
897  " HDDM_ElementList() {}\n"
898  "\n"
899  " iterator insert(int start, int count) {\n"
900  " if (m_size == 0) {\n"
901  " if (count > 0) {\n"
902  " if (m_first_iter == m_host_plist->begin()) {\n"
903  " m_host_plist->insert(m_first_iter,count,(T*)0);\n"
904  " m_first_iter = m_host_plist->begin();\n"
905  " }\n"
906  " else {\n"
907  " m_host_plist->insert(m_first_iter--,count,(T*)0);\n"
908  " ++m_first_iter;\n"
909  " }\n"
910  " --m_last_iter;\n"
911  " m_size = count;\n"
912  " }\n"
913  " return m_first_iter;\n"
914  " }\n"
915  " else if (start == 0) {\n"
916  " if (count > 0) {\n"
917  " if (m_first_iter == m_host_plist->begin()) {\n"
918  " m_host_plist->insert(m_first_iter,count,(T*)0);\n"
919  " m_first_iter = m_host_plist->begin();\n"
920  " }\n"
921  " else {\n"
922  " m_host_plist->insert(m_first_iter--,count,(T*)0);\n"
923  " ++m_first_iter;\n"
924  " }\n"
925  " m_size += count;\n"
926  " }\n"
927  " return m_first_iter;\n"
928  " }\n"
929  " else if (start == -1) {\n"
930  " if (count > 0) {\n"
931  " iterator pos(m_last_iter);\n"
932  " m_host_plist->insert(++m_last_iter,count,(T*)0);\n"
933  " --m_last_iter;\n"
934  " m_size += count;\n"
935  " return ++pos;\n"
936  " }\n"
937  " return m_last_iter;\n"
938  " }\n"
939  " else if (start > 0) {\n"
940  " if (count > 0) {\n"
941  " iterator pos(m_first_iter);\n"
942  " iterator pos2(pos += start-1);\n"
943  " m_host_plist->insert(++pos,count,(T*)0);\n"
944  " if (m_last_iter == pos2) {\n"
945  " m_last_iter = --pos;\n"
946  " }\n"
947  " m_size += count;\n"
948  " return ++pos2;\n"
949  " }\n"
950  " return m_first_iter + start;\n"
951  " }\n"
952  " else {\n"
953  " if (count > 0) {\n"
954  " iterator pos(m_last_iter);\n"
955  " iterator pos2(pos += start+1);\n"
956  " m_host_plist->insert(++pos,count,(T*)0);\n"
957  " m_size += count;\n"
958  " return ++pos2;\n"
959  " }\n"
960  " return m_last_iter + (start+1);\n"
961  " }\n"
962  " }\n"
963  "\n"
964  " iterator erase(int start, int count) {\n"
965  " if (m_size == 0) {\n"
966  " return m_first_iter+start;\n"
967  " }\n"
968  " else if ((count >= m_size || count == -1) &&\n"
969  " (start == 0 || start <= -m_size)) {\n"
970  " m_host_plist->erase(m_first_iter,++m_last_iter);\n"
971  " m_first_iter = m_last_iter;\n"
972  " m_size = 0;\n"
973  " return m_first_iter;\n"
974  " }\n"
975  " else if (start > 0 && start <= m_size) {\n"
976  " ++m_last_iter;\n"
977  " count = (count < 0)? m_size-start : count;\n"
978  " iterator pos(m_first_iter + start);\n"
979  " iterator pos2(pos + count);\n"
980  " m_host_plist->erase(pos,pos2);\n"
981  " m_size -= count;\n"
982  " --m_last_iter;\n"
983  " return pos2;\n"
984  " }\n"
985  " else if (start < 0 && start >= -m_size) {\n"
986  " ++m_last_iter;\n"
987  " count = (count < 0)? -start : count;\n"
988  " iterator pos(m_last_iter + (start+1));\n"
989  " iterator pos2(pos + count);\n"
990  " m_host_plist->erase(pos,pos2);\n"
991  " if (m_size -= count) {\n"
992  " --m_last_iter;\n"
993  " }\n"
994  " else {\n"
995  " m_first_iter = m_last_iter;\n"
996  " }\n"
997  " return pos2;\n"
998  " }\n"
999  " return m_last_iter+1;\n"
1000  " }\n"
1001  "\n"
1002  " protected:\n"
1003  " std::list<T*> *m_host_plist;\n"
1004  " iterator m_first_iter;\n"
1005  " iterator m_last_iter;\n"
1006  " HDDM_Element *m_parent;\n"
1007  " int m_size;\n"
1008  "};\n"
1009  "\n"
1010  "template <class T>\n"
1011  "class HDDM_ElementLink: public HDDM_ElementList<T> {\n"
1012  " public:\n"
1013  " HDDM_ElementLink(typename std::list<T*> *plist,\n"
1014  " typename std::list<T*>::iterator begin,\n"
1015  " typename std::list<T*>::iterator end,\n"
1016  " HDDM_Element *parent)\n"
1017  " : HDDM_ElementList<T>(plist,begin,end,parent)\n"
1018  " {}\n"
1019  " HDDM_ElementLink(const HDDM_ElementList<T> &src)\n"
1020  " : HDDM_ElementList<T>(src)\n"
1021  " {}\n"
1022  "\n"
1023  " void streamer(istream &istr) {\n"
1024  " HDDM_ElementList<T>::clear();\n"
1025  " HDDM_ElementList<T>::add().begin()->streamer(istr);\n"
1026  " }\n"
1027  "\n"
1028  " void streamer(ostream &ostr) {\n"
1029  " if (HDDM_ElementList<T>::m_size) {\n"
1030  " HDDM_ElementList<T>::begin()->streamer(ostr);\n"
1031  " }\n"
1032  " }\n"
1033  "\n"
1034  " protected:\n"
1035  " HDDM_ElementLink() {}\n"
1036  "};\n"
1037  "\n"
1038  ;
1039 
1040  builder.cFile <<
1041  "/*\n"
1042  " * hddm_" << classPrefix << ".cpp - DO NOT EDIT THIS FILE\n"
1043  " *\n"
1044  " * This file was generated automatically by hddm-cpp from the file\n"
1045  << " * " << xmlFile << std::endl <<
1046  "\n"
1047  " * This c++ source implements the methods for the classes \n"
1048  " * described in the data model (from " << xmlFile << "). \n"
1049  " *\n"
1050  " * The hddm data model tool set was written by\n"
1051  " * Richard Jones, University of Connecticut.\n"
1052  " *\n"
1053  " * For more information see the following web site\n"
1054  " *\n"
1055  " * http://zeus.phys.uconn.edu/halld/datamodel/doc\n"
1056  " */\n"
1057  "\n"
1058  "#include <sstream>\n"
1059  "#include \"hddm_" << classPrefix << ".hpp\"\n"
1060  "\n"
1061  "#ifndef _FILE_OFFSET_BITS\n"
1062  "# define _FILE_OFFSET_BITS 64\n"
1063  "#endif\n"
1064  "\n"
1065  "using namespace hddm_" << classPrefix << ";\n"
1066  "\n"
1067  "std::atomic<int> threads::next_unique_ID(0);\n"
1068  "thread_local int threads::ID(0);\n"
1069  "\n"
1070  "static int tags_match(const std::string &a, const std::string &b)\n"
1071  "{\n"
1072  " if (a == b) {\n"
1073  " return true;\n"
1074  " }\n"
1075  " else {\n"
1076  " int len = a.length();\n"
1077  " int ia=0;\n"
1078  " int ib=0;\n"
1079  " for (; a[ia] == b[ib]; ++ia, ++ib, --len) {}\n"
1080  " for (; a[ia] == ' '; ++ia, --len) {}\n"
1081  " for (; a[ia] == '/'; ++ia, --len) {}\n"
1082  " for (; b[ib] == ' '; ++ib) {}\n"
1083  " for (; b[ib] == '/'; ++ib) {}\n"
1084  " return (a.substr(ia) == b.substr(ib));\n"
1085  " }\n"
1086  "}\n"
1087  "\n"
1088  ;
1089 
1090  builder.constructGroup(rootEl);
1091  builder.constructIOstreams(rootEl);
1092  builder.constructMethods(rootEl);
1093  builder.constructStreamers(rootEl);
1094 
1095  builder.hFile <<
1096  "inline std::string HDDM::DocumentString() {\n"
1097  " return std::string(\n"
1098  ;
1099  builder.constructDocument(rootEl);
1100  builder.hFile <<
1101  " );\n"
1102  "}\n"
1103  "\n"
1104  "}\n"
1105  "#endif /* SAW_" << classPrefix << "_HDDM */\n"
1106  ;
1107 
1108  builder.cFile <<
1109  "\n"
1110  "streamposition::streamposition()\n"
1111  " : block_start(), block_offset(), block_status() {}\n"
1112  "\n"
1113  "streamposition::streamposition(uint64_t start, uint32_t offset, uint32_t status)\n"
1114  " : block_start(start), block_offset(offset), block_status(status) {}\n"
1115  "\n"
1116  "istream::istream(std::istream &src)\n"
1117  " : m_istr(src),\n"
1118  " m_status_bits(0)\n"
1119  "{\n"
1120  " char hdr[10];\n"
1121  " src.getline(hdr,7);\n"
1122  " m_documentString = hdr;\n"
1123  " if (m_documentString != \"<HDDM \") {\n"
1124  " throw std::runtime_error(\"hddm_" + classPrefix +
1125  "::istream::istream error - invalid hddm header\");\n"
1126  " }\n"
1127  " src.clear();\n"
1128  " std::string line;\n"
1129  " while (std::getline(src,line).good()) {\n"
1130  " m_documentString += line + \"\\n\";\n"
1131  " if (line == \"</HDDM>\") {\n"
1132  " break;\n"
1133  " }\n"
1134  " }\n"
1135  " if (src.bad()) {\n"
1136  " throw std::runtime_error(\"hddm_" + classPrefix +
1137  "::istream::istream error - invalid hddm header\");\n"
1138  " }\n"
1139  " pthread_mutex_init(&m_streambuf_mutex,0);\n"
1140  " for (int i=0; i<threads::max_threads; ++i) {\n"
1141  " my_thread_private[i] = 0;\n"
1142  " }\n"
1143  " m_leftovers[0] = 0;\n"
1144  " init_private_data();\n"
1145  "}\n"
1146  "\n"
1147  "istream::~istream() {\n"
1148  " pthread_mutex_destroy(&m_streambuf_mutex);\n"
1149  " for (int i=0; i<threads::max_threads; ++i) {\n"
1150  " thread_private_data *my_private = my_thread_private[i];\n"
1151  " if (my_private != 0) {\n"
1152  " if (MY(istr))\n"
1153  " delete MY(istr);\n"
1154  " if (MY(xcmp))\n"
1155  " delete MY(xcmp);\n"
1156  " if (MY(xstr))\n"
1157  " delete MY(xstr);\n"
1158  " if (MY(sbuf))\n"
1159  " delete MY(sbuf);\n"
1160  " delete [] MY(event_buffer);\n"
1161  " delete my_private;\n"
1162  " }\n"
1163  " }\n"
1164  "}\n"
1165  "\n"
1166  "void istream::init_private_data() {\n"
1167  " int threadID = threads::getID();\n"
1168  " if (my_thread_private[threadID] == 0) {\n"
1169  " my_thread_private[threadID] = new thread_private_data;\n"
1170  " }\n"
1171  " MY_SETUP\n"
1172  " MY(genome).m_tagname = \"HDDM\";\n"
1173  " MY(genome).m_sequence = synthesize(m_documentString,0,HDDM::DocumentString(),0);\n"
1174  " MY(event_buffer) = new char[MY(event_buffer_size) = 100000];\n"
1175  " MY(sbuf) = new istreambuffer(MY(event_buffer),MY(event_buffer_size));\n"
1176  " MY(xstr) = new xstream::xdr::istream(MY(sbuf));\n"
1177  " MY(istr) = new std::istream(m_istr.rdbuf());\n"
1178  " MY(xcmp) = 0;\n"
1179  " MY(event_size) = 0;\n"
1180  " MY(last_start) = 0;\n"
1181  " MY(last_offset) = 0;\n"
1182  " MY(next_start) = 0;\n"
1183  " MY(events_to_skip) = 0;\n"
1184  " MY(status_bits) = 0;\n"
1185  " MY(mutex_lock) = 0;\n"
1186  " MY(bytes_read) = 0;\n"
1187  " MY(records_read) = 0;\n"
1188  " MY(sequencing) = 0;\n"
1189  " MY(hit_eof) = 0;\n"
1190  "}\n"
1191  "\n"
1192  "streamposition istream::getPosition() {\n"
1193  " MY_SETUP\n"
1194  " streamposition pos;\n"
1195  " pos.block_start = MY(last_start);\n"
1196  " pos.block_offset = MY(last_offset);\n"
1197  " pos.block_status = MY(status_bits);\n"
1198  " return pos;\n"
1199  "}\n"
1200  "\n"
1201  "void istream::setPosition(const streamposition &pos) {\n"
1202  " MY_SETUP\n"
1203  " m_status_bits = pos.block_status;\n"
1204  " lock_streambufs();\n"
1205  " update_streambufs();\n"
1206  " unlock_streambufs();\n"
1207  " if (MY(status_bits) & (k_bz2_compression | k_z_compression)) {\n"
1208  " if (((int)m_status_bits & k_bits_compression) != 0 &&\n"
1209  " ((int)m_status_bits & k_can_reposition) == 0)\n"
1210  " {\n"
1211  " throw std::runtime_error(\"hddm_"
1212  << classPrefix << "::istream::setPosition error - \"\n"
1213  " \"old-format hddm input file does not support repositioning.\");\n"
1214  " }\n"
1215  " else if (MY(xcmp) == 0) {\n"
1216  " throw std::runtime_error(\"hddm_"
1217  << classPrefix << "::istream::setPosition error - \"\n"
1218  " \"compressed stream encountered but no decompressor configured.\");\n"
1219  " }\n"
1220  " if (MY(status_bits) & k_z_compression) {\n"
1221  " ((xstream::z::istreambuf*)MY(xcmp))->\n"
1222  " set_new_position(pos.block_start, pos.block_offset);\n"
1223  " }\n"
1224  " else if (MY(status_bits) & k_bz2_compression) {\n"
1225  " ((xstream::bz::istreambuf*)MY(xcmp))->\n"
1226  " set_new_position(pos.block_start, pos.block_offset);\n"
1227  " }\n"
1228  " }\n"
1229  " else {\n"
1230  " MY(next_start) = pos.block_start;\n"
1231  " }\n"
1232  "}\n"
1233  "\n"
1234  "void istream::update_streambufs() {\n"
1235  " MY_SETUP\n"
1236  " if ((int)m_status_bits != MY(status_bits)) {\n"
1237  " configure_streambufs();\n"
1238  " }\n"
1239  "}\n"
1240  "\n"
1241  "void istream::configure_streambufs() {\n"
1242  " MY_SETUP\n"
1243  " int oldcmp = MY(status_bits) & k_bits_compression;\n"
1244  " int newcmp = (int)m_status_bits & k_bits_compression;\n"
1245  " if (oldcmp != newcmp) {\n"
1246  " if (oldcmp != k_no_compression) {\n"
1247  " MY(istr)->rdbuf(m_istr.rdbuf());\n"
1248  " delete MY(xcmp);\n"
1249  " MY(xcmp) = 0;\n"
1250  " }\n"
1251  " if (newcmp == k_z_compression) {\n"
1252  " //std::cerr << \"input switched on z compression\" << std::endl;\n"
1253  " MY(xcmp) = new xstream::z::istreambuf(m_istr.rdbuf(), m_leftovers,\n"
1254  " sizeof(m_leftovers));\n"
1255  " MY(istr)->rdbuf(MY(xcmp));\n"
1256  " }\n"
1257  " else if (newcmp == k_bz2_compression) {\n"
1258  " //std::cerr << \"input switched on bz2 compression\" << std::endl;\n"
1259  " MY(xcmp) = new xstream::bz::istreambuf(m_istr.rdbuf(), m_leftovers,\n"
1260  " sizeof(m_leftovers));\n"
1261  " MY(istr)->rdbuf(MY(xcmp));\n"
1262  " }\n"
1263  " else if (newcmp != k_no_compression) {\n"
1264  " throw std::runtime_error(\"hddm_"
1265  << classPrefix << "::istream::configure_streambufs error - \"\n"
1266  " \"unrecognized compression flag requested.\");\n"
1267  " }\n"
1268  " }\n"
1269  " MY(status_bits) = m_status_bits;\n"
1270  "}\n"
1271  "\n"
1272  "void istream::lock_streambufs() {\n"
1273  " MY_SETUP\n"
1274  " if (MY(mutex_lock) != 0) {\n"
1275  " unlock_streambufs();\n"
1276  " throw std::runtime_error(\"hddm_"
1277  << classPrefix << "::istream::lock_streambufs error - \"\n"
1278  " \"mutex lock requested when lock already held.\");\n"
1279  " }\n"
1280  " if ((MY(status_bits) & k_bits_compression) == k_no_compression) {\n"
1281  " pthread_mutex_lock(&m_streambuf_mutex);\n"
1282  " MY(mutex_lock) = 1;\n"
1283  " }\n"
1284  " else if ((MY(status_bits) & k_bits_compression) == k_z_compression) {\n"
1285  " ((xstream::z::istreambuf*)MY(xcmp))->set_streambuf_mutex(&m_streambuf_mutex);\n"
1286  " MY(mutex_lock) = 2;\n"
1287  " }\n"
1288  " else if ((MY(status_bits) & k_bits_compression) == k_bz2_compression) {\n"
1289  " ((xstream::bz::istreambuf*)MY(xcmp))->set_streambuf_mutex(&m_streambuf_mutex);\n"
1290  " MY(mutex_lock) = 3;\n"
1291  " }\n"
1292  " else {\n"
1293  " MY(mutex_lock) = -1;\n"
1294  " }\n"
1295  "}\n"
1296  "\n"
1297  "void istream::unlock_streambufs() {\n"
1298  " MY_SETUP\n"
1299  " if (MY(mutex_lock) == 0) {\n"
1300  " throw std::runtime_error(\"hddm_"
1301  << classPrefix << "::istream::unlock_streambufs error - \"\n"
1302  " \"mutex unlock requested when lock not held.\");\n"
1303  " }\n"
1304  " else if (MY(mutex_lock) == 1) {\n"
1305  " pthread_mutex_unlock(&m_streambuf_mutex);\n"
1306  " }\n"
1307  " else if (MY(mutex_lock) == 2) {\n"
1308  " ((xstream::z::istreambuf*)MY(xcmp))->set_streambuf_mutex(0);\n"
1309  " }\n"
1310  " else if (MY(mutex_lock) == 3) {\n"
1311  " ((xstream::bz::istreambuf*)MY(xcmp))->set_streambuf_mutex(0);\n"
1312  " }\n"
1313  " MY(mutex_lock) = 0;\n"
1314  "}\n"
1315  "\n"
1316  "istream &istream::operator>>(HDDM &record) {\n"
1317  " MY_SETUP\n"
1318  " lock_streambufs();\n"
1319  " MY(event_size) = 0;\n"
1320  " while (MY(event_size) == 0) {\n"
1321  " update_streambufs();\n"
1322  " if (MY(status_bits) & (k_bz2_compression | k_z_compression)) {\n"
1323  " if (MY(status_bits) & k_can_reposition) {\n"
1324  " MY(istr)->clear();\n"
1325  " MY(istr)->read(MY(event_buffer),4);\n"
1326  " MY(bytes_read) += MY(istr)->gcount();\n"
1327  " if (!MY(istr)->good()) {\n"
1328  " unlock_streambufs();\n"
1329  " MY(hit_eof) = 1;\n"
1330  " return *this;\n"
1331  " }\n"
1332  " if (MY(status_bits) & k_bz2_compression) {\n"
1333  " MY(last_start) = dynamic_cast<xstream::bz::istreambuf*>\n"
1334  " (MY(xcmp))->get_block_start();\n"
1335  " MY(last_offset) = dynamic_cast<xstream::bz::istreambuf*>\n"
1336  " (MY(xcmp))->get_block_offset();\n"
1337  " }\n"
1338  " else {\n"
1339  " MY(last_start) = dynamic_cast<xstream::z::istreambuf*>\n"
1340  " (MY(xcmp))->get_block_start();\n"
1341  " MY(last_offset) = dynamic_cast<xstream::z::istreambuf*>\n"
1342  " (MY(xcmp))->get_block_offset();\n"
1343  " }\n"
1344  " MY(last_offset) -= 4;\n"
1345  " }\n"
1346  " else {\n"
1347  " MY(last_start) = 0;\n"
1348  " MY(last_offset) = 0;\n"
1349  " }\n"
1350  " }\n"
1351  " else {\n"
1352  " if (MY(next_start) > 0) {\n"
1353  " m_istr.seekg(MY(next_start), std::ios_base::beg);\n"
1354  " MY(istr)->clear();\n"
1355  " MY(last_start) = MY(next_start);\n"
1356  " MY(last_offset) = 0;\n"
1357  " MY(next_start) = 0;\n"
1358  " }\n"
1359  " else {\n"
1360  " MY(last_start) = m_istr.tellg();\n"
1361  " MY(last_offset) = 0;\n"
1362  " }\n"
1363  " MY(istr)->read(MY(event_buffer),4);\n"
1364  " MY(bytes_read) += MY(istr)->gcount();\n"
1365  " if (!MY(istr)->good()) {\n"
1366  " unlock_streambufs();\n"
1367  " MY(hit_eof) = 1;\n"
1368  " return *this;\n"
1369  " }\n"
1370  " }\n"
1371  " MY(hit_eof) = 0;\n"
1372  " MY(sbuf)->reset();\n"
1373  " *MY(xstr) >> MY(event_size);\n"
1374  " if (MY(event_size) == 1) {\n"
1375  " MY(istr)->read(MY(event_buffer)+4,4);\n"
1376  " MY(bytes_read) += MY(istr)->gcount();\n"
1377  " if (!MY(istr)->good()) {\n"
1378  " unlock_streambufs();\n"
1379  " throw std::runtime_error(\"hddm_"
1380  << classPrefix << "::istream::operator>> error -\"\n"
1381  " \" read error on token input!\");\n"
1382  " }\n"
1383  " int size;\n"
1384  " *MY(xstr) >> size;\n"
1385  " MY(istr)->read(MY(event_buffer)+8,size);\n"
1386  " MY(bytes_read) += MY(istr)->gcount();\n"
1387  " if (!MY(istr)->good()) {\n"
1388  " unlock_streambufs();\n"
1389  " throw std::runtime_error(\"hddm_"
1390  << classPrefix << "::istream::operator>> error -\"\n"
1391  " \" read error on token input!\");\n"
1392  " }\n"
1393  " int format, flags;\n"
1394  " *MY(xstr) >> format >> flags;\n"
1395  " if (format != 0) {\n"
1396  " unlock_streambufs();\n"
1397  " throw std::runtime_error(\"hddm_"
1398  << classPrefix << "::istream::operator>> error - \"\n"
1399  " \"unsupported compression format!\");\n"
1400  " }\n"
1401  " m_status_bits.store(flags);\n"
1402  " MY(event_size) = 0;\n"
1403  " }\n"
1404  " }\n"
1405  " if (MY(event_size)+8 > MY(event_buffer_size)) {\n"
1406  " delete MY(xstr);\n"
1407  " delete MY(sbuf);\n"
1408  " char *newbuf = new char[MY(event_buffer_size) = MY(event_size)+1000];\n"
1409  " MY(sbuf) = new istreambuffer(newbuf, MY(event_buffer_size));\n"
1410  " MY(xstr) = new xstream::xdr::istream(MY(sbuf));\n"
1411  " memcpy(newbuf,MY(event_buffer),4);\n"
1412  " delete [] MY(event_buffer);\n"
1413  " MY(event_buffer) = newbuf;\n"
1414  " }\n"
1415  " MY(istr)->read(MY(event_buffer)+4,MY(event_size));\n"
1416  " MY(bytes_read) += MY(istr)->gcount();\n"
1417  " MY(records_read)++;\n"
1418  " if (!MY(istr)->good()) {\n"
1419  " unlock_streambufs();\n"
1420  " throw std::runtime_error(\"hddm_"
1421  << classPrefix << "::istream::operator>> error -\"\n"
1422  " \" read error in mid-record!\");\n"
1423  " }\n"
1424  " if ((MY(status_bits) & k_crc32_integrity) != 0) {\n"
1425  " unsigned int recorded_crc;\n"
1426  " char crcbuf[10];\n"
1427  " istreambuffer sbuf(crcbuf,10);\n"
1428  " xstream::xdr::istream xstr(&sbuf);\n"
1429  " MY(istr)->read(crcbuf,4);\n"
1430  " MY(bytes_read) += MY(istr)->gcount();\n"
1431  " xstr >> recorded_crc;\n"
1432  " xstream::digest::crc32 crc;\n"
1433  " std::ostream out(&crc);\n"
1434  " out.write(MY(event_buffer),MY(event_size)+4);\n"
1435  " out.flush();\n"
1436  " if (crc.digest() != recorded_crc) {\n"
1437  " char errmsg[] = \n"
1438  " \"WARNING: crc data integrity check failed\"\n"
1439  " \" on hddm_" << classPrefix << " input stream!\"\n"
1440  " \"\\nThis may be the result of a bug in the\"\n"
1441  " \" xstream library if you are analyzing a data\"\n"
1442  " \" file that was generated by code prior to svn\"\n"
1443  " \" rev 18530.\\nIf this concerns you, regenerate\"\n"
1444  " \" using a newer build of the sim-recon tools\"\n"
1445  " \" and it should go away.\\n\";\n"
1446  " if ((MY(status_bits) & 0x02) == 0) {\n"
1447  " std::cerr << errmsg << std::endl;\n"
1448  " MY(status_bits) |= 0x02;\n"
1449  " }\n"
1450  " //unlock_streambufs();\n"
1451  " //throw std::runtime_error(\"hddm_"
1452  << classPrefix << "::istream::operator>> error -\"\n"
1453  " // \" crc check error on input stream!\");\n"
1454  " }\n"
1455  " }\n"
1456  " unlock_streambufs();\n"
1457  " if (MY(events_to_skip)) {\n"
1458  " --MY(events_to_skip);\n"
1459  " return *this >> record;\n"
1460  " }\n"
1461  " MY(sbuf)->reset();\n"
1462  " MY(sequencing) = 0;\n"
1463  " MY(codon) = &MY(genome);\n"
1464  " *this >> (streamable&)record;\n"
1465  " return *this;\n"
1466  "}\n"
1467  "\n"
1468  "ostream::ostream(std::ostream &src)\n"
1469  " : m_ostr(src),\n"
1470  " m_status_bits(k_default_status)\n"
1471  "{\n"
1472  " m_ostr << HDDM::DocumentString();\n"
1473  " if (!m_ostr.good()) {\n"
1474  " throw std::runtime_error(\"hddm_" + classPrefix +
1475  "::ostream::ostream(ostream) \"\n"
1476  " \"error - write error on header output!\");\n"
1477  " }\n"
1478  " pthread_mutex_init(&m_streambuf_mutex,0);\n"
1479  " for (int i=0; i<threads::max_threads; ++i) {\n"
1480  " my_thread_private[i] = 0;\n"
1481  " }\n"
1482  " init_private_data();\n"
1483  "}\n"
1484  "\n"
1485  "ostream::~ostream() {\n"
1486  " pthread_mutex_destroy(&m_streambuf_mutex);\n"
1487  " for (int i=0; i<threads::max_threads; ++i) {\n"
1488  " thread_private_data *my_private = my_thread_private[i];\n"
1489  " if (my_private != 0) {\n"
1490  " if (MY(xstr)) {\n"
1491  " delete MY(xstr);\n"
1492  " }\n"
1493  " if (MY(sbuf)) {\n"
1494  " delete MY(sbuf);\n"
1495  " }\n"
1496  " if (MY(xcmp)) {\n"
1497  " MY(xcmp)->pubsync();\n"
1498  " MY(ostr)->rdbuf(m_ostr.rdbuf());\n"
1499  " delete MY(xcmp);\n"
1500  " }\n"
1501  " if (MY(ostr)) {\n"
1502  " MY(ostr)->flush();\n"
1503  " delete MY(ostr);\n"
1504  " }\n"
1505  " delete [] MY(event_buffer);\n"
1506  " delete my_private;\n"
1507  " }\n"
1508  " }\n"
1509  "}\n"
1510  "\n"
1511  "void ostream::init_private_data() {\n"
1512  " int threadID = threads::getID();\n"
1513  " if (my_thread_private[threadID] == 0) {\n"
1514  " my_thread_private[threadID] = new thread_private_data;\n"
1515  " }\n"
1516  " MY_SETUP\n"
1517  " MY(event_buffer) = new char[MY(event_buffer_size) = 100000];\n"
1518  " MY(sbuf) = new ostreambuffer(MY(event_buffer),MY(event_buffer_size));\n"
1519  " MY(xstr) = new xstream::xdr::ostream(MY(sbuf));\n"
1520  " MY(ostr) = new std::ostream(m_ostr.rdbuf());\n"
1521  " MY(xcmp) = 0;\n"
1522  " MY(last_start) = 0;\n"
1523  " MY(last_offset) = 0;\n"
1524  " MY(records_written) = 0;\n"
1525  " MY(bytes_written) = 0;\n"
1526  " MY(status_bits) = 0;\n"
1527  " MY(mutex_lock) = 0;\n"
1528  "}\n"
1529  "\n"
1530  "void ostream::setCompression(int flags) {\n"
1531  " MY_SETUP\n"
1532  " int oldcmp = (int)m_status_bits & k_bits_compression;\n"
1533  " int newcmp = flags & k_bits_compression;\n"
1534  " if (oldcmp != newcmp) {\n"
1535  " m_status_bits.fetch_and(~k_bits_compression | flags);\n"
1536  " m_status_bits.fetch_or(k_bits_compression & flags);\n"
1537  " if (newcmp != 0)\n"
1538  " m_status_bits.fetch_or(k_can_reposition);\n"
1539  " MY(sbuf)->reset();\n"
1540  " *MY(xstr) << 1 << 8 << 0 << (int)m_status_bits;\n"
1541  " lock_streambufs();\n"
1542  " MY(ostr)->write(MY(sbuf)->getbuf(),MY(sbuf)->size());\n"
1543  " if (!MY(ostr)->good()) {\n"
1544  " unlock_streambufs();\n"
1545  " throw std::runtime_error(\"hddm_"
1546  << classPrefix << "::ostream::setCompression\"\n"
1547  " \" error - write error on token output!\");\n"
1548  " }\n"
1549  " MY(ostr)->flush();\n"
1550  " update_streambufs();\n"
1551  " unlock_streambufs();\n"
1552  " }\n"
1553  "}\n"
1554  "\n"
1555  "void ostream::setIntegrityChecks(int flags) {\n"
1556  " MY_SETUP\n"
1557  " int oldint = (int)m_status_bits & k_bits_integrity;\n"
1558  " int newint = flags & k_bits_integrity;\n"
1559  " if (oldint != newint) {\n"
1560  " m_status_bits.fetch_and(~k_bits_integrity | flags);\n"
1561  " m_status_bits.fetch_or(k_bits_integrity & flags);\n"
1562  " MY(sbuf)->reset();\n"
1563  " *MY(xstr) << 1 << 8 << 0 << (int)m_status_bits;\n"
1564  " lock_streambufs();\n"
1565  " MY(ostr)->write(MY(sbuf)->getbuf(),MY(sbuf)->size());\n"
1566  " if (!MY(ostr)->good()) {\n"
1567  " unlock_streambufs();\n"
1568  " throw std::runtime_error(\"hddm_"
1569  << classPrefix << "::ostream::setIntegrityChecks\"\n"
1570  " \" error - write error on token output!\");\n"
1571  " }\n"
1572  " MY(ostr)->flush();\n"
1573  " update_streambufs();\n"
1574  " unlock_streambufs();\n"
1575  " }\n"
1576  "}\n"
1577  "\n"
1578  "streamposition ostream::getPosition() {\n"
1579  " MY_SETUP\n"
1580  " streamposition pos;\n"
1581  " pos.block_start = MY(last_start);\n"
1582  " pos.block_start = MY(last_offset);\n"
1583  " pos.block_status = MY(status_bits);\n"
1584  " return pos;\n"
1585  "}\n"
1586  "\n"
1587  "void ostream::update_streambufs() {\n"
1588  " MY_SETUP\n"
1589  " if ((int)m_status_bits != MY(status_bits)) {\n"
1590  " configure_streambufs();\n"
1591  " }\n"
1592  "}\n"
1593  "\n"
1594  "void ostream::configure_streambufs() {\n"
1595  " MY_SETUP\n"
1596  " int oldcmp = MY(status_bits) & k_bits_compression;\n"
1597  " int newcmp = (int)m_status_bits & k_bits_compression;\n"
1598  " if (oldcmp != newcmp) {\n"
1599  " if (oldcmp != k_no_compression) {\n"
1600  " MY(ostr)->rdbuf(m_ostr.rdbuf());\n"
1601  " delete MY(xcmp);\n"
1602  " MY(xcmp) = 0;\n"
1603  " }\n"
1604  " if (newcmp == k_z_compression) {\n"
1605  " //std::cerr << \"output switched on z compression\" << std::endl;\n"
1606  " MY(xcmp) = new xstream::z::ostreambuf(m_ostr.rdbuf());\n"
1607  " MY(ostr)->rdbuf(MY(xcmp));\n"
1608  " }\n"
1609  " else if (newcmp == k_bz2_compression) {\n"
1610  " //std::cerr << \"output switched on bz2 compression\" << std::endl;\n"
1611  " MY(xcmp )= new xstream::bz::ostreambuf(m_ostr.rdbuf());\n"
1612  " MY(ostr)->rdbuf(MY(xcmp));\n"
1613  " }\n"
1614  " else if (newcmp != k_no_compression) {\n"
1615  " throw std::runtime_error(\"hddm_"
1616  << classPrefix << "::ostream::configure_streambufs error - \"\n"
1617  " \"unrecognized compression flag requested.\");\n"
1618  " }\n"
1619  " }\n"
1620  " MY(status_bits) = m_status_bits;\n"
1621  "}\n"
1622  "\n"
1623  "void ostream::lock_streambufs() {\n"
1624  " MY_SETUP\n"
1625  " if (MY(mutex_lock) != 0) {\n"
1626  " unlock_streambufs();\n"
1627  " throw std::runtime_error(\"hddm_"
1628  << classPrefix << "::ostream::lock_streambufs error - \"\n"
1629  " \"mutex lock requested when lock already held.\");\n"
1630  " }\n"
1631  " if ((MY(status_bits) & k_bits_compression) == k_no_compression) {\n"
1632  " pthread_mutex_lock(&m_streambuf_mutex);\n"
1633  " MY(mutex_lock) = 1;\n"
1634  " }\n"
1635  " else if ((MY(status_bits) & k_bits_compression) == k_z_compression) {\n"
1636  " ((xstream::z::ostreambuf*)MY(xcmp))->set_streambuf_mutex(&m_streambuf_mutex);\n"
1637  " MY(mutex_lock) = 2;\n"
1638  " }\n"
1639  " else if ((MY(status_bits) & k_bits_compression) == k_bz2_compression) {\n"
1640  " ((xstream::bz::ostreambuf*)MY(xcmp))->set_streambuf_mutex(&m_streambuf_mutex);\n"
1641  " MY(mutex_lock) = 3;\n"
1642  " }\n"
1643  " else {\n"
1644  " MY(mutex_lock) = -1;\n"
1645  " }\n"
1646  "}\n"
1647  "\n"
1648  "void ostream::unlock_streambufs() {\n"
1649  " MY_SETUP\n"
1650  " if (MY(mutex_lock) == 0) {\n"
1651  " throw std::runtime_error(\"hddm_"
1652  << classPrefix << "::ostream::unlock_streambufs error - \"\n"
1653  " \"mutex unlock requested when lock not held.\");\n"
1654  " }\n"
1655  " else if (MY(mutex_lock) == 1) {\n"
1656  " pthread_mutex_unlock(&m_streambuf_mutex);\n"
1657  " }\n"
1658  " else if (MY(mutex_lock) == 2) {\n"
1659  " ((xstream::z::ostreambuf*)MY(xcmp))->set_streambuf_mutex(0);\n"
1660  " }\n"
1661  " else if (MY(mutex_lock) == 3) {\n"
1662  " ((xstream::bz::ostreambuf*)MY(xcmp))->set_streambuf_mutex(0);\n"
1663  " }\n"
1664  " MY(mutex_lock) = 0;\n"
1665  "}\n"
1666  "\n"
1667  "int istream::getTag(const std::string &src, int start,\n"
1668  " std::string &tag, int &level)\n"
1669  "{\n"
1670  " tag = \"\";\n"
1671  " size_t p_btag = src.find(\"<\",start);\n"
1672  " size_t p_bline = src.find_last_of(\"\\n\",p_btag);\n"
1673  " if (p_bline == std::string::npos)\n"
1674  " {\n"
1675  " p_bline = 0;\n"
1676  " }\n"
1677  " else\n"
1678  " {\n"
1679  " ++p_bline;\n"
1680  " }\n"
1681  " level = (p_btag-p_bline)/2;\n"
1682  " size_t p_etag = p_btag;\n"
1683  " for (size_t quotes=0; p_etag < src.size(); ++p_etag) {\n"
1684  " if (src[p_etag] == '\"') {\n"
1685  " tag += \"\\\"\";\n"
1686  " ++quotes;\n"
1687  " }\n"
1688  " else if (quotes/2*2 != quotes) {\n"
1689  " tag += src[p_etag];\n"
1690  " }\n"
1691  " else if (src.find_first_of(\" \\t\\n\",p_etag) == 0) {\n"
1692  " tag += \" \";\n"
1693  " p_etag = src.find_first_not_of(\" \\t\\n\",p_etag)-1;\n"
1694  " }\n"
1695  " else if (src[p_etag] == '>') {\n"
1696  " tag += \">\";\n"
1697  " break;\n"
1698  " }\n"
1699  " else {\n"
1700  " tag += src[p_etag];\n"
1701  " }\n"
1702  " }\n"
1703  " if (p_etag == src.size()) {\n"
1704  " std::stringstream sstr;\n"
1705  " sstr << \"hddm_" + classPrefix + "::istream::getTag\"\n"
1706  " << \" error - bad header format\" << std::endl\n"
1707  " << \" tag \" << tag << \" at position \" << start\n"
1708  " << std::endl;\n"
1709  " throw std::runtime_error(sstr.str());\n"
1710  " }\n"
1711  " return p_etag+2;\n"
1712  "}\n"
1713  "\n"
1714  "int istream::getEndTag(const std::string &src, int start,\n"
1715  " const std::string &tag)\n"
1716  "{\n"
1717  " if (tag.rfind(\"/>\") == tag.size()-2) {\n"
1718  " return src.find(tag,start) + tag.size()+1;\n"
1719  " }\n"
1720  " else {\n"
1721  " std::string etag = \"</\";\n"
1722  " etag += tag.substr(1,tag.find_first_of(' ')-1) + \">\";\n"
1723  " size_t p_etag = src.find(etag,start);\n"
1724  " size_t p_quote = src.find_first_of('\"',start);\n"
1725  " while (p_quote != std::string::npos && p_quote < p_etag) {\n"
1726  " p_quote = src.find_first_of('\"',p_quote+1);\n"
1727  " if (p_quote > p_etag) {\n"
1728  " p_etag = src.find(etag,p_quote+1);\n"
1729  " }\n"
1730  " p_quote = src.find_first_of('\"',p_quote+1);\n"
1731  " }\n"
1732  " if (p_etag == std::string::npos) {\n"
1733  " std::stringstream sstr;\n"
1734  " sstr << \"hddm_" + classPrefix + "::istream::getEndTag\"\n"
1735  " << \" error - bad header format\" << std::endl\n"
1736  " << \" tag \" << tag << \" at position \" << start\n"
1737  " << std::endl\n"
1738  " << \" end tag \" << etag << \" not found.\"\n"
1739  " << std::endl;\n"
1740  " throw std::runtime_error(sstr.str());\n"
1741  " }\n"
1742  " return p_etag + etag.size()+1;\n"
1743  " }\n"
1744  "}\n"
1745  "\n"
1746  "void istream::collide(const std::string &itag, const std::string &rtag) {\n"
1747  " std::string itagname = itag.substr(1,itag.find(\" \")-1);\n"
1748  " std::string rtagname = rtag.substr(1,rtag.find(\" \")-1);\n"
1749  " std::string errmsg = \"hddm_" + classPrefix +
1750  "::istream::collide warning:\\n\"\n"
1751  " \"tag \" + itagname + \" in input file \"\n"
1752  " \"does not match c++ header hddm_" << classPrefix << ".hpp\\n\"\n"
1753  " \" input file: \" + itag + \"\\n\"\n"
1754  " \" c++ header: \" + rtag + \"\\n\"\n"
1755  " \" === Tag \" + itagname + \" will be ignored,\"\n"
1756  " \" rebuild to cure the problem ===\";\n"
1757  " if (itagname != \"HDDM\") {\n"
1758  " std::cerr << errmsg << std::endl;\n"
1759  " }\n"
1760  " else {\n"
1761  " throw std::runtime_error(errmsg);\n"
1762  " }\n"
1763  "}\n"
1764  "\n"
1765  "chromosome istream::synthesize(const std::string &src, int p_src,\n"
1766  " const std::string &ref, int p_ref)\n"
1767  "{\n"
1768  " chromosome chrom;\n"
1769  " int slevel, rlevel;\n"
1770  " std::string stag, rtag;\n"
1771  " p_src = getTag(src,p_src,stag,slevel);\n"
1772  " p_ref = getTag(ref,p_ref,rtag,rlevel);\n"
1773  " std::string stagname = stag.substr(1,stag.find(\" \")-1);\n"
1774  " std::string rtagname = rtag.substr(1,rtag.find(\" \")-1);\n"
1775  " if (stagname != rtagname) {\n"
1776  " throw std::runtime_error(\"hddm_" + classPrefix +
1777  "::istream::synthesize error - matching algorithm error #2\");\n"
1778  " }\n"
1779  " else if (!tags_match(stag,rtag)) {\n"
1780  " collide(stag,rtag);\n"
1781  " return chrom;\n"
1782  " }\n"
1783  "\n"
1784  " int p2_src, p2_ref;\n"
1785  " int s2level, r2level;\n"
1786  " std::string s2tag, r2tag;\n"
1787  " getTag(src,p2_src=p_src,s2tag,s2level);\n"
1788  " while (s2level > slevel) {\n"
1789  " codon *gene = new codon();\n"
1790  " std::string s2tagname = s2tag.substr(1,s2tag.find(\" \")-1);\n"
1791  " getTag(ref,p2_ref=p_ref,r2tag,r2level);\n"
1792  " int order_of_this_tag_in_ref = 1;\n"
1793  " while (r2level == s2level) {\n"
1794  " std::string r2tagname = r2tag.substr(1,r2tag.find(\" \")-1);\n"
1795  " if (s2tagname == r2tagname) {\n"
1796  " if (!tags_match(s2tag,r2tag)) {\n"
1797  " collide(s2tag,r2tag);\n"
1798  " break;\n"
1799  " }\n"
1800  " else {\n"
1801  " gene->m_order = order_of_this_tag_in_ref;\n"
1802  " }\n"
1803  " gene->m_sequence = synthesize(src,p2_src,ref,p2_ref);\n"
1804  " break;\n"
1805  " }\n"
1806  " p2_ref = getEndTag(ref,p2_ref,r2tag);\n"
1807  " getTag(ref,p2_ref,r2tag,r2level);\n"
1808  " ++order_of_this_tag_in_ref;\n"
1809  " }\n"
1810  " gene->m_tagname = s2tagname;\n"
1811  " chrom.push_back(*gene);\n"
1812  " delete gene;\n"
1813  " p2_src = getEndTag(src,p2_src,s2tag);\n"
1814  " getTag(src,p2_src,s2tag,s2level);\n"
1815  " }\n"
1816  " return chrom;\n"
1817  "}\n"
1818  ;
1819 
1820  XMLPlatformUtils::Terminate();
1821  return 0;
1822 }
1823 
1825 {
1826  XtString p(*this);
1827  XtString::size_type len = p.size();
1828  if (len > 3 && p.substr(len-3,3) == "tum")
1829  {
1830  p.replace(len-3,3,"ta");
1831  }
1832  else if (len > 1 && p.substr(len-3,3) == "ies")
1833  {
1834  p.replace(len-3,3,"iesList");
1835  }
1836  else if (len > 2 && p.substr(len-2,2) == "ex")
1837  {
1838  p.replace(len-2,2,"ices");
1839  }
1840  else if (len > 2 && p.substr(len-2,2) == "sh")
1841  {
1842  p.replace(len-2,2,"shes");
1843  }
1844  else if (len > 1 && p.substr(len-1,1) == "s")
1845  {
1846  p.replace(len-1,1,"ses");
1847  }
1848  else if (len > 1)
1849  {
1850  p += "s";
1851  }
1852  return p;
1853 }
1854 
1855 /* Map from tag name to name of the corresponding class
1856  * for the case of simple tags (those that do not repeat)
1857  */
1859 {
1860  XtString p(*this);
1861  p[0] = toupper(p[0]);
1862  return p;
1863 }
1864 
1865 /* Map from tag name to name of the corresponding class
1866  * for the case of list tags (those that may repeat)
1867  */
1869 {
1870  XtString r(*this);
1871  r[0] = toupper(r[0]);
1872  r = r + "List";
1873  return r;
1874 }
1875 
1876 /* Map from tag name to name of the corresponding class
1877  * for the case of link tags (those that do not repeat)
1878  */
1880 {
1881  XtString r(*this);
1882  r[0] = toupper(r[0]);
1883  r = r + "Link";
1884  return r;
1885 }
1886 
1887 /* Look for a named element in a list of element pointers
1888  * and return index of first instance in the list if found,
1889  * otherwise return -1;
1890  */
1892 {
1893  int n=0;
1894  parentList_t::iterator iter;
1895  for (iter = list.begin(); iter != list.end(); ++iter, ++n)
1896  {
1897  DOMElement *el = (DOMElement*)(*iter);
1898  XtString cnameS(el->getTagName());
1899  if (cnameS == name) {
1900  return n;
1901  }
1902  }
1903  return -1;
1904 }
1905 
1906 /* Verify that the tag group under this element does not collide
1907  * with existing tag group elref, otherwise exit with fatal error
1908  */
1909 void CodeBuilder::checkConsistency(DOMElement* el, DOMElement* elref)
1910 {
1911  XtString tagS(el->getTagName());
1912  if (el->getParentNode() == elref->getParentNode())
1913  {
1914  std::cerr
1915  << "hddm-cpp error: tag " << "\"" << tagS
1916  << "\" is duplicated within one context in xml document."
1917  << std::endl;
1918  exit(1);
1919  }
1920 
1921  DOMNamedNodeMap* oldAttr = elref->getAttributes();
1922  DOMNamedNodeMap* newAttr = el->getAttributes();
1923  unsigned int listLength = oldAttr->getLength();
1924  for (unsigned int n = 0; n < listLength; n++)
1925  {
1926  XtString nameS(oldAttr->item(n)->getNodeName());
1927  XtString oldS(elref->getAttribute(X(nameS)));
1928  XtString newS(el->getAttribute(X(nameS)));
1929  if (nameS == "minOccurs")
1930  {
1931  continue;
1932  }
1933  else if (nameS == "maxOccurs")
1934  {
1935  int maxold = (oldS == "unbounded")? INT_MAX : atoi(S(oldS));
1936  int maxnew = (newS == "unbounded")? INT_MAX : atoi(S(newS));
1937  if ((maxold < 2 && maxnew > 1) || (maxold > 1 && maxnew < 2))
1938  {
1939  std::cerr
1940  << "hddm-cpp error: inconsistent maxOccurs usage by tag "
1941  << "\"" << tagS << "\" in xml document." << std::endl;
1942  exit(1);
1943  }
1944  }
1945  else if (newS != oldS)
1946  {
1947  std::cerr
1948  << "hddm-cpp error: inconsistent usage of attribute "
1949  << "\"" << nameS << "\" in tag "
1950  << "\"" << tagS << "\" in xml document." << std::endl;
1951  exit(1);
1952  }
1953  }
1954  listLength = newAttr->getLength();
1955  for (unsigned int n = 0; n < listLength; n++)
1956  {
1957  XtString nameS(newAttr->item(n)->getNodeName());
1958  XtString oldS(elref->getAttribute(X(nameS)));
1959  XtString newS(el->getAttribute(X(nameS)));
1960  if (nameS == "minOccurs")
1961  {
1962  continue;
1963  }
1964  else if (nameS == "maxOccurs")
1965  {
1966  int maxold = (oldS == "unbounded")? INT_MAX : atoi(S(oldS));
1967  int maxnew = (newS == "unbounded")? INT_MAX : atoi(S(newS));
1968  if ((maxold < 2 && maxnew > 1) || (maxold > 1 && maxnew < 2))
1969  {
1970  std::cerr
1971  << "hddm-cpp error: inconsistent maxOccurs usage by tag "
1972  << "\"" << tagS << "\" in xml document." << std::endl;
1973  exit(1);
1974  }
1975  }
1976  else if (newS != oldS)
1977  {
1978  std::cerr
1979  << "hddm-cpp error: inconsistent usage of attribute "
1980  << "\"" << nameS << "\" in tag "
1981  << "\"" << tagS << "\" in xml document." << std::endl;
1982  exit(1);
1983  }
1984  }
1985  DOMNodeList* oldList = elref->getChildNodes();
1986  DOMNodeList* newList = el->getChildNodes();
1987  listLength = oldList->getLength();
1988  if (newList->getLength() != listLength)
1989  {
1990  std::cerr
1991  << "hddm-cpp error: inconsistent usage of tag "
1992  << "\"" << tagS << "\" in xml document." << std::endl;
1993  exit(1);
1994  }
1995  for (unsigned int n = 0; n < listLength; n++)
1996  {
1997  DOMNode* cont = oldList->item(n);
1998  XtString nameS(cont->getNodeName());
1999  short type = cont->getNodeType();
2000  if (type == DOMNode::ELEMENT_NODE)
2001  {
2002  DOMNodeList* contList = el->getElementsByTagName(X(nameS));
2003  if (contList->getLength() != 1)
2004  {
2005  std::cerr
2006  << "hddm-cpp error: inconsistent usage of tag "
2007  << "\"" << tagS << "\" in xml document." << std::endl;
2008  exit(1);
2009  }
2010  }
2011  }
2012 }
2013 
2014 /* Write declaration of the classes for this tag to the header file */
2015 
2016 void CodeBuilder::writeClassdef(DOMElement* el)
2017 {
2018  XtString tagS(el->getTagName());
2019  hFile << "class " << tagS.simpleType()
2020  << ": public HDDM_Element {" << std::endl
2021  << " public:" << std::endl;
2022  if (tagS == "HDDM") {
2023  hFile << " HDDM();" << std::endl;
2024  }
2025  hFile << " ~" << tagS.simpleType() << "();" << std::endl;
2026 
2027  std::map<XtString,XtString> attrList;
2028  DOMNamedNodeMap *myAttr = el->getAttributes();
2029  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2030  {
2031  XtString attrS(myAttr->item(n)->getNodeName());
2032  XtString typeS(el->getAttribute(X(attrS)));
2033  attrList[attrS] = typeS;
2034  }
2035  parentList_t::iterator iter;
2036  for (iter = parents[tagS].begin(); iter != parents[tagS].end(); ++iter)
2037  {
2038  DOMElement *hostEl = (DOMElement*)(*iter);
2039  XtString hostS(hostEl->getTagName());
2040  DOMNamedNodeMap *hostAttr = hostEl->getAttributes();
2041  for (unsigned int n = 0; n < hostAttr->getLength(); n++)
2042  {
2043  XtString attrS(hostAttr->item(n)->getNodeName());
2044  if (attrList.find(attrS) != attrList.end())
2045  {
2046  continue;
2047  }
2048  XtString typeS(hostEl->getAttribute(X(attrS)));
2049  attrList[attrS] = typeS;
2050  XtString getS("get"+attrS.simpleType());
2051  if (typeS == "int")
2052  {
2053  hFile << " int " << getS << "() const;" << std::endl;
2054  }
2055  else if (typeS == "long")
2056  {
2057  hFile << " int64_t " << getS << "() const;" << std::endl;
2058  }
2059  else if (typeS == "float")
2060  {
2061  hFile << " float " << getS << "() const;" << std::endl;
2062  }
2063  else if (typeS == "double")
2064  {
2065  hFile << " double " << getS << "() const;" << std::endl;
2066  }
2067  else if (typeS == "boolean")
2068  {
2069  hFile << " bool " << getS << "() const;" << std::endl;
2070  }
2071  else if (typeS == "string")
2072  {
2073  hFile << " std::string " << getS << "() const;" << std::endl;
2074  }
2075  else if (typeS == "anyURI")
2076  {
2077  hFile << " std::string " << getS << "() const;" << std::endl;
2078  }
2079  else if (typeS == "Particle_t")
2080  {
2081  hFile << " Particle_t " << getS << "() const;" << std::endl;
2082  }
2083  else if (guessType(typeS) == "int")
2084  {
2085  hFile << " int " << getS << "() const;" << std::endl;
2086  }
2087  else if (guessType(typeS) == "long")
2088  {
2089  hFile << " int64_t " << getS << "() const;" << std::endl;
2090  }
2091  else if (guessType(typeS) == "float")
2092  {
2093  hFile << " float " << getS << "() const;" << std::endl;
2094  }
2095  else if (guessType(typeS) == "double")
2096  {
2097  hFile << " double " << getS << "() const;" << std::endl;
2098  }
2099  else if (guessType(typeS) == "boolean")
2100  {
2101  hFile << " bool " << getS << "() const;" << std::endl;
2102  }
2103  else if (guessType(typeS) == "Particle_t")
2104  {
2105  hFile << " Particle_t " << getS << "() const;" << std::endl;
2106  }
2107  else /* any values not matching the above are strings */
2108  {
2109  hFile << " std::string " << getS << "() const;" << std::endl;
2110  }
2111  }
2112  }
2113 
2114  myAttr = el->getAttributes();
2115  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2116  {
2117  XtString attrS(myAttr->item(n)->getNodeName());
2118  XtString typeS(el->getAttribute(X(attrS)));
2119  XtString getS("get" + attrS.simpleType());
2120  XtString setS("set" + attrS.simpleType());
2121  if (typeS == "int")
2122  {
2123  hFile << " int " << getS << "() const;" << std::endl
2124  << " void " << setS << "(int " << attrS << ");" << std::endl;
2125  }
2126  else if (typeS == "long")
2127  {
2128  hFile << " int64_t " << getS << "() const;" << std::endl
2129  << " void " << setS << "(int64_t " << attrS << ");" << std::endl;
2130  }
2131  else if (typeS == "float")
2132  {
2133  hFile << " float " << getS << "() const;" << std::endl
2134  << " void " << setS << "(float " << attrS << ");" << std::endl;
2135  }
2136  else if (typeS == "double")
2137  {
2138  hFile << " double " << getS << "() const;" << std::endl
2139  << " void " << setS << "(double " << attrS << ");" << std::endl;
2140  }
2141  else if (typeS == "boolean")
2142  {
2143  hFile << " bool " << getS << "() const;" << std::endl
2144  << " void " << setS << "(bool " << attrS << ");" << std::endl;
2145  }
2146  else if (typeS == "string")
2147  {
2148  hFile << " std::string " << getS << "() const;" << std::endl
2149  << " void " << setS << "(const std::string &" << attrS << ");"
2150  << std::endl;
2151  }
2152  else if (typeS == "anyURI")
2153  {
2154  hFile << " std::string " << getS << "() const;" << std::endl
2155  << " void " << setS << "(const std::string &" << attrS << ");"
2156  << std::endl;
2157  }
2158  else if (typeS == "Particle_t")
2159  {
2160  hFile << " Particle_t " << getS << "() const;" << std::endl
2161  << " void " << setS << "(Particle_t " << attrS << ");" << std::endl;
2162  }
2163  else if (guessType(typeS) == "int")
2164  {
2165  hFile << " int " << getS << "() const;" << std::endl;
2166  }
2167  else if (guessType(typeS) == "long")
2168  {
2169  hFile << " int64_t " << getS << "() const;" << std::endl;
2170  }
2171  else if (guessType(typeS) == "float")
2172  {
2173  hFile << " float " << getS << "() const;" << std::endl;
2174  }
2175  else if (guessType(typeS) == "double")
2176  {
2177  hFile << " double " << getS << "() const;" << std::endl;
2178  }
2179  else if (guessType(typeS) == "boolean")
2180  {
2181  hFile << " bool " << getS << "() const;" << std::endl;
2182  }
2183  else if (guessType(typeS) == "Particle_t")
2184  {
2185  hFile << " Particle_t " << getS << "() const;" << std::endl;
2186  }
2187  else /* any attributes not matching the above are strings */
2188  {
2189  hFile << " std::string " << getS << "() const;" << std::endl;
2190  }
2191  }
2192 
2193  if (tagS == "HDDM") {
2194  parentTable_t::iterator piter;
2195  for (piter = parents.begin(); piter != parents.end(); ++piter)
2196  {
2197  XtString cnameS(piter->first);
2198  if (cnameS != "HDDM" && element_in_list(cnameS,children[tagS]) == -1)
2199  {
2200  hFile << " " << cnameS.listType() << " get"
2201  << cnameS.plural().simpleType() << "();" << std::endl;
2202  }
2203  }
2204  }
2205 
2206  parentList_t::iterator citer;
2207  for (citer = children[tagS].begin(); citer != children[tagS].end(); ++citer)
2208  {
2209  DOMElement *childEl = (DOMElement*)(*citer);
2210  XtString cnameS(childEl->getTagName());
2211  XtString repS(childEl->getAttribute(X("maxOccurs")));
2212  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
2213  hFile << " " << cnameS.simpleType() << " &get"
2214  << cnameS.simpleType()
2215  << ((rep > 1)? "(int index=0);" : "();") << std::endl;
2216  hFile << " " << cnameS.listType() << " &get"
2217  << cnameS.plural().simpleType() << "();" << std::endl;
2218  hFile << " " << cnameS.listType() << " add"
2219  << cnameS.plural().simpleType()
2220  << "(int count=1, int start=-1);" << std::endl;
2221  hFile << " void delete"
2222  << cnameS.plural().simpleType()
2223  << "(int count=-1, int start=0);" << std::endl;
2224  }
2225 
2226  hFile << " const void *getAttribute(const std::string &name,"
2227  << " hddm_type *atype=0) const;\n"
2228  << " std::string toString(int indent=0);\n"
2229  << " std::string toXML(int indent=0);\n";
2230 
2231  if (tagS == "HDDM")
2232  {
2233  hFile << " void clear();" << std::endl;
2234  parentTable_t::iterator piter;
2235  for (piter = parents.begin(); piter != parents.end(); ++piter)
2236  {
2237  XtString cnameS(piter->first);
2238  if (cnameS != "HDDM") {
2239  hFile << " friend class " << cnameS.simpleType() << ";"
2240  << std::endl;
2241  }
2242  }
2243  hFile << " static std::string DocumentString();" << std::endl;
2244  hFile << " private:" << std::endl;
2245  }
2246  else
2247  {
2248  hFile << " friend class HDDM_ElementList<"
2249  << tagS.simpleType() << ">;" << std::endl
2250  << " friend class HDDM_ElementLink<"
2251  << tagS.simpleType() << ">;" << std::endl;
2252  hFile << " private:" << std::endl
2253  << " " << tagS.simpleType()
2254  << "(HDDM_Element *parent=0);" << std::endl;
2255  }
2256 
2257  hFile << " void streamer(istream &istr);" << std::endl
2258  << " void streamer(ostream &ostr);" << std::endl;
2259 
2260  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2261  {
2262  XtString attrS(myAttr->item(n)->getNodeName());
2263  XtString typeS(el->getAttribute(X(attrS)));
2264  if (typeS == "int")
2265  {
2266  hFile << " int m_" << attrS << ";" << std::endl;
2267  }
2268  else if (typeS == "long")
2269  {
2270  hFile << " int64_t m_" << attrS << ";" << std::endl;
2271  }
2272  else if (typeS == "float")
2273  {
2274  hFile << " float m_" << attrS << ";" << std::endl;
2275  }
2276  else if (typeS == "double")
2277  {
2278  hFile << " double m_" << attrS << ";" << std::endl;
2279  }
2280  else if (typeS == "boolean")
2281  {
2282  hFile << " int m_" << attrS << ";" << std::endl;
2283  }
2284  else if (typeS == "string")
2285  {
2286  hFile << " std::string m_" << attrS << ";" << std::endl;
2287  }
2288  else if (typeS == "anyURI")
2289  {
2290  hFile << " std::string m_" << attrS << ";" << std::endl;
2291  }
2292  else if (typeS == "Particle_t")
2293  {
2294  hFile << " int m_" << attrS << ";" << std::endl;
2295  }
2296  }
2297 
2298  if (tagS == "HDDM") {
2299  parentTable_t::iterator piter;
2300  for (piter = parents.begin(); piter != parents.end(); ++piter)
2301  {
2302  XtString dnameS(piter->first);
2303  if (dnameS != "HDDM") {
2304  hFile << " std::list<" << dnameS.simpleType()
2305  << "*> m_" << dnameS << "_plist;" << std::endl;
2306  }
2307  }
2308  }
2309 
2310  for (citer = children[tagS].begin(); citer != children[tagS].end(); ++citer)
2311  {
2312  DOMElement *childEl = (DOMElement*)(*citer);
2313  XtString cnameS(childEl->getTagName());
2314  XtString repS(childEl->getAttribute(X("maxOccurs")));
2315  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
2316  hFile << " " << ((rep > 1)? cnameS.listType() : cnameS.linkType())
2317  << " m_" << cnameS
2318  << ((rep > 1)? "_list;" : "_link;") << std::endl;
2319  }
2320 
2321  hFile << "};" << std::endl << std::endl;
2322 
2323  if (tagS != "HDDM")
2324  {
2325  hFile << "typedef HDDM_ElementList<"
2326  << tagS.simpleType() << "> "
2327  << tagS.listType() << ";" << std::endl
2328  << "typedef HDDM_ElementLink<"
2329  << tagS.simpleType() << "> "
2330  << tagS.linkType() << ";"
2331  << std::endl << std::endl;
2332  }
2333 }
2334 
2335 /* Generate class declarations for this tag and its descendants;
2336  * this function calls itself recursively
2337  */
2338 
2339 void CodeBuilder::constructGroup(DOMElement* el)
2340 {
2341  XtString tagS(el->getTagName());
2342  parentList_t::iterator piter;
2343  parents[tagS].insert(parents[tagS].begin(),
2344  parentList.begin(),parentList.end());
2345  std::vector<DOMElement*>::iterator iter;
2346  for (iter = tagList.begin(); iter != tagList.end(); iter++)
2347  {
2348  DOMElement* targEl = *iter;
2349  XtString targS(targEl->getTagName());
2350  if (tagS == targS)
2351  {
2352  checkConsistency(el,targEl);
2353  return;
2354  }
2355  }
2356 
2357  parentList.push_back(el);
2358  DOMNodeList* contList = el->getChildNodes();
2359  int contLength = contList->getLength();
2360  for (int c = 0; c < contLength; c++)
2361  {
2362  DOMNode* cont = contList->item(c);
2363  short type = cont->getNodeType();
2364  if (type == DOMNode::ELEMENT_NODE)
2365  {
2366  DOMElement* contEl = (DOMElement*) cont;
2367  XtString contS(contEl->getTagName());
2368  children[tagS].push_back(contEl);
2369  constructGroup(contEl);
2370  }
2371  }
2372  parentList.pop_back();
2373 
2374  tagList.push_back(el);
2375 
2376  if (tagS == "HDDM")
2377  {
2378  std::vector<DOMElement*>::iterator iter;
2379  for (iter = tagList.begin(); iter != tagList.end(); iter++)
2380  {
2381  writeClassdef(*iter);
2382  }
2383  }
2384 }
2385 
2386 /* Write method implementation of the classes for this tag to the header file */
2387 
2388 void CodeBuilder::writeClassimp(DOMElement* el)
2389 {
2390  XtString tagS(el->getTagName());
2391  if (tagS == "HDDM")
2392  {
2393  hFile << "inline " << tagS.simpleType() << "::"
2394  << tagS.simpleType() << "()" << std::endl
2395  << " : HDDM_Element()";
2396  }
2397  else
2398  {
2399  hFile << "inline " << tagS.simpleType() << "::"
2400  << tagS.simpleType() << "(HDDM_Element *parent)" << std::endl
2401  << " : HDDM_Element(parent)";
2402  }
2403  DOMNamedNodeMap *myAttr = el->getAttributes();
2404  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2405  {
2406  XtString attrS(myAttr->item(n)->getNodeName());
2407  XtString typeS(el->getAttribute(X(attrS)));
2408  if (typeS == "int")
2409  {
2410  hFile << "," << std::endl << " m_" << attrS << "(0)";
2411  }
2412  else if (typeS == "long")
2413  {
2414  hFile << "," << std::endl << " m_" << attrS << "(0)";
2415  }
2416  else if (typeS == "float")
2417  {
2418  hFile << "," << std::endl << " m_" << attrS << "(0)";
2419  }
2420  else if (typeS == "double")
2421  {
2422  hFile << "," << std::endl << " m_" << attrS << "(0)";
2423  }
2424  else if (typeS == "boolean")
2425  {
2426  hFile << "," << std::endl << " m_" << attrS << "(0)";
2427  }
2428  else if (typeS == "string")
2429  {
2430  hFile << "," << std::endl << " m_" << attrS << "(\"\")";
2431  }
2432  else if (typeS == "anyURI")
2433  {
2434  hFile << "," << std::endl << " m_" << attrS << "(\"\")";
2435  }
2436  else if (typeS == "Particle_t")
2437  {
2438  hFile << "," << std::endl << " m_" << attrS << "(0)";
2439  }
2440  else
2441  {
2442  /* ignore attributes with unrecognized values */
2443  }
2444  }
2445 
2446  // Write XXX_plist initializers first and then the XXX_list or
2447  // XXX_link initializers. This is because the plist members
2448  // appear first in the class definition.
2449  // Dec. 3, 2012 David L.
2450  parentList_t::iterator citer;
2451  for (citer = children[tagS].begin();
2452  citer != children[tagS].end();
2453  ++citer)
2454  {
2455  DOMElement *childEl = (DOMElement*)(*citer);
2456  XtString cnameS(childEl->getTagName());
2457  XtString repS(childEl->getAttribute(X("maxOccurs")));
2458  // int rep; commented out to avoid compiler warnings 4/26/2015 DL
2459  // rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
2460  XtString hostS("m_host->");
2461  if (tagS == "HDDM")
2462  {
2463  hFile << "," << std::endl << " m_" << cnameS
2464  << "_plist()";
2465  hostS = "";
2466  }
2467  }
2468  for (citer = children[tagS].begin();
2469  citer != children[tagS].end();
2470  ++citer)
2471  {
2472  DOMElement *childEl = (DOMElement*)(*citer);
2473  XtString cnameS(childEl->getTagName());
2474  XtString repS(childEl->getAttribute(X("maxOccurs")));
2475  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
2476  const char *myHost = (tagS=="HDDM" ? "this->":"m_host->");
2477  XtString hostS(myHost);
2478  hFile << "," << std::endl << " m_" << cnameS
2479  << ((rep > 1)? "_list" : "_link")
2480  << "(&" << hostS << "m_" << cnameS << "_plist," << std::endl
2481  << " "
2482  << hostS << "m_" << cnameS << "_plist.end()," << std::endl
2483  << " "
2484  << hostS << "m_" << cnameS << "_plist.end()," << std::endl
2485  << " "
2486  << "this)";
2487  }
2488  if (tagS == "HDDM")
2489  {
2490  hFile << std::endl << "{" << std::endl
2491  << " m_host = this;" << std::endl
2492  << "}" << std::endl << std::endl;
2493  }
2494  else
2495  {
2496  hFile << std::endl << "{}" << std::endl << std::endl;
2497  }
2498 
2499  hFile << "inline " << tagS.simpleType() << "::~"
2500  << tagS.simpleType() << "() {"
2501  << ((children[tagS].size())? "\n" : "");
2502  for (citer = children[tagS].begin();
2503  citer != children[tagS].end();
2504  ++citer)
2505  {
2506  DOMElement *childEl = (DOMElement*)(*citer);
2507  XtString cnameS(childEl->getTagName());
2508  hFile << " delete" << cnameS.plural().simpleType()
2509  << "();" << std::endl;
2510  }
2511  hFile << "}" << std::endl << std::endl;
2512 
2513  std::map<XtString,XtString> attrList;
2514  myAttr = el->getAttributes();
2515  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2516  {
2517  XtString attrS(myAttr->item(n)->getNodeName());
2518  XtString typeS(el->getAttribute(X(attrS)));
2519  attrList[attrS] = typeS;
2520  }
2521  parentList_t::iterator iter;
2522  for (iter = parents[tagS].begin(); iter != parents[tagS].end(); ++iter)
2523  {
2524  DOMElement *hostEl = (DOMElement*)(*iter);
2525  DOMNamedNodeMap *hostAttr = hostEl->getAttributes();
2526  for (unsigned int n = 0; n < hostAttr->getLength(); n++)
2527  {
2528  XtString attrS(hostAttr->item(n)->getNodeName());
2529  if (attrList.find(attrS) != attrList.end())
2530  {
2531  continue;
2532  }
2533  XtString typeS(hostEl->getAttribute(X(attrS)));
2534  attrList[attrS] = typeS;
2535  XtString getS("get" + attrS.simpleType());
2536  if (typeS == "int")
2537  {
2538  hFile << "inline int " << tagS.simpleType()
2539  << "::" << getS << "() const {" << std::endl
2540  << " return *(int*)m_parent->getAttribute(\""
2541  << attrS << "\");" << std::endl
2542  << "}" << std::endl << std::endl;
2543  }
2544  else if (typeS == "long")
2545  {
2546  hFile << "inline int64_t " << tagS.simpleType()
2547  << "::" << getS << "() const {" << std::endl
2548  << " return *(int64_t*)m_parent->getAttribute(\""
2549  << attrS << "\");" << std::endl
2550  << "}" << std::endl << std::endl;
2551  }
2552  else if (typeS == "float")
2553  {
2554  hFile << "inline float " << tagS.simpleType()
2555  << "::" << getS << "() const {" << std::endl
2556  << " return *(float*)m_parent->getAttribute(\""
2557  << attrS << "\");" << std::endl
2558  << "}" << std::endl << std::endl;
2559  }
2560  else if (typeS == "double")
2561  {
2562  hFile << "inline double " << tagS.simpleType()
2563  << "::" << getS << "() const {" << std::endl
2564  << " return *(double*)m_parent->getAttribute(\""
2565  << attrS << "\");" << std::endl
2566  << "}" << std::endl << std::endl;
2567  }
2568  else if (typeS == "boolean")
2569  {
2570  hFile << "inline bool " << tagS.simpleType()
2571  << "::" << getS << "() const {" << std::endl
2572  << " return *(bool*)m_parent->getAttribute(\""
2573  << attrS << "\");" << std::endl
2574  << "}" << std::endl << std::endl;
2575  }
2576  else if (typeS == "string")
2577  {
2578  hFile << "inline std::string " << tagS.simpleType()
2579  << "::" << getS << "() const {" << std::endl
2580  << " return *(const std::string*)m_parent->getAttribute(\""
2581  << attrS << "\");" << std::endl
2582  << "}" << std::endl << std::endl;
2583  }
2584  else if (typeS == "anyURI")
2585  {
2586  hFile << "inline std::string " << tagS.simpleType()
2587  << "::" << getS << "() const {" << std::endl
2588  << " return *(const std::string*)m_parent->getAttribute(\""
2589  << attrS << "\");" << std::endl
2590  << "}" << std::endl << std::endl;
2591  }
2592  else if (typeS == "Particle_t")
2593  {
2594  hFile << "inline Particle_t " << tagS.simpleType()
2595  << "::" << getS << "() const {" << std::endl
2596  << " return *(Particle_t*)m_parent->getAttribute(\""
2597  << attrS << "\");" << std::endl
2598  << "}" << std::endl << std::endl;
2599  }
2600  else if (guessType(typeS) == "int")
2601  {
2602  hFile << "inline int " << tagS.simpleType()
2603  << "::" << getS << "() const {" << std::endl
2604  << " return *(int*)m_parent->getAttribute(\""
2605  << attrS << "\");" << std::endl
2606  << "}" << std::endl << std::endl;
2607  }
2608  else if (guessType(typeS) == "long")
2609  {
2610  hFile << "inline int64_t " << tagS.simpleType()
2611  << "::" << getS << "() const {" << std::endl
2612  << " return *(long long int*)m_parent->getAttribute(\""
2613  << attrS << "\");" << std::endl
2614  << "}" << std::endl << std::endl;
2615  }
2616  else if (guessType(typeS) == "float")
2617  {
2618  hFile << "inline float " << tagS.simpleType()
2619  << "::" << getS << "() const {" << std::endl
2620  << " return *(float*)m_parent->getAttribute(\""
2621  << attrS << "\");" << std::endl
2622  << "}" << std::endl << std::endl;
2623  }
2624  else if (guessType(typeS) == "double")
2625  {
2626  hFile << "inline double " << tagS.simpleType()
2627  << "::" << getS << "() const {" << std::endl
2628  << " return *(double*)m_parent->getAttribute(\""
2629  << attrS << "\");" << std::endl
2630  << "}" << std::endl << std::endl;
2631  }
2632  else if (guessType(typeS) == "boolean")
2633  {
2634  hFile << "inline bool " << tagS.simpleType()
2635  << "::" << getS << "() const {" << std::endl
2636  << " return *(bool*)m_parent->getAttribute(\""
2637  << attrS << "\");" << std::endl
2638  << "}" << std::endl << std::endl;
2639  }
2640  else if (guessType(typeS) == "Particle_t")
2641  {
2642  hFile << "inline Particle_t " << tagS.simpleType()
2643  << "::" << getS << "() const {" << std::endl
2644  << " return *(Particle_t*)m_parent->getAttribute(\""
2645  << attrS << "\");" << std::endl
2646  << "}" << std::endl << std::endl;
2647  }
2648  else /* any attributes not of the above types are strings */
2649  {
2650  hFile << "inline std::string " << tagS.simpleType()
2651  << "::" << getS << "() const {" << std::endl
2652  << " return *(std::string*)m_parent->getAttribute(\""
2653  << attrS << "\");" << std::endl
2654  << "}" << std::endl << std::endl;
2655  }
2656  }
2657  }
2658 
2659  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2660  {
2661  XtString attrS(myAttr->item(n)->getNodeName());
2662  XtString typeS(el->getAttribute(X(attrS)));
2663  XtString getS("get" + attrS.simpleType());
2664  XtString setS("set" + attrS.simpleType());
2665  if (typeS == "int")
2666  {
2667  hFile << "inline int " << tagS.simpleType() << "::" << getS
2668  << "() const {" << std::endl
2669  << " return m_" << attrS << ";" << std::endl
2670  << "}" << std::endl << std::endl
2671  << "inline void " << tagS.simpleType() << "::" << setS
2672  << "(int " << attrS << ") {" << std::endl
2673  << " m_" << attrS << " = " << attrS << ";" << std::endl
2674  << "}" << std::endl << std::endl;
2675  }
2676  else if (typeS == "long")
2677  {
2678  hFile << "inline int64_t " << tagS.simpleType() << "::" << getS
2679  << "() const {" << std::endl
2680  << " return m_" << attrS << ";" << std::endl
2681  << "}" << std::endl << std::endl
2682  << "inline void " << tagS.simpleType() << "::" << setS
2683  << "(int64_t " << attrS << ") {" << std::endl
2684  << " m_" << attrS << " = " << attrS << ";" << std::endl
2685  << "}" << std::endl << std::endl;
2686  }
2687  else if (typeS == "float")
2688  {
2689  hFile << "inline float " << tagS.simpleType() << "::" << getS
2690  << "() const {" << std::endl
2691  << " return m_" << attrS << ";" << std::endl
2692  << "}" << std::endl << std::endl
2693  << "inline void " << tagS.simpleType() << "::" << setS
2694  << "(float " << attrS << ") {" << std::endl
2695  << " m_" << attrS << " = " << attrS << ";" << std::endl
2696  << "}" << std::endl << std::endl;
2697  }
2698  else if (typeS == "double")
2699  {
2700  hFile << "inline double " << tagS.simpleType() << "::" << getS
2701  << "() const {" << std::endl
2702  << " return m_" << attrS << ";" << std::endl
2703  << "}" << std::endl << std::endl
2704  << "inline void " << tagS.simpleType() << "::" << setS
2705  << "(double " << attrS << ") {" << std::endl
2706  << " m_" << attrS << " = " << attrS << ";" << std::endl
2707  << "}" << std::endl << std::endl;
2708  }
2709  else if (typeS == "boolean")
2710  {
2711  hFile << "inline bool " << tagS.simpleType() << "::" << getS
2712  << "() const {" << std::endl
2713  << " return m_" << attrS << ";" << std::endl
2714  << "}" << std::endl << std::endl
2715  << "inline void " << tagS.simpleType() << "::" << setS
2716  << "(bool " << attrS << ") {" << std::endl
2717  << " m_" << attrS << " = " << attrS << ";" << std::endl
2718  << "}" << std::endl << std::endl;
2719  }
2720  else if (typeS == "string")
2721  {
2722  hFile << "inline std::string " << tagS.simpleType() << "::" << getS
2723  << "() const {" << std::endl
2724  << " return m_" << attrS << ";" << std::endl
2725  << "}" << std::endl << std::endl
2726  << "inline void " << tagS.simpleType() << "::" << setS
2727  << "(const std::string &" << attrS << ") {" << std::endl
2728  << " m_" << attrS << " = " << attrS << ";" << std::endl
2729  << "}" << std::endl << std::endl;
2730  }
2731  else if (typeS == "anyURI")
2732  {
2733  hFile << "inline std::string " << tagS.simpleType() << "::" << getS
2734  << "() const {" << std::endl
2735  << " return m_" << attrS << ";" << std::endl
2736  << "}" << std::endl << std::endl
2737  << "inline void " << tagS.simpleType() << "::" << setS
2738  << "(const std::string &" << attrS << ") {" << std::endl
2739  << " m_" << attrS << " = " << attrS << ";" << std::endl
2740  << "}" << std::endl << std::endl;
2741  }
2742  else if (typeS == "Particle_t")
2743  {
2744  hFile << "inline Particle_t " << tagS.simpleType() << "::" << getS
2745  << "() const {" << std::endl
2746  << " return (Particle_t)m_" << attrS << ";" << std::endl
2747  << "}" << std::endl << std::endl
2748  << "inline void " << tagS.simpleType() << "::" << setS
2749  << "(Particle_t " << attrS << ") {" << std::endl
2750  << " m_" << attrS << " = " << attrS << ";" << std::endl
2751  << "}" << std::endl << std::endl;
2752  }
2753  else if (guessType(typeS) == "int")
2754  {
2755  hFile << "inline int " << tagS.simpleType() << "::" << getS
2756  << "() const {" << std::endl
2757  << " return " << typeS << ";" << std::endl
2758  << "}" << std::endl << std::endl;
2759  }
2760  else if (guessType(typeS) == "long")
2761  {
2762  hFile << "inline int64_t " << tagS.simpleType() << "::" << getS
2763  << "() const {" << std::endl
2764  << " return " << typeS << "LL;" << std::endl
2765  << "}" << std::endl << std::endl;
2766  }
2767  else if (guessType(typeS) == "float")
2768  {
2769  hFile << "inline float " << tagS.simpleType() << "::" << getS
2770  << "() const {" << std::endl
2771  << " return " << typeS << ";" << std::endl
2772  << "}" << std::endl << std::endl;
2773  }
2774  else if (guessType(typeS) == "double")
2775  {
2776  hFile << "inline double " << tagS.simpleType() << "::" << getS
2777  << "() const {" << std::endl
2778  << " return " << typeS << ";" << std::endl
2779  << "}" << std::endl << std::endl;
2780  }
2781  else if (guessType(typeS) == "boolean")
2782  {
2783  hFile << "inline bool " << tagS.simpleType() << "::" << getS
2784  << "() const {" << std::endl
2785  << " return " << typeS << ";" << std::endl
2786  << "}" << std::endl << std::endl;
2787  }
2788  else if (guessType(typeS) == "Particle_t")
2789  {
2790  hFile << "inline Particle_t " << tagS.simpleType()
2791  << "::" << getS << "() const {" << std::endl
2792  << " return (Particle_t)" << lookupParticle(typeS)
2793  << ";" << std::endl
2794  << "}" << std::endl << std::endl;
2795  }
2796  else /* anything not listed above is classed as a string */
2797  {
2798  hFile << "inline std::string " << tagS.simpleType()
2799  << "::" << getS << "() const {" << std::endl
2800  << " return \"" << typeS << "\";" << std::endl
2801  << "}" << std::endl << std::endl;
2802  }
2803  }
2804 
2805  if (tagS == "HDDM")
2806  {
2807  hFile << "inline void HDDM::clear() {" << std::endl;
2808  for (citer = children[tagS].begin();
2809  citer != children[tagS].end();
2810  ++citer)
2811  {
2812  DOMElement *childEl = (DOMElement*)(*citer);
2813  XtString cnameS(childEl->getTagName());
2814  hFile << " delete" << cnameS.simpleType().plural()
2815  << "();" << std::endl;
2816  }
2817  hFile << "}" << std::endl << std::endl;
2818  }
2819  hFile << "inline const void *" << tagS.simpleType()
2820  << "::getAttribute(const std::string &name,\n"
2821  << " "
2822  << "hddm_type *atype) const {" << std::endl;
2823  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2824  {
2825  XtString attrS(myAttr->item(n)->getNodeName());
2826  XtString typeS(el->getAttribute(X(attrS)));
2827  hFile << " if (name == \"" << attrS << "\") {\n"
2828  << " if (atype != 0)\n";
2829  if (typeS == "int")
2830  {
2831  hFile << " *atype = k_hddm_int;\n";
2832  }
2833  else if (typeS == "long")
2834  {
2835  hFile << " *atype = k_hddm_long;\n";
2836  }
2837  else if (typeS == "float")
2838  {
2839  hFile << " *atype = k_hddm_float;\n";
2840  }
2841  else if (typeS == "double")
2842  {
2843  hFile << " *atype = k_hddm_double;\n";
2844  }
2845  else if (typeS == "boolean")
2846  {
2847  hFile << " *atype = k_hddm_boolean;\n";
2848  }
2849  else if (typeS == "string")
2850  {
2851  hFile << " *atype = k_hddm_string;\n";
2852  }
2853  else if (typeS == "anyURI")
2854  {
2855  hFile << " *atype = k_hddm_anyURI;\n";
2856  }
2857  else if (typeS == "Particle_t")
2858  {
2859  hFile << " *atype = k_hddm_Particle_t;\n";
2860  }
2861  else if (guessType(typeS) == "int")
2862  {
2863  hFile << " *atype = k_hddm_int;\n"
2864  << " static int m_" << attrS
2865  << " = get" << attrS.simpleType() << "();\n";
2866  }
2867  else if (guessType(typeS) == "long")
2868  {
2869  hFile << " *atype = k_hddm_long;\n"
2870  << " static long m_" << attrS
2871  << " = get" << attrS.simpleType() << "();\n";
2872  }
2873  else if (guessType(typeS) == "float")
2874  {
2875  hFile << " *atype = k_hddm_float;\n"
2876  << " static float m_" << attrS
2877  << " = get" << attrS.simpleType() << "();\n";
2878  }
2879  else if (guessType(typeS) == "double")
2880  {
2881  hFile << " *atype = k_hddm_double;\n"
2882  << " static double m_" << attrS
2883  << " = get" << attrS.simpleType() << "();\n";
2884  }
2885  else if (guessType(typeS) == "boolean")
2886  {
2887  hFile << " *atype = k_hddm_boolean;\n"
2888  << " static int m_" << attrS
2889  << " = get" << attrS.simpleType() << "();\n";
2890  }
2891  else if (guessType(typeS) == "Particle_t")
2892  {
2893  hFile << " *atype = k_hddm_Particle_t;\n"
2894  << " static Particle_t m_" << attrS
2895  << " = get" << attrS.simpleType() << "();\n";
2896  }
2897  else
2898  {
2899  hFile << " *atype = k_hddm_unknown;\n"
2900  << " static std::string m_" << attrS
2901  << " = get" << attrS.simpleType() << "();\n";
2902  }
2903  hFile << " return &m_" << attrS << ";\n"
2904  << " }\n";
2905  }
2906  if (tagS != "HDDM")
2907  {
2908  hFile << " return m_parent->getAttribute(name, atype);" << std::endl;
2909  }
2910  else
2911  {
2912  hFile << " return 0;" << std::endl;
2913  }
2914  hFile << "}" << std::endl << std::endl;
2915 
2916  cFile << "std::string " << tagS.simpleType()
2917  << "::toString(int indent) {\n"
2918  << " std::stringstream ostr;\n"
2919  << " for (int n=0; n < indent; ++n)\n"
2920  << " ostr << \" \";\n"
2921  << " ostr << \"" << tagS << "\"\n";
2922  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2923  {
2924  XtString attrS(myAttr->item(n)->getNodeName());
2925  XtString typeS(el->getAttribute(X(attrS)));
2926  if (typeS == "int" || typeS == "long" ||
2927  typeS == "float" || typeS == "double")
2928  {
2929  cFile << " << \" " << attrS << "=\" << "
2930  << "m_" << attrS << std::endl;
2931  }
2932  else if (typeS == "boolean")
2933  {
2934  cFile << " << \" " << attrS << "=\" << "
2935  << "((m_" << attrS << " == 0)? \"true\" : \"false\")"
2936  << std::endl;
2937  }
2938  else if (typeS == "string" || typeS == "anyURI")
2939  {
2940  cFile << " << \" " << attrS << "=\" << "
2941  << "\"\\\"\" << m_" << attrS << " << \"\\\"\"" << std::endl;
2942  }
2943  else if (typeS == "Particle_t")
2944  {
2945  cFile << " << \" " << attrS << "=\" << "
2946  << "ParticleType((Particle_t)m_" << attrS << ")" << std::endl;
2947  }
2948  }
2949  cFile << " << std::endl;" << std::endl;
2950  for (citer = children[tagS].begin(); citer != children[tagS].end(); ++citer)
2951  {
2952  DOMElement *childEl = (DOMElement*)(*citer);
2953  XtString cnameS(childEl->getTagName());
2954  XtString repS(childEl->getAttribute(X("maxOccurs")));
2955  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
2956  if (rep > 1)
2957  {
2958  cFile << " int " << cnameS.listType() << "Count=0;" << std::endl
2959  << " for (" << cnameS.listType() << "::iterator it = "
2960  << "m_" << cnameS << "_list.begin();" << std::endl
2961  << " it != "
2962  << "m_" << cnameS << "_list.end(); ++it)" << std::endl
2963  << " {" << std::endl
2964  << " if (++" << cnameS.listType() << "Count > "
2965  << "m_" << cnameS << "_list.size()) {" << std::endl
2966  << " throw std::runtime_error(\"hddm_"
2967  << classPrefix << "::toString error - "
2968  "list improperly terminated!\");" << std::endl
2969  << " }" << std::endl
2970  << " ostr << it->toString(indent + 2);" << std::endl
2971  << " }" << std::endl;
2972  }
2973  else
2974  {
2975  cFile << " if (! m_" << cnameS << "_link.empty()) {\n"
2976  << " ostr << m_" << cnameS << "_link.begin()"
2977  << "->toString(indent + 2);\n"
2978  << " }" << std::endl;
2979  }
2980  }
2981  cFile << " return ostr.str();" << std::endl
2982  << "}" << std::endl << std::endl;
2983 
2984  cFile << "std::string " << tagS.simpleType()
2985  << "::toXML(int indent) {\n"
2986  << " std::stringstream ostr;\n"
2987  << " for (int n=0; n < indent; ++n)\n"
2988  << " ostr << \" \";\n"
2989  << " ostr << \"<" << tagS << "\"\n";
2990  for (unsigned int n = 0; n < myAttr->getLength(); n++)
2991  {
2992  XtString attrS(myAttr->item(n)->getNodeName());
2993  XtString typeS(el->getAttribute(X(attrS)));
2994  if (attrS == "minOccurs" || attrS == "maxOccurs")
2995  {
2996  continue;
2997  }
2998  if (typeS == "boolean")
2999  {
3000  cFile << " << \" " << attrS << "=\" << "
3001  << "((m_" << attrS << " == 0)? \"\\\"true\\\"\" : \"\\\"false\\\"\")"
3002  << std::endl;
3003  }
3004  else if (typeS == "Particle_t")
3005  {
3006  cFile << " << \" " << attrS << "=\\\"\" << "
3007  << "ParticleType((Particle_t)m_" << attrS << ") << \"\\\"\""
3008  << std::endl;
3009  }
3010  else
3011  {
3012  cFile << " << \" " << attrS << "=\" << "
3013  << "\"\\\"\" << get" << attrS.simpleType()
3014  << "() << \"\\\"\"" << std::endl;
3015  }
3016  }
3017  if (children[tagS].size() > 0)
3018  {
3019  cFile << " << \">\" << std::endl;" << std::endl;
3020  }
3021  else
3022  {
3023  cFile << " << \" />\" << std::endl;" << std::endl;
3024  }
3025  for (citer = children[tagS].begin(); citer != children[tagS].end(); ++citer)
3026  {
3027  DOMElement *childEl = (DOMElement*)(*citer);
3028  XtString cnameS(childEl->getTagName());
3029  XtString repS(childEl->getAttribute(X("maxOccurs")));
3030  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
3031  if (rep > 1)
3032  {
3033  cFile << " int " << cnameS.listType() << "Count=0;" << std::endl
3034  << " for (" << cnameS.listType() << "::iterator it = "
3035  << "m_" << cnameS << "_list.begin();" << std::endl
3036  << " it != "
3037  << "m_" << cnameS << "_list.end(); ++it)" << std::endl
3038  << " {" << std::endl
3039  << " if (++" << cnameS.listType() << "Count > "
3040  << "m_" << cnameS << "_list.size()) {" << std::endl
3041  << " throw std::runtime_error(\"hddm_"
3042  << classPrefix << "::toXML error - "
3043  "list improperly terminated!\");" << std::endl
3044  << " }" << std::endl
3045  << " ostr << it->toXML(indent + 2);" << std::endl
3046  << " }" << std::endl;
3047  }
3048  else
3049  {
3050  cFile << " if (! m_" << cnameS << "_link.empty()) {\n"
3051  << " ostr << m_" << cnameS << "_link.begin()"
3052  << "->toXML(indent + 2);" << std::endl
3053  << " }" << std::endl;
3054  }
3055  }
3056  if (children[tagS].size() > 0)
3057  {
3058  cFile << " for (int n=0; n < indent; ++n)\n"
3059  << " ostr << \" \";\n"
3060  << " ostr << \"</" << tagS << ">\"\n"
3061  << " << std::endl;" << std::endl;
3062  }
3063  cFile << " return ostr.str();" << std::endl
3064  << "}" << std::endl << std::endl;
3065 
3066  for (citer = children[tagS].begin(); citer != children[tagS].end(); ++citer)
3067  {
3068  DOMElement *childEl = (DOMElement*)(*citer);
3069  XtString cnameS(childEl->getTagName());
3070  XtString repS(childEl->getAttribute(X("maxOccurs")));
3071  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
3072  if (rep > 1)
3073  {
3074  hFile << "inline " << cnameS.simpleType() << " &"
3075  << tagS.simpleType() << "::get" << cnameS.simpleType()
3076  << "(int index) {" << std::endl
3077  << " return m_" << cnameS << "_list(index);" << std::endl
3078  << "}" << std::endl << std::endl
3079  << "inline " << cnameS.listType() << " &"
3080  << tagS.simpleType() << "::get" << cnameS.plural().simpleType()
3081  << "() {" << std::endl
3082  << " return m_" << cnameS << "_list;" << std::endl
3083  << "}" << std::endl << std::endl
3084  << "inline " << cnameS.listType() << " "
3085  << tagS.simpleType() << "::add" << cnameS.plural().simpleType()
3086  << "(int count, int start) {" << std::endl
3087  << " return m_" << cnameS << "_list.add(count,start);"
3088  << std::endl << "}" << std::endl << std::endl
3089  << "inline void " << tagS.simpleType() << "::delete"
3090  << cnameS.simpleType().plural()
3091  << "(int count, int start) {" << std::endl
3092  << " m_" << cnameS << "_list.del(count,start);"
3093  << std::endl << "}" << std::endl << std::endl;
3094  }
3095  else
3096  {
3097  hFile << "inline " << cnameS.simpleType() << " &"
3098  << tagS.simpleType() << "::get" << cnameS.simpleType()
3099  << "() {" << std::endl
3100  << " return m_" << cnameS << "_link.front();" << std::endl
3101  << "}" << std::endl << std::endl
3102  << "inline " << cnameS.listType() << " &"
3103  << tagS.simpleType() << "::get" << cnameS.plural().simpleType()
3104  << "() {" << std::endl
3105  << " return m_" << cnameS << "_link;" << std::endl
3106  << "}" << std::endl << std::endl
3107  << "inline " << cnameS.listType() << " "
3108  << tagS.simpleType() << "::add" << cnameS.plural().simpleType()
3109  << "(int count, int start) {" << std::endl
3110  << " return m_" << cnameS << "_link.add(count,start);"
3111  << std::endl << "}" << std::endl << std::endl
3112  << "inline void " << tagS.simpleType() << "::delete"
3113  << cnameS.simpleType().plural()
3114  << "(int count, int start) {" << std::endl
3115  << " m_" << cnameS << "_link.del(count,start);"
3116  << std::endl << "}" << std::endl << std::endl;
3117  }
3118  }
3119 
3120  if (tagS == "HDDM")
3121  {
3122  parentTable_t::iterator piter;
3123  for (piter = parents.begin(); piter != parents.end(); ++piter)
3124  {
3125  XtString cnameS(piter->first);
3126  if (cnameS != "HDDM" && element_in_list(cnameS,children[tagS]) == -1)
3127  {
3128  hFile << "inline " << cnameS.listType() << " "
3129  << "HDDM::get" << cnameS.plural().simpleType() << "() {"
3130  << std::endl << " return " << cnameS.listType()
3131  << "(&m_" << cnameS << "_plist," << std::endl
3132  << " "
3133  << "m_" << cnameS << "_plist.begin()," << std::endl
3134  << " "
3135  << "m_" << cnameS << "_plist.end());" << std::endl
3136  << "}" << std::endl << std::endl;
3137  }
3138  }
3139  }
3140 }
3141 
3142 /* Generate implementation code for data model classes */
3143 
3144 void CodeBuilder::constructMethods(DOMElement* el)
3145 {
3146  std::vector<DOMElement*>::iterator iter;
3147  for (iter = tagList.begin(); iter != tagList.end(); iter++)
3148  {
3149  writeClassimp(*iter);
3150  }
3151 }
3152 
3153 /* Generate methods for serializing classes to a stream and back again */
3154 
3155 void CodeBuilder::writeStreamers(DOMElement* el)
3156 {
3157  XtString tagS(el->getTagName());
3158 
3159  std::vector<XtString> attrV;
3160  DOMNamedNodeMap *myAttr = el->getAttributes();
3161  for (unsigned int n = 0; n < myAttr->getLength(); n++)
3162  {
3163  XtString attrS(myAttr->item(n)->getNodeName());
3164  XtString typeS(el->getAttribute(X(attrS)));
3165  if (typeS == "int" || typeS == "long" || typeS == "float" ||
3166  typeS == "double" || typeS == "boolean" || typeS == "string" ||
3167  typeS == "anyURI" || typeS == "Particle_t")
3168  {
3169  attrV.push_back(attrS);
3170  }
3171  }
3172 
3173  std::vector<XtString> contV;
3174  DOMNodeList* contList = el->getChildNodes();
3175  int contListLength = contList->getLength();
3176  for (int c = 0; c < contListLength; c++)
3177  {
3178  DOMNode* node = contList->item(c);
3179  if (node->getNodeType() == DOMNode::ELEMENT_NODE)
3180  {
3181  DOMElement *contEl = (DOMElement*)node;
3182  XtString contS(contEl->getTagName());
3183  XtString repS(contEl->getAttribute(X("maxOccurs")));
3184  int rep = (repS == "unbounded")? INT_MAX : atoi(S(repS));
3185  contV.push_back(contS + ((rep > 1)? "_list" : "_link"));
3186  }
3187  }
3188 
3189  hFile << "inline void " << tagS.simpleType() << "::streamer"
3190  << "(istream &istr) {" << std::endl;
3191  if (attrV.size()) {
3192  hFile << " *istr.getXDRistream()";
3193  for (unsigned int n=0; n < attrV.size(); ++n)
3194  {
3195  hFile << " >> m_" << attrV[n];
3196  }
3197  hFile << ";" << std::endl;
3198  }
3199  if (contV.size()) {
3200  hFile << " istr";
3201  for (unsigned int n=0; n < contV.size(); ++n)
3202  {
3203  hFile << " >> m_" << contV[n];
3204  }
3205  hFile << ";" << std::endl;
3206  }
3207  hFile << "}" << std::endl << std::endl;
3208 
3209  hFile << "inline void " << tagS.simpleType() << "::streamer"
3210  << "(ostream &ostr) {" << std::endl;
3211  if (attrV.size()) {
3212  hFile << " *ostr.getXDRostream()";
3213  for (unsigned int n=0; n < attrV.size(); ++n)
3214  {
3215  hFile << " << m_" << attrV[n];
3216  }
3217  hFile << ";" << std::endl;
3218  }
3219  if (contV.size()) {
3220  hFile << " ostr";
3221  for (unsigned int n=0; n < contV.size(); ++n)
3222  {
3223  hFile << " << m_" << contV[n];
3224  }
3225  hFile << ";" << std::endl;
3226  }
3227  hFile << "}" << std::endl << std::endl;
3228 }
3229 
3231 {
3232  std::vector<DOMElement*>::iterator iter;
3233  for (iter = tagList.begin(); iter != tagList.end(); ++iter)
3234  {
3235  writeStreamers(*iter);
3236  }
3237 }
3238 
3239 /* Generate methods to read from binary stream into classes */
3240 
3242 {
3243  hFile <<
3244  "inline istream::thread_private_data *istream::lookup_private_data() {\n"
3245  " thread_private_data *my_private = my_thread_private[threads::getID()];\n"
3246  " if (my_private != 0)\n"
3247  " return my_private;\n"
3248  " init_private_data();\n"
3249  " return my_thread_private[threads::ID];\n"
3250  "}\n"
3251  "\n"
3252  "inline ostream::thread_private_data *ostream::lookup_private_data() {\n"
3253  " thread_private_data *my_private = my_thread_private[threads::getID()];\n"
3254  " if (my_private != 0)\n"
3255  " return my_private;\n"
3256  " init_private_data();\n"
3257  " return my_thread_private[threads::ID];\n"
3258  "}\n"
3259  "\n"
3260  "inline void istream::skip(int count) {\n"
3261  " MY_SETUP\n"
3262  " MY(events_to_skip) = count;\n"
3263  "}\n"
3264  "\n"
3265  "inline bool istream::eof() {\n"
3266  " MY_SETUP\n"
3267  " return MY(hit_eof);\n"
3268  "}\n"
3269  "\n"
3270  "inline bool istream::operator!() {\n"
3271  " return eof();\n"
3272  "}\n"
3273  "\n"
3274  "inline istream::operator void*() {\n"
3275  " MY_SETUP\n"
3276  " if (MY(hit_eof))\n"
3277  " return NULL;\n"
3278  " else\n"
3279  " return this;\n"
3280  "}\n"
3281  "\n"
3282  "inline int istream::getCompression() const {\n"
3283  " return (int)m_status_bits & k_bits_compression;\n"
3284  "}\n"
3285  "\n"
3286  "inline int ostream::getCompression() const {\n"
3287  " return (int)m_status_bits & k_bits_compression;\n"
3288  "}\n"
3289  "\n"
3290  "inline int istream::getIntegrityChecks() const {\n"
3291  " return (int)m_status_bits & k_bits_integrity;\n"
3292  "}\n"
3293  "\n"
3294  "inline int istream::getBytesRead() const {\n"
3295  " int bytes = 0;\n"
3296  " for (int i=1; i < threads::max_threads; ++i)\n"
3297  " if (my_thread_private[i])\n"
3298  " bytes += my_thread_private[i]->m_bytes_read;\n"
3299  " return bytes;\n"
3300  "}\n"
3301  "\n"
3302  "inline int istream::getRecordsRead() const {\n"
3303  " int records = 0;\n"
3304  " for (int i=1; i < threads::max_threads; ++i)\n"
3305  " if (my_thread_private[i])\n"
3306  " records += my_thread_private[i]->m_records_read;\n"
3307  " return records;\n"
3308  "}\n"
3309  "\n"
3310  "inline int ostream::getIntegrityChecks() const {\n"
3311  " return (int)m_status_bits & k_bits_integrity;\n"
3312  "}\n"
3313  "\n"
3314  "inline int ostream::getBytesWritten() const {\n"
3315  " int bytes = 0;\n"
3316  " for (int i=1; i < threads::max_threads; ++i)\n"
3317  " if (my_thread_private[i])\n"
3318  " bytes += my_thread_private[i]->m_bytes_written;\n"
3319  " return bytes;\n"
3320  "}\n"
3321  "\n"
3322  "inline int ostream::getRecordsWritten() const {\n"
3323  " int records = 0;\n"
3324  " for (int i=1; i < threads::max_threads; ++i)\n"
3325  " if (my_thread_private[i])\n"
3326  " records += my_thread_private[i]->m_records_written;\n"
3327  " return records;\n"
3328  "}\n"
3329  "\n"
3330  "inline istream &istream::operator>>(streamable &object) {\n"
3331  " MY_SETUP\n"
3332  " if (MY(sequencing)) {\n"
3333  " MY(codon)->m_target.push_back(&object);\n"
3334  " }\n"
3335  " else {\n"
3336  " int size;\n"
3337  " *MY(xstr) >> size;\n"
3338  " if (size > 0) {\n"
3339  " std::streampos start = MY(sbuf)->tellg();\n"
3340  " sequencer(object);\n"
3341  " MY(sbuf)->seekg(start+(std::streamoff)size);\n"
3342  " }\n"
3343  " }\n"
3344  " return *this;\n"
3345  "}\n"
3346  "\n"
3347  "inline void istream::reset_sequencer() {\n"
3348  " MY_SETUP\n"
3349  " MY(sequencing) = 0;\n"
3350  "}\n"
3351  "\n"
3352  "inline void istream::sequencer(streamable &object) {\n"
3353  " MY_SETUP\n"
3354  " MY(sequencing) = 1;\n"
3355  " MY(codon)->m_target.clear();\n"
3356  " object.streamer(*this);\n"
3357  " if (MY(sequencing)) {\n"
3358  " MY(sequencing) = 0;\n"
3359  " codon &gene = *MY(codon);\n"
3360  " streamable null_streamable;\n"
3361  " gene.m_target.push_front(&null_streamable);\n"
3362  " chromosome::iterator iter;\n"
3363  " for (iter = gene.m_sequence.begin();\n"
3364  " iter != gene.m_sequence.end();\n"
3365  " ++iter)\n"
3366  " {\n"
3367  " MY(codon) = &(*iter);\n"
3368  " *this >> *gene.m_target[iter->m_order];\n"
3369  " }\n"
3370  " MY(codon) = &gene;\n"
3371  " }\n"
3372  "}\n"
3373  "\n"
3374  "inline ostream &ostream::operator<<(HDDM &record) {\n"
3375  " MY_SETUP\n"
3376  " MY(sbuf)->reset();\n"
3377  " *this << (streamable&)record;\n"
3378  " while (MY(sbuf)->size() == MY(event_buffer_size)) {\n"
3379  " delete MY(xstr);\n"
3380  " delete MY(sbuf);\n"
3381  " char *newbuf = new char[MY(event_buffer_size) *= 2];\n"
3382  " MY(sbuf) = new ostreambuffer(newbuf, MY(event_buffer_size));\n"
3383  " MY(xstr) = new xstream::xdr::ostream(MY(sbuf));\n"
3384  " delete [] MY(event_buffer);\n"
3385  " MY(event_buffer) = newbuf;\n"
3386  " *this << (streamable&)record;\n"
3387  " }\n"
3388  " lock_streambufs();\n"
3389  " update_streambufs();\n"
3390  " if ((MY(status_bits) & k_crc32_integrity) != 0) {\n"
3391  " xstream::digest::crc32 crc;\n"
3392  " std::ostream out(&crc);\n"
3393  " out.write(MY(sbuf)->getbuf(),MY(sbuf)->size());\n"
3394  " out.flush();\n"
3395  " unsigned int crc32 = crc.digest();\n"
3396  " *MY(xstr) << crc32;\n"
3397  " }\n"
3398  " MY(ostr)->write(MY(sbuf)->getbuf(),MY(sbuf)->size());\n"
3399  " if (!MY(ostr)->good()) {\n"
3400  " unlock_streambufs();\n"
3401  " throw std::runtime_error(\"hddm_"
3402  << classPrefix << "::ostream::operator<< error - \"\n"
3403  " \"write error on event output!\");\n"
3404  " }\n"
3405  " if (MY(status_bits) & k_bz2_compression) {\n"
3406  " MY(last_start) = ((xstream::bz::ostreambuf*)MY(xcmp))->get_block_start();\n"
3407  " MY(last_offset) = ((xstream::bz::ostreambuf*)MY(xcmp))->get_block_offset();\n"
3408  " }\n"
3409  " else if (MY(status_bits) & k_z_compression) {\n"
3410  " MY(last_start) = ((xstream::z::ostreambuf*)MY(xcmp))->get_block_start();\n"
3411  " MY(last_offset) = ((xstream::z::ostreambuf*)MY(xcmp))->get_block_offset();\n"
3412  " }\n"
3413  " else {\n"
3414  " MY(last_start) = m_ostr.tellp();\n"
3415  " MY(last_offset) = 0;\n"
3416  " }\n"
3417  " unlock_streambufs();\n"
3418  " MY(bytes_written) += MY(sbuf)->size();\n"
3419  " MY(records_written)++;\n"
3420  " return *this;\n"
3421  "}\n"
3422  "\n"
3423  "inline ostream &ostream::operator<<(streamable &object) {\n"
3424  " MY_SETUP\n"
3425  " *MY(xstr) << 0;\n"
3426  " std::streampos start = MY(sbuf)->tellp();\n"
3427  " object.streamer(*this);\n"
3428  " std::streampos end = MY(sbuf)->tellp();\n"
3429  " MY(sbuf)->seekp(start-std::streamoff(4));\n"
3430  " *MY(xstr) << (int)(end-start);\n"
3431  " MY(sbuf)->seekp(end);\n"
3432  " return *this;\n"
3433  "}\n\n"
3434  ;
3435 }
3436 
3437 /* Generate the xml template in normal form and store in a string */
3438 
3439 void CodeBuilder::constructDocument(DOMElement* el)
3440 {
3441  static int indent = 0;
3442  hFile << "\"";
3443  for (int n = 0; n < indent; n++)
3444  {
3445  hFile << " ";
3446  }
3447 
3448  XtString tagS(el->getTagName());
3449  hFile << "<" << tagS;
3450  DOMNamedNodeMap* attrList = el->getAttributes();
3451  int attrListLength = attrList->getLength();
3452  for (int a = 0; a < attrListLength; a++)
3453  {
3454  DOMNode* node = attrList->item(a);
3455  XtString nameS(node->getNodeName());
3456  XtString valueS(node->getNodeValue());
3457  hFile << " " << nameS << "=\\\"" << valueS << "\\\"";
3458  }
3459 
3460  DOMNodeList* contList = el->getChildNodes();
3461  int contListLength = contList->getLength();
3462  if (contListLength > 0)
3463  {
3464  hFile << ">\\n\"" << std::endl;
3465  indent++;
3466  for (int c = 0; c < contListLength; c++)
3467  {
3468  DOMNode* node = contList->item(c);
3469  if (node->getNodeType() == DOMNode::ELEMENT_NODE)
3470  {
3471  DOMElement* contEl = (DOMElement*) node;
3472  constructDocument(contEl);
3473  }
3474  }
3475  indent--;
3476  hFile << "\"";
3477  for (int n = 0; n < indent; n++)
3478  {
3479  hFile << " ";
3480  }
3481  hFile << "</" << tagS << ">\\n\"" << std::endl;
3482  }
3483  else
3484  {
3485  hFile << " />\\n\"" << std::endl;
3486  }
3487 }
3488 
3490 {
3491  const char *str = literal.c_str();
3492  char *endptr;
3493  errno=0;
3494  long long int llvalue = strtoll(str,&endptr,0);
3495  if (errno == 0 && *endptr == 0) {
3496  errno=0;
3497  int lvalue = strtol(str,&endptr,0);
3498  if (errno == 0 && *endptr == 0 && lvalue == llvalue) {
3499  return "int";
3500  }
3501  else {
3502  return "long";
3503  }
3504  }
3505  errno=0;
3506  strtof(str,&endptr);
3507  if (errno == 0 && *endptr == 0) {
3508  return "float";
3509  }
3510  errno=0;
3511  strtod(str,&endptr);
3512  if (errno == 0 && *endptr == 0) {
3513  return "double";
3514  }
3515  if (literal == "true" || literal == "false") {
3516  return "boolean";
3517  }
3518  if ((int)lookupParticle(literal) != 0) {
3519  return "Particle_t";
3520  }
3521  if (XMLUri::isValidURI(false,X(literal))) {
3522  return "anyURI";
3523  }
3524  return "string";
3525 }
3526 
3528 {
3529  for (int p=0; p<100; ++p) {
3530  if (ParticleType((Particle_t)p) == name) {
3531  return (Particle_t)p;
3532  }
3533  }
3534  return Unknown;
3535 }
int element_in_list(XtString &name, parentList_t list)
Definition: hddm-cpp.cpp:1891
void constructGroup(DOMElement *el)
Definition: hddm-c.cpp:804
#define S(str)
Definition: hddm-cpp.cpp:84
std::string guessType(const std::string &literal)
Definition: hddm-cpp.cpp:3489
parentTable_t parents
Definition: hddm-cpp.cpp:151
char str[256]
XString classPrefix
Definition: hddm-c.cpp:88
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
char string[256]
#define c
xercesc::DOMDocument * buildDOMDocument(const XString &xmlFile, bool keep)
Definition: XParsers.cpp:142
parentTable_t children
Definition: hddm-cpp.cpp:152
void constructIOstreams(DOMElement *el)
Definition: hddm-cpp.cpp:3241
void checkConsistency(DOMElement *el, DOMElement *elref)
Definition: hddm-c.cpp:598
std::ofstream cFile
Definition: hddm-c.cpp:126
XtString(const XString &x)
Definition: hddm-cpp.cpp:114
void usage()
Definition: t_rest.cxx:114
void writeStreamers(DOMElement *el)
Definition: hddm-cpp.cpp:3155
static char * ParticleType(Particle_t p)
Definition: particleType.h:142
XtString(const XMLCh *p)
Definition: hddm-cpp.cpp:112
xercesc::DOMDocument * parseInputDocument(const XString &xmlFile, bool keep)
Definition: XParsers.cpp:73
std::ofstream hFile
Definition: hddm-c.cpp:125
XtString simpleType()
Definition: hddm-c.cpp:576
std::vector< DOMNode * > parentList_t
Definition: hddm-cpp.cpp:148
XtString(const XtString &t)
Definition: hddm-cpp.cpp:115
XtString plural()
Definition: hddm-c.cpp:542
XtString listType()
Definition: hddm-c.cpp:587
void constructDocument(DOMElement *el)
Definition: hddm-c.cpp:2033
Particle_t lookupParticle(const std::string &name)
Definition: hddm-cpp.cpp:3527
XtString linkType()
Definition: hddm-cpp.cpp:1879
XtString(const char *s)
Definition: hddm-cpp.cpp:111
parentList_t parentList
Definition: hddm-cpp.cpp:150
void writeClassimp(DOMElement *el)
Definition: hddm-cpp.cpp:2388
void constructMethods(DOMElement *el)
Definition: hddm-cpp.cpp:3144
XtString(const std::string &s)
Definition: hddm-cpp.cpp:113
void writeClassdef(DOMElement *el)
Definition: hddm-cpp.cpp:2016
std::map< const XtString, parentList_t > parentTable_t
Definition: hddm-cpp.cpp:149
#define X(str)
Definition: hddm-cpp.cpp:83
int main(int argc, char *argv[])
Definition: gendoc.cc:6
void constructStreamers(DOMElement *el)
Definition: hddm-cpp.cpp:3230
Particle_t
Definition: particleType.h:12