Equalizer  1.2.1
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 void reset() { _reset(); }
00051 
00055         template< typename T > DataIStream& operator >> ( T& value )
00056             { read( &value, sizeof( value )); return *this; }
00057 
00059         template< typename T >
00060         DataIStream& operator >> ( std::vector< T >& value )
00061         {
00062             uint64_t nElems = 0;
00063             read( &nElems, sizeof( nElems ));
00064             value.resize( nElems );
00065             for( uint64_t i = 0; i < nElems; i++ )
00066                 (*this) >> value[i];
00067 
00068             return *this; 
00069         }
00070 
00082         template< typename O, typename C >
00083         void deserializeChildren( O* object, const std::vector< C* >& old,
00084                                   std::vector< C* >& result );
00085 
00087         CO_API void read( void* data, uint64_t size );
00088 
00100         CO_API const void* getRemainingBuffer();
00101 
00103         CO_API uint64_t getRemainingBufferSize();
00104 
00106         CO_API void advanceBuffer( const uint64_t offset );
00107 
00109         bool hasData() { return _checkBuffer(); }
00111  
00112     protected:
00113         virtual bool getNextBuffer( uint32_t* compressor, uint32_t* nChunks,
00114                                     const void** chunkData, uint64_t* size )=0;
00115 
00116     private:
00118         const uint8_t* _input;
00120         uint64_t _inputSize;
00122         uint64_t  _position;
00123 
00124         base::CPUCompressor* const _decompressor; 
00125         base::Bufferb _data; 
00126 
00131         CO_API bool _checkBuffer();
00132         CO_API void _reset();
00133         
00134         const uint8_t* _decompress( const void* data, const uint32_t name,
00135                                     const uint32_t nChunks,
00136                                     const uint64_t dataSize );
00137 
00139         template< typename T >
00140         DataIStream& _readFlatVector ( std::vector< T >& value )
00141         {
00142             uint64_t nElems = 0;
00143             read( &nElems, sizeof( nElems ));
00144             EQASSERTINFO( nElems < EQ_BIT48,
00145                   "Out-of-sync co::DataIStream: " << nElems << " elements?" );
00146             value.resize( size_t( nElems ));
00147             if( nElems > 0 )
00148                 read( &value.front(), nElems * sizeof( T ));
00149             return *this; 
00150         }
00151     };
00152 }
00153 
00154 #include <co/object.h>
00155 #include <co/objectVersion.h>
00156 
00157 namespace co{
00161     template<>
00162     inline DataIStream& DataIStream::operator >> ( std::string& str )
00163     { 
00164         uint64_t nElems = 0;
00165         read( &nElems, sizeof( nElems ));
00166         EQASSERTINFO( nElems <= getRemainingBufferSize(),
00167                       nElems << " > " << getRemainingBufferSize( ));
00168         if( nElems == 0 )
00169             str.clear();
00170         else
00171         {
00172             str.assign( static_cast< const char* >( getRemainingBuffer( )), 
00173                         size_t( nElems ));
00174             advanceBuffer( nElems );
00175         }
00176         return *this; 
00177     }
00178 
00180     template<> inline DataIStream& DataIStream::operator >> ( Object*& object )
00181     {
00182         ObjectVersion data;
00183         (*this) >> data;
00184         EQASSERT( object->getID() == data.identifier );
00185         object->sync( data.version );
00186         return *this;
00187     }
00188 
00189     namespace
00190     {
00191     class ObjectFinder
00192     {
00193     public:
00194         ObjectFinder( const base::UUID& id ) : _id( id ) {}
00195         bool operator()( co::Object* candidate )
00196             { return candidate->getID() == _id; }
00197 
00198     private:
00199         const base::UUID _id;
00200     };
00201     }
00202 
00204     template< typename O, typename C > inline void
00205     DataIStream::deserializeChildren( O* object, const std::vector< C* >& old_,
00206                                       std::vector< C* >& result )
00207     {
00208         ObjectVersions versions;
00209         (*this) >> versions;
00210         std::vector< C* > old = old_;
00211 
00212         // rebuild vector from serialized list
00213         result.clear();
00214         for( ObjectVersions::const_iterator i = versions.begin();
00215              i != versions.end(); ++i )
00216         {
00217             const ObjectVersion& version = *i;
00218             
00219             if( version.identifier == base::UUID::ZERO )
00220             {
00221                 result.push_back( 0 );
00222                 continue;
00223             }
00224 
00225             typename std::vector< C* >::iterator j =
00226                 stde::find_if( old, ObjectFinder( version.identifier ));
00227 
00228             if( j == old.end( )) // previously unknown child
00229             {
00230                 C* child = 0;
00231                 object->create( &child );
00232                 LocalNodePtr localNode = object->getLocalNode();
00233                 EQASSERT( child );
00234                 EQASSERT( !object->isMaster( ));
00235 
00236                 EQCHECK( localNode->mapObject( child, version ));
00237                 result.push_back( child );
00238             }
00239             else
00240             {
00241                 C* child = *j;
00242                 old.erase( j );
00243                 if( object->isMaster( ))
00244                     child->sync( VERSION_HEAD );
00245                 else
00246                     child->sync( version.version );
00247 
00248                 result.push_back( child );
00249             }
00250         }
00251 
00252         while( !old.empty( )) // removed children
00253         {
00254             C* child = old.back();
00255             old.pop_back();
00256             if( !child )
00257                 continue;
00258 
00259             if( child->isAttached() && !child->isMaster( ))
00260             {
00261                 LocalNodePtr localNode = object->getLocalNode();
00262                 localNode->unmapObject( child );
00263             }
00264             object->release( child );
00265         }
00266     }
00270     template<> inline DataIStream&
00271     DataIStream::operator >> ( std::vector< uint8_t >& value )
00272     { return _readFlatVector( value );}
00273 
00275     template<> inline DataIStream&
00276     DataIStream::operator >> ( std::vector< uint16_t >& value )
00277     { return _readFlatVector( value ); }
00278 
00280     template<> inline DataIStream&
00281     DataIStream::operator >> ( std::vector< int16_t >& value )
00282     { return _readFlatVector( value ); }
00283 
00285     template<> inline DataIStream&
00286     DataIStream::operator >> ( std::vector< uint32_t >& value )
00287     { return _readFlatVector( value ); }
00288 
00290     template<> inline DataIStream&
00291     DataIStream::operator >> ( std::vector< int32_t >& value )
00292     { return _readFlatVector( value ); }
00293 
00295     template<> inline DataIStream&
00296     DataIStream::operator >> ( std::vector< uint64_t>& value )
00297     { return _readFlatVector( value ); }
00298 
00300     template<> inline DataIStream&
00301     DataIStream::operator >> ( std::vector< int64_t >& value )
00302     { return _readFlatVector( value ); }
00303 
00305     template<> inline DataIStream&
00306     DataIStream::operator >> ( std::vector< float >& value )
00307     { return _readFlatVector( value ); }
00308 
00310     template<> inline DataIStream&
00311     DataIStream::operator >> ( std::vector< double >& value )
00312     { return _readFlatVector( value ); }
00313 
00315     template<> inline DataIStream&
00316     DataIStream::operator >> ( std::vector< ObjectVersion >& value )
00317     { return _readFlatVector( value ); }
00319 }
00320 
00321 #endif //CO_DATAISTREAM_H
Generated on Fri Jun 8 2012 15:44:30 for Equalizer 1.2.1 by  doxygen 1.8.0