* Copyright (c) 2024 Huawei Technologies Co., Ltd.
* openUBMC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#include <mc/db/byte_buffer.h>
#include <algorithm>
namespace mc::db {
byte_buffer::byte_buffer() : m_size(0), m_capacity(64), m_using_bootstrap(true) {
}
void byte_buffer::reset() {
if (!m_using_bootstrap) {
m_buf.clear();
m_using_bootstrap = true;
}
m_size = 0;
m_capacity = 64;
}
void byte_buffer::grow(size_t n) {
grow_internal(n);
}
std::pair<size_t, bool> byte_buffer::try_grow_by_reslice(size_t n) {
size_t old_size = m_size;
if (n <= capacity() - m_size) {
return {old_size, true};
}
return {old_size, false};
}
size_t byte_buffer::len() const {
return m_size;
}
size_t byte_buffer::cap() const {
return capacity();
}
size_t byte_buffer::capacity() const {
return m_using_bootstrap ? 64 : m_capacity;
}
std::string_view byte_buffer::bytes() const {
if (m_using_bootstrap) {
return std::string_view(reinterpret_cast<const char*>(m_bootstrap), m_size);
}
return std::string_view(reinterpret_cast<const char*>(m_buf.data()), m_size);
}
const uint8_t* byte_buffer::data() const {
return m_using_bootstrap ? m_bootstrap : m_buf.data();
}
size_t byte_buffer::grow_internal(size_t n) {
size_t old_size = m_size;
size_t new_size = old_size + n;
if (m_using_bootstrap && new_size > 64) {
m_buf.reserve(new_size * 2);
m_buf.assign(m_bootstrap, m_bootstrap + old_size);
m_using_bootstrap = false;
m_capacity = m_buf.capacity();
} else if (!m_using_bootstrap && new_size > m_capacity) {
m_buf.reserve(new_size * 2);
m_capacity = m_buf.capacity();
}
if (m_using_bootstrap) {
m_size = new_size;
} else {
m_buf.resize(new_size);
m_size = m_buf.size();
}
return old_size;
}
void byte_buffer::truncate(size_t n) {
if (n >= m_size) {
return;
}
if (m_using_bootstrap) {
m_size = n;
} else {
m_buf.resize(n);
m_size = m_buf.size();
if (n <= 64) {
std::memcpy(m_bootstrap, m_buf.data(), n);
m_buf.clear();
m_using_bootstrap = true;
m_capacity = 64;
}
}
}
void byte_buffer::write(const uint8_t* p, size_t size) {
size_t old_size = grow_internal(size);
if (m_using_bootstrap) {
std::memcpy(m_bootstrap + old_size, p, size);
} else {
std::memcpy(m_buf.data() + old_size, p, size);
}
}
void byte_buffer::write(const std::vector<uint8_t>& p) {
write(p.data(), p.size());
}
void byte_buffer::write_byte(uint8_t c) {
size_t old_size = grow_internal(1);
if (m_using_bootstrap) {
m_bootstrap[old_size] = c;
} else {
m_buf[old_size] = c;
}
}
void byte_buffer::write_string(std::string_view v) {
write(reinterpret_cast<const uint8_t*>(v.data()), v.size());
}
void byte_buffer::write_uint16(uint16_t v) {
size_t old_size = grow_internal(2);
uint8_t* dest = m_using_bootstrap ? m_bootstrap + old_size : m_buf.data() + old_size;
dest[0] = static_cast<uint8_t>((v >> 8) & 0xFF);
dest[1] = static_cast<uint8_t>(v & 0xFF);
}
void byte_buffer::write_uint32(uint32_t v) {
size_t old_size = grow_internal(4);
uint8_t* dest = m_using_bootstrap ? m_bootstrap + old_size : m_buf.data() + old_size;
dest[0] = static_cast<uint8_t>((v >> 24) & 0xFF);
dest[1] = static_cast<uint8_t>((v >> 16) & 0xFF);
dest[2] = static_cast<uint8_t>((v >> 8) & 0xFF);
dest[3] = static_cast<uint8_t>(v & 0xFF);
}
void byte_buffer::write_uint64(uint64_t v) {
size_t old_size = grow_internal(8);
uint8_t* dest = m_using_bootstrap ? m_bootstrap + old_size : m_buf.data() + old_size;
dest[0] = static_cast<uint8_t>((v >> 56) & 0xFF);
dest[1] = static_cast<uint8_t>((v >> 48) & 0xFF);
dest[2] = static_cast<uint8_t>((v >> 40) & 0xFF);
dest[3] = static_cast<uint8_t>((v >> 32) & 0xFF);
dest[4] = static_cast<uint8_t>((v >> 24) & 0xFF);
dest[5] = static_cast<uint8_t>((v >> 16) & 0xFF);
dest[6] = static_cast<uint8_t>((v >> 8) & 0xFF);
dest[7] = static_cast<uint8_t>(v & 0xFF);
}
}