Home | History | Annotate | Download | only in flip_server
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__
      6 #define NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__
      7 
      8 #include "base/compiler_specific.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "net/tools/flip_server/buffer_interface.h"
     11 
     12 namespace net {
     13 
     14 // The ring buffer is a circular buffer, that is, reads or writes may wrap
     15 // around the end of the linear memory contained by the class (and back to
     16 // the beginning). This is a good choice when you want to use a fixed amount
     17 // of buffering and don't want to be moving memory around a lot.
     18 //
     19 // What is the penalty for using this over a normal, linear buffer?
     20 // Reading all the data may take two operations, and
     21 // writing all the data may take two operations.
     22 //
     23 // In the proxy, this class is used as a fixed size buffer between
     24 // clients and servers (so that the memory size is constrained).
     25 
     26 class RingBuffer : public BufferInterface {
     27  public:
     28   explicit RingBuffer(int buffer_size);
     29   virtual ~RingBuffer();
     30 
     31   // Resize the buffer to the size specified here.  If the buffer_size passed
     32   // in here is smaller than the amount of data in the buffer, then the oldest
     33   // data will be dropped, but all other data will be saved.
     34   // This means: If the buffer size is increasing, all data  that was resident
     35   // in the buffer prior to this call will be resident after this call.
     36   void Resize(int buffer_size);
     37 
     38   // The following functions all override pure virtual functions
     39   // in BufferInterface. See buffer_interface.h for a description
     40   // of what they do if the function isn't documented here.
     41   virtual int ReadableBytes() const OVERRIDE;
     42   virtual int BufferSize() const OVERRIDE;
     43   virtual int BytesFree() const OVERRIDE;
     44 
     45   virtual bool Empty() const OVERRIDE;
     46   virtual bool Full() const OVERRIDE;
     47 
     48   // returns the number of characters written.
     49   // appends up-to-'size' bytes to the ringbuffer.
     50   virtual int Write(const char * bytes, int size) OVERRIDE;
     51 
     52   // Stores a pointer into the ring buffer in *ptr,  and stores the number of
     53   // characters which are allowed to be written in *size.
     54   // If there are no writable bytes available, then *size will contain 0.
     55   virtual void GetWritablePtr(char** ptr, int* size) const OVERRIDE;
     56 
     57   // Stores a pointer into the ring buffer in *ptr,  and stores the number of
     58   // characters which are allowed to be read in *size.
     59   // If there are no readable bytes available, then *size will contain 0.
     60   virtual void GetReadablePtr(char** ptr, int* size) const OVERRIDE;
     61 
     62   // Returns the number of bytes read into 'bytes'.
     63   virtual int Read(char* bytes, int size) OVERRIDE;
     64 
     65   // Removes all data from the ring buffer.
     66   virtual void Clear() OVERRIDE;
     67 
     68   // Reserves contiguous writable empty space in the buffer of size bytes.
     69   // Since the point of this class is to have a fixed size buffer, be careful
     70   // not to inadvertently resize the buffer using Reserve(). If the reserve
     71   // size is <= BytesFree(), it is guaranteed that the buffer size will not
     72   // change.
     73   // This can be an expensive operation, it may new a buffer copy all existing
     74   // data and delete the old data. Even if the existing buffer does not need
     75   // to be resized, unread data may still need to be non-destructively copied
     76   // to consolidate fragmented free space. If the size requested is less than
     77   // or equal to BytesFree(), it is guaranteed that the buffer size will not
     78   // change.
     79   virtual bool Reserve(int size) OVERRIDE;
     80 
     81   // Removes the oldest 'amount_to_advance' characters.
     82   // If amount_to_consume > ReadableBytes(), this performs a Clear() instead.
     83   virtual void AdvanceReadablePtr(int amount_to_advance) OVERRIDE;
     84 
     85   // Moves the internal pointers around such that the  amount of data specified
     86   // here is expected to already be resident (as if it was Written).
     87   virtual void AdvanceWritablePtr(int amount_to_advance) OVERRIDE;
     88 
     89  protected:
     90   int read_idx() const { return read_idx_; }
     91   int write_idx() const { return write_idx_; }
     92   int bytes_used() const { return bytes_used_; }
     93   int buffer_size() const { return buffer_size_; }
     94   const char* buffer() const { return buffer_.get(); }
     95 
     96   int set_read_idx(int idx) { return read_idx_ = idx; }
     97   int set_write_idx(int idx) { return write_idx_ = idx; }
     98 
     99  private:
    100   scoped_ptr<char[]> buffer_;
    101   int buffer_size_;
    102   int bytes_used_;
    103   int read_idx_;
    104   int write_idx_;
    105 
    106   RingBuffer(const RingBuffer&);
    107   void operator=(const RingBuffer&);
    108 };
    109 
    110 }  // namespace net
    111 
    112 #endif  // NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__
    113 
    114