// Copyright 2015 The Chromium OS 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 LIBBRILLO_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
#define LIBBRILLO_BRILLO_STREAMS_MEMORY_CONTAINERS_H_

#include <string>
#include <utility>
#include <vector>

#include <brillo/brillo_export.h>
#include <brillo/errors/error.h>
#include <brillo/streams/stream.h>

namespace brillo {
namespace data_container {

// MemoryStream class relies on helper classes defined below to support data
// storage in various types of containers.
// A particular implementation of container type (e.g. based on raw memory
// buffers, std::vector, std::string or others) need to implement the container
// interface provided by data_container::DataContainerInterface.
// Low-level functionality such as reading data from and writing data to the
// container, getting and changing the buffer size, and so on, must be provided.
// Not all methods must be provided. For example, for read-only containers, only
// read operations can be provided.
class BRILLO_EXPORT DataContainerInterface {
 public:
  DataContainerInterface() = default;
  DataContainerInterface(const DataContainerInterface&) = delete;
  DataContainerInterface& operator=(const DataContainerInterface&) = delete;

  virtual ~DataContainerInterface() = default;

  // Read the data from the container into |buffer|. Up to |size_to_read| bytes
  // must be read at a time. The container can return fewer bytes. The actual
  // size of data read is provided in |size_read|.
  // If the read operation fails, the function must return false and provide
  // additional information about the error in |error| object.
  virtual bool Read(void* buffer,
                    size_t size_to_read,
                    size_t offset,
                    size_t* size_read,
                    ErrorPtr* error) = 0;

  // Writes |size_to_write| bytes of data from |buffer| into the container.
  // The container may accept fewer bytes of data. The actual size of data
  // written is provided in |size_written|.
  // If the read operation fails, the function must return false and provide
  // additional information about the error in |error| object.
  virtual bool Write(const void* buffer,
                     size_t size_to_write,
                     size_t offset,
                     size_t* size_written,
                     ErrorPtr* error) = 0;
  // Resizes the container to the new size specified in |new_size|.
  virtual bool Resize(size_t new_size, ErrorPtr* error) = 0;
  // Returns the current size of the container.
  virtual size_t GetSize() const = 0;
  // Returns true if the container is read-only.
  virtual bool IsReadOnly() const = 0;
};

// ContiguousBufferBase is a helper base class for memory containers that
// employ contiguous memory for all of their data. This class provides the
// default implementation for Read() and Write() functions and requires the
// implementations to provide GetBuffer() and/or ReadOnlyBuffer() functions.
class BRILLO_EXPORT ContiguousBufferBase : public DataContainerInterface {
 public:
  ContiguousBufferBase() = default;
  ContiguousBufferBase(const ContiguousBufferBase&) = delete;
  ContiguousBufferBase& operator=(const ContiguousBufferBase&) = delete;

  // Implementation of DataContainerInterface::Read().
  bool Read(void* buffer,
            size_t size_to_read,
            size_t offset,
            size_t* size_read,
            ErrorPtr* error) override;
  // Implementation of DataContainerInterface::Write().
  bool Write(const void* buffer,
             size_t size_to_write,
             size_t offset,
             size_t* size_written,
             ErrorPtr* error) override;

  // Overload to provide the pointer to the read-only data for the container at
  // the specified |offset|. In case of an error, this function must return
  // nullptr and provide error details in |error| object if provided.
  virtual const void* GetReadOnlyBuffer(size_t offset,
                                        ErrorPtr* error) const = 0;
  // Overload to provide the pointer to the read/write data for the container at
  // the specified |offset|. In case of an error, this function must return
  // nullptr and provide error details in |error| object if provided.
  virtual void* GetBuffer(size_t offset, ErrorPtr* error) = 0;

