Carna  Version 3.0.1
HUIO.h
1 #pragma once
2 
3 #include <Carna/Carna.h>
4 #include <ostream>
5 #include <istream>
6 #include <queue>
7 #include <cstdint>
8 
9 namespace Carna
10 {
11 
12 namespace testing
13 {
14 
15 namespace HUIO
16 {
17 
18 
19 
20 // ----------------------------------------------------------------------------------
21 // Types & Constants
22 // ----------------------------------------------------------------------------------
23 
24 typedef uint16_t shifted_huv_t;
25 
26 struct buffer_t
27 {
28  unsigned int first : 12;
29  unsigned int second : 12;
30 };
31 
32 const std::streamsize BUFFER_LENGTH = 3;
33 
34 
35 
36 // ----------------------------------------------------------------------------------
37 // Writer
38 // ----------------------------------------------------------------------------------
39 
40 struct Writer
41 {
42 
43  Writer( std::ostream& out )
44  : out( out )
45  {
46  }
47 
48  ~Writer()
49  {
50  flush();
51  }
52 
53  void write( signed short huv )
54  {
55  const signed short shifted_huv = huv + 1024;
56  buffered_shifted_huv.push( static_cast< shifted_huv_t >( shifted_huv ) );
57  if( buffered_shifted_huv.size() % 2 == 0 )
58  {
59  flush();
60  }
61  }
62 
63 private:
64 
65  std::ostream& out;
66 
67  std::queue< shifted_huv_t > buffered_shifted_huv;
68  buffer_t buffer;
69 
70  void flush()
71  {
72  if( buffered_shifted_huv.empty() )
73  {
74  return;
75  }
76 
77  buffer.first = buffered_shifted_huv.front();
78  buffered_shifted_huv.pop();
79 
80  if( buffered_shifted_huv.empty() )
81  {
82  buffer.second = 0; // padding
83  }
84  else
85  {
86  buffer.second = buffered_shifted_huv.front();
87  buffered_shifted_huv.pop();
88  }
89 
90  out.write( reinterpret_cast< const char* >( &buffer ), BUFFER_LENGTH );
91  }
92 
93 }; // HUIO :: Writer
94 
95 
96 
97 // ----------------------------------------------------------------------------------
98 // Reader
99 // ----------------------------------------------------------------------------------
100 
101 struct Reader
102 {
103 
104  Reader( std::istream& in )
105  : in( in )
106  {
107  }
108 
109  signed short read()
110  {
111  if( read_values.empty() )
112  {
113  readAhead();
114  }
115  const shifted_huv_t shifted_huv = read_values.front();
116  read_values.pop();
117  const signed short huv = static_cast< signed short >( shifted_huv ) - 1024;
118  return huv;
119  }
120 
121 private:
122 
123  std::istream& in;
124 
125  buffer_t buffer;
126  std::queue< shifted_huv_t > read_values;
127 
128  void readAhead()
129  {
130  in.read( reinterpret_cast< char* >( &buffer ), BUFFER_LENGTH );
131  read_values.push( buffer.first );
132  read_values.push( buffer.second );
133  }
134 
135 }; // HUIO :: Reader
136 
137 
138 
139 } // namespace HUIO
140 
141 } // namespace testing
142 
143 } // namespace Carna