15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 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)#ifndef NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/tools/balsa/buffer_interface.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The ring buffer is a circular buffer, that is, reads or writes may wrap 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// around the end of the linear memory contained by the class (and back to 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the beginning). This is a good choice when you want to use a fixed amount 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of buffering and don't want to be moving memory around a lot. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What is the penalty for using this over a normal, linear buffer? 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reading all the data may take two operations, and 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writing all the data may take two operations. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In the proxy, this class is used as a fixed size buffer between 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// clients and servers (so that the memory size is constrained). 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RingBuffer : public BufferInterface { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit RingBuffer(int buffer_size); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~RingBuffer(); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Resize the buffer to the size specified here. If the buffer_size passed 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in here is smaller than the amount of data in the buffer, then the oldest 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data will be dropped, but all other data will be saved. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This means: If the buffer size is increasing, all data that was resident 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the buffer prior to this call will be resident after this call. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Resize(int buffer_size); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The following functions all override pure virtual functions 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in BufferInterface. See buffer_interface.h for a description 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of what they do if the function isn't documented here. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int ReadableBytes() const OVERRIDE; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int BufferSize() const OVERRIDE; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int BytesFree() const OVERRIDE; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Empty() const OVERRIDE; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Full() const OVERRIDE; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns the number of characters written. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // appends up-to-'size' bytes to the ringbuffer. 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) virtual int Write(const char* bytes, int size) OVERRIDE; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stores a pointer into the ring buffer in *ptr, and stores the number of 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // characters which are allowed to be written in *size. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no writable bytes available, then *size will contain 0. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetWritablePtr(char** ptr, int* size) const OVERRIDE; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stores a pointer into the ring buffer in *ptr, and stores the number of 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // characters which are allowed to be read in *size. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If there are no readable bytes available, then *size will contain 0. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetReadablePtr(char** ptr, int* size) const OVERRIDE; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of bytes read into 'bytes'. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Read(char* bytes, int size) OVERRIDE; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes all data from the ring buffer. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Clear() OVERRIDE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reserves contiguous writable empty space in the buffer of size bytes. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the point of this class is to have a fixed size buffer, be careful 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // not to inadvertently resize the buffer using Reserve(). If the reserve 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size is <= BytesFree(), it is guaranteed that the buffer size will not 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can be an expensive operation, it may new a buffer copy all existing 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // data and delete the old data. Even if the existing buffer does not need 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be resized, unread data may still need to be non-destructively copied 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to consolidate fragmented free space. If the size requested is less than 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or equal to BytesFree(), it is guaranteed that the buffer size will not 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // change. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Reserve(int size) OVERRIDE; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes the oldest 'amount_to_advance' characters. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If amount_to_consume > ReadableBytes(), this performs a Clear() instead. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AdvanceReadablePtr(int amount_to_advance) OVERRIDE; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Moves the internal pointers around such that the amount of data specified 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here is expected to already be resident (as if it was Written). 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void AdvanceWritablePtr(int amount_to_advance) OVERRIDE; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read_idx() const { return read_idx_; } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_idx() const { return write_idx_; } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_used() const { return bytes_used_; } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size() const { return buffer_size_; } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* buffer() const { return buffer_.get(); } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int set_read_idx(int idx) { return read_idx_ = idx; } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int set_write_idx(int idx) { return write_idx_ = idx; } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> buffer_; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_used_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int read_idx_; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_idx_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RingBuffer(const RingBuffer&); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator=(const RingBuffer&); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__ 113