blob: e2acde0b70008a2461aa0eb02366725ecfb1f95a [file] [log] [blame]
#ifndef QUICHE_COMMON_QUICHE_DEFAULT_MEM_SLICE_IMPL_H_
#define QUICHE_COMMON_QUICHE_DEFAULT_MEM_SLICE_IMPL_H_
#include <cstddef>
#include <cstdlib>
#include <memory>
#include <utility>
#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_callbacks.h"
namespace quiche {
// The default (and soon, hopefully the only) implementation of QuicheMemSlice.
class QUICHE_EXPORT QuicheDefaultMemSliceImpl {
public:
QuicheDefaultMemSliceImpl() = default;
explicit QuicheDefaultMemSliceImpl(QuicheBuffer buffer)
: data_(buffer.data()), size_(buffer.size()) {
QuicheUniqueBufferPtr owned = buffer.Release();
QuicheBufferAllocator* allocator = owned.get_deleter().allocator();
owned.release();
done_callback_ = [allocator](const char* ptr) {
allocator->Delete(const_cast<char*>(ptr));
};
}
QuicheDefaultMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length)
: data_(buffer.release()),
size_(length),
done_callback_(+[](const char* ptr) { delete[] ptr; }) {}
QuicheDefaultMemSliceImpl(const char* buffer, size_t length,
SingleUseCallback<void(const char*)> done_callback)
: data_(buffer),
size_(length),
done_callback_(std::move(done_callback)) {}
QuicheDefaultMemSliceImpl(const QuicheDefaultMemSliceImpl& other) = delete;
QuicheDefaultMemSliceImpl& operator=(const QuicheDefaultMemSliceImpl& other) =
delete;
// Move constructors. |other| will not hold a reference to the data buffer
// after this call completes.
QuicheDefaultMemSliceImpl(QuicheDefaultMemSliceImpl&& other) {
data_ = other.data_;
size_ = other.size_;
done_callback_ = std::move(other.done_callback_);
other.data_ = nullptr;
other.size_ = 0;
other.done_callback_ = nullptr;
}
QuicheDefaultMemSliceImpl& operator=(QuicheDefaultMemSliceImpl&& other) {
Reset();
data_ = other.data_;
size_ = other.size_;
done_callback_ = std::move(other.done_callback_);
other.data_ = nullptr;
other.size_ = 0;
other.done_callback_ = nullptr;
return *this;
}
~QuicheDefaultMemSliceImpl() { Reset(); }
void Reset() {
if (done_callback_ && data_ != nullptr) {
std::move(done_callback_)(data_);
}
data_ = nullptr;
size_ = 0;
done_callback_ = nullptr;
}
const char* data() const { return data_; }
size_t length() const { return size_; }
bool empty() const { return size_ == 0; }
private:
const char* data_ = nullptr;
size_t size_ = 0;
SingleUseCallback<void(const char*)> done_callback_ = nullptr;
};
} // namespace quiche
#endif // QUICHE_COMMON_QUICHE_DEFAULT_MEM_SLICE_IMPL_H_