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