nds2-client - ClientDeveloper  0.16.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
basic_io.hh
Go to the documentation of this file.
1 //
2 // Created by jonathan.hanks on 5/4/18.
3 //
4 
5 #ifndef NDS2_CLIENT_BASIC_IO_HH
6 #define NDS2_CLIENT_BASIC_IO_HH
7 
8 #include <cstdint>
9 
10 #include "common/status_codes.hh"
11 
12 namespace nds_impl
13 {
14  namespace nds1
15  {
16  namespace common
17  {
18 
25  template < typename BufferedReader >
26  class Basic_IO
27  {
28  public:
29  Basic_IO( BufferedReader& r ) : r_( r )
30  {
31  }
32 
38  {
40  r_.read_exactly( result.data( ),
41  result.data( ) + result.size( ) );
42  return result;
43  }
44 
50  std::uint32_t
52  {
53  uint32_t val = 0;
54  std::array< char, 8 > buf;
55  r_.read_exactly( buf.data( ), buf.data( ) + buf.size( ) );
56  for ( const auto byte : buf )
57  {
58  val = ( val << 4 ) | from_hex_nibble( byte );
59  }
60  return val;
61  }
62 
68  float
70  {
71  uint32_t tmp = read_uint32_hex( );
72  return *reinterpret_cast< float* >( &tmp );
73  }
74 
75  private:
76  BufferedReader& r_;
77 
78  int
79  from_hex_nibble( int nibble )
80  {
81  if ( nibble >= '0' && nibble <= '9' )
82  {
83  return nibble - '0';
84  }
85  if ( nibble >= 'a' && nibble <= 'f' )
86  {
87  return ( nibble - 'a' ) + 10;
88  }
89  if ( nibble >= 'A' && nibble <= 'F' )
90  {
91  return ( nibble - 'A' ) + 10;
92  }
93  throw std::invalid_argument(
94  "Unknown input found while converting a hex value" );
95  }
96  };
97  }
98  }
99 }
100 
102 // Tests only after this point.
104 
105 #ifdef _NDS_IMPL_ENABLE_CATCH_TESTS_
106 
107 #include "common/status_codes.hh"
108 #include "socket/buffered_reader.hh"
109 #include "tests/dummy_socket.hh"
110 #include "catch.hpp"
111 
112 TEST_CASE( "You should be able to create a basic_io object",
113  "[nds2,basic_io,create]" )
114 {
115  using namespace nds_testing;
116 
118 
119  DummySocket s( "" );
120  sock_type buf_s( s );
122 }
123 
124 TEST_CASE( "You should be able to read a nds1 status code", "[nds1]" )
125 {
126  using namespace nds_testing;
127  using namespace nds_impl::common;
128 
130 
131  DummySocket s1( "0000000d" );
132  sock_type buf_s1( s1 );
134 
135  REQUIRE( b.read_status_code( ) == STATUS_DAQD_OK );
136  REQUIRE( b.read_status_code( ) == STATUS_DAQD_NOT_FOUND );
137 }
138 
139 TEST_CASE( "You should be able to read a 32bit ascii/hex value",
140  "[nds1,basic_io,hex]" )
141 {
142  using namespace nds_testing;
144 
145  DummySocket s1( "0000034000000000f7F8f9aB" );
146  sock_type buf_s1( s1 );
148 
149  REQUIRE( b.read_uint32_hex( ) == 0x340 );
150  REQUIRE( b.read_uint32_hex( ) == 0x0 );
151  REQUIRE( b.read_uint32_hex( ) == 0xf7f8f9ab );
152 }
153 
154 TEST_CASE( "Exceptions are thrown when reading a bad 32bit ascii/hex value",
155  "[nds1,basic_io,hex]" )
156 {
157  using namespace nds_testing;
159 
160  // two tests, one with an invalid char '&'
161  // another with a short input
162  DummySocket s1( "0000&3400000" );
163  sock_type buf_s1( s1 );
165 
166  REQUIRE_THROWS_AS( b.read_uint32_hex( ), std::invalid_argument );
167  REQUIRE_THROWS( b.read_uint32_hex( ) );
168 }
169 
170 TEST_CASE( "You should be able to read a 32bit float ascii/hex value",
171  "[nds1,basic_io,hex]" )
172 {
173  using namespace nds_testing;
175 
176  DummySocket s1( "3f800000" );
177  sock_type buf_s1( s1 );
179 
180  REQUIRE( b.read_float32_hex( ) == 1.0f );
181 }
182 
183 TEST_CASE(
184  "Exceptions are thrown when reading a bad 32bit float ascii/hex value",
185  "[nds1,basic_io,hex]" )
186 {
187  using namespace nds_testing;
189 
190  // two tests, one with an invalid char '&'
191  // another with a short input
192  DummySocket s1( "3f8&0000000" );
193  sock_type buf_s1( s1 );
195 
196  REQUIRE_THROWS_AS( b.read_float32_hex( ), std::invalid_argument );
197  REQUIRE_THROWS( b.read_float32_hex( ) );
198 }
199 
200 #endif // _NDS_IMPL_ENABLE_CATCH_TESTS_
201 
202 #endif // NDS2_CLIENT_BASIC_IO_HH
Definition: basic_io.hh:26
std::array< char, 4 > status_code
Definition: status_codes.hh:14
const auto STATUS_DAQD_OK
Definition: status_codes.hh:16
std::uint32_t read_uint32_hex()
Definition: basic_io.hh:51
TEST_CASE("daq_strlcpy copies strings safely when buffers are sufficiently large")
Definition: test_bsd_string.cc:9
nds_impl::common::status_code read_status_code()
Definition: basic_io.hh:37
Definition: dummy_socket.hh:45
int from_hex_nibble(int nibble)
Definition: basic_io.hh:79
const auto STATUS_DAQD_NOT_FOUND
Definition: status_codes.hh:20
float read_float32_hex()
Definition: basic_io.hh:69
BufferedReader & r_
Definition: basic_io.hh:76
Basic_IO(BufferedReader &r)
Definition: basic_io.hh:29
Definition: buffered_reader.hh:17