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

Generated by: LCOV version 1.14