1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file.
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/tools/flip_server/ring_buffer.h"
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h"
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottRingBuffer::RingBuffer(int buffer_size)
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    : buffer_(new char[buffer_size]),
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      buffer_size_(buffer_size),
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      bytes_used_(0),
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      read_idx_(0),
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      write_idx_(0) {
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenRingBuffer::~RingBuffer() {}
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RingBuffer::ReadableBytes() const {
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return bytes_used_;
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RingBuffer::BufferSize() const {
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return buffer_size_;
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RingBuffer::BytesFree() const {
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return BufferSize() - ReadableBytes();
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RingBuffer::Empty() const {
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return ReadableBytes() == 0;
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool RingBuffer::Full() const {
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return ReadableBytes() == BufferSize();
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns the number of characters written.
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Appends up-to-'size' bytes to the ringbuffer.
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RingBuffer::Write(const char* bytes, int size) {
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK_GE(size, 0);
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if 1
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* wptr;
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int wsize;
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GetWritablePtr(&wptr, &wsize);
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_remaining = size;
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_written = 0;
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (wsize && bytes_remaining) {
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (wsize > bytes_remaining) {
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      wsize = bytes_remaining;
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    memcpy(wptr, bytes + bytes_written, wsize);
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_written += wsize;
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_remaining -= wsize;
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    AdvanceWritablePtr(wsize);
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GetWritablePtr(&wptr, &wsize);
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return bytes_written;
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* p = bytes;
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_to_write = size;
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_available = BytesFree();
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (bytes_available < bytes_to_write) {
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_to_write = bytes_available;
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  const char* end = bytes + bytes_to_write;
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (p != end) {
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    this->buffer_[this->write_idx_] = *p;
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++p;
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++this->write_idx_;
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (this->write_idx_ >= this->buffer_size_) {
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      this->write_idx_ = 0;
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bytes_used_ += bytes_to_write;
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return bytes_to_write;
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Sets *ptr to the beginning of writable memory, and sets *size to the size
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// available for writing using this pointer.
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RingBuffer::GetWritablePtr(char** ptr, int* size) const {
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *ptr = buffer_.get() + write_idx_;
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (bytes_used_ == buffer_size_) {
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *size = 0;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else if (read_idx_ > write_idx_) {
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *size = read_idx_ - write_idx_;
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *size = buffer_size_ - write_idx_;
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Sets *ptr to the beginning of readable memory, and sets *size to the size
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// available for reading using this pointer.
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RingBuffer::GetReadablePtr(char** ptr, int* size) const {
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  *ptr = buffer_.get() + read_idx_;
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (bytes_used_ == 0) {
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *size = 0;
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else if (write_idx_ > read_idx_) {
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *size = write_idx_ - read_idx_;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  } else {
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *size = buffer_size_ - read_idx_;
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// returns the number of bytes read into
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RingBuffer::Read(char* bytes, int size) {
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK_GE(size, 0);
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if 1
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* rptr;
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int rsize;
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GetReadablePtr(&rptr, &rsize);
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_remaining = size;
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_read = 0;
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (rsize && bytes_remaining) {
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (rsize > bytes_remaining) {
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      rsize = bytes_remaining;
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    memcpy(bytes + bytes_read, rptr, rsize);
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_read += rsize;
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_remaining -= rsize;
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    AdvanceReadablePtr(rsize);
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GetReadablePtr(&rptr, &rsize);
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return bytes_read;
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* p = bytes;
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_to_read = size;
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_used = ReadableBytes();
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (bytes_used < bytes_to_read) {
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_to_read = bytes_used;
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* end = bytes + bytes_to_read;
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (p != end) {
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *p = this->buffer_[this->read_idx_];
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++p;
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ++this->read_idx_;
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (this->read_idx_ >= this->buffer_size_) {
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      this->read_idx_ = 0;
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  this->bytes_used_ -= bytes_to_read;
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return bytes_to_read;
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RingBuffer::Clear() {
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bytes_used_ = 0;
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  write_idx_ = 0;
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  read_idx_ = 0;
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool RingBuffer::Reserve(int size) {
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK(size > 0);
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* write_ptr = NULL;
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int write_size = 0;
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  GetWritablePtr(&write_ptr, &write_size);
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (write_size < size) {
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char* read_ptr = NULL;
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int read_size = 0;
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GetReadablePtr(&read_ptr, &read_size);
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (size <= BytesFree()) {
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // The fact that the total Free size is big enough but writable size is
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // not means that the writeable region is broken into two pieces: only
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // possible if the read_idx < write_idx. If write_idx < read_idx, then
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // the writeable region must be contiguous: [write_idx, read_idx). There
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      // is no work to be done for the latter.
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DCHECK(read_idx_ <= write_idx_);
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      DCHECK(read_size == ReadableBytes());
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      if (read_idx_ < write_idx_) {
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // Writeable area fragmented, consolidate it.
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        memmove(buffer_.get(), read_ptr, read_size);
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        read_idx_ = 0;
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        write_idx_ = read_size;
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      } else if (read_idx_ == write_idx_) {
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // No unconsumed data in the buffer, simply reset the indexes.
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        DCHECK(ReadableBytes() == 0);
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        read_idx_ = 0;
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        write_idx_ = 0;
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      }
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    } else {
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      Resize(ReadableBytes() + size);
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  DCHECK_LE(size, buffer_size_ - write_idx_);
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  return true;
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RingBuffer::AdvanceReadablePtr(int amount_to_consume) {
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK_GE(amount_to_consume, 0);
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (amount_to_consume >= bytes_used_) {
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    Clear();
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return;
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  read_idx_ += amount_to_consume;
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  read_idx_ %= buffer_size_;
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bytes_used_ -= amount_to_consume;
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RingBuffer::AdvanceWritablePtr(int amount_to_produce) {
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK_GE(amount_to_produce, 0);
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK_LE(amount_to_produce, BytesFree());
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  write_idx_ += amount_to_produce;
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  write_idx_ %= buffer_size_;
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bytes_used_ += amount_to_produce;
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott////////////////////////////////////////////////////////////////////////////////
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid RingBuffer::Resize(int buffer_size) {
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  CHECK_GE(buffer_size, 0);
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (buffer_size == buffer_size_) return;
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  char* new_buffer = new char[buffer_size];
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (buffer_size < bytes_used_) {
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // consume the oldest data.
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    AdvanceReadablePtr(bytes_used_ - buffer_size);
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_written = 0;
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  int bytes_used = bytes_used_;
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  while (true) {
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int size;
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    char* ptr;
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    GetReadablePtr(&ptr, &size);
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (size == 0) break;
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (size > buffer_size) {
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott      size = buffer_size;
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    memcpy(new_buffer + bytes_written, ptr, size);
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bytes_written += size;
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    AdvanceReadablePtr(size);
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  buffer_.reset(new_buffer);
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  buffer_size_ = buffer_size;
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bytes_used_ = bytes_used;
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  read_idx_ = 0;
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  write_idx_ = bytes_used_ % buffer_size_;
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
280