Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
unpack_vector.h
Go to the documentation of this file.
1 /// @file detail/unpack_vector.h
2 ///
3 /// Unpacks the bytes from a raw memory buffer into a dynamically sized vector field.
4 ///
5 /// The MIT License(MIT)
6 /// @copyright 2014 Paul M Watt
7 // ****************************************************************************
8 #ifndef UNPACK_VECTOR_H_INCLUDED
9 #define UNPACK_VECTOR_H_INCLUDED
10 // Private Usage Include Guard ************************************************
11 // Only allow this header file to be included through unpack_message.h
12 #ifndef UNPACK_MESSAGE_H_INCLUDED
13 # error Do not include this file directly. Use <detail/unpack_message.h> instead
14 #endif
15 
16 namespace Hg
17 {
18 
19 namespace detail
20 {
21 
22 // Forward Declarations *******************************************************
23 template< class T,
24  class A,
25  class BufferT
26  >
27 size_t DeserializeInBulk( std::vector<T,A>&, BufferT&, size_t);
28 
29 template< class T,
30  class A,
31  class BufferT
32  >
33 size_t DeserializeByItem( std::vector<T,A>&, BufferT&, size_t);
34 
35 
36 namespace Vector
37 {
38 
39 // ****************************************************************************
40 // Imports data from the vector for fixed-size POD types.
41 //
42 template< typename VectorT,
43  typename BufferT,
44  typename TraitT
45  >
46 struct Deserializer;
47 
48 
49 
50 // ****************************************************************************
51 // Imports data from the vector for fixed-size fundamental types.
52 //
53 template< typename VectorT,
54  typename BufferT
55  >
56 struct Deserializer <VectorT, BufferT, fundamental_trait>
57 {
58  typedef VectorT vector_type;
59 
60  typedef typename
61  vector_type::value_type value_type;
62 
63  typedef BufferT buffer_type;
64 
65  typedef fundamental_trait data_type_trait;
66 
67  // **************************************************************************
68  size_t Read ( vector_type &value,
69  size_t count,
70  buffer_type &buffer,
71  size_t offset)
72  {
73  if (0 == count)
74  {
75  return 0;
76  }
77 
78  // Calculate the size of data to write in bytes.
79  size_t size = count * sizeof(value_type);
80 
81  value_type *pFirst = &value[0];
82  return buffer.get_range(pFirst, size, offset);
83  }
84 
85  // **************************************************************************
86  size_t Read ( value_type &value,
87  buffer_type &buffer,
88  size_t offset)
89  {
90  return buffer.get_data( value, offset);
91  }
92 
93 };
94 
95 // ****************************************************************************
96 // Imports a vector of bit-list fields.
97 //
98 template< typename T,
99  typename A,
100  typename BufferT
101  >
102 struct Deserializer <Hg::BitFieldVector<T,A>, BufferT, packed_trait>
103 {
104  typedef Hg::BitFieldVector<T,A> vector_type;
105  typedef typename
106  vector_type::value_type value_type;
107  typedef BufferT buffer_type;
108  typedef packed_trait data_type_trait;
109 
110  // **************************************************************************
111  size_t Read ( vector_type &value,
112  size_t count,
113  buffer_type &buffer,
114  size_t offset)
115  {
116  if (0 == count)
117  {
118  return 0;
119  }
120 
121  // Calculate the size of data to write in bytes.
122  size_t size = count * sizeof(value_type);
123 
124  value_type *pFirst = &(value[0].value());
125 
126  return buffer.get_range(pFirst, size, offset);
127  }
128 
129  // **************************************************************************
130  size_t Read ( value_type &value,
131  buffer_type &buffer,
132  size_t offset)
133  {
134  return buffer.get_data( value, offset);
135  }
136 };
137 
138 
139 // ****************************************************************************
140 // Exports a vector of nested types with each sub-item written individually.
141 //
142 template< typename T,
143  typename A,
144  typename BufferT
145  >
146 struct Deserializer <std::vector<T, A>, BufferT, nested_trait>
147 {
148  typedef std::vector<T,A> vector_type;
149  typedef T value_type;
150  typedef BufferT buffer_type;
151  typedef nested_trait data_type_trait;
152 
153  // **************************************************************************
154  size_t Read ( vector_type &value,
155  size_t count,
156  buffer_type &buffer,
157  size_t offset)
158  {
159  if (0 == count)
160  {
161  return 0;
162  }
163 
164  size_t bytes_read = 0;
165 
166  // Process each item individually.
167  for (size_t index = 0; index < count; ++index)
168  {
169  // The offset for each item progressively increases
170  // by the number of bytes read from the input buffer.
171  size_t item_offset = offset + bytes_read;
172 
173  bytes_read += Read(value[index], buffer, item_offset);
174  }
175 
176  return bytes_read;
177  }
178 
179  // **************************************************************************
180  size_t Read ( value_type &value,
181  buffer_type &buffer,
182  size_t offset)
183  {
184  // An important typedef for selecting the proper
185  // version of the unpack function for the sub-elements.
186  typedef typename
187  message_size_trait<typename value_type::format_type>::type size_trait;
188 
189  return unpack_message< value_type,
190  buffer_type,
191  size_trait
192  >(value, buffer, offset);
193  }
194 };
195 
196 
197 
198 // ****************************************************************************
199 // Exports a vector of arrays with each sub-item written individually.
200 //
201 template< typename T,
202  typename A,
203  typename BufferT
204  >
205 struct Deserializer <std::vector<T, A>, BufferT, array_trait>
206 {
207  typedef std::vector<T,A> vector_type;
208  typedef typename
209  vector_type::value_type value_type;
210 
211  typedef BufferT buffer_type;
212 
213  // The next step discriminates on the value_type managed
214  // by the vector to select the most efficient and correct
215  // method of deserializing the data.
216  typedef typename
218  < value_type >::type data_type_trait;
219 
220  // **************************************************************************
221  size_t Read ( vector_type &value,
222  size_t count,
223  buffer_type &buffer,
224  size_t offset)
225  {
226  return DeserializeByItem(value, buffer, offset);
227  }
228 
229  // **************************************************************************
230  size_t Read ( value_type &value,
231  buffer_type &buffer,
232  size_t offset)
233  {
234  return DeserializeArray(value, buffer, offset);
235  }
236 };
237 
238 // ****************************************************************************
239 // Exports a vector of vectors with each sub-item written individually.
240 //
241 template< typename T,
242  typename A,
243  typename BufferT
244  >
245 struct Deserializer <std::vector<T, A>, BufferT, vector_trait>
246 {
247  typedef std::vector<T, A> vector_type;
248  typedef typename
249  vector_type::value_type value_type;
250  typedef BufferT buffer_type;
251 
252  // The next step discriminates on the value_type managed
253  // by the vector to select the most efficient and correct
254  // method of deserializing the data.
255  typedef typename
257  < value_type >::type data_type_trait;
258 
259  // **************************************************************************
260  size_t Read ( vector_type &value,
261  size_t count,
262  buffer_type &buffer,
263  size_t offset)
264  {
265  return DeserializeByItem(value, buffer, offset);
266  }
267 
268  // **************************************************************************
269  size_t Read ( value_type &value,
270  buffer_type &buffer,
271  size_t offset)
272  {
273  size_t bytes_written =
274  DeserializeVector(value, value.size(), buffer, offset);
275 
276  return bytes_written;
277  }
278 };
279 
280 } // namespace Vector
281 
282 // **************************************************************************
283 // This version reads all of the items to the buffer at once.
284 //
285 template< class T,
286  class A,
287  class BufferT
288  >
289 size_t DeserializeInBulk( std::vector<T,A> &value,
290  size_t count,
291  BufferT &buffer,
292  size_t offset)
293 {
294  typedef std::vector<T,A> vector_type;
295 
296  typedef typename
297  vector_type::value_type data_type;
298  typedef typename
299  vector_type::allocator_type allocator_type;
300 
301  // The next step discriminates on the value_type managed
302  // by the vector to select the most efficient and correct
303  // method of deserializing the data.
304  typedef typename
306  < data_type >::type data_type_trait;
307 
308  typedef
309  Vector::Deserializer
310  < vector_type,
311  BufferT,
312  data_type_trait
313  > deserializer_t;
314 
315  deserializer_t deserializer;
316  size_t bytes_written = 0;
317 
318  // TODO: (Optimazation) Return and add this optimization for bulk reads if possible.
319  // Process each item individually.
320  for (size_t index = 0; index < count; ++index)
321  {
322  // The offset for each item progressively increases
323  // by the number of bytes read from the input buffer.
324  size_t item_offset = offset + bytes_written;
325 
326  // Export sub-values one item at a time.
327  size_t read_len =
328  deserializer.Read( value[index], buffer, item_offset);
329 
330  bytes_written += read_len;
331  }
332 
333  return bytes_written;
334 }
335 
336 
337 // **************************************************************************
338 // This version reads each item from the raw buffer individually.
339 // These fields may be because they are distinct fields of a nested definition,
340 // or variable length items.
341 //
342 // ValueT Must be a type that contains a sub-type defined as value_type.
343 // Such as std::vector or std::array
344 //
345 template< class T,
346  class A,
347  class BufferT
348  >
349 size_t DeserializeByItem( std::vector<T,A> &value,
350  BufferT &buffer,
351  size_t offset)
352 {
353  typedef std::vector<T,A> vector_type;
354 
355  typedef typename
356  vector_type::value_type data_type;
357  typedef typename
358  vector_type::allocator_type allocator_type;
359 
360  // The next step discriminates on the value_type managed
361  // by the vector to select the most efficient and correct
362  // method of deserializing the data.
363  typedef typename
365  < data_type >::type data_type_trait;
366 
367  Vector::Deserializer< vector_type,
368  BufferT,
369  data_type_trait> deserializer;
370 
371  size_t count = value.size();
372  size_t bytes_written = 0;
373 
374  // Process each item individually.
375  for (size_t index = 0; index < count; ++index)
376  {
377  // The offset for each item progressively increases
378  // by the number of bytes read from the input buffer.
379  size_t item_offset = offset + bytes_written;
380 
381  // Export sub-values one item at a time.
382  size_t read_len =
383  deserializer.Read( value[index], buffer, item_offset);
384 
385  bytes_written += read_len;
386  }
387 
388  return bytes_written;
389 }
390 
391 // ****************************************************************************
392 // Adapter function to simplify deserializing a buffer from a vector-field.
393 //
394 template< class T,
395  class A,
396  class BufferT,
397  template <typename, typename> class VectorT
398  >
399 size_t DeserializeVector (VectorT<T, A> &value,
400  size_t count,
401  BufferT &buffer,
402  size_t offset)
403 {
404  // The next step discriminates on the value_type managed
405  // by the vector to select the most efficient and correct
406  // method of deserializing the data.
407  typedef VectorT<T, A> vector_type;
408 
409  typedef T value_type;
410 
411  typedef typename
413  < value_type >::type value_type_trait;
414 
415 
416  // Define the correct type of deserialize functor
417  // based on the type contained within the vector.
418  typedef Vector::Deserializer< vector_type,
419  BufferT,
420  value_type_trait
421  > deserializer_t;
422 
423  deserializer_t deserializer;
424  return deserializer.Read(value, count, buffer, offset);
425 }
426 
427 
428 
429 // ****************************************************************************
430 // A specialized functor to read vector types.
431 //
432 // @tparam IdxT [size_t] The index of the field to read.
433 // @tparam MsgT [typename] The message defintition used to parse the
434 // buffer.
435 // @tparam BufferT [typename] The buffer type that provides the data
436 // to read into the message.
437 //
438 template< size_t IdxT,
439  typename MsgT,
440  typename BufferT
441  >
442 struct UnpackDatum< IdxT,
443  MsgT,
444  BufferT,
445  vector_trait>
446 {
447  // Typedefs *****************************************************************
448  typedef typename
450  < IdxT,
451  typename MsgT::format_type
452  >::type proxy_type;
453 
454  typedef typename
455  proxy_type::value_type value_type;
456  typedef typename
457  value_type::value_type data_type;
458 
459  typedef MsgT message_type;
460 
461  typedef BufferT buffer_type;
462 
463  // **************************************************************************
464  // Reads a dynamically-size field from the specified buffer.
465  //
466  // @param msg The message object to accept the data to be read.
467  // @param buffer The buffer object to read from.
468  // @param dynamic_offset An additional offset for messages with dynamically
469  // sized fields. The length of the dynamic field read
470  // will be added to this input value to report how much
471  // larger the message has become.
472  //
473  void operator()( message_type &msg,
474  const buffer_type &buffer,
475  size_t &dynamic_offset)
476  {
478  + dynamic_offset;
479 
480  // Query the message object for the number of elements in the buffer;
481  size_t count = msg.Size(buffer, &msg.template FieldAt<IdxT>());
482 
483  // For zero-size move on.
484  if (0 == count)
485  {
486  return;
487  }
488 
489  // Allocate space for the incoming data.
490  value_type& value = msg.template FieldAt<IdxT>().get();
491  value.resize(count);
492 
493  size_t bytes_read =
494  DeserializeVector(value, count, buffer, offset);
495 
496  dynamic_offset += bytes_read;
497  }
498 };
499 
500 } // namespace detail
501 
502 } // namespace Hg
503 
504 #endif