LCOV - code coverage report
Current view: top level - src/test - streams_tests.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 308 309 99.7 %
Date: 2022-04-21 14:51:19 Functions: 7 7 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 46 48 95.8 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2012-2021 The Bitcoin Core developers
#       2                 :            : // Distributed under the MIT software license, see the accompanying
#       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       4                 :            : 
#       5                 :            : #include <fs.h>
#       6                 :            : #include <streams.h>
#       7                 :            : #include <test/util/setup_common.h>
#       8                 :            : 
#       9                 :            : #include <boost/test/unit_test.hpp>
#      10                 :            : 
#      11                 :            : using namespace std::string_literals;
#      12                 :            : 
#      13                 :            : BOOST_FIXTURE_TEST_SUITE(streams_tests, BasicTestingSetup)
#      14                 :            : 
#      15                 :            : BOOST_AUTO_TEST_CASE(streams_vector_writer)
#      16                 :          2 : {
#      17                 :          2 :     unsigned char a(1);
#      18                 :          2 :     unsigned char b(2);
#      19                 :          2 :     unsigned char bytes[] = { 3, 4, 5, 6 };
#      20                 :          2 :     std::vector<unsigned char> vch;
#      21                 :            : 
#      22                 :            :     // Each test runs twice. Serializing a second time at the same starting
#      23                 :            :     // point should yield the same results, even if the first test grew the
#      24                 :            :     // vector.
#      25                 :            : 
#      26                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b);
#      27                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
#      28                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, a, b);
#      29                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{1, 2}}));
#      30                 :          2 :     vch.clear();
#      31                 :            : 
#      32                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
#      33                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
#      34                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
#      35                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2}}));
#      36                 :          2 :     vch.clear();
#      37                 :            : 
#      38                 :          2 :     vch.resize(5, 0);
#      39                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
#      40                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
#      41                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, b);
#      42                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 1, 2, 0}}));
#      43                 :          2 :     vch.clear();
#      44                 :            : 
#      45                 :          2 :     vch.resize(4, 0);
#      46                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b);
#      47                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
#      48                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 3, a, b);
#      49                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 1, 2}}));
#      50                 :          2 :     vch.clear();
#      51                 :            : 
#      52                 :          2 :     vch.resize(4, 0);
#      53                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b);
#      54                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
#      55                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 4, a, b);
#      56                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{0, 0, 0, 0, 1, 2}}));
#      57                 :          2 :     vch.clear();
#      58                 :            : 
#      59                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
#      60                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
#      61                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 0, bytes);
#      62                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{3, 4, 5, 6}}));
#      63                 :          2 :     vch.clear();
#      64                 :            : 
#      65                 :          2 :     vch.resize(4, 8);
#      66                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
#      67                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
#      68                 :          2 :     CVectorWriter(SER_NETWORK, INIT_PROTO_VERSION, vch, 2, a, bytes, b);
#      69                 :          2 :     BOOST_CHECK((vch == std::vector<unsigned char>{{8, 8, 1, 3, 4, 5, 6, 2}}));
#      70                 :          2 :     vch.clear();
#      71                 :          2 : }
#      72                 :            : 
#      73                 :            : BOOST_AUTO_TEST_CASE(streams_vector_reader)
#      74                 :          2 : {
#      75                 :          2 :     std::vector<unsigned char> vch = {1, 255, 3, 4, 5, 6};
#      76                 :            : 
#      77                 :          2 :     SpanReader reader{SER_NETWORK, INIT_PROTO_VERSION, vch};
#      78                 :          2 :     BOOST_CHECK_EQUAL(reader.size(), 6U);
#      79                 :          2 :     BOOST_CHECK(!reader.empty());
#      80                 :            : 
#      81                 :            :     // Read a single byte as an unsigned char.
#      82                 :          2 :     unsigned char a;
#      83                 :          2 :     reader >> a;
#      84                 :          2 :     BOOST_CHECK_EQUAL(a, 1);
#      85                 :          2 :     BOOST_CHECK_EQUAL(reader.size(), 5U);
#      86                 :          2 :     BOOST_CHECK(!reader.empty());
#      87                 :            : 
#      88                 :            :     // Read a single byte as a signed char.
#      89                 :          2 :     signed char b;
#      90                 :          2 :     reader >> b;
#      91                 :          2 :     BOOST_CHECK_EQUAL(b, -1);
#      92                 :          2 :     BOOST_CHECK_EQUAL(reader.size(), 4U);
#      93                 :          2 :     BOOST_CHECK(!reader.empty());
#      94                 :            : 
#      95                 :            :     // Read a 4 bytes as an unsigned int.
#      96                 :          2 :     unsigned int c;
#      97                 :          2 :     reader >> c;
#      98                 :          2 :     BOOST_CHECK_EQUAL(c, 100992003U); // 3,4,5,6 in little-endian base-256
#      99                 :          2 :     BOOST_CHECK_EQUAL(reader.size(), 0U);
#     100                 :          2 :     BOOST_CHECK(reader.empty());
#     101                 :            : 
#     102                 :            :     // Reading after end of byte vector throws an error.
#     103                 :          2 :     signed int d;
#     104                 :          2 :     BOOST_CHECK_THROW(reader >> d, std::ios_base::failure);
#     105                 :            : 
#     106                 :            :     // Read a 4 bytes as a signed int from the beginning of the buffer.
#     107                 :          2 :     SpanReader new_reader{SER_NETWORK, INIT_PROTO_VERSION, vch};
#     108                 :          2 :     new_reader >> d;
#     109                 :          2 :     BOOST_CHECK_EQUAL(d, 67370753); // 1,255,3,4 in little-endian base-256
#     110                 :          2 :     BOOST_CHECK_EQUAL(new_reader.size(), 2U);
#     111                 :          2 :     BOOST_CHECK(!new_reader.empty());
#     112                 :            : 
#     113                 :            :     // Reading after end of byte vector throws an error even if the reader is
#     114                 :            :     // not totally empty.
#     115                 :          2 :     BOOST_CHECK_THROW(new_reader >> d, std::ios_base::failure);
#     116                 :          2 : }
#     117                 :            : 
#     118                 :            : BOOST_AUTO_TEST_CASE(streams_vector_reader_rvalue)
#     119                 :          2 : {
#     120                 :          2 :     std::vector<uint8_t> data{0x82, 0xa7, 0x31};
#     121                 :          2 :     SpanReader reader{SER_NETWORK, INIT_PROTO_VERSION, data};
#     122                 :          2 :     uint32_t varint = 0;
#     123                 :            :     // Deserialize into r-value
#     124                 :          2 :     reader >> VARINT(varint);
#     125                 :          2 :     BOOST_CHECK_EQUAL(varint, 54321U);
#     126                 :          2 :     BOOST_CHECK(reader.empty());
#     127                 :          2 : }
#     128                 :            : 
#     129                 :            : BOOST_AUTO_TEST_CASE(bitstream_reader_writer)
#     130                 :          2 : {
#     131                 :          2 :     CDataStream data(SER_NETWORK, INIT_PROTO_VERSION);
#     132                 :            : 
#     133                 :          2 :     BitStreamWriter<CDataStream> bit_writer(data);
#     134                 :          2 :     bit_writer.Write(0, 1);
#     135                 :          2 :     bit_writer.Write(2, 2);
#     136                 :          2 :     bit_writer.Write(6, 3);
#     137                 :          2 :     bit_writer.Write(11, 4);
#     138                 :          2 :     bit_writer.Write(1, 5);
#     139                 :          2 :     bit_writer.Write(32, 6);
#     140                 :          2 :     bit_writer.Write(7, 7);
#     141                 :          2 :     bit_writer.Write(30497, 16);
#     142                 :          2 :     bit_writer.Flush();
#     143                 :            : 
#     144                 :          2 :     CDataStream data_copy(data);
#     145                 :          2 :     uint32_t serialized_int1;
#     146                 :          2 :     data >> serialized_int1;
#     147                 :          2 :     BOOST_CHECK_EQUAL(serialized_int1, (uint32_t)0x7700C35A); // NOTE: Serialized as LE
#     148                 :          2 :     uint16_t serialized_int2;
#     149                 :          2 :     data >> serialized_int2;
#     150                 :          2 :     BOOST_CHECK_EQUAL(serialized_int2, (uint16_t)0x1072); // NOTE: Serialized as LE
#     151                 :            : 
#     152                 :          2 :     BitStreamReader<CDataStream> bit_reader(data_copy);
#     153                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(1), 0U);
#     154                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(2), 2U);
#     155                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(3), 6U);
#     156                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(4), 11U);
#     157                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(5), 1U);
#     158                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(6), 32U);
#     159                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(7), 7U);
#     160                 :          2 :     BOOST_CHECK_EQUAL(bit_reader.Read(16), 30497U);
#     161                 :          2 :     BOOST_CHECK_THROW(bit_reader.Read(8), std::ios_base::failure);
#     162                 :          2 : }
#     163                 :            : 
#     164                 :            : BOOST_AUTO_TEST_CASE(streams_serializedata_xor)
#     165                 :          2 : {
#     166                 :          2 :     std::vector<std::byte> in;
#     167                 :            : 
#     168                 :            :     // Degenerate case
#     169                 :          2 :     {
#     170                 :          2 :         CDataStream ds{in, 0, 0};
#     171                 :          2 :         ds.Xor({0x00, 0x00});
#     172                 :          2 :         BOOST_CHECK_EQUAL(""s, ds.str());
#     173                 :          2 :     }
#     174                 :            : 
#     175                 :          2 :     in.push_back(std::byte{0x0f});
#     176                 :          2 :     in.push_back(std::byte{0xf0});
#     177                 :            : 
#     178                 :            :     // Single character key
#     179                 :          2 :     {
#     180                 :          2 :         CDataStream ds{in, 0, 0};
#     181                 :          2 :         ds.Xor({0xff});
#     182                 :          2 :         BOOST_CHECK_EQUAL("\xf0\x0f"s, ds.str());
#     183                 :          2 :     }
#     184                 :            : 
#     185                 :            :     // Multi character key
#     186                 :            : 
#     187                 :          2 :     in.clear();
#     188                 :          2 :     in.push_back(std::byte{0xf0});
#     189                 :          2 :     in.push_back(std::byte{0x0f});
#     190                 :            : 
#     191                 :          2 :     {
#     192                 :          2 :         CDataStream ds{in, 0, 0};
#     193                 :          2 :         ds.Xor({0xff, 0x0f});
#     194                 :          2 :         BOOST_CHECK_EQUAL("\x0f\x00"s, ds.str());
#     195                 :          2 :     }
#     196                 :          2 : }
#     197                 :            : 
#     198                 :            : BOOST_AUTO_TEST_CASE(streams_buffered_file)
#     199                 :          2 : {
#     200                 :          2 :     fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
#     201                 :          2 :     FILE* file = fsbridge::fopen(streams_test_filename, "w+b");
#     202                 :            : 
#     203                 :            :     // The value at each offset is the offset.
#     204         [ +  + ]:         82 :     for (uint8_t j = 0; j < 40; ++j) {
#     205                 :         80 :         fwrite(&j, 1, 1, file);
#     206                 :         80 :     }
#     207                 :          2 :     rewind(file);
#     208                 :            : 
#     209                 :            :     // The buffer size (second arg) must be greater than the rewind
#     210                 :            :     // amount (third arg).
#     211                 :          2 :     try {
#     212                 :          2 :         CBufferedFile bfbad(file, 25, 25, 222, 333);
#     213                 :          2 :         BOOST_CHECK(false);
#     214                 :          2 :     } catch (const std::exception& e) {
#     215                 :          2 :         BOOST_CHECK(strstr(e.what(),
#     216                 :          2 :                         "Rewind limit must be less than buffer size") != nullptr);
#     217                 :          2 :     }
#     218                 :            : 
#     219                 :            :     // The buffer is 25 bytes, allow rewinding 10 bytes.
#     220                 :          2 :     CBufferedFile bf(file, 25, 10, 222, 333);
#     221                 :          2 :     BOOST_CHECK(!bf.eof());
#     222                 :            : 
#     223                 :            :     // These two members have no functional effect.
#     224                 :          2 :     BOOST_CHECK_EQUAL(bf.GetType(), 222);
#     225                 :          2 :     BOOST_CHECK_EQUAL(bf.GetVersion(), 333);
#     226                 :            : 
#     227                 :          2 :     uint8_t i;
#     228                 :          2 :     bf >> i;
#     229                 :          2 :     BOOST_CHECK_EQUAL(i, 0);
#     230                 :          2 :     bf >> i;
#     231                 :          2 :     BOOST_CHECK_EQUAL(i, 1);
#     232                 :            : 
#     233                 :            :     // After reading bytes 0 and 1, we're positioned at 2.
#     234                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 2U);
#     235                 :            : 
#     236                 :            :     // Rewind to offset 0, ok (within the 10 byte window).
#     237                 :          2 :     BOOST_CHECK(bf.SetPos(0));
#     238                 :          2 :     bf >> i;
#     239                 :          2 :     BOOST_CHECK_EQUAL(i, 0);
#     240                 :            : 
#     241                 :            :     // We can go forward to where we've been, but beyond may fail.
#     242                 :          2 :     BOOST_CHECK(bf.SetPos(2));
#     243                 :          2 :     bf >> i;
#     244                 :          2 :     BOOST_CHECK_EQUAL(i, 2);
#     245                 :            : 
#     246                 :            :     // If you know the maximum number of bytes that should be
#     247                 :            :     // read to deserialize the variable, you can limit the read
#     248                 :            :     // extent. The current file offset is 3, so the following
#     249                 :            :     // SetLimit() allows zero bytes to be read.
#     250                 :          2 :     BOOST_CHECK(bf.SetLimit(3));
#     251                 :          2 :     try {
#     252                 :          2 :         bf >> i;
#     253                 :          2 :         BOOST_CHECK(false);
#     254                 :          2 :     } catch (const std::exception& e) {
#     255                 :          2 :         BOOST_CHECK(strstr(e.what(),
#     256                 :          2 :                         "Read attempted past buffer limit") != nullptr);
#     257                 :          2 :     }
#     258                 :            :     // The default argument removes the limit completely.
#     259                 :          2 :     BOOST_CHECK(bf.SetLimit());
#     260                 :            :     // The read position should still be at 3 (no change).
#     261                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 3U);
#     262                 :            : 
#     263                 :            :     // Read from current offset, 3, forward until position 10.
#     264         [ +  + ]:         16 :     for (uint8_t j = 3; j < 10; ++j) {
#     265                 :         14 :         bf >> i;
#     266                 :         14 :         BOOST_CHECK_EQUAL(i, j);
#     267                 :         14 :     }
#     268                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 10U);
#     269                 :            : 
#     270                 :            :     // We're guaranteed (just barely) to be able to rewind to zero.
#     271                 :          2 :     BOOST_CHECK(bf.SetPos(0));
#     272                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 0U);
#     273                 :          2 :     bf >> i;
#     274                 :          2 :     BOOST_CHECK_EQUAL(i, 0);
#     275                 :            : 
#     276                 :            :     // We can set the position forward again up to the farthest
#     277                 :            :     // into the stream we've been, but no farther. (Attempting
#     278                 :            :     // to go farther may succeed, but it's not guaranteed.)
#     279                 :          2 :     BOOST_CHECK(bf.SetPos(10));
#     280                 :          2 :     bf >> i;
#     281                 :          2 :     BOOST_CHECK_EQUAL(i, 10);
#     282                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 11U);
#     283                 :            : 
#     284                 :            :     // Now it's only guaranteed that we can rewind to offset 1
#     285                 :            :     // (current read position, 11, minus rewind amount, 10).
#     286                 :          2 :     BOOST_CHECK(bf.SetPos(1));
#     287                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 1U);
#     288                 :          2 :     bf >> i;
#     289                 :          2 :     BOOST_CHECK_EQUAL(i, 1);
#     290                 :            : 
#     291                 :            :     // We can stream into large variables, even larger than
#     292                 :            :     // the buffer size.
#     293                 :          2 :     BOOST_CHECK(bf.SetPos(11));
#     294                 :          2 :     {
#     295                 :          2 :         uint8_t a[40 - 11];
#     296                 :          2 :         bf >> a;
#     297         [ +  + ]:         60 :         for (uint8_t j = 0; j < sizeof(a); ++j) {
#     298                 :         58 :             BOOST_CHECK_EQUAL(a[j], 11 + j);
#     299                 :         58 :         }
#     300                 :          2 :     }
#     301                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 40U);
#     302                 :            : 
#     303                 :            :     // We've read the entire file, the next read should throw.
#     304                 :          2 :     try {
#     305                 :          2 :         bf >> i;
#     306                 :          2 :         BOOST_CHECK(false);
#     307                 :          2 :     } catch (const std::exception& e) {
#     308                 :          2 :         BOOST_CHECK(strstr(e.what(),
#     309                 :          2 :                         "CBufferedFile::Fill: end of file") != nullptr);
#     310                 :          2 :     }
#     311                 :            :     // Attempting to read beyond the end sets the EOF indicator.
#     312                 :          2 :     BOOST_CHECK(bf.eof());
#     313                 :            : 
#     314                 :            :     // Still at offset 40, we can go back 10, to 30.
#     315                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 40U);
#     316                 :          2 :     BOOST_CHECK(bf.SetPos(30));
#     317                 :          2 :     bf >> i;
#     318                 :          2 :     BOOST_CHECK_EQUAL(i, 30);
#     319                 :          2 :     BOOST_CHECK_EQUAL(bf.GetPos(), 31U);
#     320                 :            : 
#     321                 :            :     // We're too far to rewind to position zero.
#     322                 :          2 :     BOOST_CHECK(!bf.SetPos(0));
#     323                 :            :     // But we should now be positioned at least as far back as allowed
#     324                 :            :     // by the rewind window (relative to our farthest read position, 40).
#     325                 :          2 :     BOOST_CHECK(bf.GetPos() <= 30);
#     326                 :            : 
#     327                 :            :     // We can explicitly close the file, or the destructor will do it.
#     328                 :          2 :     bf.fclose();
#     329                 :            : 
#     330                 :          2 :     fs::remove(streams_test_filename);
#     331                 :          2 : }
#     332                 :            : 
#     333                 :            : BOOST_AUTO_TEST_CASE(streams_buffered_file_rand)
#     334                 :          2 : {
#     335                 :            :     // Make this test deterministic.
#     336                 :          2 :     SeedInsecureRand(SeedRand::ZEROS);
#     337                 :            : 
#     338                 :          2 :     fs::path streams_test_filename = m_args.GetDataDirBase() / "streams_test_tmp";
#     339         [ +  + ]:        102 :     for (int rep = 0; rep < 50; ++rep) {
#     340                 :        100 :         FILE* file = fsbridge::fopen(streams_test_filename, "w+b");
#     341                 :        100 :         size_t fileSize = InsecureRandRange(256);
#     342         [ +  + ]:      11592 :         for (uint8_t i = 0; i < fileSize; ++i) {
#     343                 :      11492 :             fwrite(&i, 1, 1, file);
#     344                 :      11492 :         }
#     345                 :        100 :         rewind(file);
#     346                 :            : 
#     347                 :        100 :         size_t bufSize = InsecureRandRange(300) + 1;
#     348                 :        100 :         size_t rewindSize = InsecureRandRange(bufSize);
#     349                 :        100 :         CBufferedFile bf(file, bufSize, rewindSize, 222, 333);
#     350                 :        100 :         size_t currentPos = 0;
#     351                 :        100 :         size_t maxPos = 0;
#     352         [ +  + ]:       7444 :         for (int step = 0; step < 100; ++step) {
#     353         [ +  + ]:       7388 :             if (currentPos >= fileSize)
#     354                 :         44 :                 break;
#     355                 :            : 
#     356                 :            :             // We haven't read to the end of the file yet.
#     357                 :       7344 :             BOOST_CHECK(!bf.eof());
#     358                 :       7344 :             BOOST_CHECK_EQUAL(bf.GetPos(), currentPos);
#     359                 :            : 
#     360                 :            :             // Pretend the file consists of a series of objects of varying
#     361                 :            :             // sizes; the boundaries of the objects can interact arbitrarily
#     362                 :            :             // with the CBufferFile's internal buffer. These first three
#     363                 :            :             // cases simulate objects of various sizes (1, 2, 5 bytes).
#     364         [ -  + ]:       7344 :             switch (InsecureRandRange(5)) {
#     365         [ +  + ]:       1514 :             case 0: {
#     366                 :       1514 :                 uint8_t a[1];
#     367         [ -  + ]:       1514 :                 if (currentPos + 1 > fileSize)
#     368                 :          0 :                     continue;
#     369                 :       1514 :                 bf.SetLimit(currentPos + 1);
#     370                 :       1514 :                 bf >> a;
#     371         [ +  + ]:       3028 :                 for (uint8_t i = 0; i < 1; ++i) {
#     372                 :       1514 :                     BOOST_CHECK_EQUAL(a[i], currentPos);
#     373                 :       1514 :                     currentPos++;
#     374                 :       1514 :                 }
#     375                 :       1514 :                 break;
#     376                 :       1514 :             }
#     377         [ +  + ]:       1446 :             case 1: {
#     378                 :       1446 :                 uint8_t a[2];
#     379         [ +  + ]:       1446 :                 if (currentPos + 2 > fileSize)
#     380                 :          6 :                     continue;
#     381                 :       1440 :                 bf.SetLimit(currentPos + 2);
#     382                 :       1440 :                 bf >> a;
#     383         [ +  + ]:       4320 :                 for (uint8_t i = 0; i < 2; ++i) {
#     384                 :       2880 :                     BOOST_CHECK_EQUAL(a[i], currentPos);
#     385                 :       2880 :                     currentPos++;
#     386                 :       2880 :                 }
#     387                 :       1440 :                 break;
#     388                 :       1446 :             }
#     389         [ +  + ]:       1512 :             case 2: {
#     390                 :       1512 :                 uint8_t a[5];
#     391         [ +  + ]:       1512 :                 if (currentPos + 5 > fileSize)
#     392                 :         22 :                     continue;
#     393                 :       1490 :                 bf.SetLimit(currentPos + 5);
#     394                 :       1490 :                 bf >> a;
#     395         [ +  + ]:       8940 :                 for (uint8_t i = 0; i < 5; ++i) {
#     396                 :       7450 :                     BOOST_CHECK_EQUAL(a[i], currentPos);
#     397                 :       7450 :                     currentPos++;
#     398                 :       7450 :                 }
#     399                 :       1490 :                 break;
#     400                 :       1512 :             }
#     401         [ +  + ]:       1492 :             case 3: {
#     402                 :            :                 // Find a byte value (that is at or ahead of the current position).
#     403                 :       1492 :                 size_t find = currentPos + InsecureRandRange(8);
#     404         [ +  + ]:       1492 :                 if (find >= fileSize)
#     405                 :         10 :                     find = fileSize - 1;
#     406                 :       1492 :                 bf.FindByte(uint8_t(find));
#     407                 :            :                 // The value at each offset is the offset.
#     408                 :       1492 :                 BOOST_CHECK_EQUAL(bf.GetPos(), find);
#     409                 :       1492 :                 currentPos = find;
#     410                 :            : 
#     411                 :       1492 :                 bf.SetLimit(currentPos + 1);
#     412                 :       1492 :                 uint8_t i;
#     413                 :       1492 :                 bf >> i;
#     414                 :       1492 :                 BOOST_CHECK_EQUAL(i, currentPos);
#     415                 :       1492 :                 currentPos++;
#     416                 :       1492 :                 break;
#     417                 :       1512 :             }
#     418         [ +  + ]:       1380 :             case 4: {
#     419                 :       1380 :                 size_t requestPos = InsecureRandRange(maxPos + 4);
#     420                 :       1380 :                 bool okay = bf.SetPos(requestPos);
#     421                 :            :                 // The new position may differ from the requested position
#     422                 :            :                 // because we may not be able to rewind beyond the rewind
#     423                 :            :                 // window, and we may not be able to move forward beyond the
#     424                 :            :                 // farthest position we've reached so far.
#     425                 :       1380 :                 currentPos = bf.GetPos();
#     426                 :       1380 :                 BOOST_CHECK_EQUAL(okay, currentPos == requestPos);
#     427                 :            :                 // Check that we can position within the rewind window.
#     428         [ +  + ]:       1380 :                 if (requestPos <= maxPos &&
#     429         [ +  + ]:       1380 :                     maxPos > rewindSize &&
#     430         [ +  + ]:       1380 :                     requestPos >= maxPos - rewindSize) {
#     431                 :            :                     // We requested a position within the rewind window.
#     432                 :        220 :                     BOOST_CHECK(okay);
#     433                 :        220 :                 }
#     434                 :       1380 :                 break;
#     435                 :       1512 :             }
#     436                 :       7344 :             }
#     437         [ +  + ]:       7316 :             if (maxPos < currentPos)
#     438                 :       2768 :                 maxPos = currentPos;
#     439                 :       7316 :         }
#     440                 :        100 :     }
#     441                 :          2 :     fs::remove(streams_test_filename);
#     442                 :          2 : }
#     443                 :            : 
#     444                 :            : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a