// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__
#define NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__
#pragma once

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "net/tools/flip_server/buffer_interface.h"

namespace net {

// The ring buffer is a circular buffer, that is, reads or writes may wrap
// around the end of the linear memory contained by the class (and back to
// the beginning). This is a good choice when you want to use a fixed amount
// of buffering and don't want to be moving memory around a lot.
//
// What is the penalty for using this over a normal, linear buffer?
// Reading all the data may take two operations, and
// writing all the data may take two operations.
//
// In the proxy, this class is used as a fixed size buffer between
// clients and servers (so that the memory size is constrained).

class RingBuffer : public BufferInterface {
 public:
  explicit RingBuffer(int buffer_size);
  virtual ~RingBuffer();

  // Resize the buffer to the size specified here.  If the buffer_size passed
  // in here is smaller than the amount of data in the buffer, then the oldest
  // data will be dropped, but all other data will be saved.
  // This means: If the buffer size is increasing, all data  that was resident
  // in the buffer prior to this call will be resident after this call.
  void Resize(int buffer_size);

  // The following functions all override pure virtual functions
  // in BufferInterface. See buffer_interface.h for a description
  // of what they do if the function isn't documented here.
  virtual int ReadableBytes() const OVERRIDE;
  virtual int BufferSize() const OVERRIDE;
  virtual int BytesFree() const OVERRIDE;

  virtual bool Empty() const OVERRIDE;
  virtual bool Full() const OVERRIDE;

  // returns the number of characters written.
  // appends up-to-'size' bytes to the ringbuffer.
  virtual int Write(const char * bytes, int size) OVERRIDE;

  // Stores a pointer into the ring buffer in *ptr,  and stores the number of
  // characters which are allowed to be written in *size.
  // If there are no writable bytes available, then *size will contain 0.
  virtual void GetWritablePtr(char** ptr, int* size) const OVERRIDE;

  // Stores a pointer into the ring buffer in *ptr,  and stores the number of
  // characters which are allowed to be read in *size.
  // If there are no readable bytes available, then *size will contain 0.
  virtual void GetReadablePtr(char** ptr, int* size) const OVERRIDE;

  // Returns the number of bytes read into 'bytes'.
  virtual int Read(char* bytes, int size) OVERRIDE;

  // Removes all data from the ring buffer.
  virtual void Clear() OVERRIDE;

  // Reserves contiguous writable empty space in the buffer of size bytes.
  // Since the point of this class is to have a fixed size buffer, be careful
  // not to inadvertently resize the buffer using Reserve(). If the reserve
  // size is <= BytesFree(), it is guaranteed that the buffer size will not
  // change.
  // This can be an expensive operation, it may new a buffer copy all existing
  // data and delete the old data. Even if the existing buffer does not need
  // to be resized, unread data may still need to be non-destructively copied
  // to consolidate fragmented free space. If the size requested is less than
  // or equal to BytesFree(), it is guaranteed that the buffer size will not
  // change.
  virtual bool Reserve(int size) OVERRIDE;

  // Removes the oldest 'amount_to_advance' characters.
  // If amount_to_consume > ReadableBytes(), this performs a Clear() instead.
  virtual void AdvanceReadablePtr(int amount_to_advance) OVERRIDE;

  // Moves the internal pointers around such that the  amount of data specified
  // here is expected to already be resident (as if it was Written).
  virtual void AdvanceWritablePtr(int amount_to_advance) OVERRIDE;

 protected:
  int read_idx() const { return read_idx_; }
  int write_idx() const { return write_idx_; }
  int bytes_used() const { return bytes_used_; }
  int buffer_size() const { return buffer_size_; }
  const char* buffer() const { return buffer_.get(); }

  int set_read_idx(int idx) { return read_idx_ = idx; }
  int set_write_idx(int idx) { return write_idx_ = idx; }

 private:
  scoped_array<char> buffer_;
  int buffer_size_;
  int bytes_used_;
  int read_idx_;
  int write_idx_;

  RingBuffer(const RingBuffer&);
  void operator=(const RingBuffer&);
};

}  // namespace net

#endif  // NET_TOOLS_FLIP_SERVER_RING_BUFFER_H__

