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 #ifndef TEST_UTILS_LIMITED_READER_H_
9 #define TEST_UTILS_LIMITED_READER_H_
10 
11 #include <algorithm>
12 #include <cassert>
13 #include <cstddef>
14 #include <cstdint>
15 #include <limits>
16 #include <memory>
17 
18 #include "webm/reader.h"
19 #include "webm/status.h"
20 
21 namespace webm {
22 
23 // An adapter that uses an underlying reader to read data, but with added
24 // limitations on how much data can be read/skipped. Its primary use is for
25 // testing APIs that consume a reader to make sure they gracefully handle
26 // arbitrary reading failures.
27 class LimitedReader : public Reader {
28  public:
29   LimitedReader() = delete;
30   LimitedReader(const LimitedReader&) = delete;
31   LimitedReader& operator=(const LimitedReader&) = delete;
32 
33   LimitedReader(LimitedReader&&) = default;
34   LimitedReader& operator=(LimitedReader&&) = default;
35 
36   explicit LimitedReader(std::unique_ptr<Reader> impl);
37 
38   // Reads data using the internal reader, but limits the number of bytes that
39   // can be read based on the settings of this LimitedReader. If this reader has
40   // reached its cap of maximum number of bytes allowed to be read, the chosen
41   // status will be returned.
42   Status Read(std::size_t num_to_read, std::uint8_t* buffer,
43               std::uint64_t* num_actually_read) override;
44 
45   // Skips data using the internal reader, but limits the number of bytes that
46   // can be skipped based on the settings of this LimitedReader. If this reader
47   // has reached its cap of maximum number of bytes allowed to be skipped, the
48   // chosen status will be returned.
49   Status Skip(std::uint64_t num_to_skip,
50               std::uint64_t* num_actually_skipped) override;
51 
52   std::uint64_t Position() const override;
53 
54   // Sets the status that should be returned when the reader reaches its cap of
55   // maximum number of bytes that can be read/skipped and cannot read/skip any
56   // more bytes. By default, this reader will return Status::kWouldBlock when
57   // this maximum limit is hit.
58   void set_return_status_when_blocked(Status status);
59 
60   // Sets the total number of bytes that can be read in a single call to Read.
61   void set_single_read_limit(std::size_t max_num_bytes);
62 
63   // Sets the total number of bytes that can be skipped in a single call to
64   // Skip.
65   void set_single_skip_limit(std::uint64_t max_num_bytes);
66 
67   // Sets the total number of bytes that can be read by the reader with Read.
68   // This total is considered to be cumulative for reads, but not skips.
69   // Setting this to std::numeric_limits<std::size_t>::max() will result in no
70   // extra limitation being imposed on reads.
71   void set_total_read_limit(std::size_t max_num_bytes);
72 
73   // Sets the total number of bytes that can be skipped by the reader with Skip.
74   // This total is considered to be cumulative for skips, but not reads.
75   // Setting this to std::numeric_limits<std::uint64_t>::max() will result in no
76   // extra limitation being imposed on skips.
77   void set_total_skip_limit(std::uint64_t max_num_bytes);
78 
79   // Sets the total number of bytes that can be read/skipped by the reader.
80   // This total is considered to be cumulative between reads and skips.
81   // Setting this to std::numeric_limits<std::uint64_t>::max() will result in no
82   // extra limitation being imposed on reads/skips.
83   void set_total_read_skip_limit(std::uint64_t max_num_bytes);
84 
85  private:
86   // The maximum number of bytes to let a single call to Read return.
87   std::size_t single_read_limit_ = std::numeric_limits<std::size_t>::max();
88 
89   // The maximum number of bytes to let a single call to Skip return.
90   std::uint64_t single_skip_limit_ = std::numeric_limits<std::uint64_t>::max();
91 
92   // The total maximum number of bytes that can be read with multiple calls to
93   // Read.
94   std::size_t total_read_limit_ = std::numeric_limits<std::size_t>::max();
95 
96   // The total maximum number of bytes that can be skipped with multiple calls
97   // to Skip.
98   std::uint64_t total_skip_limit_ = std::numeric_limits<std::uint64_t>::max();
99 
100   // The total maximum number of bytes that can be read or skipped with multiple
101   // calls to Read and/or Skip.
102   std::uint64_t total_read_skip_limit_ =
103       std::numeric_limits<std::uint64_t>::max();
104 
105   // The status to return when the reader has reached is maximum limit for
106   // Read/Skip and cannot read or skip any data.
107   Status return_status_when_blocked_ = Status(Status::kWouldBlock);
108 
109   // The actual reader that does the real reading/skipping.
110   std::unique_ptr<Reader> impl_;
111 };
112 
113 }  // namespace webm
114 
115 #endif  // TEST_UTILS_LIMITED_READER_H_
116