Collage  0.6.1
dataIStream.h
00001 
00002 /* Copyright (c) 2007-2012, 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 <lunchbox/buffer.h> // member
00026 #include <lunchbox/types.h>
00027 
00028 #include <iostream>
00029 #include <vector>
00030 
00031 namespace co
00032 {
00034     class DataIStream
00035     {
00036     public:
00039         CO_API DataIStream();
00040         DataIStream( const DataIStream& );
00041         CO_API virtual ~DataIStream();
00042 
00044         virtual size_t nRemainingBuffers() const = 0;
00045 
00046         virtual uint128_t getVersion() const = 0;
00047 
00048         virtual void reset() { _reset(); }
00050 
00054         template< typename T > DataIStream& operator >> ( T& value )
00055             { read( &value, sizeof( value )); return *this; }
00056 
00058         template< typename T >
00059         DataIStream& operator >> ( std::vector< T >& value )
00060         {
00061             uint64_t nElems = 0;
00062             read( &nElems, sizeof( nElems ));
00063             value.resize( nElems );
00064             for( uint64_t i = 0; i < nElems; i++ )
00065                 (*this) >> value[i];
00066 
00067             return *this; 
00068         }
00069 
00081         template< typename O, typename C >
00082         void deserializeChildren( O* object, const std::vector< C* >& old,
00083                                   std::vector< C* >& result );
00084 
00086         CO_API void read( void* data, uint64_t size );
00087 
00099         CO_API const void* getRemainingBuffer();
00100 
00102         CO_API uint64_t getRemainingBufferSize();
00103 
00105         CO_API void advanceBuffer( const uint64_t offset );
00106 
00108         bool hasData() { return _checkBuffer(); }
00110 
00112         CO_API virtual NodePtr getMaster() = 0;
00113 
00114     protected:
00115         virtual bool getNextBuffer( uint32_t* compressor, uint32_t* nChunks,
00116                                     const void** chunkData, uint64_t* size )=0;
00117 
00118     private:
00120         const uint8_t* _input;
00122         uint64_t _inputSize;
00124         uint64_t  _position;
00125 
00126         CPUCompressor* const _decompressor; 
00127         lunchbox::Bufferb _data; 
00128 
00133         CO_API bool _checkBuffer();
00134         CO_API void _reset();
00135         
00136         const uint8_t* _decompress( const void* data, const uint32_t name,
00137                                     const uint32_t nChunks,
00138                                     const uint64_t dataSize );
00139 
00141         template< typename T >
00142         DataIStream& _readFlatVector ( std::vector< T >& value )
00143         {
00144             uint64_t nElems = 0;
00145             read( &nElems, sizeof( nElems ));
00146             LBASSERTINFO( nElems < LB_BIT48,
00147                   "Out-of-sync co::DataIStream: " << nElems << " elements?" );
00148             value.resize( size_t( nElems ));
00149             if( nElems > 0 )
00150                 read( &value.front(), nElems * sizeof( T ));
00151             return *this; 
00152         }
00153     };
00154 }
00155 
00156 #include <co/object.h>
00157 #include <co/objectVersion.h>
00158 
00159 namespace co{
00163     template<>
00164     inline DataIStream& DataIStream::operator >> ( std::string& str )
00165     { 
00166         uint64_t nElems = 0;
00167         read( &nElems, sizeof( nElems ));
00168         LBASSERTINFO( nElems <= getRemainingBufferSize(),
00169                       nElems << " > " << getRemainingBufferSize( ));
00170         if( nElems == 0 )
00171             str.clear();
00172         else
00173         {
00174             str.assign( static_cast< const char* >( getRemainingBuffer( )), 
00175                         size_t( nElems ));
00176             advanceBuffer( nElems );
00177         }
00178         return *this; 
00179     }
00180 
00182     template<> inline DataIStream& DataIStream::operator >> ( Object*& object )
00183     {
00184         ObjectVersion data;
00185         (*this) >> data;
00186         LBASSERT( object->getID() == data.identifier );
00187         object->sync( data.version );
00188         return *this;
00189     }
00190 
00191     namespace
00192     {
00193     class ObjectFinder
00194     {
00195     public:
00196         ObjectFinder( const UUID& id ) : _id( id ) {}
00197         bool operator()( co::Object* candidate )
00198             { return candidate->getID() == _id; }
00199 
00200     private:
00201         const UUID _id;
00202     };
00203     }
00204 
00206     template< typename O, typename C > inline void
00207     DataIStream::deserializeChildren( O* object, const std::vector< C* >& old_,
00208                                       std::vector< C* >& result )
00209     {
00210         ObjectVersions versions;
00211         (*this) >> versions;
00212         std::vector< C* > old = old_;
00213 
00214         // rebuild vector from serialized list
00215         result.clear();
00216         for( ObjectVersions::const_iterator i = versions.begin();
00217              i != versions.end(); ++i )
00218         {
00219             const ObjectVersion& version = *i;
00220             
00221             if( version.identifier == UUID::ZERO )
00222             {
00223                 result.push_back( 0 );
00224                 continue;
00225             }
00226 
00227             typename std::vector< C* >::iterator j =
00228                 stde::find_if( old, ObjectFinder( version.identifier ));
00229 
00230             if( j == old.end( )) // previously unknown child
00231             {
00232                 C* child = 0;
00233                 object->create( &child );
00234                 LocalNodePtr localNode = object->getLocalNode();
00235                 LBASSERT( child );
00236                 LBASSERT( !object->isMaster( ));
00237 
00238                 LBCHECK( localNode->mapObject( child, version ));
00239                 result.push_back( child );
00240             }
00241             else
00242             {
00243                 C* child = *j;
00244                 old.erase( j );
00245                 if( object->isMaster( ))
00246                     child->sync( VERSION_HEAD );
00247                 else
00248                     child->sync( version.version );
00249 
00250                 result.push_back( child );
00251             }
00252         }
00253 
00254         while( !old.empty( )) // removed children
00255         {
00256             C* child = old.back();
00257             old.pop_back();
00258             if( !child )
00259                 continue;
00260 
00261             if( child->isAttached() && !child->isMaster( ))
00262             {
00263                 LocalNodePtr localNode = object->getLocalNode();
00264                 localNode->unmapObject( child );
00265             }
00266             object->release( child );
00267         }
00268     }
00272     template<> inline DataIStream&
00273     DataIStream::operator >> ( std::vector< uint8_t >& value )
00274     { return _readFlatVector( value );}
00275 
00277     template<> inline DataIStream&
00278     DataIStream::operator >> ( std::vector< uint16_t >& value )
00279     { return _readFlatVector( value ); }
00280 
00282     template<> inline DataIStream&
00283     DataIStream::operator >> ( std::vector< int16_t >& value )
00284     { return _readFlatVector( value ); }
00285 
00287     template<> inline DataIStream&
00288     DataIStream::operator >> ( std::vector< uint32_t >& value )
00289     { return _readFlatVector( value ); }
00290 
00292     template<> inline DataIStream&
00293     DataIStream::operator >> ( std::vector< int32_t >& value )
00294     { return _readFlatVector( value ); }
00295 
00297     template<> inline DataIStream&
00298     DataIStream::operator >> ( std::vector< uint64_t>& value )
00299     { return _readFlatVector( value ); }
00300 
00302     template<> inline DataIStream&
00303     DataIStream::operator >> ( std::vector< int64_t >& value )
00304     { return _readFlatVector( value ); }
00305 
00307     template<> inline DataIStream&
00308     DataIStream::operator >> ( std::vector< float >& value )
00309     { return _readFlatVector( value ); }
00310 
00312     template<> inline DataIStream&
00313     DataIStream::operator >> ( std::vector< double >& value )
00314     { return _readFlatVector( value ); }
00315 
00317     template<> inline DataIStream&
00318     DataIStream::operator >> ( std::vector< ObjectVersion >& value )
00319     { return _readFlatVector( value ); }
00321 }
00322 
00323 #endif //CO_DATAISTREAM_H
Generated on Mon Nov 26 2012 14:41:44 for Collage 0.6.1 by  doxygen 1.7.6.1