From 12967bdf8a271faeaf160b88bc8c5c800703af82 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Sun, 4 Sep 2022 14:48:25 -0700 Subject: Take advantage of unique_ptr and move construction for Buffer Since Buffer has always implemented its copy constructor with a deep copy, its Members object will never have multiple owners. Change to unique_ptr. Also implement move constructors for Buffer, since there may be cases where a deep copy is not needed. --- include/qpdf/Buffer.hh | 6 +++++- libqpdf/Buffer.cc | 14 +++++++++++++- libtests/buffer.cc | 17 +++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/qpdf/Buffer.hh b/include/qpdf/Buffer.hh index fdb07ba7..56441df9 100644 --- a/include/qpdf/Buffer.hh +++ b/include/qpdf/Buffer.hh @@ -49,6 +49,10 @@ class Buffer QPDF_DLL Buffer& operator=(Buffer const&); QPDF_DLL + Buffer(Buffer &&) noexcept; + QPDF_DLL + Buffer& operator=(Buffer &&) noexcept; + QPDF_DLL size_t getSize() const; QPDF_DLL unsigned char const* getBuffer() const; @@ -75,7 +79,7 @@ class Buffer void copy(Buffer const&); - std::shared_ptr m; + std::unique_ptr m; }; #endif // BUFFER_HH diff --git a/libqpdf/Buffer.cc b/libqpdf/Buffer.cc index 4e8a17ae..98a524ce 100644 --- a/libqpdf/Buffer.cc +++ b/libqpdf/Buffer.cc @@ -48,12 +48,24 @@ Buffer::operator=(Buffer const& rhs) return *this; } +Buffer::Buffer(Buffer&& rhs) noexcept : + m(std::move(rhs.m)) +{ +} + +Buffer& +Buffer::operator=(Buffer&& rhs) noexcept +{ + std::swap(this->m, rhs.m); + return *this; +} + void Buffer::copy(Buffer const& rhs) { if (this != &rhs) { this->m = - std::shared_ptr(new Members(rhs.m->size, nullptr, true)); + std::unique_ptr(new Members(rhs.m->size, nullptr, true)); if (this->m->size) { memcpy(this->m->buf, rhs.m->buf, this->m->size); } diff --git a/libtests/buffer.cc b/libtests/buffer.cc index a65efb1c..f372e7b4 100644 --- a/libtests/buffer.cc +++ b/libtests/buffer.cc @@ -37,6 +37,23 @@ main() assert(bc2p[1] == 'W'); } + { + // Test that buffers can be moved. + Buffer bm1(2); + unsigned char* bm1p = bm1.getBuffer(); + bm1p[0] = 'Q'; + bm1p[1] = 'W'; + Buffer bm2(std::move(bm1)); + bm1p[0] = 'R'; + unsigned char* bm2p = bm2.getBuffer(); + assert(bm2p == bm1p); + assert(bm2p[0] == 'R'); + + Buffer bm3 = std::move(bm2); + unsigned char* bm3p = bm3.getBuffer(); + assert(bm3p == bm2p); + } + try { Pl_Discard discard; Pl_Count count("count", &discard); -- cgit v1.2.3-54-g00ecf