LCOV - code coverage report
Current view: top level - co - dataIStream.ipp (source / functions) Hit Total Coverage
Test: Collage Lines: 38 40 95.0 %
Date: 2016-12-14 01:26:48 Functions: 10 10 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2012-2016, Daniel Nachbaur <danielnachbaur@gmail.com>
       3             :  *                          Stefan.Eilemann@epfl.ch
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include <co/object.h>
      20             : #include <co/objectVersion.h>
      21             : #include <servus/serializable.h> // used inline
      22             : 
      23             : namespace co
      24             : {
      25             : /** @name Specialized input operators */
      26             : //@{
      27             : /** Read a std::string. */
      28      406381 : template<> inline DataIStream& DataIStream::operator >> ( std::string& str )
      29             : {
      30      406381 :     uint64_t nElems = 0;
      31      406381 :     *this >> nElems;
      32      406381 :     const uint64_t maxElems = getRemainingBufferSize();
      33      406381 :     LBASSERTINFO( nElems <= maxElems,
      34             :                   nElems << " > " << maxElems );
      35      406381 :     if( nElems == 0 )
      36      395247 :         str.clear();
      37       11134 :     else if( nElems <= maxElems )
      38       11134 :         str.assign( static_cast< const char* >( getRemainingBuffer(nElems)),
      39       22268 :                     size_t( nElems ));
      40             :     else
      41             :         str.assign(
      42           0 :             static_cast< const char* >( getRemainingBuffer(maxElems)),
      43           0 :                 size_t( maxElems ));
      44      406381 :     return *this;
      45             : }
      46             : 
      47             : /** Deserialize an object (id+version). */
      48             : template<> inline DataIStream& DataIStream::operator >> ( Object*& object )
      49             : {
      50             :     ObjectVersion data;
      51             :     *this >> data;
      52             :     LBASSERT( object->getID() == data.identifier );
      53             :     object->sync( data.version );
      54             :     return *this;
      55             : }
      56             : 
      57             : /** Deserialize an inline serializable object. */
      58             : template< class T >
      59             : void DataIStream::_readSerializable( T& object, const boost::true_type& )
      60             : {
      61             :     const size_t size = read< size_t >();
      62             :     object.fromBinary( getRemainingBuffer( size ), size );
      63             : }
      64             : 
      65             : /** @cond IGNORE */
      66             : template< class T >
      67           5 : void DataIStream::_readArray( Array< T > array, const boost::true_type& )
      68             : {
      69           5 :     _read( array.data, array.getNumBytes( ));
      70           5 :     _swap( array );
      71           5 : }
      72             : 
      73             : /** Read an Array of non-POD data */
      74             : template< class T >
      75           1 : void DataIStream::_readArray( Array< T > array, const boost::false_type& )
      76             : {
      77           3 :     for( size_t i = 0; i < array.num; ++i )
      78           2 :         *this >> array.data[ i ];
      79           1 : }
      80             : 
      81             : template<> inline
      82          12 : void DataIStream::_readArray( Array< void > array, const boost::false_type& )
      83             : {
      84          12 :     _read( array.data, array.getNumBytes( ));
      85          12 : }
      86             : 
      87             : template< class T > inline DataIStream&
      88          34 : DataIStream::operator >> ( lunchbox::RefPtr< T >& ptr )
      89             : {
      90          34 :     T* object = 0;
      91          34 :     *this >> object;
      92          34 :     ptr = object;
      93          34 :     return *this;
      94             : }
      95             : 
      96             : template< class T > inline DataIStream&
      97             : DataIStream::operator >> ( lunchbox::Buffer< T >& buffer )
      98             : {
      99             :     uint64_t nElems = 0;
     100             :     *this >> nElems;
     101             :     LBASSERTINFO( nElems < LB_BIT48,
     102             :                   "Out-of-sync co::DataIStream: " << nElems << " elements?" );
     103             :     buffer.resize( nElems );
     104             :     return *this >> Array< T >( buffer.getData(), nElems );
     105             : }
     106             : 
     107             : 
     108             : template< class T > inline DataIStream&
     109           2 : DataIStream::operator >> ( std::vector< T >& value )
     110             : {
     111           2 :     uint64_t nElems = 0;
     112           2 :     *this >> nElems;
     113           2 :     value.resize( nElems );
     114           5 :     for( uint64_t i = 0; i < nElems; ++i )
     115           3 :         *this >> value[i];
     116           2 :     return *this;
     117             : }
     118             : 
     119             : template< class K, class V > inline DataIStream&
     120             : DataIStream::operator >> ( std::map< K, V >& map )
     121             : {
     122             :     map.clear();
     123             :     uint64_t nElems = 0;
     124             :     *this >> nElems;
     125             :     for( uint64_t i = 0; i < nElems; ++i )
     126             :     {
     127             :         typename std::map< K, V >::key_type key;
     128             :         typename std::map< K, V >::mapped_type value;
     129             :         *this >> key >> value;
     130             :         map.insert( std::make_pair( key, value ));
     131             :     }
     132             :     return *this;
     133             : }
     134             : 
     135             : template< class T > inline DataIStream&
     136             : DataIStream::operator >> ( std::set< T >& value )
     137             : {
     138             :     value.clear();
     139             :     uint64_t nElems = 0;
     140             :     *this >> nElems;
     141             :     for( uint64_t i = 0; i < nElems; ++i )
     142             :     {
     143             :         T item;
     144             :         *this >> item;
     145             :         value.insert( item );
     146             :     }
     147             :     return *this;
     148             : }
     149             : 
     150             : template< class K, class V > inline DataIStream&
     151             : DataIStream::operator >> ( stde::hash_map< K, V >& map )
     152             : {
     153             :     map.clear();
     154             :     uint64_t nElems = 0;
     155             :     *this >> nElems;
     156             :     for( uint64_t i = 0; i < nElems; ++i )
     157             :     {
     158             :         typename stde::hash_map< K, V >::key_type key;
     159             :         typename stde::hash_map< K, V >::mapped_type value;
     160             :         *this >> key >> value;
     161             :         map.insert( std::make_pair( key, value ));
     162             :     }
     163             :     return *this;
     164             : }
     165             : 
     166             : template< class T > inline DataIStream&
     167             : DataIStream::operator >> ( stde::hash_set< T >& value )
     168             : {
     169             :     value.clear();
     170             :     uint64_t nElems = 0;
     171             :     *this >> nElems;
     172             :     for( uint64_t i = 0; i < nElems; ++i )
     173             :     {
     174             :         T item;
     175             :         *this >> item;
     176             :         value.insert( item );
     177             :     }
     178             :     return *this;
     179             : }
     180             : 
     181             : namespace
     182             : {
     183             : class ObjectFinder
     184             : {
     185             : public:
     186             :     explicit ObjectFinder( const uint128_t& id ) : _id( id ) {}
     187             :     bool operator()( co::Object* candidate )
     188             :         { return candidate->getID() == _id; }
     189             : 
     190             : private:
     191             :     const uint128_t _id;
     192             : };
     193             : }
     194             : 
     195             : template< typename O, typename C > inline void
     196             : DataIStream::deserializeChildren( O* object, const std::vector< C* >& old_,
     197             :                                   std::vector< C* >& result )
     198             : {
     199             :     ObjectVersions versions;
     200             :     *this >> versions;
     201             :     std::vector< C* > old = old_;
     202             : 
     203             :     // rebuild vector from serialized list
     204             :     result.clear();
     205             :     for( ObjectVersions::const_iterator i = versions.begin();
     206             :          i != versions.end(); ++i )
     207             :     {
     208             :         const ObjectVersion& version = *i;
     209             : 
     210             :         if( version.identifier == uint128_t( ))
     211             :         {
     212             :             result.push_back( 0 );
     213             :             continue;
     214             :         }
     215             : 
     216             :         typename std::vector< C* >::iterator j =
     217             :             lunchbox::find_if( old, ObjectFinder( version.identifier ));
     218             : 
     219             :         if( j == old.end( )) // previously unknown child
     220             :         {
     221             :             C* child = 0;
     222             :             object->create( &child );
     223             :             LocalNodePtr localNode = object->getLocalNode();
     224             :             LBASSERT( child );
     225             :             LBASSERT( !object->isMaster( ));
     226             : 
     227             :             LBCHECK( localNode->mapObject( child, version ));
     228             :             result.push_back( child );
     229             :         }
     230             :         else
     231             :         {
     232             :             C* child = *j;
     233             :             old.erase( j );
     234             :             if( object->isMaster( ))
     235             :                 child->sync( VERSION_HEAD );
     236             :             else
     237             :                 child->sync( version.version );
     238             : 
     239             :             result.push_back( child );
     240             :         }
     241             :     }
     242             : 
     243             :     while( !old.empty( )) // removed children
     244             :     {
     245             :         C* child = old.back();
     246             :         old.pop_back();
     247             :         if( !child )
     248             :             continue;
     249             : 
     250             :         if( child->isAttached() && !child->isMaster( ))
     251             :         {
     252             :             LocalNodePtr localNode = object->getLocalNode();
     253             :             localNode->unmapObject( child );
     254             :         }
     255             :         object->release( child );
     256             :     }
     257             : }
     258             : /** @endcond */
     259             : 
     260             : /** Optimized specialization to read a std::vector of uint8_t. */
     261             : template<> inline DataIStream&
     262             : DataIStream::operator >> ( std::vector< uint8_t >& value )
     263             : { return _readFlatVector( value );}
     264             : 
     265             : /** Optimized specialization to read a std::vector of uint16_t. */
     266             : template<> inline DataIStream&
     267             : DataIStream::operator >> ( std::vector< uint16_t >& value )
     268             : { return _readFlatVector( value ); }
     269             : 
     270             : /** Optimized specialization to read a std::vector of int16_t. */
     271             : template<> inline DataIStream&
     272             : DataIStream::operator >> ( std::vector< int16_t >& value )
     273             : { return _readFlatVector( value ); }
     274             : 
     275             : /** Optimized specialization to read a std::vector of uint32_t. */
     276             : template<> inline DataIStream&
     277             : DataIStream::operator >> ( std::vector< uint32_t >& value )
     278             : { return _readFlatVector( value ); }
     279             : 
     280             : /** Optimized specialization to read a std::vector of int32_t. */
     281             : template<> inline DataIStream&
     282             : DataIStream::operator >> ( std::vector< int32_t >& value )
     283             : { return _readFlatVector( value ); }
     284             : 
     285             : /** Optimized specialization to read a std::vector of uint64_t. */
     286             : template<> inline DataIStream&
     287             : DataIStream::operator >> ( std::vector< uint64_t>& value )
     288             : { return _readFlatVector( value ); }
     289             : 
     290             : /** Optimized specialization to read a std::vector of int64_t. */
     291             : template<> inline DataIStream&
     292             : DataIStream::operator >> ( std::vector< int64_t >& value )
     293             : { return _readFlatVector( value ); }
     294             : 
     295             : /** Optimized specialization to read a std::vector of float. */
     296             : template<> inline DataIStream&
     297             : DataIStream::operator >> ( std::vector< float >& value )
     298             : { return _readFlatVector( value ); }
     299             : 
     300             : /** Optimized specialization to read a std::vector of double. */
     301             : template<> inline DataIStream&
     302           1 : DataIStream::operator >> ( std::vector< double >& value )
     303           1 : { return _readFlatVector( value ); }
     304             : 
     305             : /** Optimized specialization to read a std::vector of ObjectVersion. */
     306             : template<> inline DataIStream&
     307           3 : DataIStream::operator >> ( std::vector< ObjectVersion >& value )
     308           3 : { return _readFlatVector( value ); }
     309             : //@}
     310             : }

Generated by: LCOV version 1.11