blob: 1434a2518d4f7a7432eeb51de290cff91c675db1 [file] [edit]
// Copyright 2026 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "pw_buf/buf.h"
#include "pw_allocator/allocator.h"
#include "pw_assert/assert.h"
#include "pw_assert/check.h"
namespace pw {
ConstBuf& ConstBuf::operator=(ConstBuf&& other) noexcept {
if (this != &other) {
reset();
MoveFrom(std::move(other));
}
return *this;
}
ConstBuf& ConstBuf::operator=(Buf&& other) noexcept {
if (this != &other.const_buf_) {
reset();
MoveFrom(std::move(other.const_buf_));
}
return *this;
}
void ConstBuf::reset() {
if (deallocator_ != nullptr && base_ != nullptr) {
deallocator_->Deallocate(base_);
}
base_ = nullptr;
view_ = {};
deallocator_ = nullptr;
}
void ConstBuf::MoveFrom(ConstBuf&& other) {
base_ = std::exchange(other.base_, nullptr);
view_ = std::exchange(other.view_, pw::span<std::byte>{});
deallocator_ = std::exchange(other.deallocator_, nullptr);
}
ConstBuf ConstBuf::Slice(size_t offset, size_t length) && {
PW_CHECK(offset <= view_.size());
PW_CHECK(length <= view_.size() - offset);
view_ = view_.subspan(offset, length);
return std::move(*this);
}
ConstBuf ConstBuf::Reclaim(size_t prefix_count, size_t suffix_count) && {
PW_CHECK(prefix_count <= static_cast<size_t>(view_.data() - base_));
view_ = pw::span<std::byte>(view_.data() - prefix_count,
view_.size() + prefix_count + suffix_count);
return std::move(*this);
}
Buf Buf::Allocate(Allocator& allocator, size_t offset, size_t size) {
size_t allocation_size = offset + size;
void* ptr =
allocator.Allocate(allocator::Layout::Of<std::byte[]>(allocation_size));
PW_ASSERT(ptr != nullptr);
std::byte* byte_ptr = static_cast<std::byte*>(ptr);
return Buf(byte_ptr, offset, size, allocator);
}
Buf Buf::TryAllocate(Allocator& allocator, size_t offset, size_t size) {
size_t allocation_size = offset + size;
void* ptr =
allocator.Allocate(allocator::Layout::Of<std::byte[]>(allocation_size));
if (ptr == nullptr) {
return Buf();
}
std::byte* byte_ptr = static_cast<std::byte*>(ptr);
return Buf(byte_ptr, offset, size, allocator);
}
} // namespace pw