Collage
0.6.1
|
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