diff --git a/DDCore/include/DD4hep/Factories.h b/DDCore/include/DD4hep/Factories.h index aab050570e9d5fd30a1faa1c7abcd05c846371e2..ce5d53dc98ff18b6b525ded7285c8bc54478b445 100644 --- a/DDCore/include/DD4hep/Factories.h +++ b/DDCore/include/DD4hep/Factories.h @@ -38,6 +38,10 @@ namespace DD4hep { struct SensitiveDetector; struct DetElement; + template <typename T> class ConstructionFactory { + public: static void* create(const char* arg); + }; + /** @class TranslationFactory Factories.h DDCore/Factories.h * Specialized factory to translate objects, which can be retrieved from LCDD * Example: Translate DD4hep geometry to Geant4 @@ -117,6 +121,12 @@ namespace DD4hep { namespace { + template < typename P > class Factory<P, void*(const char*)> { + public: + static void Func(void *ret, void*, const std::vector<void*>& arg, void*) + { *(void**)ret=DD4hep::Geometry::ConstructionFactory<P>::create((const char*)arg[0]); } + }; + template < typename P > class Factory<P, TNamed*(DD4hep::Geometry::LCDD*)> { public: typedef DD4hep::Geometry::LCDD LCDD; @@ -201,6 +211,11 @@ namespace { using DD4hep::Geometry::name;\ DECLARE_NAMED_APPLY_FACTORY(DD4hep::Geometry,name) +#define DECLARE_CONSTRUCTOR(name,func) \ + namespace DD4hep { namespace Geometry { namespace { struct name {}; } \ + template <> void* ConstructionFactory<name>::create(const char* n) { return func(n);}}} \ + PLUGINSVC_FACTORY_WITH_ID(name,std::string(#name),void*(const char*)) + #define DECLARE_TRANSLATION(name,func) \ namespace DD4hep { namespace Geometry { namespace { struct name {}; } \ template <> DD4hep::Geometry::Ref_t TranslationFactory<name>::create(DD4hep::Geometry::LCDD& l) {return func(l);} }} \ diff --git a/DDCore/include/XML/DocumentHandler.h b/DDCore/include/XML/DocumentHandler.h index 65bb19852c9a23387872b950215dd373a3e7807a..85c038d6721618313c476fa188aa6c77ad556840 100644 --- a/DDCore/include/XML/DocumentHandler.h +++ b/DDCore/include/XML/DocumentHandler.h @@ -47,6 +47,8 @@ namespace DD4hep { virtual Document load(Handle_t base, const XmlChar* fname) const; /// Parse a standalong XML string into a document. virtual Document parse(const char* doc_string, size_t length) const; + /// Write xml document to output file (stdout if file name empty) + virtual int output(Document doc, const std::string& fname) const; }; } } /* End namespace DD4hep */ diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h index 5cb194c7d2c9a48ea145592746d2dfd15dfa1d4e..f4775fd809ed0122e30a45b48185bc043d3a417a 100644 --- a/DDCore/include/XML/XMLElements.h +++ b/DDCore/include/XML/XMLElements.h @@ -35,8 +35,6 @@ namespace DD4hep { typedef const XmlAttr* Attribute; - -#ifdef __TIXML__ /** XmlString XMLElements.h XML/XMLElements.h * * Definition of the XmlString class. @@ -54,8 +52,15 @@ namespace DD4hep { /// Transcode string static XmlChar* transcode(const char* c); /// Release string + static void release(char** p); +#ifndef __TIXML__ + static char* transcode(const XmlChar* c); + /// Release string static void release(XmlChar** p); +#endif }; + +#ifdef __TIXML__ /** XmlException XMLElements.h XML/XMLElements.h * * Definition of the XmlException class. @@ -294,27 +299,19 @@ namespace DD4hep { Elt_t ptr() const { return m_node; } /// Clone the DOMelement - with the option of a deep copy Handle_t clone(XmlDocument* new_doc) const; -#ifndef __TIXML__ - /// Unicode text access to the element's tag - const XmlChar* rawTag() const { return m_node->getTagName(); } - /// Unicode text access to the element's text - const XmlChar* rawText() const { return m_node->getTextContent(); } - /// Unicode text access to the element's value - const XmlChar* rawValue() const { return m_node->getNodeValue(); } -#else + /// Unicode text access to the element's tag. Tis must be wrong .... - const XmlChar* rawTag() const { return m_node->Value(); } + const XmlChar* rawTag() const; /// Unicode text access to the element's text - const XmlChar* rawText() const { return m_node->GetText(); } + const XmlChar* rawText() const; /// Unicode text access to the element's value - const XmlChar* rawValue() const { return m_node->Value(); } -#endif + const XmlChar* rawValue() const; /// Text access to the element's tag - std::string tag() const { return _toString(rawTag()); } + std::string tag() const { return _toString(rawTag()); } /// Text access to the element's text - std::string text() const { return _toString(rawText()); } + std::string text() const { return _toString(rawText()); } /// Text access to the element's value - std::string value() const { return _toString(rawValue()); } + std::string value() const { return _toString(rawValue()); } /// Set the element's value void setValue(const XmlChar* text) const; /// Set the element's value @@ -454,10 +451,10 @@ namespace DD4hep { NodeList m_children; #ifndef __TIXML__ /// Constructor over XmlElements with a given tag name - Collection_t(Elt_t node, const XmlChar* tag); + Collection_t(Handle_t node, const XmlChar* tag); #endif /// Constructor over XmlElements with a given tag name - Collection_t(Elt_t node, const char* tag); + Collection_t(Handle_t node, const char* tag); /// Constructor over XmlElements in a node list Collection_t(NodeList children); /// Reset the collection object to restart the iteration diff --git a/DDCore/include/XML/config.h b/DDCore/include/XML/config.h index 40f146373a7143a86d8b968c17c4a9336f48e6b4..d9ae580e39f88699db822b0086678c29cabd832a 100644 --- a/DDCore/include/XML/config.h +++ b/DDCore/include/XML/config.h @@ -9,23 +9,26 @@ #ifndef DD4HEP_XML_CONFIG_H #define DD4HEP_XML_CONFIG_H -#define __TIXML__ +#define __TIXML__ #ifndef __TIXML__ -/* Setup XML parsing for the use of XercesC +/* Setup XML parsing for the use of Apache Xerces-C * * @author M.Frank */ -#include "xercesc/util/XMLString.hpp" -#include "xercesc/dom/DOMElement.hpp" -#include "xercesc/dom/DOMDocument.hpp" -#include "xercesc/dom/DOMNodeList.hpp" #include "xercesc/dom/DOMException.hpp" +XERCES_CPP_NAMESPACE_BEGIN + class DOMElement; + class DOMDocument; + class DOMNodeList; + class DOMNode; + class DOMAttr; + class DOMException; +XERCES_CPP_NAMESPACE_END namespace DD4hep { namespace XML { typedef XMLSize_t XmlSize_t; typedef XMLCh XmlChar; - typedef xercesc::XMLString XmlString; typedef xercesc::DOMElement XmlElement; typedef xercesc::DOMDocument XmlDocument; typedef xercesc::DOMNodeList XmlNodeList; @@ -33,15 +36,20 @@ namespace DD4hep { namespace XML { typedef xercesc::DOMAttr XmlAttr; typedef xercesc::DOMException XmlException; }} +#define XML_IMPLEMENTATION_TYPE " Apache Xerces-C DOM Parser" +#define XML_HEADER_DECLARATION #else // __TIXML__ +#include <cstdlib> /* Setup XML parsing for the use of TiXml * * @author M.Frank */ -#include "XML/tinyxml.h" -//#error("using tixml") +class TiXmlElement; +class TiXmlDocument; +class TiXmlNode; +class TiXmlAttribute; namespace DD4hep { namespace XML { typedef std::size_t XmlSize_t; typedef char XmlChar; @@ -51,5 +59,8 @@ namespace DD4hep { namespace XML { typedef TiXmlNode XmlNode; typedef TiXmlAttribute XmlAttr; }} +#define XML_IMPLEMENTATION_TYPE " TinyXML DOM mini-parser " +#define XML_HEADER_DECLARATION "<?xml version=\"1.0\" encoding=\"UTF-8\">\n" #endif // __TIXML__ + #endif // DD4HEP_XML_CONFIG_H diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp index 22fe70b778082aa64bbb593b6b1208cc16fef362..f5a3b3ab4b967772ea6190a9e025776b0d08d50f 100644 --- a/DDCore/src/LCDDImp.cpp +++ b/DDCore/src/LCDDImp.cpp @@ -260,7 +260,7 @@ void LCDDImp::fromXML(const string& xmlfile, LCDDBuildType build_type) { } catch(...) { cout << "UNKNOWN Exception" << endl; - throw runtime_error("UNKNOWN excetion while parsing "+xmlfile); + throw runtime_error("UNKNOWN exception while parsing "+xmlfile); } #endif } @@ -291,6 +291,6 @@ void LCDDImp::apply(const char* factory_type, int argc, char** argv) { } catch(...) { cout << "UNKNOWN Exception" << endl; - throw runtime_error("UNKNOWN excetion from plugin:"+fac); + throw runtime_error("UNKNOWN exception from plugin:"+fac); } } diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp index 75d30e722b2dbacf0d735909906919524af1e320..eb5492f1ef9f6e370aed539db739756641fb62e1 100644 --- a/DDCore/src/XML/DocumentHandler.cpp +++ b/DDCore/src/XML/DocumentHandler.cpp @@ -27,11 +27,13 @@ using namespace xercesc; namespace { - XercesDOMParser* make_parser(xercesc::ErrorHandler* err_handler) { + XercesDOMParser* make_parser(xercesc::ErrorHandler* err_handler=0) { XercesDOMParser* parser = new XercesDOMParser; parser->setValidationScheme(XercesDOMParser::Val_Auto); parser->setValidationSchemaFullChecking(true); - parser->setErrorHandler(err_handler); + if ( err_handler ) { + parser->setErrorHandler(err_handler); + } parser->setDoNamespaces(true); parser->setDoSchema(true); return parser; @@ -168,7 +170,7 @@ Document DocumentHandler::load(const string& fname) const { /// Parse a standalong XML string into a document. Document DocumentHandler::parse(const char* bytes, size_t length) const { - auto_ptr<XercesDOMParser> parser(makeParser()); + auto_ptr<XercesDOMParser> parser(make_parser(m_errHdlr.get())); MemBufInputSource src((const XMLByte*)bytes,length,"memory"); parser->setValidationSchemaFullChecking(true); parser->parse(src); @@ -178,11 +180,29 @@ Document DocumentHandler::parse(const char* bytes, size_t length) const { return doc; } +/// Write xml document to output file (stdout if file name empty) +int DocumentHandler::output(Document doc, const std::string& fname) const { + XMLFormatTarget *tar = 0; + DOMImplementation *imp = DOMImplementationRegistry::getDOMImplementation(Strng_t("LS")); + DOMLSOutput *out = imp->createLSOutput(); + DOMLSSerializer *wrt = imp->createLSSerializer(); + + if ( fname.empty() ) tar = new StdOutFormatTarget(); + else tar = new LocalFileFormatTarget(Strng_t(fname)); + + out->setByteStream(tar); + wrt->getDomConfig()->setParameter(Strng_t("format-pretty-print"), true); + wrt->write(doc, out); + out->release(); + wrt->release(); + delete tar; + return 1; +} #else -#ifdef _WIN32 -#include <cstdlib> -#else + +#include "XML/tinyxml.h" +#ifndef _WIN32 #include <libgen.h> #endif #include <sys/stat.h> @@ -283,4 +303,16 @@ Document DocumentHandler::parse(const char* doc_string, size_t length) const { return 0; } +/// Write xml document to output file (stdout if file name empty) +int DocumentHandler::output(Document doc, const std::string& fname) const { + FILE* file = fname.empty() ? stdout : ::fopen(fname.c_str(),"w"); + if ( !file ) { + cout << "Failed to open output file:" << fname << endl; + return 0; + } + doc->Print(file); + if ( !fname.empty() ) ::fclose(file); + return 1; +} + #endif diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp index ecfefdcac5b1695d5fd161885a13416a1ef6559c..f9f4918675ba1e0ed905d5a42c15bdb948abeec2 100644 --- a/DDCore/src/XML/XMLElements.cpp +++ b/DDCore/src/XML/XMLElements.cpp @@ -6,15 +6,25 @@ // Author : M.Frank // //==================================================================== - // Framework include files #include "XML/XMLElements.h" + +#ifdef __TIXML__ +#include "XML/tinyxml.h" +#else +#include "xercesc/util/XMLString.hpp" +#include "xercesc/dom/DOMElement.hpp" +#include "xercesc/dom/DOMDocument.hpp" +#include "xercesc/dom/DOMNodeList.hpp" +#endif + #include "XML/Evaluator.h" #include "XML/XMLTags.h" // C/C++ include files #include <iostream> #include <stdexcept> +#include <cstdio> #include <map> using namespace std; @@ -46,10 +56,16 @@ namespace { } XmlChar* DD4hep::XML::XmlString::replicate(const XmlChar* c) { return c ? ::strdup(c) : 0; } XmlChar* DD4hep::XML::XmlString::transcode(const char* c) { return c ? ::strdup(c) : 0; } -void DD4hep::XML::XmlString::release(XmlChar** p) { if(p && *p) { ::free(*p); *p=0;} } +void DD4hep::XML::XmlString::release(char** p) { if(p && *p) { ::free(*p); *p=0;} } #else +XmlChar* DD4hep::XML::XmlString::replicate(const XmlChar* c) { return xercesc::XMLString::replicate(c); } +char* DD4hep::XML::XmlString::transcode(const XmlChar* c) { return xercesc::XMLString::transcode(c); } +XmlChar* DD4hep::XML::XmlString::transcode(const char* c) { return xercesc::XMLString::transcode(c); } +void DD4hep::XML::XmlString::release(XmlChar** p) { return xercesc::XMLString::release(p); } +void DD4hep::XML::XmlString::release(char** p) { return xercesc::XMLString::release(p); } + #define ELEMENT_NODE_TYPE XmlNode::ELEMENT_NODE #include "xercesc/dom/DOM.hpp" namespace { @@ -356,6 +372,33 @@ NodeList& NodeList::operator=(const NodeList& l) { return *this; } +/// Unicode text access to the element's tag. Tis must be wrong .... +const XmlChar* Handle_t::rawTag() const { +#ifdef __TIXML__ + return m_node->Value(); +#else + return m_node->getTagName(); +#endif +} + +/// Unicode text access to the element's text +const XmlChar* Handle_t::rawText() const { +#ifdef __TIXML__ + return m_node->GetText(); +#else + return m_node->getTextContent(); +#endif +} + +/// Unicode text access to the element's value +const XmlChar* Handle_t::rawValue() const { +#ifdef __TIXML__ + return m_node->Value(); +#else + return m_node->getNodeValue(); +#endif +} + /// Clone the DOMelement - with the option of a deep copy Handle_t Handle_t::clone(XmlDocument* new_doc) const { if ( m_node ) { @@ -499,7 +542,7 @@ void Handle_t::setValue(const string& text) const { #ifdef __TIXML__ m_node->SetValue(text.c_str()); #else - m_node->setNodeValue(Strng(text)); + m_node->setNodeValue(Strng_t(text)); #endif } @@ -508,7 +551,7 @@ void Handle_t::setText(const XmlChar* text) const { #ifdef __TIXML__ m_node->LinkEndChild(new TiXmlText(text)); #else - m_node->setNodeText(text); + m_node->setTextContent(text); #endif } @@ -517,7 +560,7 @@ void Handle_t::setText(const string& text) const { #ifdef __TIXML__ m_node->LinkEndChild(new TiXmlText(text.c_str())); #else - m_node->setNodeText(Strng(text)); + m_node->setTextContent(Strng_t(text)); #endif } @@ -849,14 +892,14 @@ void RefElement::setName(const XmlChar* new_name) { } #ifndef __TIXML__ -Collection_t::Collection_t(Elt_t element, const XmlChar* tag) +Collection_t::Collection_t(Handle_t element, const XmlChar* tag) : m_children(element,tag) { m_node = m_children.reset(); } #endif -Collection_t::Collection_t(Elt_t element, const char* tag) +Collection_t::Collection_t(Handle_t element, const char* tag) : m_children(element,Strng_t(tag)) { m_node = m_children.reset(); @@ -911,7 +954,8 @@ Handle_t Document::clone(Handle_t source) const { #ifdef __TIXML__ return (XmlElement*)source.clone(0); #else - return (XmlElement*)(m_doc->importNode(source)); + + return (XmlElement*)(m_doc->importNode(source.ptr(),true)); #endif } diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp index 9ded4a55b2ebcff805fcdbe0b4f97a6ce9bcd4b1..188eaa8f0562c256f71dcb169d369d477d5992bd 100644 --- a/DDCore/src/plugins/LCDDConverter.cpp +++ b/DDCore/src/plugins/LCDDConverter.cpp @@ -604,7 +604,7 @@ xml_h LCDDConverter::handlePlacement(const string& name, const TGeoNode* node) c PlacedVolume p = Ref_t(node); const PlacedVolume::VolIDs& ids = p.volIDs(); for(PlacedVolume::VolIDs::const_iterator i=ids.begin(); i!=ids.end(); ++i) { - xml_h pvid = xml_elt_t(geo.doc,"physvolid"); + xml_h pvid = xml_elt_t(geo.doc,_U(physvolid)); pvid.setAttr(_U(field_name),(*i).first); pvid.setAttr(_U(value),(*i).second); place.append(pvid); @@ -692,7 +692,7 @@ xml_h LCDDConverter::handleIdSpec(const std::string& name, const TNamed* id_spec id.setAttr(_U(name),name); const IDDescriptor::FieldMap& m = desc.fields(); for(IDDescriptor::FieldMap::const_iterator i=m.begin(); i!=m.end(); ++i) { - xml_h idfield = xml_elt_t(geo.doc,"idfield"); + xml_h idfield = xml_elt_t(geo.doc,_U(idfield)); const IDDescriptor::Field& f = (*i).second; idfield.setAttr(_U(signed),f.second<0 ? true : false); idfield.setAttr(_U(label),(*i).first); @@ -806,16 +806,16 @@ void LCDDConverter::handleHeader() const { GeometryInfo& geo = data(); Header hdr = m_lcdd.header(); xml_h obj; - geo.doc_header.append(obj=xml_elt_t(geo.doc,"detector")); + geo.doc_header.append(obj=xml_elt_t(geo.doc,_U(detector))); obj.setAttr(_U(name),hdr.name()); - geo.doc_header.append(obj=xml_elt_t(geo.doc,"generator")); + geo.doc_header.append(obj=xml_elt_t(geo.doc,_U(generator))); obj.setAttr(_U(name),"LCDDConverter"); obj.setAttr(_U(version),hdr.version()); obj.setAttr(_U(file),hdr.url()); - obj.setAttr(_U(checksum),m_lcdd.constantAsString("compact_checksum")); - geo.doc_header.append(obj=xml_elt_t(geo.doc,"author")); + obj.setAttr(_U(checksum),Unicode(m_lcdd.constantAsString("compact_checksum"))); + geo.doc_header.append(obj=xml_elt_t(geo.doc,_U(author))); obj.setAttr(_U(name),hdr.author()); - geo.doc_header.append(obj=xml_elt_t(geo.doc,"comment")); + geo.doc_header.append(obj=xml_elt_t(geo.doc,_U(comment))); obj.setText(hdr.comment()); } @@ -844,13 +844,14 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) { collect(top,geo); m_checkOverlaps = false; - const char empty_gdml[] = - "<?xml version=\"1.0\" encoding=\"UTF-8\">\n" + const char empty_gdml[] = XML_HEADER_DECLARATION "<!-- \n" " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" " ++++ Linear collider detector description GDML in C++ ++++\n" " ++++ DD4hep Detector description generator. ++++\n" " ++++ ++++\n" + " ++++ Parser:" XML_IMPLEMENTATION_TYPE " ++++\n" + " ++++ ++++\n" " ++++ M.Frank CERN/LHCb ++++\n" " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" "-->\n" @@ -909,13 +910,14 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) { #define ns_location "http://www.lcsim.org.schemas/lcdd/1.0" - const char empty_lcdd[] = - "<?xml version=\"1.0\" encoding=\"UTF-8\">\n" + const char empty_lcdd[] = XML_HEADER_DECLARATION "<!-- \n" " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" " ++++ Linear collider detector description LCDD in C++ ++++\n" " ++++ DD4hep Detector description generator. ++++\n" " ++++ ++++\n" + " ++++ Parser:" XML_IMPLEMENTATION_TYPE " ++++\n" + " ++++ ++++\n" " ++++ M.Frank CERN/LHCb ++++\n" " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" "-->\n" @@ -1014,14 +1016,8 @@ LCDDConverter::GeometryInfo::GeometryInfo() } static long dump_output(xml_doc_t doc, int argc, char** argv) { - FILE* file = argc>0 ? ::fopen(argv[0],"w") : stdout; - if ( !file ) { - cout << "Failed to open output file:" << argv[0] << endl; - return 0; - } - doc->Print(file); - if ( argc>0 ) ::fclose(file); - return 1; + XML::DocumentHandler docH; + return docH.output(doc, argc>0 ? argv[0] : ""); } static long create_gdml(LCDD& lcdd, int argc, char** argv) { diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp index aa8b0af376a6de3cb5b249527cfd900ab40baf3e..3d52716d33ef70d72b056844dcd0a91347eaa5ca 100644 --- a/DDCore/src/plugins/StandardPlugins.cpp +++ b/DDCore/src/plugins/StandardPlugins.cpp @@ -19,6 +19,11 @@ using namespace std; using namespace DD4hep::Geometry; +static void* create_lcdd_instance(const char* /* name */) { + return &LCDD::getInstance(); +} +DECLARE_CONSTRUCTOR(LCDD_constructor,create_lcdd_instance); + static long display(LCDD& /* lcdd */,int argc,char** argv) { TGeoManager* mgr = gGeoManager; const char* opt = "ogl";