#include "buffer.h"
#include "mem_copy.h"
#include "string.h"
#include "ymath.h"
#include <util/system/sys_alloc.h>
#include <util/system/sanitizers.h>
TBuffer::TBuffer(size_t len)
: Data_(nullptr)
, Len_(0)
, Pos_(0)
{
Reserve(len);
}
TBuffer::TBuffer(TBuffer&& b) noexcept
: Data_(nullptr)
, Len_(0)
, Pos_(0)
{
Swap(b);
}
TBuffer::TBuffer(const char* buf, size_t len)
: Data_(nullptr)
, Len_(0)
, Pos_(0)
{
Append(buf, len);
}
TBuffer& TBuffer::operator=(TBuffer&& b) noexcept {
y_deallocate(Data_);
Data_ = b.Data_;
Len_ = b.Len_;
Pos_ = b.Pos_;
b.Data_ = nullptr;
b.Len_ = 0;
b.Pos_ = 0;
return *this;
}
void TBuffer::Append(const char* buf, size_t len) {
if (len > Avail()) {
Reserve(Pos_ + len);
}
Y_ASSERT(len <= Avail());
MemCopy(Data() + Pos_, buf, len);
NSan::Unpoison(Data() + Pos_, len);
Pos_ += len;
Y_ASSERT(Pos_ <= Len_);
}
void TBuffer::Fill(char ch, size_t len) {
if (len > Avail()) {
Reserve(Pos_ + len);
}
Y_ASSERT(len <= Avail());
memset(Data() + Pos_, ch, len);
NSan::Unpoison(Data() + Pos_, len);
Pos_ += len;
Y_ASSERT(Pos_ <= Len_);
}
void TBuffer::DoReserve(size_t realLen) {
// FastClp2<T>(x) returns 0 on x from [Max<T>/2 + 2, Max<T>]
const size_t len = Max<size_t>(FastClp2(realLen), realLen);
Y_ASSERT(realLen > Len_);
Y_ASSERT(len >= realLen);
Realloc(len);
}
void TBuffer::Realloc(size_t len) {
Y_ASSERT(Pos_ <= len);
Data_ = (char*)y_reallocate(Data_, len);
Len_ = len;
}
TBuffer::~TBuffer() {
y_deallocate(Data_);
}
void TBuffer::AsString(TString& s) {
s.assign(Data(), Size());
Clear();
}