diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Buffer.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/common/Buffer.cpp b/src/common/Buffer.cpp index e69de29b..62904b17 100644 --- a/src/common/Buffer.cpp +++ b/src/common/Buffer.cpp @@ -0,0 +1,124 @@ +#include "cru/common/Buffer.h" +#include <cstring> +#include "cru/common/Exception.h" + +namespace cru { +namespace { +void CheckSize(Index size) { + if (size < 0) { + throw Exception(u"Size of buffer can't be smaller than 0."); + } +} +} // namespace + +Buffer::Buffer(Index size) { + CheckSize(size); + if (size == 0) { + ptr_ = nullptr; + size_ = used_size_ = 0; + } else { + ptr_ = new std::byte[size]; + size_ = size; + used_size_ = 0; + } +} + +Buffer::Buffer(const Buffer& other) { Copy_(other); } + +Buffer::Buffer(Buffer&& other) noexcept { Move_(std::move(other)); } + +Buffer& Buffer::operator=(const Buffer& other) { + if (this != &other) { + Delete_(); + Copy_(other); + } + return *this; +} + +Buffer& Buffer::operator=(Buffer&& other) noexcept { + if (this != &other) { + Delete_(); + Move_(std::move(other)); + } + return *this; +} + +Buffer::~Buffer() { Delete_(); } + +void Buffer::AssignBytes(Index dst_offset, std::byte* src, Index src_offset, + Index src_size) { + std::memcpy(ptr_ + dst_offset, src + src_offset, src_size); +} + +void Buffer::SetUsedSize(Index new_size) { used_size_ = new_size; } + +void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { + if (new_size == 0) { + Delete_(); + ptr_ = nullptr; + size_ = used_size_ = 0; + return; + } + + auto old_ptr = ptr_; + + ptr_ = new std::byte[new_size]; + size_ = new_size; + + if (old_ptr) { + if (preserve_used) { + auto copy_size = std::min(used_size_, new_size); + std::memcpy(ptr_, old_ptr, copy_size); + used_size_ = copy_size; + } + delete[] old_ptr; + } +} + +Index Buffer::PushEnd(std::byte* other, Index other_size) { + auto copy_size = std::min(GetRestSize(), other_size); + + if (copy_size) { + std::memcpy(GetUsedEndPtr(), other, copy_size); + used_size_ += copy_size; + } + + return copy_size; +} + +Index Buffer::PopEnd(Index size) { + if (used_size_ < size) { + used_size_ = 0; + return used_size_; + } else { + used_size_ -= size; + return size; + } +} + +void Buffer::Copy_(const Buffer& other) { + if (other.ptr_ == nullptr) { + ptr_ = nullptr; + size_ = used_size_ = 0; + } else { + ptr_ = new std::byte[other.size_]; + size_ = other.size_; + used_size_ = other.used_size_; + std::memcpy(ptr_, other.ptr_, used_size_); + } +} + +void Buffer::Move_(Buffer&& other) noexcept { + ptr_ = other.ptr_; + size_ = other.size_; + used_size_ = other.used_size_; + other.ptr_ = nullptr; + other.size_ = other.used_size_ = 0; +} + +void Buffer::Delete_() noexcept { + if (ptr_) { + delete[] ptr_; + } +} +} // namespace cru |