blob: 177cc690fadcfdd9dfc33ad81c072eed3b84ebfa [file] [log] [blame]
#ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
#define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_
#include <cstdlib>
#include <optional>
#include <utility>
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_callbacks.h"
#include "quiche/common/simple_buffer_allocator.h"
namespace quiche {
class QUICHE_EXPORT QuicheMemSliceImpl {
public:
QuicheMemSliceImpl() = default;
explicit QuicheMemSliceImpl(QuicheBuffer buffer)
: buffer_(std::move(buffer)) {}
QuicheMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length)
: buffer_(
QuicheBuffer(QuicheUniqueBufferPtr(
buffer.release(),
QuicheBufferDeleter(SimpleBufferAllocator::Get())),
length)) {}
QuicheMemSliceImpl(char buffer[], size_t length,
quiche::SingleUseCallback<void(const char*)> done_callback)
: allocator_(std::in_place, std::move(done_callback)),
buffer_(QuicheBuffer(
QuicheUniqueBufferPtr(buffer, QuicheBufferDeleter(&*allocator_)),
length)) {}
QuicheMemSliceImpl(const QuicheMemSliceImpl& other) = delete;
QuicheMemSliceImpl& operator=(const QuicheMemSliceImpl& other) = delete;
// Move constructors. |other| will not hold a reference to the data buffer
// after this call completes.
QuicheMemSliceImpl(QuicheMemSliceImpl&& other) = default;
QuicheMemSliceImpl& operator=(QuicheMemSliceImpl&& other) = default;
~QuicheMemSliceImpl() = default;
void Reset() { buffer_ = QuicheBuffer(); }
const char* data() const { return buffer_.data(); }
size_t length() const { return buffer_.size(); }
bool empty() const { return buffer_.empty(); }
private:
// Allocator that is only used for a special `done` callback.
class LambdaAllocator : public QuicheBufferAllocator {
public:
LambdaAllocator(quiche::SingleUseCallback<void(const char*)> done_callback)
: done_callback_(std::move(done_callback)) {}
// Noncompliant. Will cause program termination.
char* New(size_t) override {
std::exit(-1);
return nullptr;
}
char* New(size_t, bool) override {
std::exit(-1);
return nullptr;
}
void Delete(char* buffer) override {
if (done_callback_ != nullptr) {
std::move(done_callback_)(buffer);
}
}
private:
quiche::SingleUseCallback<void(const char*)> done_callback_;
};
std::optional<LambdaAllocator> allocator_;
QuicheBuffer buffer_;
};
} // namespace quiche
#endif // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_