1 #ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_ 2 #define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_ 3 4 #include <cstddef> 5 #include <cstdlib> 6 #include <memory> 7 #include <utility> 8 9 #include "quiche/common/platform/api/quiche_export.h" 10 #include "quiche/common/quiche_buffer_allocator.h" 11 #include "quiche/common/quiche_callbacks.h" 12 13 namespace quiche { 14 15 class QUICHE_EXPORT QuicheMemSliceImpl { 16 public: 17 QuicheMemSliceImpl() = default; 18 QuicheMemSliceImpl(QuicheBuffer buffer)19 explicit QuicheMemSliceImpl(QuicheBuffer buffer) 20 : data_(buffer.data()), size_(buffer.size()) { 21 QuicheUniqueBufferPtr owned = buffer.Release(); 22 QuicheBufferAllocator* allocator = owned.get_deleter().allocator(); 23 owned.release(); 24 done_callback_ = [allocator](const char* ptr) { 25 allocator->Delete(const_cast<char*>(ptr)); 26 }; 27 } 28 QuicheMemSliceImpl(std::unique_ptr<char[]> buffer,size_t length)29 QuicheMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length) 30 : data_(buffer.release()), 31 size_(length), 32 done_callback_(+[](const char* ptr) { delete[] ptr; }) {} 33 QuicheMemSliceImpl(const char * buffer,size_t length,SingleUseCallback<void (const char *)> done_callback)34 QuicheMemSliceImpl(const char* buffer, size_t length, 35 SingleUseCallback<void(const char*)> done_callback) 36 : data_(buffer), 37 size_(length), 38 done_callback_(std::move(done_callback)) {} 39 40 QuicheMemSliceImpl(const QuicheMemSliceImpl& other) = delete; 41 QuicheMemSliceImpl& operator=(const QuicheMemSliceImpl& other) = delete; 42 43 // Move constructors. |other| will not hold a reference to the data buffer 44 // after this call completes. QuicheMemSliceImpl(QuicheMemSliceImpl && other)45 QuicheMemSliceImpl(QuicheMemSliceImpl&& other) { 46 data_ = other.data_; 47 size_ = other.size_; 48 done_callback_ = std::move(other.done_callback_); 49 other.data_ = nullptr; 50 other.size_ = 0; 51 other.done_callback_ = nullptr; 52 } 53 QuicheMemSliceImpl& operator=(QuicheMemSliceImpl&& other) { 54 Reset(); 55 data_ = other.data_; 56 size_ = other.size_; 57 done_callback_ = std::move(other.done_callback_); 58 other.data_ = nullptr; 59 other.size_ = 0; 60 other.done_callback_ = nullptr; 61 return *this; 62 } 63 ~QuicheMemSliceImpl()64 ~QuicheMemSliceImpl() { Reset(); } 65 Reset()66 void Reset() { 67 if (done_callback_ && data_ != nullptr) { 68 std::move(done_callback_)(data_); 69 } 70 data_ = nullptr; 71 size_ = 0; 72 done_callback_ = nullptr; 73 } 74 data()75 const char* data() const { return data_; } length()76 size_t length() const { return size_; } empty()77 bool empty() const { return size_ == 0; } 78 79 private: 80 const char* data_; 81 size_t size_; 82 SingleUseCallback<void(const char*)> done_callback_; 83 }; 84 85 } // namespace quiche 86 87 #endif // QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_MEM_SLICE_IMPL_H_ 88