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

#ifndef BASE_CIRCULAR_BUFFER_SHELL_H_
#define BASE_CIRCULAR_BUFFER_SHELL_H_

#include "base/base_export.h"
#include "base/synchronization/lock.h"

namespace base {

// A thread-safe circular buffer implementation.
// TODO: Returns the size in Read(), Peek(), and Skip() as a return
// value.
class BASE_EXPORT CircularBufferShell {
 public:
  enum ReserveType { kDoNotReserve, kReserve };

  explicit CircularBufferShell(size_t max_capacity,
                               ReserveType reserve_type = kDoNotReserve);
  ~CircularBufferShell();

  // Clears out all data in the buffer, releasing any allocated memory.
  // Idempotent.
  void Clear();

  // Reads the requested amount of data into the given buffer, writing the
  // number of bytes actually read into the bytes_read paramter. If there is
  // less data then requested, then the remaining data will be consumed.
  void Read(void* destination, size_t length, size_t* bytes_read);

  // It works the same as Read() except:
  // 1. It doesn't modify the buffer in any way.
  // 2. It allows the caller to specify an offset inside the buffer where the
  // peek starts.
  void Peek(void* destination, size_t length, size_t source_offset,
            size_t* bytes_peeked) const;

  // Advance the buffer cursor without reading any data.
  void Skip(size_t length, size_t* bytes_skipped);

  // Writes the given data into the circular buffer. Returns false if the buffer
  // could not be expanded to hold the new data. If returning false,
  // bytes_written will not be set, and the buffer will remain unchanged.
  // TODO: Remove bytes_written.  Because Write returns false when
  // the buffer cannot hold all data, bytes_written isn't useful here unless we
  // allow partial write.
  bool Write(const void* source, size_t length, size_t* bytes_written);

  // Returns the length of the data left in the buffer to read.
  size_t GetLength() const;

  // Returns the maximum capacity this circular buffer can grow to.
  size_t GetMaxCapacity() const;

  // Increase the max capacity to |new_max_capacity| which has to be greater
  // than the previous one.  The content of the class will be kept.
  void IncreaseMaxCapacityTo(size_t new_max_capacity);

 private:
  // Ensures that there is enough capacity to write length bytes to the
  // buffer. Returns false if it was unable to ensure that capacity due to an
  // allocation error, or if it would surpass the configured maximum capacity.
  bool EnsureCapacityToWrite_Locked(size_t length);

  // Increases the capacity to the given absolute size in bytes. Returns false
  // if there was an allocation error, or it would surpass the configured
  // maximum capacity.
  bool IncreaseCapacityTo_Locked(size_t capacity);

  // Private workhorse for Read without the parameter validation or locking.
  // When |destination| is NULL, it purely calculates the the bytes that would
  // have been read.
  // Note that the function doesn't advance the read cursor or modify the
  // length.  It is caller's responsibility to adjust |read_position_| and
  // |length_| according to the return value, which is the actual number of
  // bytes read.
  void ReadUnchecked_Locked(void* destination, size_t destination_length,
                            size_t source_offset, size_t* bytes_read) const;

  // The same the as above functions except that it also advance the
  // |read_position_| and adjust the |length_| accordingly.
  void ReadAndAdvanceUnchecked_Locked(void* destination,
                                      size_t destination_length,
                                      size_t* bytes_read);

  // Gets a pointer to the current write position.
  void* GetWritePointer_Locked() const;

  // Gets the current write position.
  size_t GetWritePosition_Locked() const;

  size_t max_capacity_;
  void* buffer_;
  size_t capacity_;
  size_t length_;
  size_t read_position_;
  mutable base::Lock lock_;
};

}  // namespace base

#endif  // BASE_CIRCULAR_BUFFER_SHELL_H_
