Commit 12967bdf8a271faeaf160b88bc8c5c800703af82

Authored by James R. Barlow
1 parent 952b00ae

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
@@ -49,6 +49,10 @@ class Buffer @@ -49,6 +49,10 @@ class Buffer
49 QPDF_DLL 49 QPDF_DLL
50 Buffer& operator=(Buffer const&); 50 Buffer& operator=(Buffer const&);
51 QPDF_DLL 51 QPDF_DLL
  52 + Buffer(Buffer &&) noexcept;
  53 + QPDF_DLL
  54 + Buffer& operator=(Buffer &&) noexcept;
  55 + QPDF_DLL
52 size_t getSize() const; 56 size_t getSize() const;
53 QPDF_DLL 57 QPDF_DLL
54 unsigned char const* getBuffer() const; 58 unsigned char const* getBuffer() const;
@@ -75,7 +79,7 @@ class Buffer @@ -75,7 +79,7 @@ class Buffer
75 79
76 void copy(Buffer const&); 80 void copy(Buffer const&);
77 81
78 - std::shared_ptr<Members> m; 82 + std::unique_ptr<Members> m;
79 }; 83 };
80 84
81 #endif // BUFFER_HH 85 #endif // BUFFER_HH
libqpdf/Buffer.cc
@@ -48,12 +48,24 @@ Buffer::operator=(Buffer const&amp; rhs) @@ -48,12 +48,24 @@ Buffer::operator=(Buffer const&amp; rhs)
48 return *this; 48 return *this;
49 } 49 }
50 50
  51 +Buffer::Buffer(Buffer&& rhs) noexcept :
  52 + m(std::move(rhs.m))
  53 +{
  54 +}
  55 +
  56 +Buffer&
  57 +Buffer::operator=(Buffer&& rhs) noexcept
  58 +{
  59 + std::swap(this->m, rhs.m);
  60 + return *this;
  61 +}
  62 +
51 void 63 void
52 Buffer::copy(Buffer const& rhs) 64 Buffer::copy(Buffer const& rhs)
53 { 65 {
54 if (this != &rhs) { 66 if (this != &rhs) {
55 this->m = 67 this->m =
56 - std::shared_ptr<Members>(new Members(rhs.m->size, nullptr, true)); 68 + std::unique_ptr<Members>(new Members(rhs.m->size, nullptr, true));
57 if (this->m->size) { 69 if (this->m->size) {
58 memcpy(this->m->buf, rhs.m->buf, this->m->size); 70 memcpy(this->m->buf, rhs.m->buf, this->m->size);
59 } 71 }
libtests/buffer.cc
@@ -37,6 +37,23 @@ main() @@ -37,6 +37,23 @@ main()
37 assert(bc2p[1] == 'W'); 37 assert(bc2p[1] == 'W');
38 } 38 }
39 39
  40 + {
  41 + // Test that buffers can be moved.
  42 + Buffer bm1(2);
  43 + unsigned char* bm1p = bm1.getBuffer();
  44 + bm1p[0] = 'Q';
  45 + bm1p[1] = 'W';
  46 + Buffer bm2(std::move(bm1));
  47 + bm1p[0] = 'R';
  48 + unsigned char* bm2p = bm2.getBuffer();
  49 + assert(bm2p == bm1p);
  50 + assert(bm2p[0] == 'R');
  51 +
  52 + Buffer bm3 = std::move(bm2);
  53 + unsigned char* bm3p = bm3.getBuffer();
  54 + assert(bm3p == bm2p);
  55 + }
  56 +
40 try { 57 try {
41 Pl_Discard discard; 58 Pl_Discard discard;
42 Pl_Count count("count", &discard); 59 Pl_Count count("count", &discard);