Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:26:02

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 #ifndef JSON_ELEMENTS_H
0014 #define JSON_ELEMENTS_H
0015 
0016 // C/C++ include files
0017 #include <cmath>
0018 #include <string>
0019 #include <vector>
0020 
0021 // Framework include files
0022 #include <JSON/config.h>
0023 
0024 #ifndef RAD_2_DEGREE
0025 #define RAD_2_DEGREE 57.295779513082320876798154814105
0026 #endif
0027 #ifndef M_PI
0028 #define M_PI 3.14159265358979323846
0029 #endif
0030 
0031 /// Namespace for the AIDA detector description toolkit
0032 namespace dd4hep {
0033 
0034   /// Namespace for the AIDA detector description toolkit supporting JSON utilities
0035   namespace json {
0036 
0037     typedef const JsonAttr* Attribute;
0038 
0039     /// Convert json attribute to STL string  \ingroup DD4HEP_JSON
0040     std::string _toString(const Attribute attr);
0041     /// Convert json string to STL string  \ingroup DD4HEP_JSON
0042     std::string _toString(const char *toTranscode);
0043     /// Do-nothing version. Present for completeness and argument interchangeability  \ingroup DD4HEP_JSON
0044     std::string _toString(const char* s);
0045     /// Do-nothing version. Present for completeness and argument interchangeability  \ingroup DD4HEP_JSON
0046     std::string _toString(const std::string& s);
0047     /// Format unsigned long integer to string with arbitrary format  \ingroup DD4HEP_JSON
0048     std::string _toString(unsigned long i, const char* fmt = "%lu");
0049     /// Format unsigned integer (32 bits) to string with arbitrary format  \ingroup DD4HEP_JSON
0050     std::string _toString(unsigned int i, const char* fmt = "%u");
0051     /// Format signed integer (32 bits) to string with arbitrary format  \ingroup DD4HEP_JSON
0052     std::string _toString(int i, const char* fmt = "%d");
0053     /// Format signed long integer to string with arbitrary format  \ingroup DD4HEP_JSON
0054     std::string _toString(long i, const char* fmt = "%ld");
0055     /// Format single procision float number (32 bits) to string with arbitrary format  \ingroup DD4HEP_JSON
0056     std::string _toString(float d, const char* fmt = "%.17e");
0057     /// Format double procision float number (64 bits) to string with arbitrary format  \ingroup DD4HEP_JSON
0058     std::string _toString(double d, const char* fmt = "%.17e");
0059     /// Format void pointer (64 bits) to string with arbitrary format  \ingroup DD4HEP_JSON
0060     std::string _ptrToString(const void* p, const char* fmt = "%p");
0061     /// Format void pointer (64 bits) to string with arbitrary format  \ingroup DD4HEP_JSON
0062     template <typename T> std::string _toString(const T* p, const char* fmt = "%p")
0063     {      return _ptrToString((void*)p,fmt);       }
0064 
0065     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_JSON
0066     template <typename T> void _toDictionary(const char* name, T value);
0067     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_JSON
0068     void _toDictionary(const char* name, const char* value);
0069     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_JSON
0070     inline void _toDictionary(const std::string& name, const char* value)
0071     {  _toDictionary(name.c_str(), value);          }
0072     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_JSON
0073     void _toDictionary(const char* name, float  value);
0074     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_JSON
0075     void _toDictionary(const char* name, double value);
0076     /// Helper function to lookup environment from the expression evaluator
0077     std::string getEnviron(const std::string& env);
0078 
0079     /// Conversion function from raw unicode string to bool  \ingroup DD4HEP_JSON
0080     bool   _toBool(const char* value);
0081     /// Conversion function from raw unicode string to int  \ingroup DD4HEP_JSON
0082     int    _toInt(const char* value);
0083     /// Conversion function from raw unicode string to long  \ingroup DD4HEP_JSON
0084     long   _toLong(const char* value);
0085     /// Conversion function from raw unicode string to float  \ingroup DD4HEP_JSON
0086     float  _toFloat(const char* value);
0087     /// Conversion function from raw unicode string to double  \ingroup DD4HEP_JSON
0088     double _toDouble(const char* value);
0089 
0090     /// Class describing a list of JSON nodes
0091     /**
0092      *  Definition of a "list" of json elements hanging of the parent.
0093      *  The list allows iterations, which can be restarted.
0094      *  Please not: Copies are not entirely free, since the
0095      *  string tag need to be replicated using strdup/free
0096      *  (or when using xerces the corresponding unicode routines).
0097      *
0098      *  \author   M.Frank
0099      *  \version  1.0
0100      *  \ingroup DD4HEP_JSON
0101      */
0102     class NodeList {
0103     public:
0104       typedef std::pair<JsonElement::second_type::assoc_iterator,JsonElement::second_type::assoc_iterator> iter_t;
0105       std::string    m_tag;
0106       JsonElement*   m_node;
0107       mutable iter_t m_ptr;
0108 
0109       /// Copy constructor
0110       NodeList(const NodeList& l);
0111       /// Initializing constructor
0112       NodeList(JsonElement* frst, const std::string& tag);
0113       /// Default destructor
0114       ~NodeList();
0115       /// Reset the nodelist - e.g. restart iteration from beginning
0116       JsonElement* reset();
0117       /// Advance to next element
0118       JsonElement* next() const;
0119       /// Go back to previous element
0120       JsonElement* previous() const;
0121       /// Assignment operator
0122       NodeList& operator=(const NodeList& l);
0123     };
0124 
0125     /// Class to easily access the properties of single JsonElements.
0126     /**
0127      *  Note: The assignmant operator as well as the copy constructor
0128      *  do not have to be implemented, they are aut-generated by the compiler!
0129      *
0130      *  \author  M.Frank
0131      *  \version 1.0
0132      *  \ingroup DD4HEP_JSON
0133      */
0134     class Handle_t {
0135     public:
0136       // Abbreviation for internal use
0137       typedef JsonElement* Elt_t;
0138 
0139       /// The pointer to the JsonElement
0140       mutable Elt_t m_node;
0141 
0142       /// Initializing constructor
0143       Handle_t(Elt_t e = 0) : m_node(e)   {                                 }
0144       /// Direct access to the JsonElement using the operator->
0145       Elt_t operator->() const  {        return m_node;                     }
0146       /// Direct access to the JsonElement by dereferencing
0147       operator Elt_t() const    {        return m_node;                     }
0148       /// Direct access to the JsonElement by function
0149       Elt_t ptr() const         {        return m_node;                     }
0150       /// Unicode text access to the element's tag.
0151       const char* rawTag() const;
0152       /// Unicode text access to the element's text
0153       const char* rawText() const;
0154       /// Unicode text access to the element's value
0155       const char* rawValue() const;
0156       /// Text access to the element's tag
0157       std::string tag() const   {          return _toString(rawTag());      }
0158       /// Text access to the element's text
0159       std::string text() const  {          return _toString(rawText());     }
0160       /// Text access to the element's value
0161       std::string value() const {          return _toString(rawValue());    }
0162 
0163       /*** Attribute handling                                              */
0164       /// Access attribute name (throws exception if not present)
0165       const char* attr_name(const Attribute attr) const;
0166       /// Access attribute value by the attribute  (throws exception if not present)
0167       const char* attr_value(const Attribute attr) const;
0168       /// Access attribute value by the attribute's unicode name (throws exception if not present)
0169       const char* attr_value(const char* attr) const;
0170       /// Access attribute value by the attribute's unicode name (no exception thrown if not present)
0171       const char* attr_value_nothrow(const char* attr) const;
0172 
0173       /// Access attribute pointer by the attribute's unicode name (throws exception if not present)
0174       Attribute attr_ptr(const char* attr) const;
0175       /// Access attribute pointer by the attribute's unicode name (no exception thrown if not present)
0176       Attribute attr_nothrow(const char* tag) const;
0177       /// Check for the existence of a named attribute
0178       bool hasAttr(const char* t) const;
0179       /// Retrieve a collection of all attributes of this DOM element
0180       std::vector<Attribute> attributes() const;
0181       /// Access typed attribute value by the JsonAttr
0182       template <class T> T attr(const Attribute a) const {
0183         return this->attr<T>(this->attr_name(a));
0184       }
0185       /// Access typed attribute value by its unicode name
0186       template <class T> T attr(const char* name) const;
0187 
0188       /*** DOM Element child handling                                     */
0189       /// Check the existence of a child with a given tag name
0190       bool hasChild(const char* tag) const;
0191       /// Access a single child by its tag name (unicode)
0192       Handle_t child(const char* tag, bool throw_exception = true) const;
0193       /// Access a group of children identified by the same tag name
0194       NodeList children(const char* tag) const;
0195       /// Access the number of children of this DOM element with a given tag name
0196       size_t numChildren(const char* tag, bool throw_exception) const;
0197     };
0198 
0199 #define INLINE inline
0200     template <> INLINE Attribute Handle_t::attr<Attribute>(const char* tag_value) const {
0201       return attr_ptr(tag_value);
0202     }
0203 
0204     template <> INLINE const char* Handle_t::attr<const char*>(const char* tag_value) const {
0205       return attr_value(tag_value);
0206     }
0207 
0208     template <> INLINE bool Handle_t::attr<bool>(const char* tag_value) const {
0209       return _toBool(attr_value(tag_value));
0210     }
0211 
0212     template <> INLINE int Handle_t::attr<int>(const char* tag_value) const {
0213       return _toInt(attr_value(tag_value));
0214     }
0215     
0216     template <> INLINE long Handle_t::attr<long>(const char* tag_value) const {
0217       return _toLong(attr_value(tag_value));
0218     }
0219 
0220     template <> INLINE float Handle_t::attr<float>(const char* tag_value) const {
0221       return _toFloat(attr_value(tag_value));
0222     }
0223 
0224     template <> INLINE double Handle_t::attr<double>(const char* tag_value) const {
0225       return _toDouble(attr_value(tag_value));
0226     }
0227 
0228     template <> INLINE std::string Handle_t::attr<std::string>(const char* tag_value) const {
0229       return _toString(attr_value(tag_value));
0230     }
0231 
0232     /// Class to support the access to collections of JsonNodes (or JsonElements)
0233     /**
0234      *  \author  M.Frank
0235      *  \version 1.0
0236      *  \ingroup DD4HEP_JSON
0237      */
0238     class Collection_t : public Handle_t {
0239     public:
0240       /// Reference to the list of child nodes
0241       NodeList m_children;
0242       /// Constructor over JsonElements with a given tag name
0243       Collection_t(Handle_t node, const char* tag);
0244       /// Constructor over JsonElements in a node list
0245       Collection_t(NodeList children);
0246       /// Reset the collection object to restart the iteration
0247       Collection_t& reset();
0248       /// Access the collection size. Avoid this call -- sloooow!
0249       size_t size() const;
0250       /// Operator to advance the collection (pre increment)
0251       void operator++() const;
0252       /// Operator to advance the collection (post increment)
0253       void operator++(int) const;
0254       /// Operator to advance the collection (pre decrement)
0255       void operator--() const;
0256       /// Operator to advance the collection (post decrement)
0257       void operator--(int) const;
0258       /// Access to current element
0259       Elt_t current() const {
0260         return m_node;
0261       }
0262       /// Helper function to throw an exception
0263       void throw_loop_exception(const std::exception& e) const;
0264       /// Loop processor using function object
0265       template <class T> void for_each(T oper) const {
0266         try {
0267           for (const Collection_t& c = *this; c; ++c)
0268             oper(*this);
0269         }
0270         catch (const std::exception& e) {
0271           throw_loop_exception(e);
0272         }
0273       }
0274       /// Loop processor using function object
0275       template <class T> void for_each(const char* tag_name, T oper) const {
0276         try {
0277           for (const Collection_t& c = *this; c; ++c)
0278             Collection_t(c.m_node, tag_name).for_each(oper);
0279         }
0280         catch (const std::exception& e) {
0281           throw_loop_exception(e);
0282         }
0283       }
0284     };
0285 
0286     /// Class supporting the basic functionality of an JSON document
0287     /**
0288      *  User class encapsulating a DOM document.
0289      *  Nothing special - normal handle around pointer.
0290      *
0291      *  \author  M.Frank
0292      *  \version 1.0
0293      *  \ingroup DD4HEP_JSON
0294      */
0295     class Document {
0296     public:
0297       typedef JsonElement* DOC;
0298       DOC m_doc;
0299 
0300       /// Constructor
0301       Document(DOC d=0) : m_doc(d) {
0302       }
0303       /// Auto-conversion to DOM document
0304       operator DOC() const {
0305         return m_doc;
0306       }
0307       /// Accessot to DOM document behaviour using arrow operator
0308       DOC operator->() const {
0309         return m_doc;
0310       }
0311       /// Accessot to DOM document behaviour
0312       DOC ptr() const {
0313         return m_doc;
0314       }
0315       /// Access the ROOT eleemnt of the DOM document
0316       Handle_t root() const;
0317     };
0318 
0319     /// Class supporting the basic functionality of an JSON document including ownership
0320     /**
0321      *  User class encapsulating a DOM document.
0322      *  Nothing special - normal handle around pointer.
0323      *  Contrary to the Document class, on destruction the
0324      *  JSON document shall be destroyed and the corresponding
0325      *  resources released.
0326      *
0327      *  \author  M.Frank
0328      *  \version 1.0
0329      *  \ingroup DD4HEP_JSON
0330      */
0331     class DocumentHolder : public Document {
0332     public:
0333       /// Default Constructor
0334       DocumentHolder() : Document() {
0335       }
0336       /// Constructor
0337       DocumentHolder(DOC d) : Document(d) {
0338       }
0339       /// Assign new document. Old document is dropped.
0340       DocumentHolder& assign(DOC d);
0341       /// Standard destructor - releases the document
0342       virtual ~DocumentHolder();
0343     };
0344 
0345     /// User abstraction class to manipulate JSON elements within a document
0346     /**
0347      *  User class encapsulating a DOM element
0348      *  using the Handle_t helper.
0349      *  This is the main class we interact with when
0350      *  analysing the json documents for constructing
0351      *  sub-detectors etc.
0352      *
0353      *  \author  M.Frank
0354      *  \version 1.0
0355      *  \ingroup DD4HEP_JSON
0356      */
0357     class Element {
0358     public:
0359       /// Simplification type declarations
0360       typedef Handle_t::Elt_t Elt_t;
0361 
0362       /// The underlying object holding the JsonElement pointer
0363       Handle_t m_element;
0364 
0365       /// Constructor from JsonElement handle
0366       Element(const Handle_t& e) : m_element(e)          {      }
0367       /// Constructor from JsonElement handle
0368       Element(const Element& e) : m_element(e.m_element) {      }
0369 
0370       /// Assignment operator
0371       Element& operator=(const Element& c)  {
0372         m_element = c.m_element;
0373         return *this;
0374       }
0375       /// Assignment operator
0376       Element& operator=(Handle_t handle)  {
0377         m_element = handle;
0378         return *this;
0379       }
0380       /// operator bool: check handle validity
0381       operator bool() const        {        return 0 != m_element.ptr();      }
0382       /// operator NOT: check handle validity
0383       bool operator!() const       {        return 0 == m_element.ptr();      }
0384       /// Automatic conversion to DOM element handle
0385       operator Handle_t() const    {        return m_element;                 }
0386       /// Automatic conversion to JsonElement pointer
0387       operator Elt_t() const       {        return m_element;                 }
0388       /// Access to JsonElement pointer
0389       Elt_t ptr() const            {        return m_element;                 }
0390       /// Access the tag name of this element
0391       std::string tag() const      {        return m_element.tag();           }
0392       /// Access the tag name of this element
0393       const char* tagName() const  {        return m_element.rawTag();        }
0394       /// Access the tag name of this element
0395       std::string text() const     {        return m_element.text();          }
0396       /// Check for the existence of a named attribute
0397       bool hasAttr(const char* name) const {return m_element.hasAttr(name);   }
0398       /// Access attribute with implicit return type conversion
0399       template <class T> T attr(const char* tag_value) const
0400       {  return m_element.attr<T>(tag_value);                                 }
0401       /// Access attribute name (throws exception if not present)
0402       const char* attr_name(const Attribute a) const
0403       {  return m_element.attr_name(a);                                       }
0404       /// Access attribute value by the attribute  (throws exception if not present)
0405       const char* attr_value(const Attribute a) const
0406       {  return m_element.attr_value(a);                                      }
0407       /// Access the number of children of this element with a given tag name
0408       size_t numChildren(const char* tag_value, bool exc = true) const
0409       {  return m_element.numChildren(tag_value, exc);                        }
0410       /// Retrieve a collection of all attributes of this element
0411       std::vector<Attribute> attributes() const
0412       {  return m_element.attributes();                                       }
0413       /// Access single attribute by its name
0414       Attribute getAttr(const char* name) const;
0415      /// Access child by tag name. Thow an exception if required in case the child is not present
0416       Handle_t child(const char* tag_value, bool except = true) const
0417       {  return m_element.child(tag_value, except);                           }
0418       /// Check the existence of a child with a given tag name
0419       bool hasChild(const char* tag_value) const
0420       {  return m_element.hasChild(tag_value);                                }
0421     };
0422 
0423     /// Forward declarations
0424     class DocumentHandler;    
0425 #undef INLINE
0426     
0427     void dumpTree(Handle_t elt);
0428     void dumpTree(Element elt);
0429     void dumpTree(const JsonElement* elt);
0430 
0431   }       /* End namespace json              */
0432 }         /* End namespace dd4hep            */
0433 #endif // JSON_ELEMENTS_H