00001 #ifndef _IT_BUS_NILLABLE_PTR_H_ 00002 #define _IT_BUS_NILLABLE_PTR_H_ 00003 00004 // @Copyright 2003 IONA Technologies, Plc. All Rights Reserved. 00005 // 00006 00007 #include <it_bus/nillable.h> 00008 #include <it_bus/complex_type_reader.h> 00009 #include <it_bus/complex_type_writer.h> 00010 #include <it_cal/auto_ptr.h> 00011 00012 namespace IT_Bus 00013 { 00022 template <class T> 00023 class NillablePtr : public Nillable, public IT_AutoPtr<T> 00024 { 00025 public: 00026 00027 NillablePtr(); 00028 00029 NillablePtr( 00030 const NillablePtr& other 00031 ); 00032 00033 NillablePtr( 00034 T* data 00035 ); 00036 00037 virtual ~NillablePtr(); 00038 00039 NillablePtr& 00040 operator=( 00041 const NillablePtr& 00042 ); 00043 00044 AnyType& 00045 copy( 00046 const AnyType& other 00047 ); 00048 00049 void 00050 set( 00051 const T* data 00052 ); 00053 00054 virtual const QName& 00055 get_type() const; 00056 00057 virtual Boolean 00058 is_nil() const; 00059 00060 virtual void 00061 set_nil(); 00062 00063 virtual void 00064 write_value( 00065 const QName& name, 00066 ComplexTypeWriter& writer 00067 ) const IT_THROW_DECL((SerializationException)); 00068 00069 virtual void 00070 read_value( 00071 const QName& name, 00072 ComplexTypeReader& reader 00073 ) IT_THROW_DECL((DeserializationException)); 00074 00075 private: 00076 typedef NillablePtr ThisType; // needed for DYNAMIC_CAST macro 00077 }; 00078 00079 00080 template <class T> 00081 NillablePtr<T>::NillablePtr() 00082 { 00083 // Complete. 00084 } 00085 00086 template <class T> 00087 NillablePtr<T>::NillablePtr( 00088 const NillablePtr<T>& other 00089 ) 00090 : 00091 IT_AutoPtr<T>(IT_CONST_CAST(NillablePtr<T>&, other)) 00092 { 00093 // Complete. 00094 } 00095 00096 template <class T> 00097 NillablePtr<T>::NillablePtr( 00098 T* data 00099 ) 00100 : 00101 IT_AutoPtr<T>(data) 00102 { 00103 // Complete. 00104 } 00105 00106 template <class T> 00107 NillablePtr<T>::~NillablePtr() 00108 { 00109 // Complete. 00110 } 00111 00112 template <class T> 00113 NillablePtr<T>& 00114 NillablePtr<T>::operator=( 00115 const NillablePtr<T>& other 00116 ) 00117 { 00118 if (other.is_nil()) 00119 { 00120 this->reset(); 00121 } 00122 else 00123 { 00124 this->reset(new T); 00125 *this->get() = *other; 00126 } 00127 return *this; 00128 } 00129 00130 template <class T> 00131 AnyType& 00132 NillablePtr<T>::copy( 00133 const AnyType& rhs 00134 ) 00135 { 00136 const ThisType& other = IT_DYNAMIC_CAST(const ThisType&, rhs); 00137 return *this = other; 00138 } 00139 00140 template <class T> 00141 const QName& 00142 NillablePtr<T>::get_type() const 00143 { 00144 return T::type_name; 00145 } 00146 00147 template <class T> 00148 Boolean 00149 NillablePtr<T>::is_nil() const 00150 { 00151 return this->get() == 0; 00152 } 00153 00154 template <class T> 00155 void 00156 NillablePtr<T>::set_nil() 00157 { 00158 this->reset(); 00159 } 00160 00161 template <class T> 00162 void 00163 NillablePtr<T>::write_value( 00164 const QName& name, 00165 ComplexTypeWriter& writer 00166 ) const IT_THROW_DECL((SerializationException)) 00167 { 00168 if (is_nil()) 00169 { 00170 throw SerializationException("Attempt to write nil value"); 00171 } 00172 writer.write(name, *this->get()); 00173 } 00174 00175 template <class T> 00176 void 00177 NillablePtr<T>::read_value( 00178 const QName& name, 00179 ComplexTypeReader& reader 00180 ) IT_THROW_DECL((DeserializationException)) 00181 { 00182 if (this->get() == 0) 00183 { 00184 this->reset(new T); 00185 } 00186 reader.read(name, *this->get()); 00187 } 00188 00189 template <class T> 00190 void 00191 NillablePtr<T>::set( 00192 const T* data 00193 ) 00194 { 00195 if (this->get() == 0 ) 00196 { 00197 if (data != 0) 00198 { 00199 reset(new T(*data)); 00200 } 00201 } 00202 else 00203 { 00204 if ( data != 0 ) 00205 { 00206 *this->get() = *data; 00207 } 00208 else 00209 { 00210 this->reset(); 00211 } 00212 } 00213 } 00214 } 00215 00216 #endif