// Copyright (c) 2012 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 QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
#define QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_

#include <stddef.h>

#include <memory>

#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_iovec.h"

namespace quiche {

// Abstract base class for classes which allocate and delete buffers.
class QUICHE_EXPORT QuicheBufferAllocator {
 public:
  virtual ~QuicheBufferAllocator() = default;

  // Returns or allocates a new buffer of |size|. Never returns null.
  virtual char* New(size_t size) = 0;

  // Returns or allocates a new buffer of |size| if |flag_enable| is true.
  // Otherwise, returns a buffer that is compatible with this class directly
  // with operator new. Never returns null.
  virtual char* New(size_t size, bool flag_enable) = 0;

  // Releases a buffer.
  virtual void Delete(char* buffer) = 0;

  // Marks the allocator as being idle. Serves as a hint to notify the allocator
  // that it should release any resources it's still holding on to.
  virtual void MarkAllocatorIdle() {}
};

// A deleter that can be used to manage ownership of buffers allocated via
// QuicheBufferAllocator through std::unique_ptr.
class QUICHE_EXPORT QuicheBufferDeleter {
 public:
  explicit QuicheBufferDeleter(QuicheBufferAllocator* allocator)
      : allocator_(allocator) {}

  QuicheBufferAllocator* allocator() { return allocator_; }
  void operator()(char* buffer) { allocator_->Delete(buffer); }

 private:
  QuicheBufferAllocator* allocator_;
};

using QuicheUniqueBufferPtr = std::unique_ptr<char[], QuicheBufferDeleter>;

inline QuicheUniqueBufferPtr MakeUniqueBuffer(QuicheBufferAllocator* allocator,
                                              size_t size) {
  return QuicheUniqueBufferPtr(allocator->New(size),
                               QuicheBufferDeleter(allocator));
}

// QuicheUniqueBufferPtr with a length attached to it.  Similar to
// QuicheMemSlice, except unlike QuicheMemSlice, QuicheBuffer is mutable and is
// not platform-specific.  Also unlike QuicheMemSlice, QuicheBuffer can be
// empty.
class QUICHE_EXPORT QuicheBuffer {
 public:
  QuicheBuffer() : buffer_(nullptr, QuicheBufferDeleter(nullptr)), size_(0) {}
  QuicheBuffer(QuicheBufferAllocator* allocator, size_t size)
      : buffer_(MakeUniqueBuffer(allocator, size)), size_(size) {}

  QuicheBuffer(QuicheUniqueBufferPtr buffer, size_t size)
      : buffer_(std::move(buffer)), size_(size) {}

  // Make sure the move constructor zeroes out the size field.
  QuicheBuffer(QuicheBuffer&& other)
      : buffer_(std::move(other.buffer_)), size_(other.size_) {
    other.buffer_ = nullptr;
    other.size_ = 0;
  }
  QuicheBuffer& operator=(QuicheBuffer&& other) {
    buffer_ = std::move(other.buffer_);
    size_ = other.size_;

    other.buffer_ = nullptr;
    other.size_ = 0;
    return *this;
  }

  // Factory method to create a QuicheBuffer that holds a copy of `data`.
  static QuicheBuffer Copy(QuicheBufferAllocator* allocator,
                           absl::string_view data) {
    QuicheBuffer buffer(allocator, data.size());
    memcpy(buffer.data(), data.data(), data.size());
    return buffer;
  }

  // Factory method to create a QuicheBuffer of length `buffer_length` that
  // holds a copy of `buffer_length` bytes from `iov` starting at offset
  // `iov_offset`.  `iov` must be at least `iov_offset + buffer_length` total
  // length.
  static QuicheBuffer CopyFromIovec(QuicheBufferAllocator* allocator,
                                    const struct iovec* iov, int iov_count,
                                    size_t iov_offset, size_t buffer_length);

  const char* data() const { return buffer_.get(); }
  char* data() { return buffer_.get(); }
  size_t size() const { return size_; }
  bool empty() const { return size_ == 0; }
  absl::string_view AsStringView() const {
    return absl::string_view(data(), size());
  }
  absl::Span<char> AsSpan() { return absl::Span<char>(data(), size()); }

  // Releases the ownership of the underlying buffer.
  QuicheUniqueBufferPtr Release() {
    size_ = 0;
    return std::move(buffer_);
  }

 private:
  QuicheUniqueBufferPtr buffer_;
  size_t size_;
};

}  // namespace quiche

#endif  // QUICHE_COMMON_QUICHE_BUFFER_ALLOCATOR_H_
