blob: de003f2d8ea0b169d2dfa417bfe92da4a7425cee [file] [log] [blame]
jbauch13041cf2016-02-25 14:16:521/*
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
Steve Anton10542f22019-01-11 17:11:0011#include "rtc_base/copy_on_write_buffer.h"
jbauch13041cf2016-02-25 14:16:5212
Yves Gerey988cc082018-10-23 10:03:0113#include <stddef.h>
14
jbauch13041cf2016-02-25 14:16:5215namespace rtc {
16
17CopyOnWriteBuffer::CopyOnWriteBuffer() {
18 RTC_DCHECK(IsConsistent());
19}
20
21CopyOnWriteBuffer::CopyOnWriteBuffer(const CopyOnWriteBuffer& buf)
Yves Gerey665174f2018-06-19 13:03:0522 : buffer_(buf.buffer_) {}
jbauch13041cf2016-02-25 14:16:5223
danilchapd8a9c532016-07-30 19:39:2624CopyOnWriteBuffer::CopyOnWriteBuffer(CopyOnWriteBuffer&& buf)
Yves Gerey665174f2018-06-19 13:03:0525 : buffer_(std::move(buf.buffer_)) {}
jbauch13041cf2016-02-25 14:16:5226
Jeroen de Borst4f6d2332018-07-18 18:25:1227CopyOnWriteBuffer::CopyOnWriteBuffer(const std::string& s)
28 : CopyOnWriteBuffer(s.data(), s.length()) {}
29
jbauch13041cf2016-02-25 14:16:5230CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size)
31 : buffer_(size > 0 ? new RefCountedObject<Buffer>(size) : nullptr) {
32 RTC_DCHECK(IsConsistent());
33}
34
35CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size, size_t capacity)
36 : buffer_(size > 0 || capacity > 0
Yves Gerey665174f2018-06-19 13:03:0537 ? new RefCountedObject<Buffer>(size, capacity)
38 : nullptr) {
jbauch13041cf2016-02-25 14:16:5239 RTC_DCHECK(IsConsistent());
40}
41
42CopyOnWriteBuffer::~CopyOnWriteBuffer() = default;
43
Danil Chapovalov3626d7e2016-09-14 15:14:3044bool CopyOnWriteBuffer::operator==(const CopyOnWriteBuffer& buf) const {
45 // Must either use the same buffer internally or have the same contents.
46 RTC_DCHECK(IsConsistent());
47 RTC_DCHECK(buf.IsConsistent());
48 return buffer_.get() == buf.buffer_.get() ||
Yves Gerey665174f2018-06-19 13:03:0549 (buffer_.get() && buf.buffer_.get() &&
50 *buffer_.get() == *buf.buffer_.get());
Danil Chapovalov3626d7e2016-09-14 15:14:3051}
52
53void CopyOnWriteBuffer::SetSize(size_t size) {
54 RTC_DCHECK(IsConsistent());
55 if (!buffer_) {
56 if (size > 0) {
57 buffer_ = new RefCountedObject<Buffer>(size);
58 }
59 RTC_DCHECK(IsConsistent());
60 return;
61 }
62
63 // Clone data if referenced.
64 if (!buffer_->HasOneRef()) {
Yves Gerey665174f2018-06-19 13:03:0565 buffer_ = new RefCountedObject<Buffer>(buffer_->data(),
66 std::min(buffer_->size(), size),
67 std::max(buffer_->capacity(), size));
Danil Chapovalov3626d7e2016-09-14 15:14:3068 }
69 buffer_->SetSize(size);
70 RTC_DCHECK(IsConsistent());
71}
72
73void CopyOnWriteBuffer::EnsureCapacity(size_t capacity) {
74 RTC_DCHECK(IsConsistent());
75 if (!buffer_) {
76 if (capacity > 0) {
77 buffer_ = new RefCountedObject<Buffer>(0, capacity);
78 }
79 RTC_DCHECK(IsConsistent());
80 return;
81 } else if (capacity <= buffer_->capacity()) {
82 return;
83 }
84
85 CloneDataIfReferenced(std::max(buffer_->capacity(), capacity));
86 buffer_->EnsureCapacity(capacity);
87 RTC_DCHECK(IsConsistent());
88}
89
90void CopyOnWriteBuffer::Clear() {
91 if (!buffer_)
92 return;
93
94 if (buffer_->HasOneRef()) {
95 buffer_->Clear();
96 } else {
97 buffer_ = new RefCountedObject<Buffer>(0, buffer_->capacity());
98 }
99 RTC_DCHECK(IsConsistent());
100}
101
102void CopyOnWriteBuffer::CloneDataIfReferenced(size_t new_capacity) {
103 if (buffer_->HasOneRef()) {
104 return;
105 }
106
107 buffer_ = new RefCountedObject<Buffer>(buffer_->data(), buffer_->size(),
Yves Gerey665174f2018-06-19 13:03:05108 new_capacity);
Danil Chapovalov3626d7e2016-09-14 15:14:30109 RTC_DCHECK(IsConsistent());
110}
111
jbauch13041cf2016-02-25 14:16:52112} // namespace rtc