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