diff options
author | Sen Jiang <senj@google.com> | 2015-11-25 01:17:37 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-11-25 01:17:37 +0000 |
commit | 2c1607d13402172c129d73d76a6a351e78a44328 (patch) | |
tree | 8ac7172a77e17c3335aa7f5c6627177979a2b463 | |
parent | a1e8251cad073f210d86a3e99b166b75409891fc (diff) | |
parent | f822e6c031de113b790d622b0cd0e98f7d49ea5e (diff) | |
download | bsdiff-2c1607d13402172c129d73d76a6a351e78a44328.tar.gz |
Merge "Fix reading extents file if not start from the beginning of a extent."android-n-preview-1brillo-m9-releasebrillo-m9-devbrillo-m8-releasebrillo-m8-devbrillo-m10-releasebrillo-m10-dev
-rw-r--r-- | extents_file.cc | 9 | ||||
-rw-r--r-- | extents_file_unittest.cc | 26 |
2 files changed, 31 insertions, 4 deletions
diff --git a/extents_file.cc b/extents_file.cc index 2d2ea83..01d31a6 100644 --- a/extents_file.cc +++ b/extents_file.cc @@ -86,14 +86,15 @@ bool ExtentsFile::IOOperation(bool (FileInterface::*io_op)(T*, size_t, size_t*), AdvancePos(0); while (count > 0 && curr_ex_idx_ < extents_.size()) { const ex_t& ex = extents_[curr_ex_idx_]; - size_t chunk_size = std::min(static_cast<uint64_t>(count), ex.len); + off_t curr_ex_off = curr_pos_ - acc_len_[curr_ex_idx_]; + size_t chunk_size = + std::min(static_cast<uint64_t>(count), ex.len - curr_ex_off); size_t chunk_processed = 0; if (ex.off < 0) { chunk_processed = chunk_size; } else { - uint64_t file_pos = ex.off + (curr_pos_ - acc_len_[curr_ex_idx_]); - if (!file_->Seek(file_pos) || - !((file_.get()->*io_op))(buf, chunk_size, &chunk_processed)) { + if (!file_->Seek(ex.off + curr_ex_off) || + !(file_.get()->*io_op)(buf, chunk_size, &chunk_processed)) { processed += chunk_processed; result = processed > 0; break; diff --git a/extents_file_unittest.cc b/extents_file_unittest.cc index fa9ed22..73cedb2 100644 --- a/extents_file_unittest.cc +++ b/extents_file_unittest.cc @@ -128,6 +128,32 @@ TEST_F(ExtentsFileTest, ReadAcrossAllExtents) { EXPECT_EQ(15U, bytes_read); } +TEST_F(ExtentsFileTest, MultiReadAcrossAllExtents) { + ExtentsFile file(std::move(mock_file_ptr_), + {ex_t{10, 5}, ex_t{20, 7}, {27, 3}}); + InSequence s; + char* buf = reinterpret_cast<char*>(0x1234); + + EXPECT_CALL(*mock_file_, Seek(10)).WillOnce(Return(true)); + EXPECT_CALL(*mock_file_, Read(buf, 2, _)).WillOnce(SucceedIO()); + EXPECT_CALL(*mock_file_, Seek(12)).WillOnce(Return(true)); + EXPECT_CALL(*mock_file_, Read(buf, 3, _)).WillOnce(SucceedIO()); + EXPECT_CALL(*mock_file_, Seek(20)).WillOnce(Return(true)); + EXPECT_CALL(*mock_file_, Read(buf + 3, 5, _)).WillOnce(SucceedIO()); + EXPECT_CALL(*mock_file_, Seek(25)).WillOnce(Return(true)); + EXPECT_CALL(*mock_file_, Read(buf, 2, _)).WillOnce(SucceedIO()); + EXPECT_CALL(*mock_file_, Seek(27)).WillOnce(Return(true)); + EXPECT_CALL(*mock_file_, Read(buf + 2, 3, _)).WillOnce(SucceedIO()); + + size_t bytes_read = 0; + EXPECT_TRUE(file.Read(buf, 2, &bytes_read)); + EXPECT_EQ(2U, bytes_read); + EXPECT_TRUE(file.Read(buf, 8, &bytes_read)); + EXPECT_EQ(8U, bytes_read); + EXPECT_TRUE(file.Read(buf, 100, &bytes_read)); + EXPECT_EQ(5U, bytes_read); +} + TEST_F(ExtentsFileTest, ReadSmallChunks) { ExtentsFile file(std::move(mock_file_ptr_), {ex_t{10, 1}, ex_t{20, 10}}); InSequence s; |