/src/qpdf/libqpdf/Buffer.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include <qpdf/assert_test.h> |
2 | | |
3 | | #include <qpdf/Buffer.hh> |
4 | | |
5 | | #include <cstring> |
6 | | |
7 | | bool test_mode = false; |
8 | | |
9 | | // During CI the Buffer copy constructor and copy assignment operator throw an assertion error to |
10 | | // detect their accidental use. Call setTestMode to surpress the assertion errors for testing of |
11 | | // copy construction and assignment. |
12 | | void |
13 | | Buffer::setTestMode() noexcept |
14 | 0 | { |
15 | 0 | test_mode = true; |
16 | 0 | } |
17 | | |
18 | | Buffer::Members::Members(size_t size, unsigned char* buf, bool own_memory) : |
19 | | own_memory(own_memory), |
20 | | size(size), |
21 | | buf(nullptr) |
22 | 2.46M | { |
23 | 2.46M | if (own_memory) { |
24 | 2.44M | this->buf = (size ? new unsigned char[size] : nullptr); |
25 | 2.44M | } else { |
26 | 19.7k | this->buf = buf; |
27 | 19.7k | } |
28 | 2.46M | } |
29 | | |
30 | | Buffer::Members::Members(std::string&& content) : |
31 | | str(std::move(content)), |
32 | | own_memory(false), |
33 | | size(str.size()), |
34 | | buf(reinterpret_cast<unsigned char*>(str.data())) |
35 | 374k | { |
36 | 374k | } |
37 | | |
38 | | Buffer::Members::~Members() |
39 | 2.83M | { |
40 | 2.83M | if (this->own_memory) { |
41 | 2.44M | delete[] this->buf; |
42 | 2.44M | } |
43 | 2.83M | } |
44 | | |
45 | | Buffer::Buffer() : |
46 | | m(new Members(0, nullptr, true)) |
47 | 0 | { |
48 | 0 | } |
49 | | |
50 | | Buffer::Buffer(size_t size) : |
51 | | m(new Members(size, nullptr, true)) |
52 | 2.44M | { |
53 | 2.44M | } |
54 | | |
55 | | Buffer::Buffer(std::string&& content) : |
56 | | m(new Members(std::move(content))) |
57 | 374k | { |
58 | 374k | } |
59 | | |
60 | | Buffer::Buffer(unsigned char* buf, size_t size) : |
61 | | m(new Members(size, buf, false)) |
62 | 19.7k | { |
63 | 19.7k | } |
64 | | |
65 | | Buffer::Buffer(std::string& content) : |
66 | | m(new Members(content.size(), reinterpret_cast<unsigned char*>(content.data()), false)) |
67 | 0 | { |
68 | 0 | } |
69 | | |
70 | | Buffer::Buffer(Buffer const& rhs) |
71 | 0 | { |
72 | 0 | assert(test_mode); |
73 | 0 | copy(rhs); |
74 | 0 | } |
75 | | |
76 | | Buffer& |
77 | | Buffer::operator=(Buffer const& rhs) |
78 | 0 | { |
79 | 0 | assert(test_mode); |
80 | 0 | copy(rhs); |
81 | 0 | return *this; |
82 | 0 | } |
83 | | |
84 | | Buffer::Buffer(Buffer&& rhs) noexcept : |
85 | | m(std::move(rhs.m)) |
86 | 3.70M | { |
87 | 3.70M | } |
88 | | |
89 | | Buffer& |
90 | | Buffer::operator=(Buffer&& rhs) noexcept |
91 | 0 | { |
92 | 0 | std::swap(m, rhs.m); |
93 | 0 | return *this; |
94 | 0 | } |
95 | | |
96 | | void |
97 | | Buffer::copy(Buffer const& rhs) |
98 | 0 | { |
99 | 0 | if (this != &rhs) { |
100 | 0 | m = std::unique_ptr<Members>(new Members(rhs.m->size, nullptr, true)); |
101 | 0 | if (m->size) { |
102 | 0 | memcpy(m->buf, rhs.m->buf, m->size); |
103 | 0 | } |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | | size_t |
108 | | Buffer::getSize() const |
109 | 2.38M | { |
110 | 2.38M | return m->size; |
111 | 2.38M | } |
112 | | |
113 | | unsigned char const* |
114 | | Buffer::getBuffer() const |
115 | 0 | { |
116 | 0 | return m->buf; |
117 | 0 | } |
118 | | |
119 | | unsigned char* |
120 | | Buffer::getBuffer() |
121 | 52.6M | { |
122 | 52.6M | return m->buf; |
123 | 52.6M | } |
124 | | |
125 | | Buffer |
126 | | Buffer::copy() const |
127 | 0 | { |
128 | 0 | auto result = Buffer(m->size); |
129 | 0 | if (m->size) { |
130 | 0 | memcpy(result.m->buf, m->buf, m->size); |
131 | 0 | } |
132 | 0 | return result; |
133 | 0 | } |