30#include <jau/test/catch2_ext.hpp>
47 const size_t IDX_11kiB = 0;
48 const size_t IDX_65MiB = 1;
51 static std::vector<std::string> fname_payload_lst;
52 static std::vector<std::string> fname_payload_copy_lst;
53 static std::vector<uint64_t> fname_payload_size_lst;
54 const std::string url_input_root =
"http://localhost:8080/";
58 static bool add_test_file(
const std::string&
name,
const size_t size_limit) {
65 static const std::string one_line =
"Hello World, this is a test and I like it. Exactly 100 characters long. 0123456780 abcdefghjklmnop..";
68 REQUIRE( ofs.
good() ==
true );
69 REQUIRE( ofs.
isOpen() ==
true );
71 for(size=0; size < size_limit; size+=one_line.size()) {
72 if( one_line.size() != ofs.
write(one_line.data(), one_line.size()) ) {
73 ERR_PRINT(
"Write %zu bytes to test file failed: %s", one_line.size(), ofs.
toString().c_str());
77 if( 1 != ofs.
write(
"X", 1) ) {
83 fname_payload_lst.push_back(
name);
84 fname_payload_copy_lst.push_back(
name+
".copy");
85 fname_payload_size_lst.push_back( size );
88 static bool add_test_skipfile(
const std::string& name_in,
const std::string& name_out,
const size_t take,
const size_t skip) {
93 REQUIRE(
true == out.
good() );
94 REQUIRE(
true == out.
isOpen() );
96 REQUIRE(
true == in.
isOpen() );
103 uint64_t l0 = std::min(in_left, std::min(
sizeof(buffer), take));
104 REQUIRE( l0 == in.
read(buffer, l0) );
105 REQUIRE( l0 == out.
write(buffer, l0) );
108 l0 = std::min(in_left, std::min(
sizeof(buffer), skip));
109 const uint64_t p0 = in.
position() + l0;
111 REQUIRE(p0 == in.
seek(p0) );
114 fname_payload_lst.push_back(name_out);
118 REQUIRE(
true == add_test_file(
"testfile_blob_01_11kiB.bin", (
size_t)(1024*11)) );
119 REQUIRE(
true == add_test_file(
"testfile_blob_02_65MiB.bin", (
size_t)(1024*1024*65)) );
120 REQUIRE(
true == add_test_skipfile(
"testfile_blob_01_11kiB.bin",
"testfile_blob_03_skip1.bin", 10, 9) );
121 REQUIRE(
true == add_test_skipfile(
"testfile_blob_01_11kiB.bin",
"testfile_blob_04_skip2.bin", 9, 10) );
124 static const data& get() {
125 static data instance;
133 const data& d = data::get();
139 int res = std::system(
"killall mini_httpd");
146 int res = std::system(
"killall mini_httpd");
149 const std::string cmd = std::string(
mini_httpd_exe)+
" -p 8080 -l "+cwd+
"/mini_httpd.log";
151 res = std::system(cmd.c_str());
161 if( output_stats.
exists() ) {
164 ERR_PRINT2(
"ByteStream copy failed: Failed deletion of existing output file %s", output_fname.c_str());
168 ERR_PRINT2(
"ByteStream copy failed: Not overwriting existing output file %s", output_fname.c_str());
175 ERR_PRINT2(
"ByteStream copy failed: Couldn't open output file %s", output_fname.c_str());
179 uint64_t out_bytes_payload = 0;
182 const size_t written = outfile.
write(data.data(), data.size());
183 out_bytes_payload += written;
184 return data.size() == written;
186 const size_t written = outfile.
write(data.data(), data.size());
187 out_bytes_payload += written;
192 io_buffer.reserve(buffer_size);
196 if ( 0==in_bytes_total || input.
fail() ) {
197 IRQ_PRINT(
"ByteStream copy failed: Input file read failed in %s, out %s", input.
toString().c_str(), outfile.
toString().c_str());
200 if ( outfile.
fail() ) {
201 IRQ_PRINT(
"ByteStream copy failed: Output file write failed in %s, out %s", input.
toString().c_str(), outfile.
toString().c_str());
220 if( http_support_expected ) {
221 REQUIRE( 0 < protos.size() );
223 REQUIRE( 0 == protos.size() );
226 const size_t file_idx = IDX_11kiB;
228 const std::string url =
"not_exiting_file.txt";
233 if(
nullptr != in ) {
234 jau::PLAIN_PRINT(
true,
"test00_protocols: not_exiting_file: %s", in->toString().c_str());
236 REQUIRE(
nullptr == in );
239 const std::string url =
"file://not_exiting_file_uri.txt";
244 if(
nullptr != in ) {
245 jau::PLAIN_PRINT(
true,
"test00_protocols: not_exiting_file_uri: %s", in->toString().c_str());
247 REQUIRE(
nullptr == in );
250 const std::string url =
"lala://localhost:8080/" + fname_payload_lst[file_idx];
255 if(
nullptr != in ) {
256 jau::PLAIN_PRINT(
true,
"test00_protocols: not_exiting_protocol_uri: %s", in->toString().c_str());
258 REQUIRE(
nullptr == in );
261 const std::string url = url_input_root +
"not_exiting_http_uri.txt";
266 if( http_support_expected ) {
267 REQUIRE(
nullptr != in );
269 jau::PLAIN_PRINT(
true,
"test00_protocols: not_exiting_http_uri: %s", in->toString().c_str());
270 REQUIRE(
false == in->good() );
271 REQUIRE(
true == in->fail() );
272 REQUIRE( 0 == in->contentSize() );
274 REQUIRE(
nullptr == in );
284 const size_t file_idx = IDX_11kiB;
286 const std::string& url = fname_payload_lst[file_idx];
291 if(
nullptr != in ) {
292 jau::PLAIN_PRINT(
true,
"test00_protocols: local-file-0: %s", in->toString().c_str());
294 REQUIRE(
nullptr != in );
295 REQUIRE(
false == in->fail() );
297 bool res =
transfer(*in, fname_payload_copy_lst[file_idx]);
298 REQUIRE(
true == res );
301 REQUIRE(
true == out_stats.
exists() );
302 REQUIRE(
true == out_stats.
is_file() );
303 REQUIRE( in->contentSize() == out_stats.
size() );
304 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
308 const std::string url =
"file://" + fname_payload_lst[file_idx];
313 if(
nullptr != in ) {
314 jau::PLAIN_PRINT(
true,
"test00_protocols: local-file-1: %s", in->toString().c_str());
316 jau::PLAIN_PRINT(
true,
"test00_protocols: local-file-1: NULL from url '%s'", url.c_str());
318 REQUIRE(
nullptr != in );
319 REQUIRE(
false == in->fail() );
321 bool res =
transfer(*in, fname_payload_copy_lst[file_idx]);
322 REQUIRE(
true == res );
325 REQUIRE(
true == out_stats.
exists() );
326 REQUIRE(
true == out_stats.
is_file() );
327 REQUIRE( in->contentSize() == out_stats.
size() );
328 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
332 const std::string url = url_input_root + fname_payload_lst[file_idx];
337 if(
nullptr != in ) {
338 jau::PLAIN_PRINT(
true,
"test00_protocols: http: %s", in->toString().c_str());
340 if( http_support_expected ) {
341 REQUIRE(
nullptr != in );
342 REQUIRE(
false == in->fail() );
344 bool res =
transfer(*in, fname_payload_copy_lst[file_idx]);
345 REQUIRE(
true == res );
348 REQUIRE(
true == out_stats.
exists() );
349 REQUIRE(
true == out_stats.
is_file() );
350 REQUIRE( in->contentSize() == out_stats.
size() );
351 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
354 REQUIRE(
nullptr == in );
361 const size_t file_idx = IDX_11kiB;
364 bool res =
transfer(data_stream, fname_payload_copy_lst[file_idx], 4096);
365 REQUIRE(
true == res );
368 REQUIRE(
true == out_stats.
exists() );
369 REQUIRE(
true == out_stats.
is_file() );
371 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
377 const size_t file_idx = IDX_65MiB;
380 bool res =
transfer(data_stream, fname_payload_copy_lst[file_idx], 4096);
381 REQUIRE(
true == res );
384 REQUIRE(
true == out_stats.
exists() );
385 REQUIRE(
true == out_stats.
is_file() );
387 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
393 const size_t file_idx = IDX_65MiB;
396 bool res =
transfer(data_stream, fname_payload_copy_lst[file_idx], 32768);
397 REQUIRE(
true == res );
400 REQUIRE(
true == out_stats.
exists() );
401 REQUIRE(
true == out_stats.
is_file() );
403 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
415 const size_t file_idx = IDX_11kiB;
417 const std::string uri_original = url_input_root + fname_payload_lst[file_idx];
421 bool res =
transfer(data_stream, fname_payload_copy_lst[file_idx], 32768);
422 REQUIRE(
true == res );
425 REQUIRE(
true == out_stats.
exists() );
426 REQUIRE(
true == out_stats.
is_file() );
428 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
432 const size_t file_idx = IDX_65MiB;
434 const std::string uri_original = url_input_root + fname_payload_lst[file_idx];
438 bool res =
transfer(data_stream, fname_payload_copy_lst[file_idx], 32768);
439 REQUIRE(
true == res );
442 REQUIRE(
true == out_stats.
exists() );
443 REQUIRE(
true == out_stats.
is_file() );
445 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
458 const size_t file_idx = IDX_11kiB;
460 const std::string uri_original = url_input_root +
"doesnt_exists.txt";
464 bool res =
transfer(data_stream, fname_payload_copy_lst[file_idx]);
465 REQUIRE(
false == res );
468 REQUIRE(
true == out_stats.
exists() );
469 REQUIRE(
true == out_stats.
is_file() );
470 REQUIRE( data_stream.
fail() ==
true );
473 REQUIRE( 0 == out_stats.
size() );
479 uint64_t xfer_total = 0;
481 std::vector<uint8_t> buffer;
482 buffer.resize(feed_size);
483 while( data_stream.
good() ) {
484 size_t count = data_stream.
read(buffer.data(), buffer.size());
487 if( data_feed->
write(buffer.data(), count) ) {
501 uint64_t xfer_total = 0;
503 const uint64_t file_size = data_stream.
contentSize();
505 std::vector<uint8_t> buffer;
506 buffer.resize(feed_size);
507 while( data_stream.
good() && xfer_total < file_size ) {
508 size_t count = data_stream.
read(buffer.data(), buffer.size());
511 if( data_feed->
write(buffer.data(), count) ) {
524 uint64_t xfer_total = 0;
526 const uint64_t file_size = data_stream.
contentSize();
528 std::vector<uint8_t> buffer;
529 buffer.resize(feed_size);
530 while( data_stream.
good() && xfer_total < file_size ) {
531 size_t count = data_stream.
read(buffer.data(), buffer.size());
534 if( !data_feed->
write(buffer.data(), count) ) {
544 uint64_t xfer_total = 0;
546 std::vector<uint8_t> buffer;
547 buffer.resize(feed_size);
548 while( data_stream.
good() ) {
549 size_t count = data_stream.
read(buffer.data(), buffer.size());
552 if( data_feed->
write(buffer.data(), count) ) {
553 if( xfer_total >= 1024 ) {
568 uint64_t xfer_total = 0;
570 const uint64_t file_size = data_stream.
contentSize();
572 std::vector<uint8_t> buffer;
573 buffer.resize(feed_size);
574 while( data_stream.
good() ) {
575 size_t count = data_stream.
read(buffer.data(), buffer.size());
578 if( data_feed->
write(buffer.data(), count) ) {
579 if( xfer_total >= file_size/4 ) {
594 const size_t buffer_size = 4096;
595 const size_t feed_size = 1024;
597 const size_t file_idx = IDX_11kiB;
601 std::thread feeder_thread= std::thread(&
feed_source_10, &data_feed, feed_size);
603 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
604 if( feeder_thread.joinable() ) {
605 feeder_thread.join();
607 REQUIRE(
true == res );
610 REQUIRE(
true == out_stats.
exists() );
611 REQUIRE(
true == out_stats.
is_file() );
613 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
619 std::thread feeder_thread= std::thread(&
feed_source_01, &data_feed, feed_size);
621 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
622 if( feeder_thread.joinable() ) {
623 feeder_thread.join();
625 REQUIRE(
true == res );
628 REQUIRE(
true == out_stats.
exists() );
629 REQUIRE(
true == out_stats.
is_file() );
631 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
637 std::thread feeder_thread= std::thread(&
feed_source_00, &data_feed, feed_size);
639 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
640 if( feeder_thread.joinable() ) {
641 feeder_thread.join();
643 REQUIRE(
true == res );
646 REQUIRE(
true == out_stats.
exists() );
647 REQUIRE(
true == out_stats.
is_file() );
649 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
654 const size_t file_idx = IDX_65MiB;
658 std::thread feeder_thread= std::thread(&
feed_source_10, &data_feed, feed_size);
660 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
661 if( feeder_thread.joinable() ) {
662 feeder_thread.join();
664 REQUIRE(
true == res );
667 REQUIRE(
true == out_stats.
exists() );
668 REQUIRE(
true == out_stats.
is_file() );
670 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
678 const size_t buffer_size = 32768;
679 const size_t feed_size = 32768;
681 const size_t file_idx = IDX_11kiB;
685 std::thread feeder_thread= std::thread(&
feed_source_10, &data_feed, feed_size);
687 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
688 if( feeder_thread.joinable() ) {
689 feeder_thread.join();
691 REQUIRE(
true == res );
694 REQUIRE(
true == out_stats.
exists() );
695 REQUIRE(
true == out_stats.
is_file() );
697 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
703 std::thread feeder_thread= std::thread(&
feed_source_01, &data_feed, feed_size);
705 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
706 if( feeder_thread.joinable() ) {
707 feeder_thread.join();
709 REQUIRE(
true == res );
712 REQUIRE(
true == out_stats.
exists() );
713 REQUIRE(
true == out_stats.
is_file() );
715 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
721 std::thread feeder_thread= std::thread(&
feed_source_00, &data_feed, feed_size);
723 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
724 if( feeder_thread.joinable() ) {
725 feeder_thread.join();
727 REQUIRE(
true == res );
730 REQUIRE(
true == out_stats.
exists() );
731 REQUIRE(
true == out_stats.
is_file() );
733 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
741 const size_t buffer_size = 32768;
742 const size_t feed_size = 32768;
744 const size_t file_idx = IDX_65MiB;
748 std::thread feeder_thread= std::thread(&
feed_source_10, &data_feed, feed_size);
750 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
751 if( feeder_thread.joinable() ) {
752 feeder_thread.join();
754 REQUIRE(
true == res );
757 REQUIRE(
true == out_stats.
exists() );
758 REQUIRE(
true == out_stats.
is_file() );
760 REQUIRE( fname_payload_size_lst[file_idx] == out_stats.
size() );
768 const size_t buffer_size = 4096;
769 const size_t feed_size = 1024;
771 const size_t file_idx = IDX_65MiB;
775 std::thread feeder_thread= std::thread(&
feed_source_20, &data_feed, feed_size);
777 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
778 if( feeder_thread.joinable() ) {
779 feeder_thread.join();
781 REQUIRE(
false == res );
784 REQUIRE(
true == out_stats.
exists() );
785 REQUIRE(
true == out_stats.
is_file() );
788 REQUIRE( fname_payload_size_lst[file_idx] > out_stats.
size() );
794 std::thread feeder_thread= std::thread(&
feed_source_21, &data_feed, feed_size);
796 bool res =
transfer(data_feed, fname_payload_copy_lst[file_idx], buffer_size);
797 if( feeder_thread.joinable() ) {
798 feeder_thread.join();
800 REQUIRE(
false == res );
803 REQUIRE(
true == out_stats.
exists() );
804 REQUIRE(
true == out_stats.
is_file() );
806 REQUIRE( fname_payload_size_lst[file_idx] == data_feed.
contentSize() );
814 REQUIRE(
true == in.
isOpen() );
823 REQUIRE( p0 == in.
seek(p0) );
826 REQUIRE( p0 == in.
discard(p0) );
834 jau::io::ByteStream_SecMemory data_stream(
"0123456789abcdefghjklmnopqrstuvwxyz_()#$0123456789abcdefghjklmnopqrstuvwxyz_()#$0123456789abcdefghjklmnopqrstuvwxyz_()#$0123456789abcdefghjklmnopqrstuvwxyz_()#$");
839 const size_t file_idx = IDX_65MiB;
856 jau::io::ByteStream_SecMemory in(
"0123456789abcdefghjklmnopqrstuvwxyz_()#$0123456789abcdefghjklmnopqrstuvwxyz_()#$0123456789abcdefghjklmnopqrstuvwxyz_()#$0123456789abcdefghjklmnopqrstuvwxyz_()#$");
865 jau::io::ByteStream_SecMemory cmp3(
"0123456789abcde||0123456789abcde||#$||#$||#$||abcdefghjklmnopqrstuvwxy||abcdefghjklmnopqrstuvwxy||abcdefghjklmnopqrstuvwxyz||abcdefghjklmnopqrstuvwxyz||abcdefghjklmnopqrstuvwxyz||");
870 size_t skip1,
size_t take1,
size_t skip2,
size_t take2) {
871 REQUIRE(
true == in.
isOpen() );
876 REQUIRE(
true == out.
good() );
877 REQUIRE(
true == out.
isOpen() );
887 REQUIRE( p0 == in.
seek(p0) );
891 REQUIRE( take1 == in.
read(buffer, take1) );
894 REQUIRE(take1 == out.
write(buffer, take1) );
897 REQUIRE( skip2 == in.
discard(skip2) );
904 REQUIRE( take2 == in.
read(buffer, take2) );
907 REQUIRE(take2 == out.
write(buffer, take2) );
908 REQUIRE(take1+take2 == out.
position() );
910 REQUIRE(
true == in.
eof() );
916 const std::string outfile_name01 =
"test41_seek.01.out";
917 const std::string outfile_name02 =
"test41_seek.02.out";
921 REQUIRE(
true == in.
isOpen() );
925 REQUIRE(0 == in.
seek(0) );
931 const std::string outfile_name01 =
"test42_seek.01.out";
932 const std::string outfile_name02 =
"test42_seek.02.out";
943 REQUIRE(
true == in.
isOpen() );
952 REQUIRE(
true == in.
isOpen() );
961 REQUIRE(
true == in.
isOpen() );
966 REQUIRE(
true == out.
good() );
967 REQUIRE(
true == out.
isOpen() );
985 REQUIRE(
true == in.
setMark(5) );
986 REQUIRE( 0 == in.
mark() );
987 std::memset(buffer, 0,
sizeof(buffer));
988 REQUIRE( 15 == in.
read(buffer, 15) );
996 std::memset(buffer, 0,
sizeof(buffer));
997 REQUIRE( 38-15 == in.
read(buffer, 38-15) );
1000 REQUIRE(
true == in.
setMark(17) );
1001 REQUIRE( 38 == in.
mark() );
1005 std::memset(buffer, 0,
sizeof(buffer));
1006 REQUIRE( 40-38 == in.
read(buffer, 40-38) );
1010 REQUIRE( 38 == in.
mark() );
1012 std::memset(buffer, 0,
sizeof(buffer));
1013 REQUIRE( 15 == in.
read(buffer, 15) );
1015 REQUIRE( 38 == in.
mark() );
1016 REQUIRE( 15 == out.
write(buffer, 15) );
1017 REQUIRE( 2 == out.
write(
"||", 2) );
1018 REQUIRE( 40 == in.
seek(40) );
1022 std::memset(buffer, 0,
sizeof(buffer));
1023 REQUIRE( 15 == in.
read(buffer, 15) );
1025 REQUIRE( 38 == in.
mark() );
1026 REQUIRE( 15 == out.
write(buffer, 15) );
1027 REQUIRE( 2 == out.
write(
"||", 2) );
1033 REQUIRE( 38 == in.
mark() );
1035 std::memset(buffer, 0,
sizeof(buffer));
1036 REQUIRE( 2 == in.
read(buffer, 2) );
1038 REQUIRE( 38 == in.
mark() );
1039 REQUIRE( 2 == out.
write(buffer, 2) );
1040 REQUIRE( 2 == out.
write(
"||", 2) );
1044 std::memset(buffer, 0,
sizeof(buffer));
1045 REQUIRE( 2 == in.
read(buffer, 2) );
1047 REQUIRE( 38 == in.
mark() );
1048 REQUIRE( 2 == out.
write(buffer, 2) );
1049 REQUIRE( 2 == out.
write(
"||", 2) );
1053 std::memset(buffer, 0,
sizeof(buffer));
1054 REQUIRE( 2 == in.
read(buffer, 2) );
1056 REQUIRE( 38 == in.
mark() );
1057 REQUIRE( 2 == out.
write(buffer, 2) );
1058 REQUIRE( 2 == out.
write(
"||", 2) );
1062 std::memset(buffer, 0,
sizeof(buffer));
1063 REQUIRE( 50 == in.
seek(50) );
1067 REQUIRE(
true == in.
setMark(25) );
1068 REQUIRE( 50 == in.
mark() );
1070 std::memset(buffer, 0,
sizeof(buffer));
1071 REQUIRE( 24 == in.
read(buffer, 24) );
1073 REQUIRE( 50 == in.
mark() );
1074 REQUIRE( 24 == out.
write(buffer, 24) );
1075 REQUIRE( 2 == out.
write(
"||", 2) );
1076 REQUIRE( 50 == in.
seek(50) );
1079 std::memset(buffer, 0,
sizeof(buffer));
1080 REQUIRE( 24 == in.
read(buffer, 24) );
1082 REQUIRE( 50 == in.
mark() );
1083 REQUIRE( 24 == out.
write(buffer, 24) );
1084 REQUIRE( 2 == out.
write(
"||", 2) );
1087 std::memset(buffer, 0,
sizeof(buffer));
1088 REQUIRE( 130-74 == in.
read(buffer, 130-74) );
1093 REQUIRE( 130 == in.
mark() );
1095 std::memset(buffer, 0,
sizeof(buffer));
1096 REQUIRE( 25 == in.
read(buffer, 25) );
1098 REQUIRE( 130 == in.
mark() );
1099 REQUIRE( 25 == out.
write(buffer, 25) );
1100 REQUIRE( 2 == out.
write(
"||", 2) );
1101 REQUIRE( 130 == in.
seek(130) );
1104 std::memset(buffer, 0,
sizeof(buffer));
1105 REQUIRE( 25 == in.
read(buffer, 25) );
1107 REQUIRE( 130 == in.
mark() );
1108 REQUIRE( 25 == out.
write(buffer, 25) );
1109 REQUIRE( 2 == out.
write(
"||", 2) );
1113 std::memset(buffer, 0,
sizeof(buffer));
1114 REQUIRE( 25 == in.
read(buffer, 25) );
1116 REQUIRE( 130 == in.
mark() );
1117 REQUIRE( 25 == out.
write(buffer, 25) );
1118 REQUIRE( 2 == out.
write(
"||", 2) );
1123 REQUIRE(
false == in.
eof() );
1129 const std::string outfile_name01 =
"test4a_rewind.01.out";
1133 REQUIRE(
true == in.
isOpen() );
1141 const std::string outfile_name01 =
"test4b_rewind.01.out";
1151 REQUIRE(
true == in.
isOpen() );
1160std::vector<std::string> TestByteStream01::fname_payload_lst;
1161std::vector<std::string> TestByteStream01::fname_payload_copy_lst;
1162std::vector<uint64_t> TestByteStream01::fname_payload_size_lst;
static void feed_source_00(jau::io::ByteInStream_Feed *data_feed, const size_t feed_size=1024)
static void feed_source_20(jau::io::ByteInStream_Feed *data_feed, const size_t feed_size=1024)
void test_stream_seek(jau::io::ByteStream &in, const std::string &out_name, const std::string &cmp_name, size_t skip1, size_t take1, size_t skip2, size_t take2)
static constexpr const char * test40_cmp1_name
static bool transfer(jau::io::ByteStream &input, const std::string &output_fname, const size_t buffer_size=4096)
void test04_copy_file_ok_65MiB_buff32k()
static constexpr const char * test40_cmp2_name
void test41_seek_rw_file()
void test_stream_seek(jau::io::ByteStream &in)
static void httpd_start()
void test11_copy_http_ok_buff32k()
static void feed_source_01(jau::io::ByteInStream_Feed *data_feed, const size_t feed_size=1024)
void test22_copy_fed_ok_buff32k()
void test20_copy_fed_ok_buff4k_feed1k()
void test4b_rewind_rw_url()
void test42_seek_rw_url()
void test01_copy_file_ok_11kiB_buff4k()
void test23_copy_fed_irq()
void test4a_rewind_rw_file()
static constexpr const char * test40_src_name
static constexpr const char * test40_cmp3_name
void test00a_protocols_error()
void test02_copy_file_ok_65MiB_buff4k()
void test21_copy_fed_ok_buff32k()
void test_stream_rewind(jau::io::ByteStream &in, const std::string &out_name, const std::string &cmp_name)
void test12_copy_http_404()
static void feed_source_10(jau::io::ByteInStream_Feed *data_feed, const size_t feed_size=1024)
static void feed_source_21(jau::io::ByteInStream_Feed *data_feed, const size_t feed_size=1024)
void test00b_protocols_ok()
Ringbuffer-Based byte input stream with an externally provisioned data feed.
void setEOF(const io_result_t result) noexcept
Set end-of-data (EOS), i.e.
void setContentSize(const size_type size) noexcept
Set known content size, informal only.
size_type contentSize() const noexcept override
Returns the content_size if known.
size_t write(const void *in, size_t length, const jau::fraction_i64 &timeout) noexcept
Write given bytes to the async ringbuffer using explicit given timeout.
bool hasContentSize() const noexcept override
Returns true if implementation is aware of content_size(), otherwise false.
std::string id() const noexcept override
return the id of this data source
Ringbuffer-Based byte input stream with a URL connection provisioned data feed.
bool isOpen() const noexcept override
Checks if the stream has an associated file.
bool hasContentSize() const noexcept override
Returns true if implementation is aware of content_size(), otherwise false.
size_type seek(size_type newPos) noexcept override
newPos < position() limited to markpos, see setMark().
size_type contentSize() const noexcept override
Returns the content_size if known.
File based byte input stream, including named file descriptor.
size_type seek(size_type newPos) noexcept override
Sets position indicator for output-streams or input-streams with known length, similar to e....
size_type position() const noexcept override
Returns the position indicator, similar to e.g.
bool hasContentSize() const noexcept override
Returns true if implementation is aware of content_size(), otherwise false.
size_type contentSize() const noexcept override
Returns the content_size if known.
bool isOpen() const noexcept override
Checks if the stream has an associated file.
size_t write(const void *, size_t) noexcept override
Write to the data sink.
std::string id() const noexcept override
return the id of this data source
std::string toString() const noexcept override
size_t read(void *, size_t) noexcept override
Read from the source.
Secure Memory-Based byte input stream.
virtual size_t read(void *out, size_t length) noexcept=0
Read from the source.
virtual bool isOpen() const noexcept=0
Checks if the stream has an associated file.
constexpr bool canWrite() const noexcept
Returns true in case stream has iomode::write capabilities.
virtual size_type mark() const noexcept=0
Returns the markpos set via setMark() or ByteStream::npos if unset.
virtual bool seekMark() noexcept=0
Seeks stream position to markpos as set via setMark().
virtual size_type markReadLimit() const noexcept=0
Returns the readLimit set via setMark().
virtual size_t discard(size_t N) noexcept=0
Discard the next N bytes of the data.
virtual bool setMark(size_type readLimit) noexcept=0
Set markpos to current position, allowing the stream to be seekMark().
virtual std::string toString() const noexcept=0
virtual bool hasContentSize() const noexcept=0
Returns true if implementation is aware of content_size(), otherwise false.
virtual void close() noexcept=0
Close the stream if supported by the underlying mechanism.
virtual size_type contentSize() const noexcept=0
Returns the content_size if known.
virtual bool available(size_t n) noexcept=0
Return whether n bytes are available in the input stream, if has_content_size() or using an asynchron...
virtual size_type position() const noexcept=0
Returns the position indicator, similar to e.g.
virtual size_type seek(size_type newPos) noexcept=0
Sets position indicator for output-streams or input-streams with known length, similar to e....
static constexpr size_type npos
Invalid position constant, denoting unset mark() or invalid position.
bool fail() const noexcept
Checks if an error has occurred.
bool good() const noexcept
Checks if no error nor eof() has occurred i.e.
bool eof() const noexcept
Checks if end-of-file has been reached.
Platform agnostic representation of POSIX ::lstat() and ::stat() for a given pathname.
constexpr bool is_file() const noexcept
Returns true if entity is a file, might be in combination with is_link().
uint64_t size() const noexcept
Returns the size in bytes of this element if is_file(), otherwise zero.
std::string path() const noexcept
Returns the unix path representation.
constexpr bool exists() const noexcept
Returns true if entity does not exist, exclusive bit.
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
#define ERR_PRINT2(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
#define IRQ_PRINT(...)
Use for unconditional interruption messages, prefix '[elapsed_time] Interrupted @ FILE:LINE FUNC: '.
constexpr std::string_view name(const Bool v) noexcept
std::string get_cwd() noexcept
Return the current working directory or empty on failure.
bool compare(const file_stats &source1, const file_stats &source2, const bool verbose=false) noexcept
Compare the bytes of both files, denoted by source1 and source2.
bool remove(const std::string &path, const traverse_options topts=traverse_options::none) noexcept
Remove the given path.
fraction_timespec getMonotonicTime() noexcept
Returns current monotonic time since Unix Epoch 00:00:00 UTC on 1970-01-01.
FracI64SizeBoolTuple to_fraction_i64(const std::string &value, const fraction_i64 &min_allowed, const fraction_i64 &max_allowed) noexcept
Returns the fraction_i64 of the given string in format <num>/<denom>, which may contain whitespace.
fraction< int64_t > fraction_i64
fraction using int64_t as integral type
bool is_local_file_protocol(const std::string_view &uri) noexcept
Returns true if the uri-scheme of given uri matches the local file protocol, i.e.
jau::function< bool(secure_vector< uint8_t > &, bool)> StreamConsumerFunc
Stream consumer function.
uint64_t read_stream(ByteStream &in, secure_vector< uint8_t > &buffer, const StreamConsumerFunc &consumer_fn) noexcept
Synchronous byte input stream reader using the given StreamConsumerFunc consumer_fn.
std::vector< std::string_view > supported_protocols() noexcept
Returns a list of supported protocol supported by libcurl network protocols, queried at runtime.
std::unique_ptr< ByteStream > to_ByteInStream(const std::string &path_or_uri, jau::fraction_i64 timeout=20_s) noexcept
Parses the given path_or_uri, if it matches a supported protocol, see jau::io::uri::protocol_supporte...
std::vector< T, jau::callocator_sec< T > > secure_vector
void print_stats(const std::string &prefix, const uint64_t &out_bytes_total, const jau::fraction_i64 &td) noexcept
bool protocol_supported(const std::string_view &uri) noexcept
Returns true if the uri-scheme of given uri matches a supported by libcurl network protocols otherwis...
@ writetrunc
Write capabilities and truncate existing (file) stream, i.e.
@ write
Write capabilities.
@ FAILED
Operation failed.
@ SUCCESS
Operation succeeded.
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
std::string to_string(const bit_order_t v) noexcept
Return std::string representation of the given bit_order_t.
bool sleep_for(const fraction_timespec &relative_time, const bool monotonic=true, const bool ignore_irq=true) noexcept
sleep_for causes the current thread to block until a specific amount of time has passed.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
METHOD_AS_TEST_CASE(TestByteStream01::test00a_protocols_error, "test00a_protocols_error")
constexpr std::string_view mini_httpd_exe