Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_stream_send_buffer.h b/quic/core/quic_stream_send_buffer.h
new file mode 100644
index 0000000..4bcac34
--- /dev/null
+++ b/quic/core/quic_stream_send_buffer.h
@@ -0,0 +1,165 @@
+// Copyright (c) 2017 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_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
+#define QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_
+
+#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
+#include "net/third_party/quiche/src/quic/core/quic_interval_set.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_iovec.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_mem_slice.h"
+
+namespace quic {
+
+namespace test {
+class QuicStreamSendBufferPeer;
+class QuicStreamPeer;
+}  // namespace test
+
+class QuicDataWriter;
+
+// BufferedSlice comprises information of a piece of stream data stored in
+// contiguous memory space. Please note, BufferedSlice is constructed when
+// stream data is saved in send buffer and is removed when stream data is fully
+// acked. It is move-only.
+struct BufferedSlice {
+  BufferedSlice(QuicMemSlice mem_slice, QuicStreamOffset offset);
+  BufferedSlice(BufferedSlice&& other);
+  BufferedSlice& operator=(BufferedSlice&& other);
+
+  BufferedSlice(const BufferedSlice& other) = delete;
+  BufferedSlice& operator=(const BufferedSlice& other) = delete;
+  ~BufferedSlice();
+
+  // Stream data of this data slice.
+  QuicMemSlice slice;
+  // Location of this data slice in the stream.
+  QuicStreamOffset offset;
+};
+
+struct StreamPendingRetransmission {
+  StreamPendingRetransmission(QuicStreamOffset offset, QuicByteCount length)
+      : offset(offset), length(length) {}
+
+  // Starting offset of this pending retransmission.
+  QuicStreamOffset offset;
+  // Length of this pending retransmission.
+  QuicByteCount length;
+
+  QUIC_EXPORT_PRIVATE bool operator==(
+      const StreamPendingRetransmission& other) const;
+};
+
+// QuicStreamSendBuffer contains a list of QuicStreamDataSlices. New data slices
+// are added to the tail of the list. Data slices are removed from the head of
+// the list when they get fully acked. Stream data can be retrieved and acked
+// across slice boundaries.
+class QUIC_EXPORT_PRIVATE QuicStreamSendBuffer {
+ public:
+  explicit QuicStreamSendBuffer(QuicBufferAllocator* allocator);
+  QuicStreamSendBuffer(const QuicStreamSendBuffer& other) = delete;
+  QuicStreamSendBuffer(QuicStreamSendBuffer&& other) = delete;
+  ~QuicStreamSendBuffer();
+
+  // Save |data_length| of data starts at |iov_offset| in |iov| to send buffer.
+  void SaveStreamData(const struct iovec* iov,
+                      int iov_count,
+                      size_t iov_offset,
+                      QuicByteCount data_length);
+
+  // Save |slice| to send buffer.
+  void SaveMemSlice(QuicMemSlice slice);
+
+  // Called when |bytes_consumed| bytes has been consumed by the stream.
+  void OnStreamDataConsumed(size_t bytes_consumed);
+
+  // Write |data_length| of data starts at |offset|.
+  bool WriteStreamData(QuicStreamOffset offset,
+                       QuicByteCount data_length,
+                       QuicDataWriter* writer);
+
+  // Called when data [offset, offset + data_length) is acked or removed as
+  // stream is canceled. Removes fully acked data slice from send buffer. Set
+  // |newly_acked_length|. Returns false if trying to ack unsent data.
+  bool OnStreamDataAcked(QuicStreamOffset offset,
+                         QuicByteCount data_length,
+                         QuicByteCount* newly_acked_length);
+
+  // Called when data [offset, offset + data_length) is considered as lost.
+  void OnStreamDataLost(QuicStreamOffset offset, QuicByteCount data_length);
+
+  // Called when data [offset, offset + length) was retransmitted.
+  void OnStreamDataRetransmitted(QuicStreamOffset offset,
+                                 QuicByteCount data_length);
+
+  // Returns true if there is pending retransmissions.
+  bool HasPendingRetransmission() const;
+
+  // Returns next pending retransmissions.
+  StreamPendingRetransmission NextPendingRetransmission() const;
+
+  // Returns true if data [offset, offset + data_length) is outstanding and
+  // waiting to be acked. Returns false otherwise.
+  bool IsStreamDataOutstanding(QuicStreamOffset offset,
+                               QuicByteCount data_length) const;
+
+  // Number of data slices in send buffer.
+  size_t size() const;
+
+  QuicStreamOffset stream_offset() const { return stream_offset_; }
+
+  uint64_t stream_bytes_written() const { return stream_bytes_written_; }
+
+  uint64_t stream_bytes_outstanding() const {
+    return stream_bytes_outstanding_;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& bytes_acked() const {
+    return bytes_acked_;
+  }
+
+  const QuicIntervalSet<QuicStreamOffset>& pending_retransmissions() const {
+    return pending_retransmissions_;
+  }
+
+ private:
+  friend class test::QuicStreamSendBufferPeer;
+  friend class test::QuicStreamPeer;
+
+  // Called when data within offset [start, end) gets acked. Frees fully
+  // acked buffered slices if any. Returns false if the corresponding data does
+  // not exist or has been acked.
+  bool FreeMemSlices(QuicStreamOffset start, QuicStreamOffset end);
+
+  // Cleanup empty slices in order from buffered_slices_.
+  void CleanUpBufferedSlices();
+
+  QuicDeque<BufferedSlice> buffered_slices_;
+
+  // Offset of next inserted byte.
+  QuicStreamOffset stream_offset_;
+
+  QuicBufferAllocator* allocator_;
+
+  // Bytes that have been consumed by the stream.
+  uint64_t stream_bytes_written_;
+
+  // Bytes that have been consumed and are waiting to be acked.
+  uint64_t stream_bytes_outstanding_;
+
+  // Offsets of data that has been acked.
+  QuicIntervalSet<QuicStreamOffset> bytes_acked_;
+
+  // Data considered as lost and needs to be retransmitted.
+  QuicIntervalSet<QuicStreamOffset> pending_retransmissions_;
+
+  // Index of slice which contains data waiting to be written for the first
+  // time. -1 if send buffer is empty or all data has been written.
+  int32_t write_index_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_STREAM_SEND_BUFFER_H_