// 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 LIBCHROMEOS_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
#define LIBCHROMEOS_BRILLO_STREAMS_MEMORY_CONTAINERS_H_

#include <string>
#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;
  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;

 private:
  DISALLOW_COPY_AND_ASSIGN(DataContainerInterface);
};

// 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;
  // 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;

 private:
  DISALLOW_COPY_AND_ASSIGN(ContiguousBufferBase);
};

// ContiguousReadOnlyBufferBase is a specialization of ContiguousBufferBase for
// read-only containers.
class BRILLO_EXPORT ContiguousReadOnlyBufferBase : public ContiguousBufferBase {
 public:
  ContiguousReadOnlyBufferBase() = default;
  // 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;

 private:
  DISALLOW_COPY_AND_ASSIGN(ContiguousReadOnlyBufferBase);
};

// 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) {}

  // 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_;

  DISALLOW_COPY_AND_ASSIGN(ReadOnlyBuffer);
};

// 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) {}

  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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(VectorPtr);
};

// 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) {}

  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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ReadOnlyVectorRef);
};

// 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) {}

  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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ReadOnlyVectorCopy);
};

// 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() override;

 private:
  DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
};

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

  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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(StringPtr);
};

// ReadOnlyStringRef is a read-only container based on external std::string.
class BRILLO_EXPORT ReadOnlyStringRef : public ContiguousReadOnlyBufferBase {
 public:
  explicit ReadOnlyStringRef(const std::string& string);
  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_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ReadOnlyStringRef);
};

// 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);

 protected:
  std::string string_copy_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ReadOnlyStringCopy);
};

}  // namespace data_container
}  // namespace brillo

#endif  // LIBCHROMEOS_BRILLO_STREAMS_MEMORY_CONTAINERS_H_
