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), 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) write_idx_(0) {} 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RingBuffer::~RingBuffer() {} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int RingBuffer::ReadableBytes() const { return bytes_used_; } 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int RingBuffer::BufferSize() const { return buffer_size_; } 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int RingBuffer::BytesFree() const { return BufferSize() - ReadableBytes(); } 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool RingBuffer::Empty() const { return ReadableBytes() == 0; } 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool RingBuffer::Full() const { return ReadableBytes() == BufferSize(); } 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of characters written. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Appends up-to-'size' bytes to the ringbuffer. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::Write(const char* bytes, int size) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(size, 0); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 1 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* wptr; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int wsize; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWritablePtr(&wptr, &wsize); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_remaining = size; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (wsize && bytes_remaining) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (wsize > bytes_remaining) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wsize = bytes_remaining; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(wptr, bytes + bytes_written, wsize); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_written += wsize; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_remaining -= wsize; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceWritablePtr(wsize); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWritablePtr(&wptr, &wsize); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_written; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* p = bytes; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_to_write = size; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_available = BytesFree(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_available < bytes_to_write) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_to_write = bytes_available; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end = bytes + bytes_to_write; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (p != end) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->buffer_[this->write_idx_] = *p; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++p; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++this->write_idx_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this->write_idx_ >= this->buffer_size_) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->write_idx_ = 0; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_used_ += bytes_to_write; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_to_write; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets *ptr to the beginning of writable memory, and sets *size to the size 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// available for writing using this pointer. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::GetWritablePtr(char** ptr, int* size) const { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ptr = buffer_.get() + write_idx_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_used_ == buffer_size_) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = 0; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (read_idx_ > write_idx_) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = read_idx_ - write_idx_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = buffer_size_ - write_idx_; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sets *ptr to the beginning of readable memory, and sets *size to the size 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// available for reading using this pointer. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::GetReadablePtr(char** ptr, int* size) const { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ptr = buffer_.get() + read_idx_; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_used_ == 0) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = 0; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (write_idx_ > read_idx_) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = write_idx_ - read_idx_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size = buffer_size_ - read_idx_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// returns the number of bytes read into 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RingBuffer::Read(char* bytes, int size) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(size, 0); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 1 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* rptr; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rsize; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetReadablePtr(&rptr, &rsize); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_remaining = size; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (rsize && bytes_remaining) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rsize > bytes_remaining) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rsize = bytes_remaining; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(bytes + bytes_read, rptr, rsize); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_read += rsize; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_remaining -= rsize; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceReadablePtr(rsize); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetReadablePtr(&rptr, &rsize); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_read; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* p = bytes; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_to_read = size; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_used = ReadableBytes(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_used < bytes_to_read) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_to_read = bytes_used; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* end = bytes + bytes_to_read; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (p != end) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *p = this->buffer_[this->read_idx_]; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++p; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++this->read_idx_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (this->read_idx_ >= this->buffer_size_) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->read_idx_ = 0; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this->bytes_used_ -= bytes_to_read; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bytes_to_read; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::Clear() { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_used_ = 0; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_idx_ = 0; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_idx_ = 0; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RingBuffer::Reserve(int size) { 152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_GT(size, 0); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* write_ptr = NULL; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_size = 0; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWritablePtr(&write_ptr, &write_size); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (write_size < size) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* read_ptr = NULL; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read_size = 0; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetReadablePtr(&read_ptr, &read_size); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size <= BytesFree()) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The fact that the total Free size is big enough but writable size is 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not means that the writeable region is broken into two pieces: only 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // possible if the read_idx < write_idx. If write_idx < read_idx, then 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the writeable region must be contiguous: [write_idx, read_idx). There 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is no work to be done for the latter. 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_LE(read_idx_, write_idx_); 168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(read_size, ReadableBytes()); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_idx_ < write_idx_) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writeable area fragmented, consolidate it. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memmove(buffer_.get(), read_ptr, read_size); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_idx_ = 0; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_idx_ = read_size; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (read_idx_ == write_idx_) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No unconsumed data in the buffer, simply reset the indexes. 176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK_EQ(ReadableBytes(), 0); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_idx_ = 0; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_idx_ = 0; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Resize(ReadableBytes() + size); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(size, buffer_size_ - write_idx_); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::AdvanceReadablePtr(int amount_to_consume) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(amount_to_consume, 0); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (amount_to_consume >= bytes_used_) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Clear(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_idx_ += amount_to_consume; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_idx_ %= buffer_size_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_used_ -= amount_to_consume; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::AdvanceWritablePtr(int amount_to_produce) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(amount_to_produce, 0); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_LE(amount_to_produce, BytesFree()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_idx_ += amount_to_produce; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_idx_ %= buffer_size_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_used_ += amount_to_produce; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RingBuffer::Resize(int buffer_size) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(buffer_size, 0); 209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (buffer_size == buffer_size_) 210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* new_buffer = new char[buffer_size]; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buffer_size < bytes_used_) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // consume the oldest data. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceReadablePtr(bytes_used_ - buffer_size); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_written = 0; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_used = bytes_used_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* ptr; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetReadablePtr(&ptr, &size); 224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (size == 0) 225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) break; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size > buffer_size) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = buffer_size; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(new_buffer + bytes_written, ptr, size); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_written += size; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AdvanceReadablePtr(size); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(new_buffer); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_size_ = buffer_size; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_used_ = bytes_used; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_idx_ = 0; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_idx_ = bytes_used_ % buffer_size_; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 242