// ContentId.cxx #include "dataset_id/ContentId.h" #include #include #include #include #include "dataset_util/XmlElement.h" #include "dataset_util/DtdRegistry.h" using std::string; using std::map; using std::ostream; using std::endl; using std::setw; typedef ContentId::Index Index; typedef map NameMap; typedef map IndexMap; //********************************************************************** // Local definitions. //********************************************************************** namespace { // Map of names indexed by index. NameMap NAMES; // Map of indices mapped by name. IndexMap IDXS; // Initialize the class. int init = 0; int init_count = ContentId::initialize(); // Register the DTD. DtdRegistry::Status ISTAT = DtdRegistry::register_dtd("dataset"); } //********************************************************************** // Static member functions. //********************************************************************** // DTD. const Text& ContentId::dtd() { static Text txt; if ( txt.size() == 0 ) { txt.append(""); txt.append(""); } return txt; } //********************************************************************** // Initialize the class. int ContentId::initialize() { static int count = 0; if ( count ) return ++count; init = 1; private_register_id( 100, "UNKNOWN"); private_register_id( 101, "Test1"); private_register_id( 102, "Test2"); private_register_id( 103, "Test3"); private_register_id( 104, "Test4"); private_register_id( 105, "Test5"); private_register_id( 106, "Test6"); private_register_id( 2101, "EventInfo"); //private_register_id(133273, "MCEventCollection"); private_register_id(999999, "RDEvent?"); return ++count; } //********************************************************************** // Private class registration. ContentId ContentId::private_register_id(int idx, const char* name) { assert( init ); if ( idx == 0 ) return ContentId(); if ( string(name) == "" ) return ContentId(); NameMap::const_iterator inam = NAMES.find(idx); IndexMap::const_iterator iidx = IDXS.find(name); if ( inam != NAMES.end() ) { if ( iidx == IDXS.end() ) return ContentId(); if ( inam->first != iidx->second ) return ContentId(); assert( inam->second == iidx->first ); } else { if ( iidx != IDXS.end() ) return ContentId(); } NAMES[idx] = name; IDXS[name] = idx; assert( NAMES.size() == IDXS.size() ); ContentId id; id.m_idx = idx; id.m_name = name; return id; } //********************************************************************** // Public class registration. ContentId ContentId::register_id(int idx, const char* name) { if ( idx >= 1000 ) return ContentId(); return private_register_id(idx, name); } //********************************************************************** // Return the number of content ID's. unsigned int ContentId::size() { return NAMES.size(); } //********************************************************************** // Display the table of content ID's. void ContentId::display(std::ostream& strm) { strm << "Content ID table" << endl; strm << "---------------"; for ( NameMap::const_iterator inam=NAMES.begin(); inam!=NAMES.end(); ++inam ) { strm << endl; strm << setw(12) << inam->first << " " << inam->second; } strm << endl; } //********************************************************************** // Member functions. //********************************************************************** // Default constructor. ContentId::ContentId() : m_idx(0), m_name("") { } //********************************************************************** // Constructor from an index. ContentId::ContentId(Index idx, string key) : m_idx(0), m_name(""), _key(key) { NameMap::const_iterator inam = NAMES.find(idx); if ( inam != NAMES.end() ) { m_idx = idx; m_name = inam->second; } } //********************************************************************** // Constructor from a name. ContentId::ContentId(string name, string key) : m_idx(0), m_name(""), _key(key) { IndexMap::const_iterator iidx = IDXS.find(name); if ( iidx != IDXS.end() ) { m_idx = iidx->second; m_name = name; } } //********************************************************************** // Constructor from an XML element. ContentId::ContentId(const XmlElement& ele) : m_idx(0), m_name(""), _key("") { if ( ele.name() == ContentId::xml_name() ) { int errcount = ele.error_count(); if ( ele.has_attribute("name") ) { string name = ele.attribute("name"); Text::xml_to_text(name); m_name = name; if ( ele.has_attribute("key") ) { _key = ele.attribute("key"); } IndexMap::const_iterator iidx = IDXS.find(name); if ( iidx != IDXS.end() ) { m_idx = iidx->second; } } assert( errcount == ele.error_count() ); } } //********************************************************************** // Validity. bool ContentId::is_valid() const { return m_idx > 0 || m_name != ""; } //********************************************************************** // Return the index. Index ContentId::index() const { return m_idx; } //********************************************************************** // Return the name as a string. string ContentId::name() const { return m_name; } //********************************************************************** // Return the name as a C-string. const char* ContentId::cname() const { return m_name.c_str(); } //********************************************************************** // Return the key as a string. string ContentId::key() const { return _key; } //********************************************************************** // Return the key as a C-string. const char* ContentId::ckey() const { return _key.c_str(); } //********************************************************************** // Convert to xml. const XmlElement* ContentId::xml() const { XmlElement* pele = new XmlElement(ContentId::xml_name()); string xname = name(); Text::text_to_xml(xname); pele->add_attribute("name", xname); if ( _key != "" ) { pele->add_attribute("key", key()); } return pele; } //********************************************************************** // Free functions. //********************************************************************** // Ordering. bool operator<(const ContentId& lhs, const ContentId& rhs) { if ( lhs.name() < rhs.name() ) return true; if ( rhs.name() < lhs.name() ) return false; return lhs.key() < rhs.key(); } //********************************************************************** // Equality. bool operator==(const ContentId& lhs, const ContentId& rhs) { return lhs.index() == rhs.index() && lhs.key() == rhs.key(); } //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const ContentId& rhs) { if ( rhs.is_valid() ) { lhs << "type " << rhs.name() << " with"; if ( rhs.key() == "" ) { lhs << "out key"; } else { lhs << " with key " << rhs.key(); } } else { lhs << "invalid content identifier"; } return lhs; } //**********************************************************************