// file : XSCRT/XMLSchema.hpp // author : Boris Kolpackov // cvs-id : $Id$ #ifndef XSCRT_XMLSCHEMA_HPP #define XSCRT_XMLSCHEMA_HPP #include // #include //@@ tmp #include "XSCRT/Elements.hpp" namespace XMLSchema { typedef XSCRT::FundamentalType byte; typedef XSCRT::FundamentalType unsignedByte; typedef XSCRT::FundamentalType short_; typedef XSCRT::FundamentalType unsignedShort; typedef XSCRT::FundamentalType int_; typedef XSCRT::FundamentalType unsignedInt; typedef XSCRT::FundamentalType long_; typedef XSCRT::FundamentalType unsignedLong; //@@ It would be nice to use some arbitrary-length integer class. // typedef long_ decimal; typedef decimal integer; typedef integer nonPositiveInteger; typedef integer nonNegativeInteger; typedef nonNegativeInteger positiveInteger; typedef nonPositiveInteger negativeInteger; typedef XSCRT::FundamentalType boolean; typedef XSCRT::FundamentalType float_; typedef XSCRT::FundamentalType double_; // Just to make GCC 3.3 and other broken compilers shutup. // using std::basic_string; template class string : public XSCRT::Type, public basic_string { protected: typedef basic_string Base__ ; public: //@@ VC6 does not inject XSCRT::Type into the scope so I have // to qualify it all the time. // string () { } string (XSCRT::XML::Element const& e) : Base__ (e.value ()) { } string (XSCRT::XML::Attribute const& a) : Base__ (a.value ()) { } string (Base__ const& x) : Base__ (x) { } string& operator= (Base__ const& x) { static_cast (*this) = x; return *this; } }; template class normalizedString : public string { protected: typedef typename string::Base__ Base__; public: normalizedString () { } normalizedString (XSCRT::XML::Element const& e) : string (e) { } normalizedString (XSCRT::XML::Attribute const& a) : string (a) { } normalizedString (Base__ const& x) : string (x) { } normalizedString& operator= (Base__ const& x) { static_cast (*this) = x; return *this; } }; template class token : public normalizedString { protected: typedef typename normalizedString::Base__ Base__; public: token () { } token (XSCRT::XML::Element const& e) : normalizedString (e) { } token (XSCRT::XML::Attribute const& a) : normalizedString (a) { } token (Base__ const& x) : normalizedString (x) { } token& operator= (Base__ const& x) { static_cast (*this) = x; return *this; } }; template class NMTOKEN : public token { protected: typedef typename token::Base__ Base__; public: NMTOKEN () { } NMTOKEN (XSCRT::XML::Element const& e) : token (e) { } NMTOKEN (XSCRT::XML::Attribute const& a) : token (a) { } NMTOKEN (Base__ const& x) : token (x) { } NMTOKEN& operator= (Base__ const& x) { static_cast (*this) = x; return *this; } }; template class Name: public token { protected: typedef typename token::Base__ Base__; public: Name() { } Name(XSCRT::XML::Element const& e) : token (e) { } Name(XSCRT::XML::Attribute const& a) : token (a) { } Name(Base__ const& x) : token (x) { } Name& operator= (Base__ const& x) { static_cast (*this) = x; return *this; } }; template class NCName: public Name { protected: typedef typename Name::Base__ Base__; public: NCName() { } NCName(XSCRT::XML::Element const& e) : Name (e) { } NCName(XSCRT::XML::Attribute const& a) : Name (a) { } NCName(Base__ const& x) : Name (x) { } NCName& operator= (Base__ const& x) { static_cast (*this) = x; return *this; } }; template struct IdentityProvider : XSCRT::IdentityProvider { IdentityProvider (NCName const& id) : id_ (id) { } virtual bool before (XSCRT::IdentityProvider const& y) const { return id_ < dynamic_cast (y).id_; } private: NCName const& id_; private: IdentityProvider (IdentityProvider const&); IdentityProvider& operator= (IdentityProvider const&); }; template class ID : public NCName { protected: typedef typename NCName::Base__ Base__; public: ~ID() { unregister_id (); } ID () : id_provider_ (*this) { } ID (XSCRT::XML::Element const& e) : NCName (e), id_provider_ (*this) { } ID (XSCRT::XML::Attribute const& a) : NCName (a), id_provider_ (*this) { } ID (ID const& x) : NCName (x), id_provider_ (*this) { } ID (Base__ const& x) : NCName (x), id_provider_ (*this) { } ID& operator= (Base__ const& x) { unregister_id (); static_cast&>(*this) = x; register_id (); return *this; } ID& operator= (ID const& x) { unregister_id (); static_cast&>(*this) = static_cast const&>(x); register_id (); return *this; } public: using NCName::container; virtual void container (XSCRT::Type* c) { unregister_id (); NCName::container (c); register_id (); } private: using NCName::empty; using NCName::root; void register_id () { if (container () != this && !empty ()) { //std::wcerr << "registering " << container () // << " as '" << *this // << "' on " << container () << std::endl; container ()->register_id (id_provider_, container ()); } } void unregister_id () { if (container () != this && !empty ()) { //std::wcerr << "un-registering " << container () // << " as '" << *this // << "' on " << container () << std::endl; container ()->unregister_id (id_provider_); } } private: IdentityProvider id_provider_; }; struct IDREF_Base : public XSCRT::Type { virtual XSCRT::Type* get () const = 0; }; template class IDREF : public IDREF_Base { public: IDREF () : id_provider_ (id_) { } IDREF (XSCRT::XML::Element const& e) : id_ (e), id_provider_ (id_) { } IDREF (XSCRT::XML::Attribute const& a) : id_ (a), id_provider_ (id_) { } IDREF (IDREF const& x) : id_ (x.id_), id_provider_ (id_) { } IDREF (basic_string const& id) : id_ (id), id_provider_ (id_) { } IDREF& operator= (IDREF const& x) { id_ = x.id_; return *this; } IDREF& operator= (basic_string const& x) { id_ = x; return *this; } public: XSCRT::Type* operator-> () const { return get (); } XSCRT::Type& operator* () const { return *(get ()); } virtual XSCRT::Type* get () const { if (!id_.empty () && container () != this) { return root ()->lookup_id (id_provider_); } else { return 0; } } // conversion to bool // typedef XSCRT::Type* (IDREF::*bool_convertable)() const; operator bool_convertable () const { return get () ? &IDREF::operator-> : 0; } private: NCName id_; IdentityProvider id_provider_; }; } // Traversal // // #include "XSCRT/Traversal.hpp" namespace XMLSchema { namespace Traversal { template struct Traverser : XSCRT::Traversal::Traverser, XSCRT::Traversal::Traverser { typedef T Type; virtual void traverse (XMLSchema::IDREF_Base& r) { if (r.get ()) dispatch (*(r.get ())); } }; typedef Traverser byte; typedef Traverser unsignedByte; typedef Traverser short_; typedef Traverser unsignedShort; typedef Traverser int_; typedef Traverser unsignedInt; typedef Traverser long_; typedef Traverser unsignedLong; typedef Traverser boolean; typedef Traverser float_; typedef Traverser double_; template struct string : Traverser > { }; template struct ID : Traverser > { }; } } // ExtendedTypeInfo for XML Schema types // // #include "XSCRT/ExtendedTypeInfo.hpp" namespace XMLSchema { template struct TypeInfoInitializer { TypeInfoInitializer (XSCRT::ExtendedTypeInfoMap&); }; } #include "XSCRT/XMLSchema.ipp" #include "XSCRT/XMLSchema.tpp" #endif // XSCRT_XMLSCHEMA_HPP