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 #include <array>
11 #include <cstdint>
12 #include <memory>
13
14 #include "gtest/gtest.h"
15
16 #include "webm/buffer_reader.h"
17 #include "webm/reader.h"
18 #include "webm/status.h"
19
20 using webm::BufferReader;
21 using webm::LimitedReader;
22 using webm::Reader;
23 using webm::Status;
24
25 namespace {
26
27 class LimitedReaderTest : public testing::Test {};
28
TEST_F(LimitedReaderTest,UnlimitedRead)29 TEST_F(LimitedReaderTest, UnlimitedRead) {
30 std::array<std::uint8_t, 4> buffer = {{0, 0, 0, 0}};
31 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
32 std::uint64_t count;
33 Status status;
34
35 status = reader.Read(buffer.size(), buffer.data(), &count);
36 EXPECT_EQ(Status::kOkCompleted, status.code);
37 EXPECT_EQ(static_cast<std::uint64_t>(4), count);
38
39 std::array<std::uint8_t, 4> expected_buffer = {{1, 2, 3, 4}};
40 EXPECT_EQ(expected_buffer, buffer);
41 }
42
TEST_F(LimitedReaderTest,UnlimitedSkip)43 TEST_F(LimitedReaderTest, UnlimitedSkip) {
44 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
45 std::uint64_t count;
46 Status status;
47
48 status = reader.Skip(4, &count);
49 EXPECT_EQ(Status::kOkCompleted, status.code);
50 EXPECT_EQ(static_cast<std::uint64_t>(4), count);
51 }
52
TEST_F(LimitedReaderTest,Position)53 TEST_F(LimitedReaderTest, Position) {
54 std::array<std::uint8_t, 4> buffer = {{0, 0, 0, 0}};
55 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
56 std::uint64_t count;
57 Status status;
58
59 EXPECT_EQ(static_cast<std::uint64_t>(0), reader.Position());
60
61 status = reader.Read(2, buffer.data(), &count);
62 EXPECT_EQ(Status::kOkCompleted, status.code);
63 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
64
65 status = reader.Skip(2, &count);
66 EXPECT_EQ(Status::kOkCompleted, status.code);
67 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
68 EXPECT_EQ(static_cast<std::uint64_t>(4), reader.Position());
69
70 std::array<std::uint8_t, 4> expected_buffer = {{1, 2, 0, 0}};
71 EXPECT_EQ(expected_buffer, buffer);
72 }
73
TEST_F(LimitedReaderTest,LimitIndividualRead)74 TEST_F(LimitedReaderTest, LimitIndividualRead) {
75 std::array<std::uint8_t, 4> buffer = {{0, 0, 0, 0}};
76 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
77 std::uint64_t count;
78 Status status;
79
80 reader.set_single_read_limit(1);
81 status = reader.Read(buffer.size(), buffer.data(), &count);
82 EXPECT_EQ(Status::kOkPartial, status.code);
83 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
84
85 status = reader.Read(buffer.size() + 1, buffer.data() + 1, &count);
86 EXPECT_EQ(Status::kOkPartial, status.code);
87 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
88
89 reader.set_single_read_limit(2);
90 status = reader.Read(buffer.size() - 2, buffer.data() + 2, &count);
91 EXPECT_EQ(Status::kOkCompleted, status.code);
92 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
93
94 std::array<std::uint8_t, 4> expected_buffer = {{1, 2, 3, 4}};
95 EXPECT_EQ(expected_buffer, buffer);
96 }
97
TEST_F(LimitedReaderTest,LimitIndividualSkip)98 TEST_F(LimitedReaderTest, LimitIndividualSkip) {
99 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
100 std::uint64_t count;
101 Status status;
102
103 reader.set_single_skip_limit(1);
104 status = reader.Skip(4, &count);
105 EXPECT_EQ(Status::kOkPartial, status.code);
106 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
107
108 status = reader.Skip(3, &count);
109 EXPECT_EQ(Status::kOkPartial, status.code);
110 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
111
112 reader.set_single_skip_limit(2);
113 status = reader.Skip(2, &count);
114 EXPECT_EQ(Status::kOkCompleted, status.code);
115 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
116 }
117
TEST_F(LimitedReaderTest,LimitRepeatedRead)118 TEST_F(LimitedReaderTest, LimitRepeatedRead) {
119 std::array<std::uint8_t, 4> buffer = {{0, 0, 0, 0}};
120 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
121 std::uint64_t count;
122 Status status;
123
124 reader.set_total_read_limit(1);
125 status = reader.Read(buffer.size(), buffer.data(), &count);
126 EXPECT_EQ(Status::kOkPartial, status.code);
127 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
128
129 status = reader.Read(buffer.size(), buffer.data(), &count);
130 EXPECT_EQ(Status::kWouldBlock, status.code);
131 EXPECT_EQ(static_cast<std::uint64_t>(0), count);
132
133 reader.set_total_read_limit(2);
134 status = reader.Read(buffer.size() - 1, buffer.data() + 1, &count);
135 EXPECT_EQ(Status::kOkPartial, status.code);
136 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
137
138 reader.set_total_read_limit(1);
139 status = reader.Read(buffer.size() - 3, buffer.data() + 3, &count);
140 EXPECT_EQ(Status::kOkCompleted, status.code);
141 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
142
143 std::array<std::uint8_t, 4> expected_buffer = {{1, 2, 3, 4}};
144 EXPECT_EQ(expected_buffer, buffer);
145 }
146
TEST_F(LimitedReaderTest,LimitRepeatedSkip)147 TEST_F(LimitedReaderTest, LimitRepeatedSkip) {
148 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
149 std::uint64_t count;
150 Status status;
151
152 reader.set_total_skip_limit(1);
153 status = reader.Skip(4, &count);
154 EXPECT_EQ(Status::kOkPartial, status.code);
155 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
156
157 status = reader.Skip(4, &count);
158 EXPECT_EQ(Status::kWouldBlock, status.code);
159 EXPECT_EQ(static_cast<std::uint64_t>(0), count);
160
161 reader.set_total_skip_limit(2);
162 status = reader.Skip(3, &count);
163 EXPECT_EQ(Status::kOkPartial, status.code);
164 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
165
166 reader.set_total_skip_limit(1);
167 status = reader.Skip(1, &count);
168 EXPECT_EQ(Status::kOkCompleted, status.code);
169 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
170 }
171
TEST_F(LimitedReaderTest,LimitReadsAndSkips)172 TEST_F(LimitedReaderTest, LimitReadsAndSkips) {
173 std::array<std::uint8_t, 4> buffer = {{0, 0, 0, 0}};
174 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
175 std::uint64_t count;
176 Status status;
177
178 reader.set_total_read_skip_limit(1);
179 status = reader.Read(buffer.size(), buffer.data(), &count);
180 EXPECT_EQ(Status::kOkPartial, status.code);
181 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
182
183 status = reader.Skip(buffer.size(), &count);
184 EXPECT_EQ(Status::kWouldBlock, status.code);
185 EXPECT_EQ(static_cast<std::uint64_t>(0), count);
186
187 reader.set_total_read_skip_limit(2);
188 status = reader.Skip(buffer.size() - 1, &count);
189 EXPECT_EQ(Status::kOkPartial, status.code);
190 EXPECT_EQ(static_cast<std::uint64_t>(2), count);
191
192 reader.set_total_read_skip_limit(1);
193 status = reader.Read(buffer.size() - 3, buffer.data() + 3, &count);
194 EXPECT_EQ(Status::kOkCompleted, status.code);
195 EXPECT_EQ(static_cast<std::uint64_t>(1), count);
196
197 std::array<std::uint8_t, 4> expected = {{1, 0, 0, 4}};
198 EXPECT_EQ(expected, buffer);
199 }
200
TEST_F(LimitedReaderTest,CustomStatusWhenBlocked)201 TEST_F(LimitedReaderTest, CustomStatusWhenBlocked) {
202 std::array<std::uint8_t, 4> buffer = {{0, 0, 0, 0}};
203 LimitedReader reader(std::unique_ptr<Reader>(new BufferReader({1, 2, 3, 4})));
204 std::uint64_t count;
205 Status status;
206 Status expected_status = Status(-123);
207 const std::uint64_t kZeroCount = 0;
208
209 reader.set_single_read_limit(0);
210 status = reader.Read(buffer.size(), buffer.data(), &count);
211 EXPECT_EQ(Status::kWouldBlock, status.code);
212 EXPECT_EQ(kZeroCount, count);
213
214 reader.set_return_status_when_blocked(expected_status);
215 status = reader.Read(buffer.size(), buffer.data(), &count);
216 EXPECT_EQ(expected_status.code, status.code);
217 EXPECT_EQ(kZeroCount, count);
218
219 reader.set_single_read_limit(std::numeric_limits<std::size_t>::max());
220 reader.set_total_read_limit(0);
221 status = reader.Read(buffer.size(), buffer.data(), &count);
222 EXPECT_EQ(expected_status.code, status.code);
223 EXPECT_EQ(kZeroCount, count);
224
225 reader.set_total_read_limit(std::numeric_limits<std::size_t>::max());
226 reader.set_single_skip_limit(0);
227 status = reader.Skip(buffer.size(), &count);
228 EXPECT_EQ(expected_status.code, status.code);
229 EXPECT_EQ(kZeroCount, count);
230
231 reader.set_single_skip_limit(std::numeric_limits<std::uint64_t>::max());
232 reader.set_total_skip_limit(0);
233 status = reader.Skip(buffer.size(), &count);
234 EXPECT_EQ(expected_status.code, status.code);
235 EXPECT_EQ(kZeroCount, count);
236
237 reader.set_total_skip_limit(std::numeric_limits<std::uint64_t>::max());
238 reader.set_total_read_skip_limit(0);
239 status = reader.Read(buffer.size(), buffer.data(), &count);
240 EXPECT_EQ(expected_status.code, status.code);
241 EXPECT_EQ(kZeroCount, count);
242 status = reader.Skip(buffer.size(), &count);
243 EXPECT_EQ(expected_status.code, status.code);
244 EXPECT_EQ(kZeroCount, count);
245
246 std::array<std::uint8_t, 4> expected_buffer = {{0, 0, 0, 0}};
247 EXPECT_EQ(expected_buffer, buffer);
248 }
249
250 } // namespace
251