WebServer — buffer

这段代码定义了一个 Buffer 类,用于处理数据的读写操作。

包含必要的头文件

#include <iostream>
#include <vector>
#include <string>

命名空间定义

namespace bre {

定义了一个名为 bre 的命名空间,以避免全局命名冲突。

Buffer 类定义

构造函数与析构函数

class Buffer {
public:
    explicit Buffer(int initBuffSize = 1024)
        : buffer(initBuffSize), readPos(0), writePos(0) 
    { }
    ~Buffer() = default;

构造函数初始化了 buffer 的大小,并将读写指针初始化为0。析构函数使用默认定义。

拷贝控制

    Buffer(const Buffer&) = delete;              
    Buffer& operator=(const Buffer&) = delete;  

这里禁止了类的拷贝构造和赋值操作,因为这个类管理着动态分配的资源。

移动语义支持

    Buffer(Buffer&& other) noexcept
        : buffer(std::move(other.buffer)),
        readPos(other.readPos),
        writePos(other.writePos) {
        other.readPos = 0;
        other.writePos = 0;
    }
    Buffer& operator=(Buffer&& other) noexcept {
        if (this != &other) {
            buffer = std::.move(other.buffer);
            readPos = other.readPos;
            writePos = other.writePos;
            other.readPos = 0;
            other.writePos = 0;
        }
        return *this;
    }

提供了移动构造函数和移动赋值运算符,使得对象在转移所有权时更加高效。

数据读写状态查询

    size_t WritableBytes() const {
        return buffer.size() - writePos;
    }
    size_t ReadableBytes() const {
        return writePos - readPos;
    }

返回可写和可读的字节数。

获取数据视图

    const char* Peek() const {
        return buffer.data() + readPos;
    }

提供一个指向当前可读数据起始位置的指针。

数据读取

    std::string Retrieve(size_t len);
    std::string RetrieveUntil(const std::string end);
    void Clear();
    std::string RetrieveAll();

这些方法用于从缓冲区中读取数据,或者清除所有数据。

数据追加

    void Append(const std::string& str);
    void Append(const void* data, size_t len);
    void Append(const Buffer& buff);
    void Append(const char* str, size_t len);

这些方法用于向缓冲区追加数据。

扩展缓冲区大小

private:
    void expandBuffer(size_t len);

当需要追加的数据长度超过剩余空间时,此方法会扩展缓冲区大小。重置空间或者重置Pos

私有成员变量

private:
    std::vector<char> buffer;
    size_t readPos;
    size_t writePos;

定义了缓冲区和读写指针。

完整代码

#ifndef buffer_H
#define buffer_H

#include <iostream>
#include <vector>
#include <string>

namespace bre {


class Buffer {
public:
    explicit Buffer(int initBuffSize = 1024)
        : buffer(initBuffSize), readPos(0), writePos(0) 
    { }

    ~Buffer() = default;

    Buffer(const Buffer&) = delete;              // 禁止拷贝构造
    Buffer& operator=(const Buffer&) = delete;   // 禁止拷贝赋值

    // 移动构造
    Buffer(Buffer&& other) noexcept
        : buffer(std::move(other.buffer)),
        readPos(other.readPos),
        writePos(other.writePos) {
        other.readPos = 0;
        other.writePos = 0;
    }

    // 移动赋值
    Buffer& operator=(Buffer&& other) noexcept {
        if (this != &other) {
            buffer = std::move(other.buffer);
            readPos = other.readPos;
            writePos = other.writePos;
            other.readPos = 0;
            other.writePos = 0;
        }
        return *this;
    }

    // 可写字节数
    size_t WritableBytes() const {
        return buffer.size() - writePos;
    }
    // 可读字节数
    size_t ReadableBytes() const {
        return writePos - readPos;
    }

    const char* Peek() const {
        return buffer.data() + readPos;
    }

    std::string Retrieve(size_t len) {
        if (len > ReadableBytes()) {
            throw std::out_of_range("Buffer::Retrieve: len is too large");
        }
        auto ret = std::string(Peek(), len);
        readPos += len;
        return ret;
    }