 protected:
  // Wrapper around memcpy which can be mocked out in tests.
  virtual void CopyMemoryBlock(void* dest, const void* src, size_t size) const;
};

// ContiguousReadOnlyBufferBase is a specialization of ContiguousBufferBase for
// read-only containers.
class BRILLO_EXPORT ContiguousReadOnlyBufferBase : public ContiguousBufferBase {
 public:
  ContiguousReadOnlyBufferBase() = default;
  ContiguousReadOnlyBufferBase(const ContiguousReadOnlyBufferBase&) = delete;
  ContiguousReadOnlyBufferBase& operator=(const ContiguousReadOnlyBufferBase&) =
      delete;

  // Fails with an error "operation_not_supported" (Stream is read-only) error.
  bool Write(const void* buffer,
             size_t size_to_write,
             size_t offset,
             size_t* size_written,
             ErrorPtr* error) override;
  // Fails with an error "operation_not_supported" (Stream is read-only) error.
  bool Resize(size_t new_size, ErrorPtr* error) override;
  // Fails with an error "operation_not_supported" (Stream is read-only) error.
  bool IsReadOnly() const override { return true; }
  // Fails with an error "operation_not_supported" (Stream is read-only) error.
  void* GetBuffer(size_t offset, ErrorPtr* error) override;
};

// ReadOnlyBuffer implements a read-only container based on raw memory block.
class BRILLO_EXPORT ReadOnlyBuffer : public ContiguousReadOnlyBufferBase {
 public:
  // Constructs the container based at the pointer to memory |buffer| and its
  // |size|. The pointer to the memory must be valid throughout life-time of
  // the stream using this container.
  ReadOnlyBuffer(const void* buffer, size_t size)
      : buffer_(buffer), size_(size) {}
  ReadOnlyBuffer(const ReadOnlyBuffer&) = delete;
  ReadOnlyBuffer& operator=(const ReadOnlyBuffer&) = delete;

  // Returns the pointer to data at |offset|.
  const void* GetReadOnlyBuffer(size_t offset,
                                ErrorPtr* /* error */) const override {
    return reinterpret_cast<const uint8_t*>(buffer_) + offset;
  }
  // Returns the size of the container.
  size_t GetSize() const override { return size_; }

 private:
  // Raw memory pointer to the data block and its size.
  const void* buffer_;
  size_t size_;
};

// VectorPtr<T> is a read/write container based on a vector<T> pointer.
// This is a template class to allow usage of both vector<char> and
// vector<uint8_t> without duplicating the implementation.
template <typename T>
class VectorPtr : public ContiguousBufferBase {
 public:
  static_assert(sizeof(T) == 1, "Only char/byte is supported");
  explicit VectorPtr(std::vector<T>* vector) : vector_ptr_(vector) {}
  VectorPtr(const VectorPtr&) = delete;
  VectorPtr& operator=(const VectorPtr&) = delete;

  bool Resize(size_t new_size, ErrorPtr* /* error */) override {
    vector_ptr_->resize(new_size);
    return true;
  }
  size_t GetSize() const override { return vector_ptr_->size(); }
  bool IsReadOnly() const override { return false; }
  const void* GetReadOnlyBuffer(size_t offset,
                                ErrorPtr* /* error */) const override {
    return reinterpret_cast<const uint8_t*>(vector_ptr_->data()) + offset;
  }
  void* GetBuffer(size_t offset, ErrorPtr* /* error */) override {
    return reinterpret_cast<uint8_t*>(vector_ptr_->data()) + offset;
  }

 protected:
  std::vector<T>* vector_ptr_;
};

// ReadOnlyVectorRef<T> is a read-only container based on a vector<T> reference.
// This is a template class to allow usage of both vector<char> and
// vector<uint8_t> without duplicating the implementation.
template <typename T>
class ReadOnlyVectorRef : public ContiguousReadOnlyBufferBase {
 public:
  static_assert(sizeof(T) == 1, "Only char/byte is supported");
  explicit ReadOnlyVectorRef(const std::vector<T>& vector)
      : vector_ref_(vector) {}
  ReadOnlyVectorRef(const ReadOnlyVectorRef&) = delete;
  ReadOnlyVectorRef& operator=(const ReadOnlyVectorRef&) = delete;

