aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames R. Barlow <james@purplerock.ca>2022-09-04 23:48:25 +0200
committerJames R. Barlow <james@purplerock.ca>2022-09-05 22:29:56 +0200
commit12967bdf8a271faeaf160b88bc8c5c800703af82 (patch)
tree642d4000430b037c2cea9ad2f44fc8e8e87e70dc
parent952b00aecd7bfdf9db50eb6b3d922ce17e1b606c (diff)
downloadqpdf-12967bdf8a271faeaf160b88bc8c5c800703af82.tar.zst
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.
-rw-r--r--include/qpdf/Buffer.hh6
-rw-r--r--libqpdf/Buffer.cc14
-rw-r--r--libtests/buffer.cc17
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<Members> m;
+ std::unique_ptr<Members> 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<Members>(new Members(rhs.m->size, nullptr, true));
+ std::unique_ptr<Members>(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);