nds2-client - ClientAdministrator  0.16.8
 All Functions Typedefs Enumerations Enumerator Groups Pages
nds_buffer.hh
1 /* -*- mode: C++ ; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 
3 #ifndef SWIG__COMMON__NDS_BUFFER_HH
4 #define SWIG__COMMON__NDS_BUFFER_HH
5 
6 #include <cmath>
7 #include <iostream>
8 
9 #include <vector>
10 
11 #include "nds_export.hh"
12 #include "nds_channel.hh"
13 
14 namespace NDS
15 {
16 
17  inline namespace abi_0
18  {
19  //---------------------------------------------------------------------
26  //---------------------------------------------------------------------
27  class buffer : public channel
28  {
29  public:
30  //-------------------------------------------------------------------
32  //-------------------------------------------------------------------
33  typedef long gps_second_type;
34  //-------------------------------------------------------------------
36  //-------------------------------------------------------------------
37  typedef long gps_nanosecond_type;
38  //-------------------------------------------------------------------
40  //-------------------------------------------------------------------
41  typedef size_t size_type;
42  //-------------------------------------------------------------------
44  //-------------------------------------------------------------------
45  typedef std::vector< unsigned char > data_type;
46 
47  static const gps_second_type GPS_INF = 1999999999;
48 
49  //-------------------------------------------------------------------
54  //-------------------------------------------------------------------
55  DLL_EXPORT
56  buffer( );
57 
58  //-------------------------------------------------------------------
74  //-------------------------------------------------------------------
75  DLL_EXPORT
76  buffer( const channel& ChannelInfo,
77  gps_second_type Second,
78  gps_nanosecond_type NanoSecond,
79  const void* Buffer,
80  size_type BufferSize );
81 
82  //-------------------------------------------------------------------
97  //-------------------------------------------------------------------
98  DLL_EXPORT
99  buffer( const channel& ChannelInfo,
100  gps_second_type Second,
101  gps_nanosecond_type NanoSecond,
102  data_type&& Buffer );
103 
104  //-------------------------------------------------------------------
109  //-------------------------------------------------------------------
110  DLL_EXPORT size_type Samples( ) const;
111 
112  //-------------------------------------------------------------------
117  //-------------------------------------------------------------------
118  DLL_EXPORT gps_second_type Start( ) const;
119 
120  //-------------------------------------------------------------------
125  //-------------------------------------------------------------------
126  DLL_EXPORT gps_nanosecond_type StartNano( ) const;
127 
128  //-------------------------------------------------------------------
133  //-------------------------------------------------------------------
134  DLL_EXPORT gps_second_type Stop( ) const;
135 
136  //-------------------------------------------------------------------
141  //-------------------------------------------------------------------
142  DLL_EXPORT gps_nanosecond_type StopNano( ) const;
143  //-------------------------------------------------------------------
145  //-------------------------------------------------------------------
146  DLL_EXPORT void swap( buffer& Source );
147 
148  //-------------------------------------------------------------------
153  //-------------------------------------------------------------------
154  DLL_EXPORT void resize( size_type N );
155 
156  //-------------------------------------------------------------------
168  template < typename T >
169  const T*
170  cbegin( ) const
171  {
172  const auto val_type =
173  NDS::channel_data_type_conversion< T >::value;
174 
175  if ( val_type == DataType( ) ||
176  ( std::is_same< T, void >::value &&
177  val_type == NDS::channel::DATA_TYPE_UNKNOWN ) )
178  {
179  return reinterpret_cast< const T* >( data.data( ) );
180  }
181  throw std::runtime_error(
182  "Invalid cast, the buffer data type is "
183  "not compatible with your requested "
184  "type" );
185  }
186 
187  //-------------------------------------------------------------------
195  template < typename T >
196  const T*
197  cend( ) const
198  {
199  const auto val_type =
200  NDS::channel_data_type_conversion< T >::value;
201 
202  if ( val_type == DataType( ) ||
203  ( std::is_same< T, void >::value &&
204  val_type == NDS::channel::DATA_TYPE_UNKNOWN ) )
205  {
206  return reinterpret_cast< const T* >(
207  data.data( ) + ( Samples( ) * DataTypeSize( ) ) );
208  }
209  throw std::runtime_error(
210  "Invalid cast, the buffer data type is "
211  "not compatible with your requested "
212  "type" );
213  }
214 
215  //-------------------------------------------------------------------
225  template < typename T >
226  const T&
227  at( size_type index ) const
228  {
229  const T* start = cbegin< T >( );
230  if ( array_out_of_range( index, Samples( ) ) )
231  {
232  throw std::out_of_range(
233  "The requested index is out of range" );
234  }
235  return start[ index ];
236  }
237 
238  // Helper functions
239 
240  //-------------------------------------------------------------------
253  //-------------------------------------------------------------------
254  DLL_EXPORT gps_second_type
255  samples_to_seconds( size_type offset_samples ) const;
256 
257  //-------------------------------------------------------------------
271  //-------------------------------------------------------------------
272  DLL_EXPORT gps_second_type
273  samples_to_trailing_nanoseconds( size_type offset_samples ) const;
274 
275  //-------------------------------------------------------------------
284  // this byte location refers to.
285  //-------------------------------------------------------------------
286  DLL_EXPORT size_type
287  bytes_to_samples( size_type offset_bytes ) const;
288 
289  //-------------------------------------------------------------------
303  // this time location refers to.
304  //-------------------------------------------------------------------
305  DLL_EXPORT size_type
306  seconds_to_samples( gps_second_type offset_seconds,
307  gps_nanosecond_type offset_nano = 0 ) const;
308 
309  //-------------------------------------------------------------------
320  //-------------------------------------------------------------------
321  DLL_EXPORT size_type
322  samples_to_bytes( size_type offset_samples ) const;
323 
324  //-------------------------------------------------------------------
338  //-------------------------------------------------------------------
339  DLL_EXPORT void
340  reset_channel_info( const channel& ChannelInfo,
341  gps_second_type Second,
342  gps_nanosecond_type NanoSecond );
343 
344  private:
345  gps_second_type gps_second;
346  gps_nanosecond_type gps_nanosecond;
347  data_type data;
348 
349  template < typename IndexType >
350  bool array_out_of_range( IndexType Index, IndexType Max ) const;
351 
352  protected:
353  bool is_minute_trend( ) const;
354  };
355 
356  typedef std::vector< buffer > buffers_type;
357 
358  inline bool
359  buffer::is_minute_trend( ) const
360  {
361  return Type( ) == CHANNEL_TYPE_MTREND;
362  }
363 
364  //---------------------------------------------------------------------
365  //---------------------------------------------------------------------
366  inline buffer::gps_second_type
367  buffer::samples_to_seconds( buffer::size_type offset_samples ) const
368  {
369  if ( is_minute_trend( ) )
370  {
371  return static_cast< gps_second_type >( offset_samples * 60 );
372  }
373  return static_cast< gps_second_type >( offset_samples /
374  SampleRate( ) );
375  }
376 
377  //---------------------------------------------------------------------
378  //---------------------------------------------------------------------
379  inline buffer::gps_nanosecond_type
380  buffer::samples_to_trailing_nanoseconds(
381  NDS::buffer::size_type offset_samples ) const
382  {
383  if ( is_minute_trend( ) )
384  {
385  return 0;
386  }
387  gps_nanosecond_type samples = offset_samples %
388  static_cast< gps_nanosecond_type >( SampleRate( ) );
389  return static_cast< gps_nanosecond_type >( 1e+9 * samples /
390  SampleRate( ) );
391  }
392 
393  //---------------------------------------------------------------------
394  //---------------------------------------------------------------------
395  inline buffer::size_type
396  buffer::bytes_to_samples( buffer::size_type offset_bytes ) const
397  {
398  return offset_bytes / DataTypeSize( );
399  }
400 
401  //---------------------------------------------------------------------
402  //---------------------------------------------------------------------
403  inline buffer::size_type
404  buffer::seconds_to_samples(
405  buffer::gps_second_type offset_seconds,
406  buffer::gps_nanosecond_type offset_nano ) const
407  {
408  if ( is_minute_trend( ) )
409  {
410  return static_cast< size_type >( offset_seconds / 60 );
411  }
412  return static_cast< size_type >( offset_seconds * SampleRate( ) );
413  }
414 
415  //---------------------------------------------------------------------
416  //---------------------------------------------------------------------
417  inline buffer::size_type
418  buffer::samples_to_bytes( buffer::size_type offset_samples ) const
419  {
420  return offset_samples * DataTypeSize( );
421  }
422 
423  //---------------------------------------------------------------------
427  //---------------------------------------------------------------------
428  inline buffer::size_type
429  buffer::Samples( ) const
430  {
431  return data.size( ) / DataTypeSize( );
432  }
433 
434  //---------------------------------------------------------------------
435  //---------------------------------------------------------------------
436  inline buffer::gps_second_type
437  buffer::Start( ) const
438  {
439  return gps_second;
440  }
441 
442  //---------------------------------------------------------------------
443  //---------------------------------------------------------------------
444  inline buffer::gps_nanosecond_type
445  buffer::StartNano( ) const
446  {
447  return gps_nanosecond;
448  }
449 
450  //---------------------------------------------------------------------
451  //---------------------------------------------------------------------
452  inline buffer::gps_second_type
453  buffer::Stop( ) const
454  {
455  auto samples = Samples( );
456  auto total_ns =
457  StartNano( ) + samples_to_trailing_nanoseconds( samples );
458  gps_second_type additional_from_nano =
459  ( total_ns >= static_cast< gps_nanosecond_type >( 1e+9 ) ? 1
460  : 0 );
461  return gps_second + samples_to_seconds( samples ) +
462  additional_from_nano;
463  }
464 
465  inline buffer::gps_nanosecond_type
466  buffer::StopNano( ) const
467  {
468  auto samples = Samples( );
469  auto total_ns =
470  StartNano( ) + samples_to_trailing_nanoseconds( samples );
471  return total_ns % 1000000000;
472  }
473 
474  //---------------------------------------------------------------------
475  //---------------------------------------------------------------------
476  inline void
477  buffer::resize( size_type N )
478  {
479  data.resize( N * DataTypeSize( ) );
480  }
481 
482  //---------------------------------------------------------------------
483  //---------------------------------------------------------------------
484 
485  DLL_EXPORT extern std::ostream& operator<<( std::ostream& os,
486  const buffer& obj );
487 
488  DLL_EXPORT extern std::ostream& operator<<( std::ostream& os,
489  const buffers_type& obj );
490 
491  //---------------------------------------------------------------------
492  //---------------------------------------------------------------------
493 
494  template <>
495  inline bool
496  buffer::array_out_of_range< size_t >( size_t Index, size_t Max ) const
497  {
498  return ( Index >= Samples( ) );
499  }
500 
501  template < typename IndexType >
502  inline bool
503  buffer::array_out_of_range( IndexType Index, IndexType Max ) const
504  {
505  return ( Index <= 0 || Index >= Samples( ) );
506  }
507 
508  } // namespace abi_0
509 } // namespace NDS
510 
511 #endif /* SWIG__COMMON__NDS_BUFFERL_HH */