  const void* GetReadOnlyBuffer(size_t offset,
                                ErrorPtr* /* error */) const override {
    return reinterpret_cast<const uint8_t*>(vector_ref_.data()) + offset;
  }
  size_t GetSize() const override { return vector_ref_.size(); }

 protected:
  const std::vector<T>& vector_ref_;
};

// ReadOnlyVectorCopy<T> is a read-only container based on a copy of vector<T>.
// This container actually owns the data stored in the vector.
// This is a template class to allow usage of both vector<char> and
// vector<uint8_t> without duplicating the implementation.
template <typename T>
class ReadOnlyVectorCopy : public ContiguousReadOnlyBufferBase {
 public:
  static_assert(sizeof(T) == 1, "Only char/byte is supported");
  explicit ReadOnlyVectorCopy(std::vector<T> vector)
      : vector_copy_(std::move(vector)) {}

  ReadOnlyVectorCopy(const T* buffer, size_t size)
      : vector_copy_(buffer, buffer + size) {}
  ReadOnlyVectorCopy(const ReadOnlyVectorCopy&) = delete;
  ReadOnlyVectorCopy& operator=(const ReadOnlyVectorCopy&) = delete;

  const void* GetReadOnlyBuffer(size_t offset,
                                ErrorPtr* /* error */) const override {
    return reinterpret_cast<const uint8_t*>(vector_copy_.data()) + offset;
  }
  size_t GetSize() const override { return vector_copy_.size(); }

 protected:
  std::vector<T> vector_copy_;
};

// ByteBuffer is a read/write container that manages the data and underlying
// storage.
class BRILLO_EXPORT ByteBuffer : public VectorPtr<uint8_t> {
 public:
  explicit ByteBuffer(size_t reserve_size);
  ByteBuffer(const ByteBuffer&) = delete;
  ByteBuffer& operator=(const ByteBuffer&) = delete;

  ~ByteBuffer() override;
};

// StringPtr is a read/write container based on external std::string storage.
class BRILLO_EXPORT StringPtr : public ContiguousBufferBase {
 public:
  explicit StringPtr(std::string* string);
  StringPtr(const StringPtr&) = delete;
  StringPtr& operator=(const StringPtr&) = delete;

  bool Resize(size_t new_size, ErrorPtr* error) override;
  size_t GetSize() const override { return string_ptr_->size(); }
  bool IsReadOnly() const override { return false; }
  const void* GetReadOnlyBuffer(size_t offset, ErrorPtr* error) const override;
  void* GetBuffer(size_t offset, ErrorPtr* error) override;

 protected:
  std::string* string_ptr_;
};

// ReadOnlyStringRef is a read-only container based on external std::string.
class BRILLO_EXPORT ReadOnlyStringRef : public ContiguousReadOnlyBufferBase {
 public:
  explicit ReadOnlyStringRef(const std::string& string);
  ReadOnlyStringRef(const ReadOnlyStringRef&) = delete;
  ReadOnlyStringRef& operator=(const ReadOnlyStringRef&) = delete;

  const void* GetReadOnlyBuffer(size_t offset, ErrorPtr* error) const override;
  size_t GetSize() const override { return string_ref_.size(); }

 protected:
  const std::string& string_ref_;
};

// ReadOnlyStringCopy is a read-only container based on a copy of a std::string.
// This container actually owns the data stored in the string.
class BRILLO_EXPORT ReadOnlyStringCopy : public ReadOnlyStringRef {
 public:
  explicit ReadOnlyStringCopy(std::string string);
  ReadOnlyStringCopy(const ReadOnlyStringCopy&) = delete;
  ReadOnlyStringCopy& operator=(const ReadOnlyStringCopy&) = delete;

 protected:
  std::string string_copy_;
};

}  // namespace data_container
}  // namespace brillo

#endif  // LIBBRILLO_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
