2016-02-25 06:16:52 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright 2016 The WebRTC Project Authors. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "rtc_base/copy_on_write_buffer.h"
|
2016-02-25 06:16:52 -08:00
|
|
|
|
2018-10-23 12:03:01 +02:00
|
|
|
#include <stddef.h>
|
|
|
|
|
|
2022-05-09 13:33:36 +02:00
|
|
|
#include "absl/strings/string_view.h"
|
|
|
|
|
|
2025-02-07 13:24:05 +00:00
|
|
|
namespace webrtc {
|
2016-02-25 06:16:52 -08:00
|
|
|
|
2019-09-25 14:37:10 +02:00
|
|
|
CopyOnWriteBuffer::CopyOnWriteBuffer() : offset_(0), size_(0) {
|
2016-02-25 06:16:52 -08:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CopyOnWriteBuffer::CopyOnWriteBuffer(const CopyOnWriteBuffer& buf)
|
2019-09-25 14:37:10 +02:00
|
|
|
: buffer_(buf.buffer_), offset_(buf.offset_), size_(buf.size_) {}
|
2016-02-25 06:16:52 -08:00
|
|
|
|
2023-07-06 11:06:36 +02:00
|
|
|
CopyOnWriteBuffer::CopyOnWriteBuffer(CopyOnWriteBuffer&& buf) noexcept
|
2019-09-25 14:37:10 +02:00
|
|
|
: buffer_(std::move(buf.buffer_)), offset_(buf.offset_), size_(buf.size_) {
|
|
|
|
|
buf.offset_ = 0;
|
|
|
|
|
buf.size_ = 0;
|
|
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
2016-02-25 06:16:52 -08:00
|
|
|
|
2022-05-09 13:33:36 +02:00
|
|
|
CopyOnWriteBuffer::CopyOnWriteBuffer(absl::string_view s)
|
2018-07-18 11:25:12 -07:00
|
|
|
: CopyOnWriteBuffer(s.data(), s.length()) {}
|
|
|
|
|
|
2016-02-25 06:16:52 -08:00
|
|
|
CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size)
|
2021-01-22 16:11:10 +01:00
|
|
|
: buffer_(size > 0 ? new RefCountedBuffer(size) : nullptr),
|
2019-09-25 14:37:10 +02:00
|
|
|
offset_(0),
|
|
|
|
|
size_(size) {
|
2016-02-25 06:16:52 -08:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size, size_t capacity)
|
2021-01-22 16:11:10 +01:00
|
|
|
: buffer_(size > 0 || capacity > 0 ? new RefCountedBuffer(size, capacity)
|
|
|
|
|
: nullptr),
|
2019-09-25 14:37:10 +02:00
|
|
|
offset_(0),
|
|
|
|
|
size_(size) {
|
2016-02-25 06:16:52 -08:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CopyOnWriteBuffer::~CopyOnWriteBuffer() = default;
|
|
|
|
|
|
2016-09-14 17:14:30 +02:00
|
|
|
bool CopyOnWriteBuffer::operator==(const CopyOnWriteBuffer& buf) const {
|
2019-09-25 14:37:10 +02:00
|
|
|
// Must either be the same view of the same buffer or have the same contents.
|
2016-09-14 17:14:30 +02:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
RTC_DCHECK(buf.IsConsistent());
|
2019-09-25 14:37:10 +02:00
|
|
|
return size_ == buf.size_ &&
|
|
|
|
|
(cdata() == buf.cdata() || memcmp(cdata(), buf.cdata(), size_) == 0);
|
2016-09-14 17:14:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyOnWriteBuffer::SetSize(size_t size) {
|
|
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
if (!buffer_) {
|
|
|
|
|
if (size > 0) {
|
2021-01-22 16:11:10 +01:00
|
|
|
buffer_ = new RefCountedBuffer(size);
|
2019-09-25 14:37:10 +02:00
|
|
|
offset_ = 0;
|
|
|
|
|
size_ = size;
|
2016-09-14 17:14:30 +02:00
|
|
|
}
|
|
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-25 14:37:10 +02:00
|
|
|
if (size <= size_) {
|
|
|
|
|
size_ = size;
|
|
|
|
|
return;
|
2016-09-14 17:14:30 +02:00
|
|
|
}
|
2019-09-25 14:37:10 +02:00
|
|
|
|
|
|
|
|
UnshareAndEnsureCapacity(std::max(capacity(), size));
|
|
|
|
|
buffer_->SetSize(size + offset_);
|
|
|
|
|
size_ = size;
|
2016-09-14 17:14:30 +02:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-25 14:37:10 +02:00
|
|
|
void CopyOnWriteBuffer::EnsureCapacity(size_t new_capacity) {
|
2016-09-14 17:14:30 +02:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
if (!buffer_) {
|
2019-09-25 14:37:10 +02:00
|
|
|
if (new_capacity > 0) {
|
2021-01-22 16:11:10 +01:00
|
|
|
buffer_ = new RefCountedBuffer(0, new_capacity);
|
2019-09-25 14:37:10 +02:00
|
|
|
offset_ = 0;
|
|
|
|
|
size_ = 0;
|
2016-09-14 17:14:30 +02:00
|
|
|
}
|
|
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
return;
|
2019-09-25 14:37:10 +02:00
|
|
|
} else if (new_capacity <= capacity()) {
|
2016-09-14 17:14:30 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-25 14:37:10 +02:00
|
|
|
UnshareAndEnsureCapacity(new_capacity);
|
2016-09-14 17:14:30 +02:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CopyOnWriteBuffer::Clear() {
|
|
|
|
|
if (!buffer_)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (buffer_->HasOneRef()) {
|
|
|
|
|
buffer_->Clear();
|
|
|
|
|
} else {
|
2021-01-22 16:11:10 +01:00
|
|
|
buffer_ = new RefCountedBuffer(0, capacity());
|
2016-09-14 17:14:30 +02:00
|
|
|
}
|
2019-09-25 14:37:10 +02:00
|
|
|
offset_ = 0;
|
|
|
|
|
size_ = 0;
|
2016-09-14 17:14:30 +02:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-25 14:37:10 +02:00
|
|
|
void CopyOnWriteBuffer::UnshareAndEnsureCapacity(size_t new_capacity) {
|
|
|
|
|
if (buffer_->HasOneRef() && new_capacity <= capacity()) {
|
2016-09-14 17:14:30 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-22 16:11:10 +01:00
|
|
|
buffer_ =
|
|
|
|
|
new RefCountedBuffer(buffer_->data() + offset_, size_, new_capacity);
|
2019-09-25 14:37:10 +02:00
|
|
|
offset_ = 0;
|
2016-09-14 17:14:30 +02:00
|
|
|
RTC_DCHECK(IsConsistent());
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-07 13:24:05 +00:00
|
|
|
} // namespace webrtc
|