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 11090 : template<> inline DataIStream& DataIStream::operator >> ( std::string& str )
29 : {
30 11090 : uint64_t nElems = 0;
31 11090 : *this >> nElems;
32 11090 : const uint64_t maxElems = getRemainingBufferSize();
33 11090 : LBASSERTINFO( nElems <= maxElems,
34 : nElems << " > " << maxElems );
35 11090 : if( nElems == 0 )
36 0 : str.clear();
37 11090 : else if( nElems <= maxElems )
38 11090 : str.assign( static_cast< const char* >( getRemainingBuffer(nElems)),
39 22180 : size_t( nElems ));
40 : else
41 : str.assign(
42 0 : static_cast< const char* >( getRemainingBuffer(maxElems)),
43 0 : size_t( maxElems ));
44 11090 : 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 : }
|