Line data Source code
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 : {
24 : /** @name Specialized input operators */
25 : //@{
26 : /** Read a std::string. */
27 11088 : template<> inline DataIStream& DataIStream::operator >> ( std::string& str )
28 : {
29 11088 : uint64_t nElems = 0;
30 11088 : *this >> nElems;
31 11088 : const uint64_t maxElems = getRemainingBufferSize();
32 11088 : LBASSERTINFO( nElems <= maxElems,
33 : nElems << " > " << maxElems );
34 11088 : if( nElems == 0 )
35 0 : str.clear();
36 11088 : else if( nElems <= maxElems )
37 11088 : str.assign( static_cast< const char* >( getRemainingBuffer(nElems)),
38 22176 : size_t( nElems ));
39 : else
40 : str.assign(
41 0 : static_cast< const char* >( getRemainingBuffer(maxElems)),
42 0 : size_t( maxElems ));
43 :
44 11088 : 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 : /** @cond IGNORE */
58 : template< class T >
59 14 : void DataIStream::_readArray( Array< T > array, const boost::true_type& )
60 : {
61 14 : _read( array.data, array.getNumBytes( ));
62 14 : _swap( array );
63 14 : }
64 :
65 : /** Read an Array of non-POD data */
66 : template< class T >
67 4 : void DataIStream::_readArray( Array< T > array, const boost::false_type& )
68 : {
69 11 : for( size_t i = 0; i < array.num; ++i )
70 7 : *this >> array.data[ i ];
71 4 : }
72 :
73 : template< class T > inline DataIStream&
74 33 : DataIStream::operator >> ( lunchbox::RefPtr< T >& ptr )
75 : {
76 33 : T* object = 0;
77 33 : *this >> object;
78 33 : ptr = object;
79 33 : 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 2 : DataIStream::operator >> ( std::vector< T >& value )
96 : {
97 2 : uint64_t nElems = 0;
98 2 : *this >> nElems;
99 2 : value.resize( nElems );
100 5 : for( uint64_t i = 0; i < nElems; ++i )
101 3 : *this >> value[i];
102 2 : 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 : 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 12 : 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 : }
246 : /** @endcond */
247 :
248 : /** Optimized specialization to read a std::vector of uint8_t. */
249 : template<> inline DataIStream&
250 : DataIStream::operator >> ( std::vector< uint8_t >& value )
251 : { return _readFlatVector( value );}
252 :
253 : /** Optimized specialization to read a std::vector of uint16_t. */
254 : template<> inline DataIStream&
255 : DataIStream::operator >> ( std::vector< uint16_t >& value )
256 : { return _readFlatVector( value ); }
257 :
258 : /** Optimized specialization to read a std::vector of int16_t. */
259 : template<> inline DataIStream&
260 : DataIStream::operator >> ( std::vector< int16_t >& value )
261 : { return _readFlatVector( value ); }
262 :
263 : /** Optimized specialization to read a std::vector of uint32_t. */
264 : template<> inline DataIStream&
265 : DataIStream::operator >> ( std::vector< uint32_t >& value )
266 : { return _readFlatVector( value ); }
267 :
268 : /** Optimized specialization to read a std::vector of int32_t. */
269 : template<> inline DataIStream&
270 : DataIStream::operator >> ( std::vector< int32_t >& value )
271 : { return _readFlatVector( value ); }
272 :
273 : /** Optimized specialization to read a std::vector of uint64_t. */
274 : template<> inline DataIStream&
275 : DataIStream::operator >> ( std::vector< uint64_t>& value )
276 : { return _readFlatVector( value ); }
277 :
278 : /** Optimized specialization to read a std::vector of int64_t. */
279 : template<> inline DataIStream&
280 : DataIStream::operator >> ( std::vector< int64_t >& value )
281 : { return _readFlatVector( value ); }
282 :
283 : /** Optimized specialization to read a std::vector of float. */
284 : template<> inline DataIStream&
285 : DataIStream::operator >> ( std::vector< float >& value )
286 : { return _readFlatVector( value ); }
287 :
288 : /** Optimized specialization to read a std::vector of double. */
289 : template<> inline DataIStream&
290 1 : DataIStream::operator >> ( std::vector< double >& value )
291 1 : { return _readFlatVector( value ); }
292 :
293 : /** Optimized specialization to read a std::vector of ObjectVersion. */
294 : template<> inline DataIStream&
295 3 : DataIStream::operator >> ( std::vector< ObjectVersion >& value )
296 3 : { return _readFlatVector( value ); }
297 : //@}
298 : }
|