Internal change

PiperOrigin-RevId: 442098384
diff --git a/quiche/common/balsa/simple_buffer.h b/quiche/common/balsa/simple_buffer.h
new file mode 100644
index 0000000..52f3400
--- /dev/null
+++ b/quiche/common/balsa/simple_buffer.h
@@ -0,0 +1,116 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_COMMON_BALSA_SIMPLE_BUFFER_H_
+#define QUICHE_COMMON_BALSA_SIMPLE_BUFFER_H_
+
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/platform/api/quiche_mem_slice.h"
+
+namespace quiche {
+
+namespace test {
+class SimpleBufferTest;
+}  // namespace test
+
+// SimpleBuffer stores data in a contiguous region.  It can grow on demand,
+// which involves moving its data.  It keeps track of a read and a write
+// position.  Reading consumes data.
+class QUICHE_EXPORT_PRIVATE SimpleBuffer {
+ public:
+  SimpleBuffer();
+  // Create SimpleBuffer with `size` reserved capacity.
+  explicit SimpleBuffer(int size);
+
+  SimpleBuffer(const SimpleBuffer&) = delete;
+  SimpleBuffer& operator=(const SimpleBuffer&) = delete;
+
+  virtual ~SimpleBuffer() { delete[] storage_; }
+
+  // Returns the number of bytes that can be read from the buffer.
+  int ReadableBytes() const { return write_idx_ - read_idx_; }
+
+  bool Empty() const { return read_idx_ == write_idx_; }
+
+  // Copies `size` bytes to the buffer. Returns size.
+  int Write(const char* bytes, int size);
+  int WriteString(absl::string_view piece) {
+    return Write(piece.data(), piece.size());
+  }
+
+  // Gets a pointer into the buffer that can be written to.  Stores the number
+  // of characters which are allowed to be written in `*size`. The pointer and
+  // size can be used in functions like recv() or read().  If `*size` is zero
+  // upon returning from this function, then it is unsafe to dereference `*ptr`.
+  // Writing to this region after calling any other non-const method results in
+  // undefined behavior.
+  void GetWritablePtr(char** ptr, int* size) const {
+    *ptr = storage_ + write_idx_;
+    *size = storage_size_ - write_idx_;
+  }
+
+  // Gets a pointer that can be read from.  This pointer (and size) can be used
+  // in functions like send() or write().  If `*size` is zero upon returning
+  // from this function, then it is unsafe to dereference `*ptr`.  Reading from
+  // this region after calling any other non-const method results in undefined
+  // behavior.
+  void GetReadablePtr(char** ptr, int* size) const {
+    *ptr = storage_ + read_idx_;
+    *size = write_idx_ - read_idx_;
+  }
+
+  // Returns the readable region as a string_view.  Reading from this region
+  // after calling any other non-const method results in undefined behavior.
+  absl::string_view GetReadableRegion() const {
+    return absl::string_view(storage_ + read_idx_, write_idx_ - read_idx_);
+  }
+
+  // Reads bytes out of the buffer, and writes them into `bytes`.  Returns the
+  // number of bytes read.  Consumes bytes from the buffer.
+  int Read(char* bytes, int size);
+
+  // Marks all data consumed, making the entire reserved buffer available for
+  // write.  Does not resize or free up any memory.
+  void Clear() { read_idx_ = write_idx_ = 0; }
+
+  // Makes sure at least `size` bytes can be written into the buffer.  This can
+  // be an expensive operation: costing a new and a delete, and copying of all
+  // existing data. Even if the existing buffer does not need to be resized,
+  // unread data may need to be moved to consolidate fragmented free space.
+  void Reserve(int size);
+
+  // Marks the oldest `amount_to_advance` bytes as consumed.
+  // `amount_to_advance` must not be negative and it must not exceed
+  // ReadableBytes().
+  void AdvanceReadablePtr(int amount_to_advance);
+
+  // Marks the first `amount_to_advance` bytes of the writable area written.
+  // `amount_to_advance` must not be negative and it must not exceed the size of
+  // the writable area, returned as the `size` outparam of GetWritablePtr().
+  void AdvanceWritablePtr(int amount_to_advance);
+
+  // Releases the current contents of the SimpleBuffer and returns them as a
+  // MemSlice. Logically, has the same effect as calling Clear().
+  QuicheMemSlice ReleaseAsSlice();
+
+ private:
+  friend class test::SimpleBufferTest;
+
+  // The buffer owned by this class starts at `*storage_` and is `storage_size_`
+  // bytes long.
+  // `0 <= read_idx_ <= write_idx_ <= storage_size_` must always hold.
+  // If `read_idx_ == write_idx_`, then they must be equal to zero.
+  // The first `read_idx_` bytes of the buffer are consumed,
+  // the next `write_idx_ - read_idx_` bytes are the readable region, and the
+  // remaining `storage_size_ - write_idx_` bytes are the writable region.
+  char* storage_;
+  int write_idx_;
+  int read_idx_;
+  int storage_size_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_COMMON_BALSA_SIMPLE_BUFFER_H_