Refactor default QuicheMemSliceImpl to not wrap around QuicheBuffer. Since the long-term hope is to make it the only implementation of QuicheMemSlice, it makes sense to make it as simple as possible. Also make QuicheMemSlice take `const char*` instead of `char*`, as some of the wrapped types use refcounted constant buffers. PiperOrigin-RevId: 597037612
diff --git a/quiche/common/platform/api/quiche_mem_slice.h b/quiche/common/platform/api/quiche_mem_slice.h index c7d9fd7..23accb0 100644 --- a/quiche/common/platform/api/quiche_mem_slice.h +++ b/quiche/common/platform/api/quiche_mem_slice.h
@@ -5,7 +5,9 @@ #ifndef QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_ #define QUICHE_COMMON_PLATFORM_API_QUICHE_MEM_SLICE_H_ +#include <cstddef> #include <memory> +#include <utility> #include "quiche_platform_impl/quiche_mem_slice_impl.h" @@ -33,7 +35,7 @@ QuicheMemSlice(std::unique_ptr<char[]> buffer, size_t length) : impl_(std::move(buffer), length) {} - QuicheMemSlice(char buffer[], size_t length, + QuicheMemSlice(const char* buffer, size_t length, quiche::SingleUseCallback<void(const char*)> done_callback) : impl_(buffer, length, std::move(done_callback)) {}
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h index 177cc69..d20ebbe 100644 --- a/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h +++ b/quiche/common/platform/default/quiche_platform_impl/quiche_mem_slice_impl.h
@@ -1,14 +1,14 @@ #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 <cstddef> #include <cstdlib> -#include <optional> +#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" -#include "quiche/common/simple_buffer_allocator.h" namespace quiche { @@ -17,66 +17,69 @@ QuicheMemSliceImpl() = default; explicit QuicheMemSliceImpl(QuicheBuffer buffer) - : buffer_(std::move(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)); + }; + } QuicheMemSliceImpl(std::unique_ptr<char[]> buffer, size_t length) - : buffer_( - QuicheBuffer(QuicheUniqueBufferPtr( - buffer.release(), - QuicheBufferDeleter(SimpleBufferAllocator::Get())), - length)) {} + : data_(buffer.release()), + size_(length), + done_callback_(+[](const char* ptr) { delete[] ptr; }) {} - 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 char* buffer, size_t length, + SingleUseCallback<void(const char*)> done_callback) + : data_(buffer), + size_(length), + done_callback_(std::move(done_callback)) {} 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(QuicheMemSliceImpl&& other) { + data_ = other.data_; + size_ = other.size_; + done_callback_ = std::move(other.done_callback_); + other.data_ = nullptr; + other.size_ = 0; + other.done_callback_ = nullptr; + } + QuicheMemSliceImpl& operator=(QuicheMemSliceImpl&& 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; + } - ~QuicheMemSliceImpl() = default; + ~QuicheMemSliceImpl() { Reset(); } - void Reset() { buffer_ = QuicheBuffer(); } + void Reset() { + if (done_callback_ && data_ != nullptr) { + std::move(done_callback_)(data_); + } + data_ = nullptr; + size_ = 0; + done_callback_ = nullptr; + } - const char* data() const { return buffer_.data(); } - size_t length() const { return buffer_.size(); } - bool empty() const { return buffer_.empty(); } + const char* data() const { return data_; } + size_t length() const { return size_; } + bool empty() const { return size_ == 0; } 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_; + const char* data_; + size_t size_; + SingleUseCallback<void(const char*)> done_callback_; }; } // namespace quiche