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