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来设置书写光标。
我创建了一个继承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来设置书写光标。