Kylin/Universal/BufferUtility.cpp
2023-07-25 10:40:14 +08:00

99 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "BufferUtility.h"
#include <cstring>
#include <filesystem>
#include <fstream>
namespace Amass {
const char CRLF[] = "\r\n";
const char CRLFCRLF[] = "\r\n\r\n";
Buffer::Buffer(size_t initialSize) : m_buffer(initialSize) {
}
void Buffer::swap(Buffer &buffer) {
m_buffer.swap(buffer.m_buffer);
std::swap(m_readerIndex, buffer.m_readerIndex);
std::swap(m_writerIndex, buffer.m_writerIndex);
}
int Buffer::lastError() {
return m_lastError;
}
void Buffer::append(const char *data, size_t len) {
if (writableBytes() < len + 1)
makeSpace(len + 1); // 剩下的可写空间如果小于需要的空间len+1则增加len+1长度个空间,[len+1]用来加上\0进行截断
std::memcpy(writableAddress(), data, len);
std::copy(data, data + len, writableAddress()); // 其实相当于把已有数据往前挪动
m_writerIndex += len;
// 当Buffer以readableAddress()开始直接作为字符串直接使用时,在此加上\0截断,否则随机会打印出writableAddress()后的内容
m_buffer[m_writerIndex] = '\0';
}
void Buffer::appendFileContent(const std::string_view &path) {
if (path.empty() || !std::filesystem::exists(path)) return;
std::ifstream ifs(path.data(), std::ifstream::binary);
char buffer[512];
while (ifs.read(buffer, sizeof(buffer))) {
append(buffer, ifs.gcount());
}
auto size = ifs.gcount();
if (size > 0) append(buffer, size);
}
void Buffer::makeSpace(size_t needSize) {
if ((writableBytes() + m_readerIndex) < needSize) { // 即使数据前移,空间还是不足
auto remainSize = readableBytes();
auto newSize = remainSize + needSize + 1024;
std::vector<char> newBuffer(newSize);
memcpy(newBuffer.data(), readableAddress(), remainSize);
m_buffer.swap(newBuffer);
m_readerIndex = 0;
m_writerIndex = remainSize;
} else { // 将数据前移,空间满足要求
auto remainSize = readableBytes();
auto dst = m_buffer.data();
auto src = readableAddress();
for (size_t i = 0; i < remainSize; i++) {
*dst++ = *src++;
}
m_readerIndex = 0;
m_writerIndex = remainSize;
}
}
const char *Buffer::findCRLF() const {
const char *crlf = std::search(readableAddress(), writableAddress(), CRLF, CRLF + 2);
return crlf == writableAddress() ? nullptr : crlf;
}
const char *Buffer::findCRLFCRLF() const {
auto crlf = std::search(readableAddress(), writableAddress(), CRLFCRLF, CRLFCRLF + 4);
return crlf == writableAddress() ? nullptr : crlf;
}
const char *Buffer::findEOL(const char *start) const {
if (start == nullptr) start = readableAddress();
if ((readableAddress() > start) || (start >= writableAddress())) return nullptr;
const void *eol = memchr(start, '\n', static_cast<size_t>(writableAddress() - start));
return static_cast<const char *>(eol);
}
bool Buffer::retrieve(size_t len) {
if (len > readableBytes()) return false;
if (len < readableBytes()) {
m_readerIndex += len;
} else {
retrieveAll();
}
return true;
}
bool Buffer::retrieveUntil(const char *end) {
if (((uint64_t)readableAddress() > (uint64_t)end) || ((uint64_t)end > (uint64_t)writableAddress())) return false;
return retrieve(static_cast<size_t>(end - readableAddress()));
}
} // namespace Amass