1 // Copyright 2017 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "core/fxcrt/binary_buffer.h"
8
9 #include <algorithm>
10 #include <utility>
11
12 #include "core/fxcrt/fx_safe_types.h"
13 #include "core/fxcrt/span_util.h"
14 #include "core/fxcrt/stl_util.h"
15
16 namespace fxcrt {
17
18 BinaryBuffer::BinaryBuffer() = default;
19
BinaryBuffer(BinaryBuffer && that)20 BinaryBuffer::BinaryBuffer(BinaryBuffer&& that) noexcept
21 : m_AllocStep(that.m_AllocStep),
22 m_DataSize(that.m_DataSize),
23 m_buffer(std::move(that.m_buffer)) {
24 // Can't just default, need to leave |that| in a valid state, which means
25 // that the size members reflect the (null) moved-from buffer.
26 that.m_AllocStep = 0;
27 that.m_DataSize = 0;
28 }
29
30 BinaryBuffer::~BinaryBuffer() = default;
31
operator =(BinaryBuffer && that)32 BinaryBuffer& BinaryBuffer::operator=(BinaryBuffer&& that) noexcept {
33 // Can't just default, need to leave |that| in a valid state, which means
34 // that the size members reflect the (null) moved-from buffer.
35 m_AllocStep = that.m_AllocStep;
36 m_DataSize = that.m_DataSize;
37 m_buffer = std::move(that.m_buffer);
38 that.m_AllocStep = 0;
39 that.m_DataSize = 0;
40 return *this;
41 }
42
DeleteBuf(size_t start_index,size_t count)43 void BinaryBuffer::DeleteBuf(size_t start_index, size_t count) {
44 if (m_buffer.empty() || count > GetSize() || start_index > GetSize() - count)
45 return;
46
47 auto buffer_span = GetMutableSpan();
48 fxcrt::spanmove(buffer_span.subspan(start_index),
49 buffer_span.subspan(start_index + count));
50 m_DataSize -= count;
51 }
52
GetMutableSpan()53 pdfium::span<uint8_t> BinaryBuffer::GetMutableSpan() {
54 return pdfium::make_span(m_buffer).first(GetSize());
55 }
56
GetSpan() const57 pdfium::span<const uint8_t> BinaryBuffer::GetSpan() const {
58 return pdfium::make_span(m_buffer).first(GetSize());
59 }
60
GetLength() const61 size_t BinaryBuffer::GetLength() const {
62 return GetSize();
63 }
64
Clear()65 void BinaryBuffer::Clear() {
66 m_DataSize = 0;
67 }
68
DetachBuffer()69 DataVector<uint8_t> BinaryBuffer::DetachBuffer() {
70 m_buffer.resize(GetSize());
71 m_DataSize = 0;
72 return std::move(m_buffer);
73 }
74
EstimateSize(size_t size)75 void BinaryBuffer::EstimateSize(size_t size) {
76 if (m_buffer.size() < size)
77 ExpandBuf(size - GetSize());
78 }
79
ExpandBuf(size_t add_size)80 void BinaryBuffer::ExpandBuf(size_t add_size) {
81 FX_SAFE_SIZE_T new_size = GetSize();
82 new_size += add_size;
83 if (m_buffer.size() >= new_size.ValueOrDie())
84 return;
85
86 size_t alloc_step = std::max(static_cast<size_t>(128),
87 m_AllocStep ? m_AllocStep : m_buffer.size() / 4);
88 new_size += alloc_step - 1; // Quantize, don't combine these lines.
89 new_size /= alloc_step;
90 new_size *= alloc_step;
91 m_buffer.resize(new_size.ValueOrDie());
92 }
93
AppendSpan(pdfium::span<const uint8_t> span)94 void BinaryBuffer::AppendSpan(pdfium::span<const uint8_t> span) {
95 if (span.empty())
96 return;
97
98 ExpandBuf(span.size());
99 fxcrt::Copy(span, pdfium::make_span(m_buffer).subspan(GetSize()));
100 m_DataSize += span.size();
101 }
102
AppendString(const ByteString & str)103 void BinaryBuffer::AppendString(const ByteString& str) {
104 AppendSpan(str.unsigned_span());
105 }
106
AppendUint8(uint8_t value)107 void BinaryBuffer::AppendUint8(uint8_t value) {
108 AppendSpan(pdfium::span_from_ref(value));
109 }
110
AppendUint16(uint16_t value)111 void BinaryBuffer::AppendUint16(uint16_t value) {
112 AppendSpan(pdfium::as_bytes(pdfium::span_from_ref(value)));
113 }
114
AppendUint32(uint32_t value)115 void BinaryBuffer::AppendUint32(uint32_t value) {
116 AppendSpan(pdfium::as_bytes(pdfium::span_from_ref(value)));
117 }
118
AppendDouble(double value)119 void BinaryBuffer::AppendDouble(double value) {
120 AppendSpan(pdfium::as_bytes(pdfium::span_from_ref(value)));
121 }
122
123 } // namespace fxcrt
124