5 #ifndef NDS2_CLIENT_COMMONSPAN_READER_HH
6 #define NDS2_CLIENT_COMMONSPAN_READER_HH
11 #include "common/utils.hh"
30 throw std::runtime_error(
31 "Write operations not supported on the spanreader" );
48 throw std::range_error(
"No more data to read" );
55 return start + len_requested;
69 auto result =
peek( start, end );
85 peek(
char* start,
const char* end )
91 throw std::range_error(
"Insufficient data for request" );
94 return start + len_requested;
108 template <
typename It >
112 std::vector< char > result;
116 for (
bool match =
false; !match; ++cur, --rem )
120 throw std::range_error(
121 "Insufficient data for request" );
124 if ( std::find( begin_set, end_set,
cur_data( )[ cur ] ) !=
130 result.resize( cur );
148 template <
typename It,
typename OutIt >
157 OutIt dest_cur = dest_start;
159 for ( ; !match && dest_cur != dest_end;
160 ++cur, --rem, ++dest_cur )
164 throw std::range_error(
165 "Insufficient data for request" );
168 if ( std::find( begin_set, end_set,
cur_data( )[ cur ] ) !=
180 throw std::range_error(
181 "Unable to find matching sequence" );
220 #ifdef _NDS_IMPL_ENABLE_CATCH_TESTS_
225 TEST_CASE(
"You can create a span reader class",
"[common,span_reader]" )
227 std::string tmp{
"abc" };
233 TEST_CASE(
"You can cannot write to a span_reader",
"[common,span_reader]" )
235 std::string tmp{
"abc" };
239 std::string tmp2{
"ABC" };
240 REQUIRE_THROWS( r.write_all( tmp2.data( ), tmp2.data( ) + tmp2.size( ) ) );
243 TEST_CASE(
"You can read from a span reader",
"[span_reader,read]" )
245 std::vector< char > dest( 20 );
247 auto hello = std::string{
"hello world!" };
252 auto end = r.
read_available( dest.data( ), dest.data( ) + dest.size( ) );
253 REQUIRE( end != dest.data( ) );
254 REQUIRE( end == dest.data( ) + hello.size( ) );
255 auto output = std::string( dest.data( ), end );
256 REQUIRE( output == hello );
259 TEST_CASE(
"You can read the data in small segments from a span reader",
260 "[span_reader,read]" )
262 std::vector< char > dest( 5 );
264 auto hello = std::string{
"hello world!" };
270 auto end = r.
read_available( dest.data( ), dest.data( ) + dest.size( ) );
271 REQUIRE( end != dest.data( ) );
272 REQUIRE( end == dest.data( ) + dest.size( ) );
273 auto output = std::string( dest.data( ), end );
274 REQUIRE( output == hello.substr( 0, dest.size( ) ) );
276 end = r.read_available( dest.data( ), dest.data( ) + dest.size( ) );
277 REQUIRE( end != dest.data( ) );
278 REQUIRE( end == dest.data( ) + dest.size( ) );
279 output = std::string( dest.data( ), end );
280 REQUIRE( output == hello.substr( dest.size( ), dest.size( ) ) );
283 TEST_CASE(
"You can ask for an exact amount of bytes to be returned from a "
285 "[span_reader,read]" )
287 std::vector< char > dest( 10 );
289 auto input = std::string{
"0123456789" };
295 auto end = r.
read_exactly( dest.data( ), dest.data( ) + stride );
296 REQUIRE( end == dest.data( ) + stride );
299 r.read_exactly( dest.data( ), dest.data( ) + dest.size( ) ) );
302 TEST_CASE(
"You can peek at an exact amount of data without consuming it from "
304 "[span_reader,read]" )
306 std::vector< char > dest( 10 );
307 auto input = std::string{
"0123456789" };
314 auto end = r.
peek( dest.data( ), dest.data( ) + stride );
315 REQUIRE( end == dest.data( ) + stride );
316 REQUIRE( std::equal( dest.data( ), dest.data( ) + stride, input.data( ) ) );
319 std::fill( dest.begin( ), dest.end( ), 0 );
321 !std::equal( dest.data( ), dest.data( ) + stride, input.data( ) ) );
323 end = r.read_exactly( dest.data( ), dest.data( ) + stride );
324 REQUIRE( end == dest.data( ) + stride );
325 REQUIRE( std::equal( dest.data( ), dest.data( ) + stride, input.data( ) ) );
328 TEST_CASE(
"You can ask a span reader to read until a sequence is found",
329 "[buffered,read_until]" )
331 auto input = std::string{
"0123456789" };
336 auto terminators = std::string(
"59" );
337 auto result = r.read_until( terminators.begin( ), terminators.end( ) );
338 REQUIRE( std::string( result.begin( ), result.end( ) ) ==
339 std::string(
"012345" ) );
342 TEST_CASE(
"You can ask a span reader to read until a sequence is found, "
344 "[span_reader,read_until]" )
346 std::vector< char > dest( 5 );
347 auto input = std::string{
"0123456789abcdef" };
352 std::fill( dest.begin( ), dest.end( ), 0 );
353 auto terminators = std::string(
"29" );
354 auto end = r.read_until(
355 terminators.begin( ), terminators.end( ), dest.begin( ), dest.end( ) );
356 auto length = std::distance( dest.begin( ), end );
357 REQUIRE( length == 3 );
358 REQUIRE( std::string( dest.data( ), length ) == std::string(
"012" ) );
362 "A bounded span_reader read_until will throw an exception if it cannot "
364 "[span_reader,read_until]" )
366 std::vector< char > dest( 5 );
367 auto input = std::string{
"0123456789abcdef" };
372 auto terminators = std::string(
"Z" );
373 REQUIRE_THROWS_AS( r.read_until( terminators.begin( ),
381 "A bounded span_reader read_until will throw an exception if it cannot "
382 "find a sequence when input is empty",
383 "[span_reader,read_until]" )
385 std::vector< char > dest( 5 );
386 auto input = std::string{
"" };
391 auto terminators = std::string(
"Z" );
392 REQUIRE_THROWS_AS( r.read_until( terminators.begin( ),
396 std::runtime_error );
399 #endif // _NDS_IMPL_ENABLE_CATCH_TESTS_
401 #endif // NDS2_CLIENT_COMMON_SPAN_READER_HH
nds_impl::common::Span< char > span_type
Definition: span_reader.hh:21
char * peek(char *start, const char *end)
Definition: span_reader.hh:85
void consume(span_type::size_type count)
Definition: span_reader.hh:189
TEST_CASE("daq_strlcpy copies strings safely when buffers are sufficiently large")
Definition: test_bsd_string.cc:9
std::vector< char > read_until(It begin_set, It end_set)
Definition: span_reader.hh:110
span_type::size_type cur_
Definition: span_reader.hh:211
char * cur_data()
Definition: span_reader.hh:205
span_type::size_type remaining()
Definition: span_reader.hh:199
char * read_exactly(char *start, const char *end)
Definition: span_reader.hh:65
SpanReader(span_type &s)
Definition: span_reader.hh:23
Definition: span_reader.hh:18
span_type s_
Definition: span_reader.hh:210
OutIt read_until(It begin_set, It end_set, OutIt dest_start, OutIt dest_end)
Definition: span_reader.hh:150
std::size_t size_type
Definition: utils.hh:139
char * write_all(const char *begin, const char *end)
Definition: span_reader.hh:28
char * read_available(char *start, char *end)
Definition: span_reader.hh:42
pointer data() const
Definition: utils.hh:169
size_type size() const
Definition: utils.hh:154