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