Line data Source code
1 : /*
2 : * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : #include "webrtc/base/copyonwritebuffer.h"
12 :
13 : namespace rtc {
14 :
15 0 : CopyOnWriteBuffer::CopyOnWriteBuffer() {
16 0 : RTC_DCHECK(IsConsistent());
17 0 : }
18 :
19 0 : CopyOnWriteBuffer::CopyOnWriteBuffer(const CopyOnWriteBuffer& buf)
20 0 : : buffer_(buf.buffer_) {
21 0 : }
22 :
23 0 : CopyOnWriteBuffer::CopyOnWriteBuffer(CopyOnWriteBuffer&& buf)
24 0 : : buffer_(std::move(buf.buffer_)) {
25 0 : }
26 :
27 0 : CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size)
28 0 : : buffer_(size > 0 ? new RefCountedObject<Buffer>(size) : nullptr) {
29 0 : RTC_DCHECK(IsConsistent());
30 0 : }
31 :
32 0 : CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size, size_t capacity)
33 0 : : buffer_(size > 0 || capacity > 0
34 0 : ? new RefCountedObject<Buffer>(size, capacity)
35 0 : : nullptr) {
36 0 : RTC_DCHECK(IsConsistent());
37 0 : }
38 :
39 : CopyOnWriteBuffer::~CopyOnWriteBuffer() = default;
40 :
41 0 : bool CopyOnWriteBuffer::operator==(const CopyOnWriteBuffer& buf) const {
42 : // Must either use the same buffer internally or have the same contents.
43 0 : RTC_DCHECK(IsConsistent());
44 0 : RTC_DCHECK(buf.IsConsistent());
45 0 : return buffer_.get() == buf.buffer_.get() ||
46 0 : (buffer_.get() && buf.buffer_.get() &&
47 0 : *buffer_.get() == *buf.buffer_.get());
48 : }
49 :
50 0 : void CopyOnWriteBuffer::SetSize(size_t size) {
51 0 : RTC_DCHECK(IsConsistent());
52 0 : if (!buffer_) {
53 0 : if (size > 0) {
54 0 : buffer_ = new RefCountedObject<Buffer>(size);
55 : }
56 0 : RTC_DCHECK(IsConsistent());
57 0 : return;
58 : }
59 :
60 : // Clone data if referenced.
61 0 : if (!buffer_->HasOneRef()) {
62 : buffer_ = new RefCountedObject<Buffer>(
63 0 : buffer_->data(),
64 0 : std::min(buffer_->size(), size),
65 0 : std::max(buffer_->capacity(), size));
66 : }
67 0 : buffer_->SetSize(size);
68 0 : RTC_DCHECK(IsConsistent());
69 : }
70 :
71 0 : void CopyOnWriteBuffer::EnsureCapacity(size_t capacity) {
72 0 : RTC_DCHECK(IsConsistent());
73 0 : if (!buffer_) {
74 0 : if (capacity > 0) {
75 0 : buffer_ = new RefCountedObject<Buffer>(0, capacity);
76 : }
77 0 : RTC_DCHECK(IsConsistent());
78 0 : return;
79 0 : } else if (capacity <= buffer_->capacity()) {
80 0 : return;
81 : }
82 :
83 0 : CloneDataIfReferenced(std::max(buffer_->capacity(), capacity));
84 0 : buffer_->EnsureCapacity(capacity);
85 0 : RTC_DCHECK(IsConsistent());
86 : }
87 :
88 0 : void CopyOnWriteBuffer::Clear() {
89 0 : if (!buffer_)
90 0 : return;
91 :
92 0 : if (buffer_->HasOneRef()) {
93 0 : buffer_->Clear();
94 : } else {
95 0 : buffer_ = new RefCountedObject<Buffer>(0, buffer_->capacity());
96 : }
97 0 : RTC_DCHECK(IsConsistent());
98 : }
99 :
100 0 : void CopyOnWriteBuffer::CloneDataIfReferenced(size_t new_capacity) {
101 0 : if (buffer_->HasOneRef()) {
102 0 : return;
103 : }
104 :
105 0 : buffer_ = new RefCountedObject<Buffer>(buffer_->data(), buffer_->size(),
106 0 : new_capacity);
107 0 : RTC_DCHECK(IsConsistent());
108 : }
109 :
110 :
111 :
112 : } // namespace rtc
|