Teuchos - Trilinos Tools Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Teuchos_SerializerHelpers.hpp
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. 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 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_SERIALIZER_HELPERS_HPP
00043 #define TEUCHOS_SERIALIZER_HELPERS_HPP
00044 
00045 #include "Teuchos_Serializer.hpp"
00046 #include "Teuchos_Array.hpp"
00047 
00048 namespace Teuchos {
00049 
00053 template <typename Ordinal, typename T>
00054 class ReferenceTypeSerializationBuffer {
00055 public:
00057   ReferenceTypeSerializationBuffer(
00058     const Serializer<Ordinal,T> &serializer
00059     ,const Ordinal count, T*const buffer[]
00060     );
00064   ~ReferenceTypeSerializationBuffer();
00066   char* getCharBuffer() const;
00068   Ordinal getBytes() const;
00069 private:
00070   const Serializer<Ordinal,T>  &serializer_;
00071   Ordinal                      count_;
00072   T*const                      *buffer_;
00073   Array<char>                  charBuffer_;
00074   // Not defined and not to be called
00075   ReferenceTypeSerializationBuffer();
00076   ReferenceTypeSerializationBuffer(const ReferenceTypeSerializationBuffer&);
00077   ReferenceTypeSerializationBuffer& operator=(const ReferenceTypeSerializationBuffer&);
00078 };
00079 
00083 template <typename Ordinal, typename T>
00084 class ConstReferenceTypeSerializationBuffer {
00085 public:
00087   ConstReferenceTypeSerializationBuffer(
00088     const Serializer<Ordinal,T> &serializer
00089     ,const Ordinal count, const T*const buffer[]
00090     );
00094   ~ConstReferenceTypeSerializationBuffer();
00096   const char* getCharBuffer() const;
00098   Ordinal getBytes() const;
00099 private:
00100   const Serializer<Ordinal,T>  &serializer_;
00101   Ordinal                      count_;
00102   const T*const                *buffer_;
00103   Ordinal                      bytes_;
00104   Array<char>                  charBuffer_;
00105   // Not defined and not to be called
00106   ConstReferenceTypeSerializationBuffer();
00107   ConstReferenceTypeSerializationBuffer(const ConstReferenceTypeSerializationBuffer&);
00108   ConstReferenceTypeSerializationBuffer& operator=(const ConstReferenceTypeSerializationBuffer&);
00109 };
00110 
00115 template <typename Ordinal, typename T>
00116 class ReferenceTypeDeserializationBuffer {
00117 public:
00119   ReferenceTypeDeserializationBuffer(
00120     const Serializer<Ordinal,T> &serializer
00121     ,const Ordinal bytes, char charBuffer[]
00122     );
00126   ~ReferenceTypeDeserializationBuffer();
00128   T*const* getBuffer() const;
00130   Ordinal getCount() const;
00131 private:
00132   typedef Array<RCP<T> >  buffer_ptr_t;
00133   typedef Array<T*>               buffer_t;
00134   const Serializer<Ordinal,T>  &serializer_;
00135   Ordinal                      bytes_;
00136   char                         *charBuffer_;
00137   buffer_ptr_t                 buffer_ptr_;
00138   buffer_t                     buffer_;
00139   // Not defined and not to be called
00140   ReferenceTypeDeserializationBuffer();
00141   ReferenceTypeDeserializationBuffer(const ReferenceTypeDeserializationBuffer&);
00142   ReferenceTypeDeserializationBuffer& operator=(const ReferenceTypeDeserializationBuffer&);
00143 };
00144 
00149 template <typename Ordinal, typename T>
00150 class ConstReferenceTypeDeserializationBuffer {
00151 public:
00153   ConstReferenceTypeDeserializationBuffer(
00154     const Serializer<Ordinal,T> &serializer
00155     ,const Ordinal bytes, const char charBuffer[]
00156     );
00160   ~ConstReferenceTypeDeserializationBuffer();
00162   const T*const* getBuffer() const;
00164   Ordinal getCount() const;
00165 private:
00166   typedef Array<RCP<T> >  buffer_ptr_t;
00167   typedef Array<T*>               buffer_t;
00168   const Serializer<Ordinal,T>  &serializer_;
00169   Ordinal                      bytes_;
00170   const char                   *charBuffer_;
00171   buffer_ptr_t                 buffer_ptr_;
00172   buffer_t                     buffer_;
00173   // Not defined and not to be called
00174   ConstReferenceTypeDeserializationBuffer();
00175   ConstReferenceTypeDeserializationBuffer(const ConstReferenceTypeDeserializationBuffer&);
00176   ConstReferenceTypeDeserializationBuffer& operator=(const ConstReferenceTypeDeserializationBuffer&);
00177 };
00178 
00179 // /////////////////////////////////////
00180 // Template implementations
00181 
00182 //
00183 // ReferenceTypeSerializationBuffer
00184 //
00185 
00186 template <typename Ordinal, typename T>
00187 ReferenceTypeSerializationBuffer<Ordinal,T>::ReferenceTypeSerializationBuffer(
00188   const Serializer<Ordinal,T> &serializer
00189   ,const Ordinal count, T*const buffer[]
00190   )
00191   :serializer_(serializer), count_(count), buffer_(buffer)
00192 {
00193   const Ordinal bytes = serializer_.getBufferSize(count_);
00194   charBuffer_.resize(bytes);
00195   serializer_.serialize(count_,buffer_,bytes,&charBuffer_[0]);
00196 }
00197 
00198 template <typename Ordinal, typename T>
00199 ReferenceTypeSerializationBuffer<Ordinal,T>::~ReferenceTypeSerializationBuffer()
00200 {
00201   serializer_.deserialize(charBuffer_.size(),&charBuffer_[0],count_,buffer_);
00202 }
00203 
00204 template <typename Ordinal, typename T>
00205 char* ReferenceTypeSerializationBuffer<Ordinal,T>::getCharBuffer() const
00206 {
00207   typedef ReferenceTypeSerializationBuffer<Ordinal,T>* this_ptr_t;
00208   return &(const_cast<this_ptr_t>(this)->charBuffer_)[0];
00209   // The above const_cast is a better alternative to declaring charBuffer_ to
00210   // be mutable, in my opinion.
00211 }
00212 
00213 template <typename Ordinal, typename T>
00214 Ordinal ReferenceTypeSerializationBuffer<Ordinal,T>::getBytes() const
00215 {
00216   return charBuffer_.size();
00217 }
00218 
00219 //
00220 // ConstReferenceTypeSerializationBuffer
00221 //
00222 
00223 template <typename Ordinal, typename T>
00224 ConstReferenceTypeSerializationBuffer<Ordinal,T>::ConstReferenceTypeSerializationBuffer(
00225   const Serializer<Ordinal,T> &serializer
00226   ,const Ordinal count, const T*const buffer[]
00227   ):
00228   serializer_(serializer),
00229   count_(count),
00230   buffer_(buffer),
00231   bytes_(0)
00232 {
00233   const Ordinal bytes = serializer_.getBufferSize(count_);
00234   charBuffer_.resize(bytes);
00235   serializer_.serialize(count_,buffer_,bytes,&charBuffer_[0]);
00236 }
00237 
00238 template <typename Ordinal, typename T>
00239 ConstReferenceTypeSerializationBuffer<Ordinal,T>::~ConstReferenceTypeSerializationBuffer()
00240 {
00241   // No need to copy back from the char[] buffer!
00242 }
00243 
00244 template <typename Ordinal, typename T>
00245 const char* ConstReferenceTypeSerializationBuffer<Ordinal,T>::getCharBuffer() const
00246 {
00247   return &charBuffer_[0];
00248 }
00249 
00250 template <typename Ordinal, typename T>
00251 Ordinal ConstReferenceTypeSerializationBuffer<Ordinal,T>::getBytes() const
00252 {
00253   return charBuffer_.size();
00254 }
00255 
00256 //
00257 // ReferenceTypeDeserializationBuffer
00258 //
00259 
00260 template <typename Ordinal, typename T>
00261 ReferenceTypeDeserializationBuffer<Ordinal,T>::ReferenceTypeDeserializationBuffer(
00262   const Serializer<Ordinal,T> &serializer
00263   ,const Ordinal bytes, char charBuffer[]
00264   )
00265   :serializer_(serializer),bytes_(bytes),charBuffer_(charBuffer)
00266 {
00267   const Ordinal extent = serializer_.getBufferSize(1);
00268   const Ordinal count = bytes_ / extent;
00269 #ifdef TEUCHOS_DEBUG
00270   TEUCHOS_TEST_FOR_EXCEPT( !( bytes_ % extent == 0 ) );
00271 #endif
00272   buffer_ptr_.resize(count);
00273   buffer_.resize(count);
00274   for( int i = 0; i < count; ++i ) {
00275     buffer_ptr_[i] = serializer_.createObj();
00276     buffer_[i] = &*buffer_ptr_[i];
00277   }
00278   serializer_.deserialize(
00279     bytes_,charBuffer_,count,&buffer_[0]
00280     );
00281 }
00282 
00283 template <typename Ordinal, typename T>
00284 ReferenceTypeDeserializationBuffer<Ordinal,T>::~ReferenceTypeDeserializationBuffer()
00285 {
00286   serializer_.serialize(
00287     buffer_.size(),&buffer_[0],bytes_,charBuffer_
00288     );
00289 }
00290 
00291 template <typename Ordinal, typename T>
00292 T*const* ReferenceTypeDeserializationBuffer<Ordinal,T>::getBuffer() const
00293 {
00294   typedef ReferenceTypeDeserializationBuffer<Ordinal,T>* this_ptr_t;
00295   return &(const_cast<this_ptr_t>(this)->buffer_)[0];
00296   // The above const_cast is a better alternative to declaring buffer_ to be
00297   // mutable, in my opinion.
00298 }
00299 
00300 template <typename Ordinal, typename T>
00301 Ordinal ReferenceTypeDeserializationBuffer<Ordinal,T>::getCount() const
00302 {
00303   return buffer_.size();
00304 }
00305 
00306 //
00307 // ConstReferenceTypeDeserializationBuffer
00308 //
00309 
00310 template <typename Ordinal, typename T>
00311 ConstReferenceTypeDeserializationBuffer<Ordinal,T>::ConstReferenceTypeDeserializationBuffer(
00312   const Serializer<Ordinal,T> &serializer
00313   ,const Ordinal bytes, const char charBuffer[]
00314   )
00315   :serializer_(serializer),bytes_(bytes),charBuffer_(charBuffer)
00316 {
00317   const Ordinal extent = serializer_.getBufferSize(1);
00318   const Ordinal count = bytes_ / extent;
00319 #ifdef TEUCHOS_DEBUG
00320   TEUCHOS_TEST_FOR_EXCEPT( !( bytes_ % extent == 0 ) );
00321 #endif
00322   buffer_ptr_.resize(count);
00323   buffer_.resize(count);
00324   for( int i = 0; i < count; ++i ) {
00325     buffer_ptr_[i] = serializer_.createObj();
00326     buffer_[i] = &*buffer_ptr_[i];
00327   }
00328   serializer_.deserialize(
00329     bytes_,charBuffer_,count,&buffer_[0]
00330     );
00331 }
00332 
00333 template <typename Ordinal, typename T>
00334 ConstReferenceTypeDeserializationBuffer<Ordinal,T>::~ConstReferenceTypeDeserializationBuffer()
00335 {
00336   // We don't need to serialized back into charBuffer_[] since it is constant!
00337 }
00338 
00339 template <typename Ordinal, typename T>
00340 const T*const* ConstReferenceTypeDeserializationBuffer<Ordinal,T>::getBuffer() const
00341 {
00342   return &buffer_[0];
00343 }
00344 
00345 template <typename Ordinal, typename T>
00346 Ordinal ConstReferenceTypeDeserializationBuffer<Ordinal,T>::getCount() const
00347 {
00348   return buffer_.size();
00349 }
00350 
00351 } // namespace Teuchos
00352 
00353 #endif // TEUCHOS_SERIALIZER_HELPERS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines