Equalizer 1.0

dataIStream.h

00001 
00002 /* Copyright (c) 2007-2011, Stefan Eilemann <eile@equalizergraphics.com>
00003  *               2009-2010, Cedric Stalder <cedric.stalder@gmail.com> 
00004  *
00005  * This library is free software; you can redistribute it and/or modify it under
00006  * the terms of the GNU Lesser General Public License version 2.1 as published
00007  * by the Free Software Foundation.
00008  *  
00009  * This library is distributed in the hope that it will be useful, but WITHOUT
00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00012  * details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this library; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 
00019 #ifndef CO_DATAISTREAM_H
00020 #define CO_DATAISTREAM_H
00021 
00022 #include <co/api.h>
00023 #include <co/types.h>
00024 
00025 #include <co/base/buffer.h> // member
00026 #include <co/base/types.h>
00027 
00028 
00029 #include <iostream>
00030 #include <vector>
00031 
00032 namespace co
00033 {
00035     class DataIStream
00036     {
00037     public:
00040         CO_API DataIStream();
00041         DataIStream( const DataIStream& );
00042         CO_API virtual ~DataIStream();
00043 
00045         virtual size_t nRemainingBuffers() const = 0;
00046 
00047         virtual uint128_t getVersion() const = 0;
00048 
00049         virtual CO_API void reset();
00051 
00055         template< typename T >
00056         DataIStream& operator >> ( T& value )
00057             { read( &value, sizeof( value )); return *this; }
00058 
00060         template< typename T >
00061         DataIStream& operator >> ( std::vector< T >& value )
00062         {
00063             uint64_t nElems = 0;
00064             read( &nElems, sizeof( nElems ));
00065             value.resize( nElems );
00066             for( uint64_t i = 0; i < nElems; i++ )
00067                 (*this) >> value[i];
00068 
00069             return *this; 
00070         }
00071 
00083         template< typename O, typename C >
00084         void deserializeChildren( O* object, const std::vector< C* >& old,
00085                                   std::vector< C* >& result );
00086 
00088         CO_API void read( void* data, uint64_t size );
00089 
00101         CO_API const void*    getRemainingBuffer();
00102 
00104         CO_API uint64_t       getRemainingBufferSize();
00105 
00107         CO_API void           advanceBuffer( const uint64_t offset );
00109  
00110     protected:
00111         virtual bool getNextBuffer( uint32_t* compressor, uint32_t* nChunks,
00112                                     const void** chunkData, uint64_t* size )=0;
00113 
00114     private:
00116         const uint8_t* _input;
00118         uint64_t _inputSize;
00120         uint64_t  _position;
00121 
00122         base::CPUCompressor* const _decompressor; 
00123         base::Bufferb _data; 
00124 
00129         bool _checkBuffer();
00130         
00131         const uint8_t* _decompress( const void* data, const uint32_t name,
00132                                     const uint32_t nChunks,
00133                                     const uint64_t dataSize );
00134 
00136         template< typename T >
00137         DataIStream& _readFlatVector ( std::vector< T >& value )
00138         {
00139             uint64_t nElems = 0;
00140             read( &nElems, sizeof( nElems ));
00141             value.resize( nElems );
00142             if( nElems > 0 )
00143                 read( &value.front(), nElems * sizeof( T ));
00144             return *this; 
00145         }
00146     };
00147 }
00148 
00149 #include <co/object.h>
00150 #include <co/objectVersion.h>
00151 
00152 namespace co{
00156     template<>
00157     inline DataIStream& DataIStream::operator >> ( std::string& str )
00158     { 
00159         uint64_t nElems = 0;
00160         read( &nElems, sizeof( nElems ));
00161         EQASSERTINFO( nElems <= getRemainingBufferSize(),
00162                       nElems << " > " << getRemainingBufferSize( ));
00163         if( nElems == 0 )
00164             str.clear();
00165         else
00166         {
00167             str.assign( static_cast< const char* >( getRemainingBuffer( )), 
00168                         nElems );
00169             advanceBuffer( nElems );
00170         }
00171         return *this; 
00172     }
00173 
00175     template<> inline DataIStream& DataIStream::operator >> ( Object*& object )
00176     {
00177         ObjectVersion data;
00178         (*this) >> data;
00179         EQASSERT( object->getID() == data.identifier );
00180         object->sync( data.version );
00181         return *this;
00182     }
00183 
00184     namespace
00185     {
00186     class ObjectFinder
00187     {
00188     public:
00189         ObjectFinder( const base::UUID& id ) : _id( id ) {}
00190         bool operator()( co::Object* candidate )
00191             { return candidate->getID() == _id; }
00192 
00193     private:
00194         const base::UUID _id;
00195     };
00196     }
00197 
00199     template< typename O, typename C > inline void
00200     DataIStream::deserializeChildren( O* object, const std::vector< C* >& old_,
00201                                       std::vector< C* >& result )
00202     {
00203         ObjectVersions versions;
00204         (*this) >> versions;
00205         std::vector< C* > old = old_;
00206 
00207         // rebuild vector from serialized list
00208         result.clear();
00209         for( ObjectVersions::const_iterator i = versions.begin();
00210              i != versions.end(); ++i )
00211         {
00212             const ObjectVersion& version = *i;
00213             
00214             if( version.identifier == base::UUID::ZERO )
00215             {
00216                 result.push_back( 0 );
00217                 continue;
00218             }
00219 
00220             typename std::vector< C* >::iterator j =
00221                 stde::find_if( old, ObjectFinder( version.identifier ));
00222 
00223             if( j == old.end( )) // previously unknown child
00224             {
00225                 C* child = 0;
00226                 object->create( &child );
00227                 LocalNodePtr localNode = object->getLocalNode();
00228                 EQASSERT( child );
00229                 EQASSERT( !object->isMaster( ));
00230 
00231                 EQCHECK( localNode->mapObject( child, version ));
00232                 result.push_back( child );
00233             }
00234             else
00235             {
00236                 C* child = *j;
00237                 old.erase( j );
00238                 if( object->isMaster( ))
00239                     child->sync( VERSION_HEAD );
00240                 else
00241                     child->sync( version.version );
00242 
00243                 result.push_back( child );
00244             }
00245         }
00246 
00247         while( !old.empty( )) // removed children
00248         {
00249             C* child = old.back();
00250             old.pop_back();
00251             if( !child )
00252                 continue;
00253 
00254             if( child->isAttached() && !child->isMaster( ))
00255             {
00256                 LocalNodePtr localNode = object->getLocalNode();
00257                 localNode->unmapObject( child );
00258             }
00259             object->release( child );
00260         }
00261     }
00265     template<> inline DataIStream&
00266     DataIStream::operator >> ( std::vector< uint8_t >& value )
00267     { return _readFlatVector( value );}
00268 
00270     template<> inline DataIStream&
00271     DataIStream::operator >> ( std::vector< uint16_t >& value )
00272     { return _readFlatVector( value ); }
00273 
00275     template<> inline DataIStream&
00276     DataIStream::operator >> ( std::vector< int16_t >& value )
00277     { return _readFlatVector( value ); }
00278 
00280     template<> inline DataIStream&
00281     DataIStream::operator >> ( std::vector< uint32_t >& value )
00282     { return _readFlatVector( value ); }
00283 
00285     template<> inline DataIStream&
00286     DataIStream::operator >> ( std::vector< int32_t >& value )
00287     { return _readFlatVector( value ); }
00288 
00290     template<> inline DataIStream&
00291     DataIStream::operator >> ( std::vector< uint64_t>& value )
00292     { return _readFlatVector( value ); }
00293 
00295     template<> inline DataIStream&
00296     DataIStream::operator >> ( std::vector< int64_t >& value )
00297     { return _readFlatVector( value ); }
00298 
00300     template<> inline DataIStream&
00301     DataIStream::operator >> ( std::vector< float >& value )
00302     { return _readFlatVector( value ); }
00303 
00305     template<> inline DataIStream&
00306     DataIStream::operator >> ( std::vector< double >& value )
00307     { return _readFlatVector( value ); }
00308 
00310     template<> inline DataIStream&
00311     DataIStream::operator >> ( std::vector< ObjectVersion >& value )
00312     { return _readFlatVector( value ); }
00314 }
00315 
00316 #endif //CO_DATAISTREAM_H
Generated on Sun May 8 2011 19:11:05 for Equalizer 1.0 by  doxygen 1.7.3