    std::string RetrieveUntil(const std::string end) {
        const std::size_t pos = std::string(Peek(), ReadableBytes()).find(end);
        if(pos == std::string::npos) {
            return "";
        }
        return Retrieve(pos + end.size());
    }

    void Clear() {
        readPos = writePos = 0;
    }

    std::string RetrieveAll() {
        std::string ret = std::string(Peek(), ReadableBytes());
        Clear();
        return ret;
    }

    void Append(const std::string& str) {
        Append(str.data(), str.size());
    }
    void Append(const void* data, size_t len) {
        Append(static_cast<const char*>(data), len);
    }
    void Append(const Buffer& buff) {
        Append(buff.Peek(), buff.ReadableBytes());
    }
    // 最终添加数据
    void Append(const char* str, size_t len) {
        if (WritableBytes() < len) {
            expandBuffer(len);
        }
        std::copy(str, str + len, buffer.data() + writePos);
        writePos += len;
    }

private:
    void expandBuffer(size_t len) {
        if (WritableBytes() + readPos < len) {
            // 重置缓冲区
            buffer.resize(writePos + len);
        } else {
            // 移动数据
            size_t readable = ReadableBytes();
            std::copy(buffer.data() + readPos, buffer.data() + writePos, buffer.data());
            readPos = 0;
            writePos = readPos + readable;
        }
    }

private:
    std::vector<char> buffer;
    size_t readPos;     // 读取偏移量
    size_t writePos;    // 写入偏移量
};


} // namespace bre
#endif // buffer_H

测试数据

#include <iostream>
#include <chrono>
#include <functional>
#include "Buffer.hpp"

class Test {
    std::chrono::time_point<std::chrono::system_clock> start;
    std::function<void()> callable;
public:
    Test(std::function<void()> func) : callable(func) {
        start = std::chrono::system_clock::now();
        if (callable) {
            callable();
        }
    }
    ~Test() {
        auto end = std::chrono::system_clock::now(); // 获取当前时间点
        std::chrono::duration<double, std::milli> d = end - start; // 计算时间差,并转换为毫秒
        std::cout << "Spend time: " << d.count() << "ms\n"; 
    }
};

void TestBuffer() {
    bre::Buffer buffer;

    // 测试初始状态
    std::cout << "Initial Writable Bytes: " << buffer.WritableBytes() << std::endl;
    std::cout << "Initial Readable Bytes: " << buffer.ReadableBytes() << std::endl;

    // 添加
    buffer.Append("Hello, ");
    char str[] = "World!";
    buffer.Append(str, 6);  // Buffer: Hello,World!

    // 获取
    std::cout << "获取: " << buffer.Retrieve(6) << std::endl;   // 获取“Hello,”  Buffer: World!
    // 寻找
    std::cout << "寻找: " << buffer.RetrieveUntil("o") << std::endl; // “Wo”    Buffer: rld!

    // 可读字符数和可写字符数
    std::cout << "Writable Bytes: " << buffer.WritableBytes() << std::endl;
    std::cout << "Readable Bytes: " << buffer.ReadableBytes() << std::endl;

    buffer.Append(str, 6);
    buffer.Retrieve(6);

    // 写入超过1024个字符
    for(int i = 0; i < 1000; ++i) {
        buffer.Append(str, 6);
    }
    buffer.Retrieve(5990);      // d!World!World! 从后往前14个字符剩下

    // 获取所有字符
    std::cout << "buffer.RetrieveAll(): " << buffer.RetrieveAll() <<"\n";

    // 清空
    buffer.Clear();

    // 测试清空后状态
    std::cout << "After Clear Writable Bytes: " << buffer.WritableBytes() << std::endl;
    std::cout << "After Clear Readable Bytes: " << buffer.ReadableBytes() << std::endl;
}

void TestPerformance() {
    bre::Buffer buffer;
    char str[] = "world!";
    for(int i = 0; i < 10000; ++i) {
        buffer.Append(str, 6);
        buffer.Retrieve(6);
    }
}
int main() {
    Test([]{TestBuffer();});
    Test([]{TestPerformance();});
    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
https://github.com/solstice23/argon-theme/