std::iostream 使用自定义缓冲区不允许我写

std::iostream with a custom buffer doesn't allow me to write

我创建了一个继承std::streambuf的新结构,在其中创建了我自己的缓冲区, 创建另一个继承 std::iostream 的结构,在这里使用我的第一个结构,在这里创建一些有用的 reading/writing 函数,但是写入不起作用。编写函数将缓冲区置于 badbit 状态。为什么会这样?

这是完整的结构代码:

#pragma once
constexpr size_t BUF_SIZE_DEFAULT = 512;
 
struct BufferStream : std::streambuf
{
private:
    char* _buf = 0;
    size_t _buflen = 0;
 
    void _bufresize(size_t len) {
        if (_buf)
            delete[] _buf;
 
        _buflen = len;
        _buf = new char[_buflen];
    }
 
public:
    BufferStream(const char* begin, size_t len) {
        _bufresize(len);
        std::memcpy(_buf, begin, len);
        this->setg(_buf, _buf, _buf + _buflen);
    }
 
    BufferStream(size_t len = BUF_SIZE_DEFAULT) {
        _bufresize(len);
        this->setg(_buf, _buf, _buf + _buflen);
    }
 
    inline char* Buffer() {
        return _buf;
    }
 
    inline size_t Size() {
        return _buflen;
    }
};
 
struct IOBufferStream : std::iostream
{
private:
    BufferStream _stream;
 
public:
    IOBufferStream(size_t len = BUF_SIZE_DEFAULT) : _stream(len), std::iostream(&_stream) { };
    IOBufferStream(const char* begin, size_t len) : _stream(begin, len), std::iostream(&_stream) { };
 
    inline char* Buffer() {
        return _stream.Buffer();
    }
 
    inline size_t Size() {
        return _stream.Size();
    }
 
    template <typename T>
    inline T Read() {
        T var;
       
        if (!this->read((char*)&var, sizeof(T)))
            throw std::out_of_range("Failed reading bytes! Maybe the buffer is too small.");
 
        return var;
    }
 
    template <typename T>
    inline std::vector<T> ReadArray(unsigned int len = 0) {
        len = len == 0 ? Read<unsigned int>() : len;
 
        std::vector<T> arr;
        arr.resize(len);
        if (!this->read((char*)arr.data(), len * sizeof(T)))
            throw std::out_of_range("Failed reading bytes! Maybe the buffer is too small.");
 
        return arr;
    }
 
    inline std::string ReadString(unsigned int len = 0) {
        len = len == 0 ? Read<unsigned int>() : len;
 
        std::string str;
        str.resize(len);
        if (!this->read((char*)str.c_str(), len))
            throw std::out_of_range("Failed reading bytes! Maybe the buffer is too small.");
 
        return str;
    }
 
    template <typename T>
    inline void Write(T var) {
        if (!this->write((const char*)&var, sizeof(T)))
            throw std::out_of_range("Failed writing bytes! Maybe the buffer is too small.");
    }
 
    template <typename T>
    inline void WriteArray(T* arr, unsigned int len, bool writelen = true) {
        if (writelen)
            Write<unsigned int>(len);
 
        if (!this->write((const char*)arr, len * sizeof(T)))
            throw std::out_of_range("Failed writing bytes! Maybe the buffer is too small.");
    }
 
    inline void WriteString(std::string str, unsigned int len, bool writelen = true) {
        if (writelen)
            Write<unsigned int>(len);
 
        if (!this->write(str.c_str(), len))
            throw std::out_of_range("Failed writing bytes! Maybe the buffer is too small.");
    }
};

他们的用法示例:

IOBufferStream stream;
stream.Write(0x12ABCDEFu);
stream.Write((short)0xABCD);
stream.Write((char)128);

IOBufferStream read(stream.Buffer(), stream.Size());
auto r1 = read.Read<unsigned int>();
auto r2 = read.Read<short>();
auto r3 = read.Read<char>();

感谢@AlanBirtles;

解决方法是调用setp和setg来设置书写光标。