| 641 | |
| 642 | template <class CoupledTransports> |
| 643 | void test_read_partial_midframe() { |
| 644 | CoupledTransports transports; |
| 645 | BOOST_REQUIRE(transports.in != nullptr); |
| 646 | BOOST_REQUIRE(transports.out != nullptr); |
| 647 | |
| 648 | uint8_t write_buf[16]; |
| 649 | uint8_t read_buf[16]; |
| 650 | memset(write_buf, 'a', sizeof(write_buf)); |
| 651 | |
| 652 | // Attempt to read 10 bytes, when only 9 are available, but after we have |
| 653 | // already read part of the data that is available. This exercises a |
| 654 | // different code path for several of the transports. |
| 655 | // |
| 656 | // For transports that add their own framing (e.g., TFramedTransport and |
| 657 | // TFileTransport), the two flush calls break up the data in to a 10 byte |
| 658 | // frame and a 3 byte frame. The first read then puts us partway through the |
| 659 | // first frame, and then we attempt to read past the end of that frame, and |
| 660 | // through the next frame, too. |
| 661 | // |
| 662 | // For buffered transports that perform read-ahead (e.g., |
| 663 | // TBufferedTransport), the read-ahead will most likely see all 13 bytes |
| 664 | // written on the first read. The next read will then attempt to read past |
| 665 | // the end of the read-ahead buffer. |
| 666 | // |
| 667 | // Flush 10 bytes, then 3 bytes. This creates 2 separate frames for |
| 668 | // transports that track framing internally. |
| 669 | transports.out->write(write_buf, 10); |
| 670 | transports.out->flush(); |
| 671 | transports.out->write(write_buf, 3); |
| 672 | transports.out->flush(); |
| 673 | |
| 674 | // Now read 4 bytes, so that we are partway through the written data. |
| 675 | uint32_t bytes_read = transports.in->read(read_buf, 4); |
| 676 | BOOST_CHECK_EQUAL(bytes_read, (uint32_t)4); |
| 677 | |
| 678 | // Now attempt to read 10 bytes. Only 9 more are available. |
| 679 | // |
| 680 | // We should be able to get all 9 bytes, but it might take multiple read |
| 681 | // calls, since it is valid for read() to return fewer bytes than requested. |
| 682 | // (Most transports do immediately return 9 bytes, but the framing transports |
| 683 | // tend to only return to the end of the current frame, which is 6 bytes in |
| 684 | // this case.) |
| 685 | uint32_t total_read = 0; |
| 686 | while (total_read < 9) { |
| 687 | set_trigger(3, transports.out, 1); |
| 688 | bytes_read = transports.in->read(read_buf, 10); |
| 689 | BOOST_REQUIRE_EQUAL(g_numTriggersFired, (unsigned int)0); |
| 690 | BOOST_REQUIRE_GT(bytes_read, (uint32_t)0); |
| 691 | total_read += bytes_read; |
| 692 | BOOST_REQUIRE_LE(total_read, (uint32_t)9); |
| 693 | } |
| 694 | |
| 695 | BOOST_CHECK_EQUAL(total_read, (uint32_t)9); |
| 696 | |
| 697 | clear_triggers(); |
| 698 | } |
| 699 | |
| 700 | template <class CoupledTransports> |
nothing calls this directly
no test coverage detected