|  | #include "quiche/common/platform/api/quiche_mem_slice.h" | 
|  |  | 
|  | #include <cstddef> | 
|  | #include <cstdlib> | 
|  | #include <cstring> | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "quiche/common/quiche_buffer_allocator.h" | 
|  | #include "quiche/common/quiche_callbacks.h" | 
|  |  | 
|  | namespace quiche { | 
|  |  | 
|  | QuicheMemSlice::QuicheMemSlice(QuicheBuffer buffer) | 
|  | : data_(buffer.data()), size_(buffer.size()) { | 
|  | QuicheUniqueBufferPtr owned = buffer.Release(); | 
|  | QuicheBufferAllocator* allocator = owned.get_deleter().allocator(); | 
|  | owned.release(); | 
|  | done_callback_ = [allocator](absl::string_view ptr) { | 
|  | allocator->Delete(const_cast<char*>(ptr.data())); | 
|  | }; | 
|  | } | 
|  |  | 
|  | QuicheMemSlice::QuicheMemSlice(std::unique_ptr<char[]> buffer, size_t length) | 
|  | : data_(buffer.release()), | 
|  | size_(length), | 
|  | done_callback_(+[](absl::string_view ptr) { delete[] ptr.data(); }) {} | 
|  |  | 
|  | QuicheMemSlice::QuicheMemSlice( | 
|  | const char* buffer, size_t length, | 
|  | SingleUseCallback<void(absl::string_view)> done_callback) | 
|  | : data_(buffer), size_(length), done_callback_(std::move(done_callback)) {} | 
|  |  | 
|  | // Move constructors. |other| will not hold a reference to the data buffer | 
|  | // after this call completes. | 
|  | QuicheMemSlice::QuicheMemSlice(QuicheMemSlice&& other) { | 
|  | data_ = other.data_; | 
|  | size_ = other.size_; | 
|  | done_callback_ = std::move(other.done_callback_); | 
|  | other.data_ = nullptr; | 
|  | other.size_ = 0; | 
|  | other.done_callback_ = nullptr; | 
|  | } | 
|  | QuicheMemSlice& QuicheMemSlice::operator=(QuicheMemSlice&& 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; | 
|  | } | 
|  |  | 
|  | QuicheMemSlice::~QuicheMemSlice() { Reset(); } | 
|  |  | 
|  | void QuicheMemSlice::Reset() { | 
|  | if (done_callback_ && data_ != nullptr) { | 
|  | std::move(done_callback_)(AsStringView()); | 
|  | } | 
|  | data_ = nullptr; | 
|  | size_ = 0; | 
|  | done_callback_ = nullptr; | 
|  | } | 
|  |  | 
|  | QuicheMemSlice QuicheMemSlice::Copy(absl::string_view data) { | 
|  | if (data.empty()) { | 
|  | return QuicheMemSlice(); | 
|  | } | 
|  | auto buffer = std::make_unique<char[]>(data.size()); | 
|  | memcpy(buffer.get(), data.data(), data.size()); | 
|  | return QuicheMemSlice(std::move(buffer), data.size()); | 
|  | } | 
|  |  | 
|  | }  // namespace quiche |