// file : XSCRT/Elements.hpp // author : Boris Kolpackov #ifndef XSCRT_ELEMENTS_HPP #define XSCRT_ELEMENTS_HPP #include #include #include #include "ace/ace_wchar.h" // #include //@@ tmp #include #include "ace/Refcounted_Auto_Ptr.h" namespace XSCRT { struct IdentityProvider { virtual bool before (IdentityProvider const&) const = 0; virtual ~IdentityProvider (void) { } }; class Type { public: virtual ~Type (void) { } protected: Type (void) : container_ (0) { } template Type (XML::Element const&) : container_ (0) { } template Type (XML::Attribute const&) : container_ (0) { } Type (Type const&) : container_ (0) { } Type& operator= (Type const&) { //@@ I don't need this. //if (map_.get ()) map_->clear (); // Flush the map. return *this; } public: Type const* container () const { return container_ ? container_ : this; } Type* container () { return container_ ? container_ : this; } Type const* root () const { Type const* r = container (); //@@ VC6 can't handle this inside the loop. // Type const* c = r->container (); for (; c != r; c = c->container ()) r = c; return r; } Type* root () { Type* r = container (); for (Type* c = r->container (); c != r; c = c->container ()) r = c; return r; } //@@ //protected: public: virtual void container (Type* c) { if (container_ == c) return; // Revoke registrations from our old container. // if (container_ != 0 && map_.get ()) { for (Map_::iterator i (map_->begin ()); i != map_->end (); ++i) { //std::wcerr << "revoking " << i->second // << " to " << container_ << std::endl; container_->unregister_id (*(i->first)); } } // Copy registrations to our new container. // if (c != 0 && map_.get ()) { for (Map_::iterator i (map_->begin ()); i != map_->end (); ++i) { //std::wcerr << "copying " << i->second // << " to " << c << std::endl; c->register_id (*(i->first), i->second); } } container_ = c; } //@@ //protected: public: void register_id (IdentityProvider const& id, Type* t) { if (map_.get () == 0) { map_ = std::auto_ptr (new Map_); } if (!map_->insert (std::pair (&id, t)).second) { throw 1; } if (container () != this) container ()->register_id (id, t); } void unregister_id (IdentityProvider const& id) { if (map_.get ()) { Map_::iterator it (map_->find (&id)); if (it != map_->end ()) { map_->erase (it); if (container () != this) container ()->unregister_id (id); return; } } throw 1; } Type* lookup_id (IdentityProvider const& id) const { if (map_.get ()) { Map_::const_iterator it (map_->find (&id)); if (it != map_->end ()) { return it->second; } } return 0; } /// Get and set methods for the idref_map_ data member Type* get_idref (const char* name) { std::basic_string name_string (ACE_TEXT_CHAR_TO_TCHAR(name)); std::map, XSCRT::Type*>::iterator i = this->idref_map_.find(name_string); if (i != idref_map_.end()) { return i->second; } else { return 0; } } Type* get_idref (const std::basic_string& name) { std::map, XSCRT::Type*>::iterator i = this->idref_map_.find(name); if (i != idref_map_.end()) { return i->second; } else { return 0; } } Type* get_idref (const wchar_t *name) { std::basic_string name_string (ACE_TEXT_WCHAR_TO_TCHAR(name)); std::map, XSCRT::Type*>::iterator i = this->idref_map_.find(name_string); if (i != idref_map_.end()) { return i->second; } else { return 0; } } void set_idref (const std::basic_string& name, Type* new_idref) { this->idref_map_.insert(std::pair,Type*>(name, new_idref)); } private: // Data member to handle unbounded IDREF attributes and elements std::map, XSCRT::Type*> idref_map_; Type* container_; struct IdentityComparator { bool operator () (IdentityProvider const* x, IdentityProvider const* y) const { return x->before (*y); } }; typedef std::map Map_; std::auto_ptr map_; }; // Fundamental types template. // // template class FundamentalType : public Type { public: // Trait for marshaling a FundamentalType X typedef X CDR_Type__; FundamentalType () { } template FundamentalType (XML::Element const& e) { std::basic_stringstream s; s << e.value (); s >> x_; } template FundamentalType (XML::Attribute const& a) { std::basic_stringstream s; s << a.value (); s >> x_; } FundamentalType (X const& x) : x_ (x) { } FundamentalType& operator= (X const& x) { x_ = x; return *this; } public: operator X const& () const { return x_; } operator X& () { return x_; } protected: X x_; }; // Specialization for `signed char' // // template<> template inline FundamentalType:: FundamentalType (XML::Element const& e) { std::basic_stringstream s; s << e.value (); short t; s >> t; x_ = static_cast (t); } template<> template inline FundamentalType:: FundamentalType (XML::Attribute const& a) { std::basic_stringstream s; s << a.value (); short t; s >> t; x_ = static_cast (t); } // Specialization for `unsigned char' // // template<> template inline FundamentalType:: FundamentalType (XML::Element const& e) { std::basic_stringstream s; s << e.value (); unsigned short t; s >> t; x_ = static_cast (t); } template<> template inline FundamentalType:: FundamentalType (XML::Attribute const& a) { std::basic_stringstream s; s << a.value (); unsigned short t; s >> t; x_ = static_cast (t); } // Specialization for bool. // // template<> template<> inline FundamentalType:: FundamentalType (XML::Element const& e) { x_ = (e.value () == "true") || (e.value () == "1"); } template<> template<> inline FundamentalType:: FundamentalType (XML::Element const& e) { x_ = (e.value () == L"true") || (e.value () == L"1"); } template<> template<> inline FundamentalType:: FundamentalType (XML::Attribute const& a) { x_ = (a.value () == "true") || (a.value () == "1"); } template<> template<> inline FundamentalType:: FundamentalType (XML::Attribute const& a) { x_ = (a.value () == L"true") || (a.value () == L"1"); } } #endif // XSCRT_ELEMENTS_HPP