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()
|