Collage  1.3.0
High-performance C++ library for developing object-oriented distributed applications.
dataIStream.ipp
1 
2 /* Copyright (c) 2012-2014, Daniel Nachbaur <danielnachbaur@gmail.com>
3  * 2013-2014, 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 
22 namespace co
23 {
27 template<> inline DataIStream& DataIStream::operator >> ( std::string& str )
28 {
29  uint64_t nElems = 0;
30  *this >> nElems;
31  const uint64_t maxElems = getRemainingBufferSize();
32  LBASSERTINFO( nElems <= maxElems,
33  nElems << " > " << maxElems );
34  if( nElems == 0 )
35  str.clear();
36  else if( nElems <= maxElems )
37  str.assign( static_cast< const char* >( getRemainingBuffer(nElems)),
38  size_t( nElems ));
39  else
40  str.assign(
41  static_cast< const char* >( getRemainingBuffer(maxElems)),
42  size_t( maxElems ));
43 
44  return *this;
45 }
46 
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 
58 template< class T >
59 void DataIStream::_readArray( Array< T > array, const boost::true_type& )
60 {
61  _read( array.data, array.getNumBytes( ));
62  _swap( array );
63 }
64 
66 template< class T >
67 void DataIStream::_readArray( Array< T > array, const boost::false_type& )
68 {
69  for( size_t i = 0; i < array.num; ++i )
70  *this >> array.data[ i ];
71 }
72 
73 template< class T > inline DataIStream&
74 DataIStream::operator >> ( lunchbox::RefPtr< T >& ptr )
75 {
76  T* object = 0;
77  *this >> object;
78  ptr = object;
79  return *this;
80 }
81 
82 template< class T > inline DataIStream&
83 DataIStream::operator >> ( lunchbox::Buffer< T >& buffer )
84 {
85  uint64_t nElems = 0;
86  *this >> nElems;
87  LBASSERTINFO( nElems < LB_BIT48,
88  "Out-of-sync co::DataIStream: " << nElems << " elements?" );
89  buffer.resize( nElems );
90  return *this >> Array< T >( buffer.getData(), nElems );
91 }
92 
93 
94 template< class T > inline DataIStream&
95 DataIStream::operator >> ( std::vector< T >& value )
96 {
97  uint64_t nElems = 0;
98  *this >> nElems;
99  value.resize( nElems );
100  for( uint64_t i = 0; i < nElems; ++i )
101  *this >> value[i];
102  return *this;
103 }
104 
105 template< class K, class V > inline DataIStream&
106 DataIStream::operator >> ( std::map< K, V >& map )
107 {
108  map.clear();
109  uint64_t nElems = 0;
110  *this >> nElems;
111  for( uint64_t i = 0; i < nElems; ++i )
112  {
113  typename std::map< K, V >::key_type key;
114  typename std::map< K, V >::mapped_type value;
115  *this >> key >> value;
116  map.insert( std::make_pair( key, value ));
117  }
118  return *this;
119 }
120 
121 template< class T > inline DataIStream&
122 DataIStream::operator >> ( std::set< T >& value )
123 {
124  value.clear();
125  uint64_t nElems = 0;
126  *this >> nElems;
127  for( uint64_t i = 0; i < nElems; ++i )
128  {
129  T item;
130  *this >> item;
131  value.insert( item );
132  }
133  return *this;
134 }
135 
136 template< class K, class V > inline DataIStream&
137 DataIStream::operator >> ( stde::hash_map< K, V >& map )
138 {
139  map.clear();
140  uint64_t nElems = 0;
141  *this >> nElems;
142  for( uint64_t i = 0; i < nElems; ++i )
143  {
144  typename stde::hash_map< K, V >::key_type key;
145  typename stde::hash_map< K, V >::mapped_type value;
146  *this >> key >> value;
147  map.insert( std::make_pair( key, value ));
148  }
149  return *this;
150 }
151 
152 template< class T > inline DataIStream&
153 DataIStream::operator >> ( stde::hash_set< T >& value )
154 {
155  value.clear();
156  uint64_t nElems = 0;
157  *this >> nElems;
158  for( uint64_t i = 0; i < nElems; ++i )
159  {
160  T item;
161  *this >> item;
162  value.insert( item );
163  }
164  return *this;
165 }
166 
167 namespace
168 {
169 class ObjectFinder
170 {
171 public:
172  explicit ObjectFinder( const uint128_t& id ) : _id( id ) {}
173  bool operator()( co::Object* candidate )
174  { return candidate->getID() == _id; }
175 
176 private:
177  const uint128_t _id;
178 };
179 }
180 
181 template<> inline void DataIStream::_swap( Array< void > ) const { /*NOP*/ }
182 
183 template< typename O, typename C > inline void
184 DataIStream::deserializeChildren( O* object, const std::vector< C* >& old_,
185  std::vector< C* >& result )
186 {
187  ObjectVersions versions;
188  *this >> versions;
189  std::vector< C* > old = old_;
190 
191  // rebuild vector from serialized list
192  result.clear();
193  for( ObjectVersions::const_iterator i = versions.begin();
194  i != versions.end(); ++i )
195  {
196  const ObjectVersion& version = *i;
197 
198  if( version.identifier == uint128_t( ))
199  {
200  result.push_back( 0 );
201  continue;
202  }
203 
204  typename std::vector< C* >::iterator j =
205  lunchbox::find_if( old, ObjectFinder( version.identifier ));
206 
207  if( j == old.end( )) // previously unknown child
208  {
209  C* child = 0;
210  object->create( &child );
211  LocalNodePtr localNode = object->getLocalNode();
212  LBASSERT( child );
213  LBASSERT( !object->isMaster( ));
214 
215  LBCHECK( localNode->mapObject( child, version ));
216  result.push_back( child );
217  }
218  else
219  {
220  C* child = *j;
221  old.erase( j );
222  if( object->isMaster( ))
223  child->sync( VERSION_HEAD );
224  else
225  child->sync( version.version );
226 
227  result.push_back( child );
228  }
229  }
230 
231  while( !old.empty( )) // removed children
232  {
233  C* child = old.back();
234  old.pop_back();
235  if( !child )
236  continue;
237 
238  if( child->isAttached() && !child->isMaster( ))
239  {
240  LocalNodePtr localNode = object->getLocalNode();
241  localNode->unmapObject( child );
242  }
243  object->release( child );
244  }
245 }
249 template<> inline DataIStream&
250 DataIStream::operator >> ( std::vector< uint8_t >& value )
251 { return _readFlatVector( value );}
252 
254 template<> inline DataIStream&
255 DataIStream::operator >> ( std::vector< uint16_t >& value )
256 { return _readFlatVector( value ); }
257 
259 template<> inline DataIStream&
260 DataIStream::operator >> ( std::vector< int16_t >& value )
261 { return _readFlatVector( value ); }
262 
264 template<> inline DataIStream&
265 DataIStream::operator >> ( std::vector< uint32_t >& value )
266 { return _readFlatVector( value ); }
267 
269 template<> inline DataIStream&
270 DataIStream::operator >> ( std::vector< int32_t >& value )
271 { return _readFlatVector( value ); }
272 
274 template<> inline DataIStream&
275 DataIStream::operator >> ( std::vector< uint64_t>& value )
276 { return _readFlatVector( value ); }
277 
279 template<> inline DataIStream&
280 DataIStream::operator >> ( std::vector< int64_t >& value )
281 { return _readFlatVector( value ); }
282 
284 template<> inline DataIStream&
285 DataIStream::operator >> ( std::vector< float >& value )
286 { return _readFlatVector( value ); }
287 
289 template<> inline DataIStream&
290 DataIStream::operator >> ( std::vector< double >& value )
291 { return _readFlatVector( value ); }
292 
294 template<> inline DataIStream&
295 DataIStream::operator >> ( std::vector< ObjectVersion >& value )
296 { return _readFlatVector( value ); }
298 }
CO_API const uint128_t & getID() const
A distributed object.
Definition: object.h:45
lunchbox::RefPtr< LocalNode > LocalNodePtr
A reference pointer for LocalNode pointers.
Definition: types.h:91
A helper struct bundling an object identifier and version.
Definition: objectVersion.h:47
uint128_t identifier
the object identifier
Definition: objectVersion.h:95
Object-oriented network library.
Definition: barrier.h:27
CO_API const void * getRemainingBuffer(const uint64_t size)
DataIStream & operator>>(T &value)
Read a plain data item.
Definition: dataIStream.h:63
uint128_t version
the object version
Definition: objectVersion.h:96
CO_API uint64_t getRemainingBufferSize()
A std::istream-like input data stream for binary data.
Definition: dataIStream.h:41