DataWrappers.h

Go to the documentation of this file.
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__

Generated on Tue Feb 8 2011 09:32:50 for WOSH system 0.8.888 [wolf] by Alessandro Polo, using DoxyGen 1.7.2 hosted by WOSH Framework