blob: 96fd25f13e3decd6c92b0c30353b395b6608ba99 [file] [log] [blame]
QUICHE teamd7a507e2022-04-15 14:35:46 -07001// Copyright 2022 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
bnc30bbde72022-05-12 06:41:23 -07005#ifndef QUICHE_BALSA_SIMPLE_BUFFER_H_
6#define QUICHE_BALSA_SIMPLE_BUFFER_H_
QUICHE teamd7a507e2022-04-15 14:35:46 -07007
8#include "absl/strings/string_view.h"
9#include "quiche/common/platform/api/quiche_export.h"
10#include "quiche/common/platform/api/quiche_mem_slice.h"
11
12namespace quiche {
13
14namespace test {
15class SimpleBufferTest;
16} // namespace test
17
18// SimpleBuffer stores data in a contiguous region. It can grow on demand,
19// which involves moving its data. It keeps track of a read and a write
20// position. Reading consumes data.
vasilvve124b7b2022-10-21 10:09:44 -070021class QUICHE_EXPORT SimpleBuffer {
QUICHE teamd7a507e2022-04-15 14:35:46 -070022 public:
bnc53020a52022-05-16 12:35:34 -070023 SimpleBuffer() = default;
24 // Create SimpleBuffer with at least `size` reserved capacity.
QUICHE teamd7a507e2022-04-15 14:35:46 -070025 explicit SimpleBuffer(int size);
26
27 SimpleBuffer(const SimpleBuffer&) = delete;
28 SimpleBuffer& operator=(const SimpleBuffer&) = delete;
29
30 virtual ~SimpleBuffer() { delete[] storage_; }
31
32 // Returns the number of bytes that can be read from the buffer.
33 int ReadableBytes() const { return write_idx_ - read_idx_; }
34
35 bool Empty() const { return read_idx_ == write_idx_; }
36
37 // Copies `size` bytes to the buffer. Returns size.
38 int Write(const char* bytes, int size);
39 int WriteString(absl::string_view piece) {
40 return Write(piece.data(), piece.size());
41 }
42
bnc53020a52022-05-16 12:35:34 -070043 // Stores the pointer into the buffer that can be written to in `*ptr`, and
44 // the number of characters that are allowed to be written in `*size`. The
45 // pointer and size can be used in functions like recv() or read(). If
46 // `*size` is zero upon returning from this function, then it is unsafe to
47 // dereference `*ptr`. Writing to this region after calling any other
48 // non-const method results in undefined behavior.
QUICHE teamd7a507e2022-04-15 14:35:46 -070049 void GetWritablePtr(char** ptr, int* size) const {
50 *ptr = storage_ + write_idx_;
51 *size = storage_size_ - write_idx_;
52 }
53
bnc53020a52022-05-16 12:35:34 -070054 // Stores the pointer that can be read from in `*ptr`, and the number of bytes
55 // that are allowed to be read in `*size`. The pointer and size can be used
QUICHE teamd7a507e2022-04-15 14:35:46 -070056 // in functions like send() or write(). If `*size` is zero upon returning
57 // from this function, then it is unsafe to dereference `*ptr`. Reading from
58 // this region after calling any other non-const method results in undefined
59 // behavior.
60 void GetReadablePtr(char** ptr, int* size) const {
61 *ptr = storage_ + read_idx_;
62 *size = write_idx_ - read_idx_;
63 }
64
65 // Returns the readable region as a string_view. Reading from this region
66 // after calling any other non-const method results in undefined behavior.
67 absl::string_view GetReadableRegion() const {
68 return absl::string_view(storage_ + read_idx_, write_idx_ - read_idx_);
69 }
70
71 // Reads bytes out of the buffer, and writes them into `bytes`. Returns the
72 // number of bytes read. Consumes bytes from the buffer.
73 int Read(char* bytes, int size);
74
75 // Marks all data consumed, making the entire reserved buffer available for
76 // write. Does not resize or free up any memory.
77 void Clear() { read_idx_ = write_idx_ = 0; }
78
79 // Makes sure at least `size` bytes can be written into the buffer. This can
80 // be an expensive operation: costing a new and a delete, and copying of all
81 // existing data. Even if the existing buffer does not need to be resized,
82 // unread data may need to be moved to consolidate fragmented free space.
83 void Reserve(int size);
84
85 // Marks the oldest `amount_to_advance` bytes as consumed.
86 // `amount_to_advance` must not be negative and it must not exceed
87 // ReadableBytes().
88 void AdvanceReadablePtr(int amount_to_advance);
89
90 // Marks the first `amount_to_advance` bytes of the writable area written.
91 // `amount_to_advance` must not be negative and it must not exceed the size of
92 // the writable area, returned as the `size` outparam of GetWritablePtr().
93 void AdvanceWritablePtr(int amount_to_advance);
94
95 // Releases the current contents of the SimpleBuffer and returns them as a
96 // MemSlice. Logically, has the same effect as calling Clear().
97 QuicheMemSlice ReleaseAsSlice();
98
99 private:
100 friend class test::SimpleBufferTest;
101
102 // The buffer owned by this class starts at `*storage_` and is `storage_size_`
103 // bytes long.
bnc53020a52022-05-16 12:35:34 -0700104 // If `storage_` is nullptr, then `storage_size_` must be zero.
QUICHE teamd7a507e2022-04-15 14:35:46 -0700105 // `0 <= read_idx_ <= write_idx_ <= storage_size_` must always hold.
106 // If `read_idx_ == write_idx_`, then they must be equal to zero.
107 // The first `read_idx_` bytes of the buffer are consumed,
108 // the next `write_idx_ - read_idx_` bytes are the readable region, and the
109 // remaining `storage_size_ - write_idx_` bytes are the writable region.
bnc53020a52022-05-16 12:35:34 -0700110 char* storage_ = nullptr;
111 int write_idx_ = 0;
112 int read_idx_ = 0;
113 int storage_size_ = 0;
QUICHE teamd7a507e2022-04-15 14:35:46 -0700114};
115
116} // namespace quiche
117
bnc30bbde72022-05-12 06:41:23 -0700118#endif // QUICHE_BALSA_SIMPLE_BUFFER_H_