#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 {
class QUICHE_EXPORT QuicheBufferAllocator {
public:
virtual ~QuicheBufferAllocator() = default;
virtual char* New(size_t size) = 0;
virtual char* New(size_t size, bool flag_enable) = 0;
virtual void Delete(char* buffer) = 0;
virtual void MarkAllocatorIdle() {}
};
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));
}
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) {}
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;
}
static QuicheBuffer Copy(QuicheBufferAllocator* allocator,
absl::string_view data) {
QuicheBuffer buffer(allocator, data.size());
memcpy(buffer.data(), data.data(), data.size());
return buffer;
}
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()); }
QuicheUniqueBufferPtr Release() {
size_ = 0;
return std::move(buffer_);
}
private:
QuicheUniqueBufferPtr buffer_;
size_t size_;
};
}
#endif