ring_buffer.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2009 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/tools/flip_server/ring_buffer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RingBuffer::RingBuffer(int buffer_size)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : buffer_(new char[buffer_size]),
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_size_(buffer_size),
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bytes_used_(0),
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      read_idx_(0),
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      write_idx_(0) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RingBuffer::~RingBuffer() {}
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::ReadableBytes() const {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_used_;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::BufferSize() const {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return buffer_size_;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::BytesFree() const {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BufferSize() - ReadableBytes();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RingBuffer::Empty() const {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ReadableBytes() == 0;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RingBuffer::Full() const {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ReadableBytes() == BufferSize();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of characters written.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends up-to-'size' bytes to the ringbuffer.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::Write(const char* bytes, int size) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(size, 0);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 1
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* wptr;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int wsize;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWritablePtr(&wptr, &wsize);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_remaining = size;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_written = 0;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (wsize && bytes_remaining) {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (wsize > bytes_remaining) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wsize = bytes_remaining;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(wptr, bytes + bytes_written, wsize);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_written += wsize;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_remaining -= wsize;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AdvanceWritablePtr(wsize);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetWritablePtr(&wptr, &wsize);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_written;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* p = bytes;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_to_write = size;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_available = BytesFree();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_available < bytes_to_write) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_to_write = bytes_available;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* end = bytes + bytes_to_write;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (p != end) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    this->buffer_[this->write_idx_] = *p;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++p;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++this->write_idx_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (this->write_idx_ >= this->buffer_size_) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this->write_idx_ = 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_used_ += bytes_to_write;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_to_write;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets *ptr to the beginning of writable memory, and sets *size to the size
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// available for writing using this pointer.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::GetWritablePtr(char** ptr, int* size) const {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *ptr = buffer_.get() + write_idx_;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_used_ == buffer_size_) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = 0;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (read_idx_ > write_idx_) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = read_idx_ - write_idx_;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = buffer_size_ - write_idx_;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets *ptr to the beginning of readable memory, and sets *size to the size
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// available for reading using this pointer.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::GetReadablePtr(char** ptr, int* size) const {
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *ptr = buffer_.get() + read_idx_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_used_ == 0) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = 0;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (write_idx_ > read_idx_) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = write_idx_ - read_idx_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *size = buffer_size_ - read_idx_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returns the number of bytes read into
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::Read(char* bytes, int size) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(size, 0);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 1
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* rptr;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rsize;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetReadablePtr(&rptr, &rsize);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_remaining = size;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_read = 0;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (rsize && bytes_remaining) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rsize > bytes_remaining) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rsize = bytes_remaining;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(bytes + bytes_read, rptr, rsize);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_read += rsize;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_remaining -= rsize;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AdvanceReadablePtr(rsize);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetReadablePtr(&rptr, &rsize);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_read;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* p = bytes;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_to_read = size;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_used = ReadableBytes();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bytes_used < bytes_to_read) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_to_read = bytes_used;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* end = bytes + bytes_to_read;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (p != end) {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *p = this->buffer_[this->read_idx_];
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++p;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++this->read_idx_;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (this->read_idx_ >= this->buffer_size_) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this->read_idx_ = 0;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  this->bytes_used_ -= bytes_to_read;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bytes_to_read;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::Clear() {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_used_ = 0;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_idx_ = 0;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_idx_ = 0;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RingBuffer::Reserve(int size) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(size > 0);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* write_ptr = NULL;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int write_size = 0;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetWritablePtr(&write_ptr, &write_size);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_size < size) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* read_ptr = NULL;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int read_size = 0;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetReadablePtr(&read_ptr, &read_size);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (size <= BytesFree()) {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The fact that the total Free size is big enough but writable size is
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // not means that the writeable region is broken into two pieces: only
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // possible if the read_idx < write_idx. If write_idx < read_idx, then
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the writeable region must be contiguous: [write_idx, read_idx). There
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // is no work to be done for the latter.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(read_idx_ <= write_idx_);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK(read_size == ReadableBytes());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_idx_ < write_idx_) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Writeable area fragmented, consolidate it.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        memmove(buffer_.get(), read_ptr, read_size);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        read_idx_ = 0;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        write_idx_ = read_size;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else if (read_idx_ == write_idx_) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // No unconsumed data in the buffer, simply reset the indexes.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DCHECK(ReadableBytes() == 0);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        read_idx_ = 0;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        write_idx_ = 0;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Resize(ReadableBytes() + size);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_LE(size, buffer_size_ - write_idx_);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::AdvanceReadablePtr(int amount_to_consume) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(amount_to_consume, 0);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (amount_to_consume >= bytes_used_) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Clear();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_idx_ += amount_to_consume;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_idx_ %= buffer_size_;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_used_ -= amount_to_consume;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::AdvanceWritablePtr(int amount_to_produce) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(amount_to_produce, 0);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_LE(amount_to_produce, BytesFree());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_idx_ += amount_to_produce;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_idx_ %= buffer_size_;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_used_ += amount_to_produce;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::Resize(int buffer_size) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_GE(buffer_size, 0);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (buffer_size == buffer_size_) return;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* new_buffer = new char[buffer_size];
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (buffer_size < bytes_used_) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // consume the oldest data.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AdvanceReadablePtr(bytes_used_ - buffer_size);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_written = 0;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bytes_used = bytes_used_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int size;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char* ptr;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GetReadablePtr(&ptr, &size);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (size == 0) break;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (size > buffer_size) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size = buffer_size;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(new_buffer + bytes_written, ptr, size);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes_written += size;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AdvanceReadablePtr(size);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_.reset(new_buffer);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_size_ = buffer_size;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bytes_used_ = bytes_used;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  read_idx_ = 0;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  write_idx_ = bytes_used_ % buffer_size_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
280