• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #pragma once
15 
16 #include <cstddef>
17 #include <cstdint>
18 #include <deque>
19 #include <vector>
20 
21 #include "pw_assert/assert.h"
22 #include "pw_bytes/span.h"
23 #include "pw_varint/varint.h"
24 
25 namespace pw::containers {
26 
27 // Behaves like a InlineVarLenEntryQueue should, but with a std::deque-based
28 // implementation.
29 class InlineVarLenEntryQueueTestOracle {
30  public:
InlineVarLenEntryQueueTestOracle(uint32_t max_size_bytes)31   InlineVarLenEntryQueueTestOracle(uint32_t max_size_bytes)
32       : max_size_bytes_(max_size_bytes),
33         raw_size_bytes_(0),
34         raw_capacity_bytes_(
35             static_cast<uint32_t>(varint::EncodedSize(max_size_bytes)) +
36             max_size_bytes) {}
37 
clear()38   void clear() {
39     q_.clear();
40     raw_size_bytes_ = 0;
41   }
42 
push_overwrite(ConstByteSpan data)43   void push_overwrite(ConstByteSpan data) {
44     size_t encoded_size = varint::EncodedSize(data.size()) + data.size();
45     while (encoded_size > (raw_capacity_bytes_ - raw_size_bytes_)) {
46       pop();
47     }
48     push(data);
49   }
50 
push(ConstByteSpan data)51   void push(ConstByteSpan data) {
52     PW_ASSERT(data.size() <= max_size_bytes_);
53 
54     size_t encoded_size = varint::EncodedSize(data.size()) + data.size();
55     PW_ASSERT(encoded_size <= raw_capacity_bytes_ - raw_size_bytes_);
56 
57     q_.emplace_back(data.begin(), data.end());
58     raw_size_bytes_ += encoded_size;
59   }
60 
pop()61   void pop() {
62     PW_ASSERT(!q_.empty());
63     raw_size_bytes_ -=
64         varint::EncodedSize(q_.front().size()) + q_.front().size();
65     q_.pop_front();
66   }
67 
size()68   uint32_t size() const { return static_cast<uint32_t>(q_.size()); }
size_bytes()69   uint32_t size_bytes() const {
70     uint32_t total_bytes = 0;
71     for (const auto& entry : q_) {
72       total_bytes += static_cast<uint32_t>(entry.size());
73     }
74     return total_bytes;
75   }
max_size_bytes()76   uint32_t max_size_bytes() const { return max_size_bytes_; }
77 
begin()78   std::deque<std::vector<std::byte>>::const_iterator begin() const {
79     return q_.begin();
80   }
81 
end()82   std::deque<std::vector<std::byte>>::const_iterator end() const {
83     return q_.end();
84   }
85 
86  private:
87   std::deque<std::vector<std::byte>> q_;
88   const uint32_t max_size_bytes_;
89   uint32_t raw_size_bytes_;
90   const uint32_t raw_capacity_bytes_;
91 };
92 
93 }  // namespace pw::containers
94