1 // Copyright (c) 2016 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "test_utils/limited_reader.h"
9
10 namespace webm {
11
LimitedReader(std::unique_ptr<Reader> impl)12 LimitedReader::LimitedReader(std::unique_ptr<Reader> impl)
13 : impl_(std::move(impl)) {}
14
Read(std::size_t num_to_read,std::uint8_t * buffer,std::uint64_t * num_actually_read)15 Status LimitedReader::Read(std::size_t num_to_read, std::uint8_t* buffer,
16 std::uint64_t* num_actually_read) {
17 assert(num_to_read > 0);
18 assert(buffer != nullptr);
19 assert(num_actually_read != nullptr);
20
21 *num_actually_read = 0;
22 std::size_t expected = num_to_read;
23
24 num_to_read = std::min({num_to_read, single_read_limit_, total_read_limit_});
25
26 // Handle total_read_skip_limit_ separately since std::size_t can be
27 // smaller than std::uint64_t.
28 if (num_to_read > total_read_skip_limit_) {
29 num_to_read = static_cast<std::size_t>(total_read_skip_limit_);
30 }
31
32 if (num_to_read == 0) {
33 return return_status_when_blocked_;
34 }
35
36 Status status = impl_->Read(num_to_read, buffer, num_actually_read);
37 assert(*num_actually_read <= num_to_read);
38
39 if (status.code == Status::kOkCompleted && *num_actually_read < expected) {
40 status.code = Status::kOkPartial;
41 }
42
43 if (total_read_limit_ != std::numeric_limits<std::size_t>::max()) {
44 total_read_limit_ -= static_cast<std::size_t>(*num_actually_read);
45 }
46
47 if (total_read_skip_limit_ != std::numeric_limits<std::uint64_t>::max()) {
48 total_read_skip_limit_ -= *num_actually_read;
49 }
50
51 return status;
52 }
53
Skip(std::uint64_t num_to_skip,std::uint64_t * num_actually_skipped)54 Status LimitedReader::Skip(std::uint64_t num_to_skip,
55 std::uint64_t* num_actually_skipped) {
56 assert(num_to_skip > 0);
57 assert(num_actually_skipped != nullptr);
58
59 *num_actually_skipped = 0;
60 std::uint64_t expected = num_to_skip;
61
62 num_to_skip = std::min({num_to_skip, single_skip_limit_, total_skip_limit_,
63 total_read_skip_limit_});
64
65 if (num_to_skip == 0) {
66 return return_status_when_blocked_;
67 }
68
69 Status status = impl_->Skip(num_to_skip, num_actually_skipped);
70 assert(*num_actually_skipped <= num_to_skip);
71
72 if (status.code == Status::kOkCompleted && *num_actually_skipped < expected) {
73 status.code = Status::kOkPartial;
74 }
75
76 if (total_skip_limit_ != std::numeric_limits<std::uint64_t>::max()) {
77 total_skip_limit_ -= *num_actually_skipped;
78 }
79
80 if (total_read_skip_limit_ != std::numeric_limits<std::uint64_t>::max()) {
81 total_read_skip_limit_ -= *num_actually_skipped;
82 }
83
84 return status;
85 }
86
Position() const87 std::uint64_t LimitedReader::Position() const { return impl_->Position(); }
88
set_return_status_when_blocked(Status status)89 void LimitedReader::set_return_status_when_blocked(Status status) {
90 return_status_when_blocked_ = status;
91 }
92
set_single_read_limit(std::size_t max_num_bytes)93 void LimitedReader::set_single_read_limit(std::size_t max_num_bytes) {
94 single_read_limit_ = max_num_bytes;
95 }
96
set_single_skip_limit(std::uint64_t max_num_bytes)97 void LimitedReader::set_single_skip_limit(std::uint64_t max_num_bytes) {
98 single_skip_limit_ = max_num_bytes;
99 }
100
set_total_read_limit(std::size_t max_num_bytes)101 void LimitedReader::set_total_read_limit(std::size_t max_num_bytes) {
102 total_read_limit_ = max_num_bytes;
103 }
104
set_total_skip_limit(std::uint64_t max_num_bytes)105 void LimitedReader::set_total_skip_limit(std::uint64_t max_num_bytes) {
106 total_skip_limit_ = max_num_bytes;
107 }
108
set_total_read_skip_limit(std::uint64_t max_num_bytes)109 void LimitedReader::set_total_read_skip_limit(std::uint64_t max_num_bytes) {
110 total_read_skip_limit_ = max_num_bytes;
111 }
112
113 } // namespace webm
114