#include "BufferUtility.h" #include #include #include 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 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(writableAddress() - start)); return static_cast(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(end - readableAddress())); } } // namespace Amass