Equalizer
1.2.1
|
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