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