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/balsa/buffer_interface.h"
11
12namespace 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
26class 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