00001 /** 00002 * @file DataWrappers.h 00003 * @brief 00004 * 00005 **************************************************************************** 00006 * @version 0.8.534 $Id: DataWrappers.h 3775 2011-01-01 16:38:17Z alex $ 00007 * @author Alessandro Polo 00008 ****************************************************************************/ 00009 /* Copyright (c) 2007-2011, WOSH - Wide Open Smart Home 00010 * by Alessandro Polo - OpenSmartHome.com 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * * Redistributions of source code must retain the above copyright 00016 * notice, this list of conditions and the following disclaimer. 00017 * * Redistributions in binary form must reproduce the above copyright 00018 * notice, this list of conditions and the following disclaimer in the 00019 * documentation and/or other materials provided with the distribution. 00020 * * Neither the name of the OpenSmartHome.com WOSH nor the 00021 * names of its contributors may be used to endorse or promote products 00022 * derived from this software without specific prior written permission. 00023 * 00024 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY 00025 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00026 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00027 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY 00028 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00029 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00031 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00032 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00033 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00034 ****************************************************************************/ 00035 00036 #ifndef __WOSH_Core_DataWrappers_H__ 00037 #define __WOSH_Core_DataWrappers_H__ 00038 00039 #include <woshDefs.h> 00040 00041 00042 namespace wosh { 00043 00044 00045 ///---------------------------------------------------------------------------------------------------------------------- 00046 ///---------------------------------------------------------------------------------------------------------------------- 00047 /** 00048 * @class wosh::IDataFieldWrapperAlloc 00049 * @brief DataField Wrapper for \c allocating wosh::ISerializable representation of fields' value. 00050 * 00051 * @note Implementation is usually NON-OBJECT_TYPE-dependent (as read/write wrappers). 00052 * 00053 * @see wosh::DataFieldWrapperAllocT 00054 * @see (indirectly used by) wosh::IObjectReader 00055 * @see (indirectly used by) wosh::IObjectWriter 00056 ****************************************************************************/ 00057 class IDataFieldWrapperAlloc { 00058 public: 00059 IDataFieldWrapperAlloc( ) { } 00060 virtual ~IDataFieldWrapperAlloc() { } 00061 public: 00062 ///@brief allocate an empty object, able (used as default proxy) to store (read/write) passed filed, NULL on failure 00063 virtual ISerializable* alloc() const = 0; 00064 }; // class def 00065 ///---------------------------------------------------------------------------------------------------------------------- 00066 ///---------------------------------------------------------------------------------------------------------------------- 00067 00068 ///---------------------------------------------------------------------------------------------------------------------- 00069 /** 00070 * @class wosh::IDataFieldWrapperRead 00071 * @brief DataField Wrapper for \c reading fields and store into a wosh::ISerializable representation. 00072 * 00073 * Refer to default implementation wosh::IDataFieldWrapperReadT. 00074 * 00075 * @see (indirectly used by) wosh::IObjectReader 00076 ****************************************************************************/ 00077 template <class OBJECT_TYPE> 00078 class IDataFieldWrapperRead { 00079 public: 00080 IDataFieldWrapperRead( ) { } 00081 virtual ~IDataFieldWrapperRead() { } 00082 public: 00083 ///@brief read field value of passed object and return a ISerializable representation, NULL on failure 00084 virtual ISerializable* read( const OBJECT_TYPE* object ) const = 0; 00085 }; // class def 00086 ///---------------------------------------------------------------------------------------------------------------------- 00087 ///---------------------------------------------------------------------------------------------------------------------- 00088 00089 ///---------------------------------------------------------------------------------------------------------------------- 00090 /** 00091 * @class wosh::IDataFieldWrapperWrite 00092 * @brief DataField Wrapper for \c writing fields (reading) from a wosh::ISerializable representation. 00093 * 00094 * Refer to default implementation wosh::IDataFieldWrapperWriteT. 00095 * 00096 * @see (indirectly used by) wosh::IObjectReader 00097 ****************************************************************************/ 00098 template <class OBJECT_TYPE> 00099 class IDataFieldWrapperWrite { 00100 public: 00101 IDataFieldWrapperWrite( ) { } 00102 virtual ~IDataFieldWrapperWrite() { } 00103 public: 00104 ///@brief write field value of passed object from the ISerializable representation 00105 virtual WRESULT write( OBJECT_TYPE* object, const ISerializable* data ) const = 0; 00106 }; // class def 00107 ///---------------------------------------------------------------------------------------------------------------------- 00108 ///---------------------------------------------------------------------------------------------------------------------- 00109 00110 ///---------------------------------------------------------------------------------------------------------------------- 00111 ///---------------------------------------------------------------------------------------------------------------------- 00112 /** 00113 * @class wosh::DataFieldWrapperAllocT 00114 * @brief DataField \c allocate Wrapper template. Provided for convenience. 00115 * 00116 * \code 00117 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) { 00118 if ( fields == NULL ) return; 00119 DataFieldDefinitionT<myObject>* df_str = fields->add("MyStringField"); 00120 df_str->setWrapperAlloc<Variant>(); 00121 } 00122 \endcode 00123 * In this example a DataFieldWrapperAllocT<Variant> is allocated (FIELD_VALUE_PROXY_TYPE=wosh::Variant). 00124 * 00125 * Usually you don't need to explicitly set the allocator-wrapper, since the commonly used 00126 * DataFieldDefinitionT<OBJECT_TYPE>::setWrapperRead and DataFieldDefinitionT<OBJECT_TYPE>::setWrapperRead 00127 * will auto-definethe IDataFieldWrapperAlloc when missing (because the know the ALLOCATOR_TYPE class). 00128 * 00129 * This wrapper may be useful when ALLOCATOR_TYPE of read and write wrappers are different, even if it probably never happen. 00130 * 00131 ****************************************************************************/ 00132 template <class FIELD_VALUE_PROXY_TYPE> 00133 class DataFieldWrapperAllocT : public virtual IDataFieldWrapperAlloc { 00134 public: 00135 DataFieldWrapperAllocT( ) { } 00136 public: 00137 virtual inline ISerializable* alloc() const { return new FIELD_VALUE_PROXY_TYPE(); } 00138 }; // class def 00139 ///---------------------------------------------------------------------------------------------------------------------- 00140 ///---------------------------------------------------------------------------------------------------------------------- 00141 00142 ///---------------------------------------------------------------------------------------------------------------------- 00143 /** 00144 * @class wosh::IDataFieldWrapperReadT 00145 * @brief DataField \c read Wrapper template. Provided for convenience. 00146 * 00147 * \code 00148 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) { 00149 if ( fields == NULL ) return; 00150 DataFieldDefinitionT<myObject>* df_str = fields->add("MyStringField"); 00151 df_str->setWrapperRead<const std::string&, Variant>(&myObject::getStringData); 00152 } 00153 \endcode 00154 * 00155 ****************************************************************************/ 00156 template <class OBJECT_TYPE, typename RETURN_TYPE, class ALLOCATOR_TYPE> 00157 class IDataFieldWrapperReadT : public virtual IDataFieldWrapperRead<OBJECT_TYPE> { 00158 public: 00159 ///@brief definition of the (OBJECT_TYPE) member function used to extract value of type RETURN_TYPE 00160 typedef RETURN_TYPE (OBJECT_TYPE::*FieldReader)(void) const; 00161 public: 00162 IDataFieldWrapperReadT( FieldReader fptr = NULL ) 00163 : IDataFieldWrapperRead<OBJECT_TYPE>(), fieldReaderPtr(fptr) { } 00164 public: 00165 ///@brief allocate a new ISerializable data-holder for the field and initialize it with fields' value 00166 ///@note in most cases (using WOSH classes) this is memory-optimized 00167 ///@warning the caller is rensponsible for destroying the new instance 00168 virtual ISerializable* read( const OBJECT_TYPE* object ) const { 00169 if ( object == NULL || this->fieldReaderPtr == NULL ) return NULL; 00170 return new ALLOCATOR_TYPE( (object->*this->fieldReaderPtr)() ); 00171 } 00172 protected: 00173 FieldReader fieldReaderPtr; ///< pointer to the (real member) reader (function) 00174 }; // class def 00175 ///---------------------------------------------------------------------------------------------------------------------- 00176 ///---------------------------------------------------------------------------------------------------------------------- 00177 00178 ///---------------------------------------------------------------------------------------------------------------------- 00179 /** 00180 * @class wosh::IDataFieldWrapperReadSubT 00181 * @brief IDataFieldWrapperRead template for indirect getters [object->get1()->get2()]. 00182 **************************************************************************** 00183 * 00184 * @ingroup DataModels 00185 **************************************************************************** 00186 * @version 0.8.384 $Id $ 00187 * @author Alessandro Polo 00188 ****************************************************************************/ 00189 template <class OBJECT_TYPE, class PROXY_TYPE, typename RETURN_TYPE, class ALLOCATOR_TYPE> 00190 class IDataFieldWrapperReadSubT : public virtual IDataFieldWrapperRead<OBJECT_TYPE> 00191 { 00192 public: 00193 virtual ~IDataFieldWrapperReadSubT() { } 00194 }; // class def 00195 ///---------------------------------------------------------------------------------------------------------------------- 00196 // specialization for PROXY_TYPE references (they should be const! this won't free anything!) 00197 template <class OBJECT_TYPE, class PROXY_TYPE, typename RETURN_TYPE, class ALLOCATOR_TYPE> 00198 class IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE&, RETURN_TYPE, ALLOCATOR_TYPE> : public IDataFieldWrapperRead<OBJECT_TYPE> 00199 { 00200 public: 00201 typedef PROXY_TYPE& (OBJECT_TYPE::*ProxyExtractor)(void) const; 00202 typedef RETURN_TYPE (PROXY_TYPE::*FieldExtractor)(void) const; 00203 public: 00204 explicit IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE&, RETURN_TYPE, ALLOCATOR_TYPE>( ProxyExtractor proxy_fptr, FieldExtractor field_fptr ) 00205 : IDataFieldWrapperRead<OBJECT_TYPE>(), proxyExtractorPtr(proxy_fptr), fieldExtractorPtr(field_fptr) { } 00206 public: 00207 inline ISerializable* read( const OBJECT_TYPE* object ) const { 00208 PROXY_TYPE& proxy = (object->*proxyExtractorPtr)(); 00209 return new ALLOCATOR_TYPE( (proxy.*fieldExtractorPtr)() ); 00210 } 00211 protected: 00212 ProxyExtractor proxyExtractorPtr; 00213 FieldExtractor fieldExtractorPtr; 00214 }; // class def 00215 ///---------------------------------------------------------------------------------------------------------------------- 00216 // specialization for PROXY_TYPE references (they should be const! this won't free anything!) AND RETURN_TYPE pointer (acquired, not copied by allocator) 00217 template <class OBJECT_TYPE, class PROXY_TYPE, typename RETURN_TYPE> 00218 class IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE&, RETURN_TYPE, void> : public virtual IDataFieldWrapperRead<OBJECT_TYPE> 00219 { 00220 public: 00221 typedef PROXY_TYPE& (OBJECT_TYPE::*ProxyExtractor)(void) const; 00222 typedef RETURN_TYPE (PROXY_TYPE::*FieldExtractor)(void) const; 00223 public: 00224 explicit IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE&, RETURN_TYPE, void>( ProxyExtractor proxy_fptr, FieldExtractor field_fptr ) 00225 : IDataFieldWrapperRead<OBJECT_TYPE>(), proxyExtractorPtr(proxy_fptr), fieldExtractorPtr(field_fptr) { } 00226 public: 00227 inline ISerializable* read( const OBJECT_TYPE* object ) const { 00228 PROXY_TYPE& proxy = (object->*proxyExtractorPtr)(); 00229 return (proxy.*fieldExtractorPtr)(); 00230 } 00231 protected: 00232 ProxyExtractor proxyExtractorPtr; 00233 FieldExtractor fieldExtractorPtr; 00234 }; // class def 00235 ///---------------------------------------------------------------------------------------------------------------------- 00236 // specialization for PROXY_TYPE pointers (they should be const! this won't free anything!) 00237 template <class OBJECT_TYPE, class PROXY_TYPE, typename RETURN_TYPE, class ALLOCATOR_TYPE> 00238 class IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE*, RETURN_TYPE, ALLOCATOR_TYPE> : public virtual IDataFieldWrapperRead<OBJECT_TYPE> 00239 { 00240 public: 00241 typedef PROXY_TYPE* (OBJECT_TYPE::*ProxyExtractor)(void) const; 00242 typedef RETURN_TYPE (PROXY_TYPE::*FieldExtractor)(void) const; 00243 public: 00244 explicit IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE*, RETURN_TYPE, ALLOCATOR_TYPE>( ProxyExtractor proxy_fptr, FieldExtractor field_fptr ) 00245 : IDataFieldWrapperRead<OBJECT_TYPE>(), proxyExtractorPtr(proxy_fptr), fieldExtractorPtr(field_fptr) { } 00246 public: 00247 inline ISerializable* read( const OBJECT_TYPE* object ) const { 00248 PROXY_TYPE* proxy = (object->*proxyExtractorPtr)(); 00249 if ( proxy == NULL ) return NULL; 00250 return new ALLOCATOR_TYPE( (proxy->*fieldExtractorPtr)() ); 00251 } 00252 protected: 00253 ProxyExtractor proxyExtractorPtr; 00254 FieldExtractor fieldExtractorPtr; 00255 }; // class def 00256 ///---------------------------------------------------------------------------------------------------------------------- 00257 // specialization for PROXY_TYPE pointers (they should be const! this won't free anything!) AND RETURN_TYPE pointer (acquired, not copied by allocator) 00258 template <class OBJECT_TYPE, class PROXY_TYPE, typename RETURN_TYPE> 00259 class IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE*, RETURN_TYPE*, void> : public virtual IDataFieldWrapperRead<OBJECT_TYPE> 00260 { 00261 public: 00262 typedef PROXY_TYPE* (OBJECT_TYPE::*ProxyExtractor)(void) const; 00263 typedef RETURN_TYPE* (PROXY_TYPE::*FieldExtractor)(void) const; 00264 public: 00265 explicit IDataFieldWrapperReadSubT<OBJECT_TYPE, PROXY_TYPE*, RETURN_TYPE*, void>( ProxyExtractor proxy_fptr, FieldExtractor field_fptr ) 00266 : IDataFieldWrapperRead<OBJECT_TYPE>(), proxyExtractorPtr(proxy_fptr), fieldExtractorPtr(field_fptr) { } 00267 public: 00268 inline ISerializable* read( const OBJECT_TYPE* object ) const { 00269 PROXY_TYPE* proxy = (object->*proxyExtractorPtr)(); 00270 if ( proxy == NULL ) return NULL; 00271 return (proxy->*fieldExtractorPtr)(); 00272 } 00273 protected: 00274 ProxyExtractor proxyExtractorPtr; 00275 FieldExtractor fieldExtractorPtr; 00276 }; // class def 00277 ///---------------------------------------------------------------------------------------------------------------------- 00278 ///---------------------------------------------------------------------------------------------------------------------- 00279 00280 ///---------------------------------------------------------------------------------------------------------------------- 00281 /** 00282 * @class wosh::IDataFieldWrapperWriteT 00283 * @brief DataField \c write Wrapper template. Provided for convenience. 00284 * 00285 * \code 00286 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) { 00287 if ( fields == NULL ) return; 00288 DataFieldDefinitionT<myObject>* df_str = fields->add("MyURIField"); 00289 df_str->setWrapperWrite<const URI&, URI>(&myObject::getURI); 00290 } 00291 \endcode 00292 * 00293 ****************************************************************************/ 00294 template <class OBJECT_TYPE, typename ARGUMENT_TYPE, class PROXY_TYPE> 00295 class IDataFieldWrapperWriteT : public virtual IDataFieldWrapperWrite<OBJECT_TYPE> 00296 { 00297 public: 00298 ///@brief definition of the (OBJECT_TYPE) member function used to write (update) value of type ARGUMENT_TYPE 00299 typedef void (OBJECT_TYPE::*FieldWriter)(ARGUMENT_TYPE); 00300 public: 00301 IDataFieldWrapperWriteT( FieldWriter fptr = NULL ) 00302 : IDataFieldWrapperWrite<OBJECT_TYPE>(), fieldWriterPtr(fptr) { } 00303 public: 00304 virtual WRESULT write( OBJECT_TYPE* object, const ISerializable* data ) const { 00305 const PROXY_TYPE* data_proxy = dynamic_cast<const PROXY_TYPE*>(data); 00306 if ( object == NULL || data_proxy == NULL ) return WRET_ERR_PARAM; 00307 if ( this->fieldWriterPtr == NULL ) return WRET_ERR_INTERNAL; 00308 (object->*this->fieldWriterPtr)( *data_proxy ); 00309 return WRET_OK; 00310 } 00311 protected: 00312 FieldWriter fieldWriterPtr; ///< pointer to the (real member) writer (function) 00313 00314 }; // class def 00315 ///---------------------------------------------------------------------------------------------------------------------- 00316 ///---------------------------------------------------------------------------------------------------------------------- 00317 00318 00319 00320 ///---------------------------------------------------------------------------------------------------------------------- 00321 /** 00322 * @class wosh::IDataFieldWrapperWriteProxyT 00323 * @brief DataField \c write Wrapper template. Provided for convenience. 00324 * 00325 * \code 00326 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) { 00327 if ( fields == NULL ) return; 00328 DataFieldDefinitionT<myObject>* df_str = fields->add("StringData"); 00329 df_str->setWrapperWrite<const std::string&, Variant, std::string>(&myObject::setStringData, &Variant::toString ); 00330 } 00331 \endcode 00332 * 00333 * 00334 ****************************************************************************/ 00335 template <class OBJECT_TYPE, typename ARGUMENT_TYPE, class PROXY_TYPE, class PROXY_RETURN_TYPE> 00336 class IDataFieldWrapperWriteProxyT : public virtual IDataFieldWrapperWrite<OBJECT_TYPE> 00337 { 00338 public: 00339 ///@brief definition of the (OBJECT_TYPE) member function used to write (update) value of type ARGUMENT_TYPE 00340 typedef void (OBJECT_TYPE::*FieldWriter)(ARGUMENT_TYPE); 00341 typedef PROXY_RETURN_TYPE (PROXY_TYPE::*ArgumentWrapper)() const; 00342 public: 00343 IDataFieldWrapperWriteProxyT( FieldWriter fptr = NULL, ArgumentWrapper fptr_arg = NULL ) 00344 : IDataFieldWrapperWrite<OBJECT_TYPE>(), fieldWriterPtr(fptr), argumentWrapperPtr(fptr_arg) { } 00345 public: 00346 virtual WRESULT write( OBJECT_TYPE* object, const ISerializable* data ) const { 00347 const PROXY_TYPE* data_proxy = dynamic_cast<const PROXY_TYPE*>(data); 00348 if ( object == NULL || data_proxy == NULL ) return WRET_ERR_PARAM; 00349 if ( this->fieldWriterPtr == NULL || this->argumentWrapperPtr == NULL ) return WRET_ERR_INTERNAL; 00350 (object->*this->fieldWriterPtr)( (data_proxy->*this->argumentWrapperPtr)() ); 00351 return WRET_OK; 00352 } 00353 protected: 00354 FieldWriter fieldWriterPtr; ///< pointer to the (real member) writer (function) 00355 ArgumentWrapper argumentWrapperPtr; 00356 }; // class def 00357 00358 ///---------------------------------------------------------------------------------------------------------------------- 00359 /** 00360 * @class wosh::IDataFieldWrapperWriteWithArgT 00361 * @brief DataField \c write Wrapper template. Provided for convenience. 00362 * 00363 * \code 00364 void myObject::initializeDataFields( DataFieldCollection<myObject>* fields ) { 00365 if ( fields == NULL ) return; 00366 DataFieldDefinitionT<myObject>* df_int = fields->add("IntData"); 00367 df_int->setWrapperWrite<int, Variant, int, int>(&myObject::setIntData, &Variant::toInteger, -1 ); 00368 } 00369 \endcode 00370 * 00371 * 00372 ****************************************************************************/ 00373 template <class OBJECT_TYPE, typename ARGUMENT_TYPE, class PROXY_TYPE, class PROXY_RETURN_TYPE, class PROXY_ARGUMENT_TYPE> 00374 class IDataFieldWrapperWriteWithArgT : public virtual IDataFieldWrapperWrite<OBJECT_TYPE> 00375 { 00376 public: 00377 typedef void (OBJECT_TYPE::*FieldWriter)(ARGUMENT_TYPE); 00378 typedef PROXY_RETURN_TYPE (PROXY_TYPE::*ArgumentWrapper)(PROXY_ARGUMENT_TYPE) const; 00379 public: 00380 IDataFieldWrapperWriteWithArgT( FieldWriter fptr, ArgumentWrapper fptr_arg, const PROXY_ARGUMENT_TYPE& arg_value_ ) 00381 : IDataFieldWrapperWrite<OBJECT_TYPE>(), fieldWriterPtr(fptr), argumentWrapperPtr(fptr_arg), arg_value(arg_value_) { } 00382 public: 00383 virtual WRESULT write( OBJECT_TYPE* object, const ISerializable* data ) const { 00384 const PROXY_TYPE* data_proxy = dynamic_cast<const PROXY_TYPE*>(data); 00385 if ( object == NULL || data_proxy == NULL ) return WRET_ERR_PARAM; 00386 if ( fieldWriterPtr == NULL || argumentWrapperPtr == NULL ) return WRET_ERR_INTERNAL; 00387 (object->*fieldWriterPtr)( (data_proxy->*argumentWrapperPtr)(arg_value) ); 00388 return WRET_OK; 00389 } 00390 protected: 00391 FieldWriter fieldWriterPtr; ///< pointer to the (real member) writer (function) 00392 ArgumentWrapper argumentWrapperPtr; 00393 const PROXY_ARGUMENT_TYPE arg_value; 00394 }; // class def 00395 ///---------------------------------------------------------------------------------------------------------------------- 00396 ///---------------------------------------------------------------------------------------------------------------------- 00397 00398 00399 00400 }; // namespace wosh 00401 00402 #endif //__WOSH_Core_DataWrappers_H__