gpt4 book ai didi

c++ - 创建自定义 std::streambuf

转载 作者:行者123 更新时间:2023-11-30 05:42:04 28 4
gpt4 key购买 nike

我正在定义一个自定义 std::streambuf 类以用于文件 I/O。在这个类中,我正在重载函数 opencloseis_openxsgetnxsputn溢出下溢uflow。然后,我将此缓冲区插入到 std::ifstream 中,如下所示(同样的情况适用于 std::ofstream):

std::ifstream temp;
Filebuffer *buffer = new Filebuffer();
buffer->open(fileName.c_str(), std::ios_base::in | std::ios_base::binary);
temp.basic_ios<char>::rdbuf(buffer);

Filebuffer(我的自定义类)的实现如下:

std::streamsize
Filebuffer::xsputn(const char *s, std::streamsize n)
{
std::streamsize result = 0;

if(file && n)
{
for(;;)
{
size_t buffer_use = this->epptr() - this->pptr();

if(buffer_use > 0)
{
if(static_cast<int>(buffer_use) > n)
{
buffer_use = n;
}

std::char_traits<char>::copy(this->pptr(), s, buffer_use);

this->pbump(buffer_use);
result += buffer_use;
n -= buffer_use;

if(n == 0)
{
break;
}

s += buffer_use;
}

this->overflow(static_cast<int>(*s));
}
}

return result;
}

std::streamsize
Filebuffer::xsgetn(char *s, std::streamsize n)
{
std::streamsize result = 0;

if(file && n)
{
int ch; do
{
size_t buffer_use = this->egptr() - this->gptr();

if(buffer_use > 0)
{
if(static_cast<int>(buffer_use) > n)
{
buffer_use = n;
}

std::char_traits<char>::copy(s, this->gptr(), buffer_use);

this->gbump(buffer_use);
result += buffer_use;
n -= buffer_use;

if(n == 0)
{
break;
}

s += buffer_use;
}

ch = this->underflow();
} while(!(ch == std::char_traits<char>::eof()));
}

return result;
}

int
Filebuffer::underflow()
{
if(file)
{
nullify_put_area(); //clears write buffer

if(!buffer) //allocated in open()
{
int value = ungetc(fgetc(file), file);

if(value == EOF)
{
return std::char_traits<char>::eof();
}

return value;
}

char *begin = buffer;
char *end = buffer + bufferSize - 1; //bufferSize set to 4 KB
char *next = end;

if(this->gptr() < this->egptr())
{
size_t buffer_use = this->egptr() - this->gptr();

memmove(begin, next, buffer_use);
begin += buffer_use;
}

setg(begin, begin, begin);


size_t m = (bufferSize - 1 - (begin - this->eback()));

if(m > 0)
{
size_t status = fread(begin, 1, m, file);

if(status == 0)
{
return std::char_traits<char>::eof();
}

setg(this->eback(), this->gptr(), begin + status);
}

return static_cast<int>(*this->gptr());
}

return std::char_traits<char>::eof();
}

int
Filebuffer::uflow()
{
if(!file)
{
return std::char_traits<char>::eof();
}

int ch = underflow();

if(ch != std::char_traits<char>::eof())
{
if(buffer)
{
this->gbump(1);
}

else
{
fgetc(file);
}
}

return ch;
}

int
Filebuffer::overflow(int c)
{
if(!file)
{
return std::char_traits<char>::eof();
}

const char *begin = this->pbase();
char *next = this->pptr();

if(buffer)
{
setp(buffer, buffer + bufferSize - 1);
}

nullify_get_area(); //clears read buffer

char temp;
if(c == std::char_traits<char>::eof())
{
c = std::char_traits<char>::not_eof(std::char_traits<char>::eof());
}

else
{
if(!next)
{
begin = next = &temp;
}

assert(next == &temp || buffer <= next);
assert(next == &temp || next < buffer + bufferSize);
*next++ = static_cast<char>(c);
}

if(begin != next)
{
if(begin == &temp)
{
fputc(temp, file);
return c;
}

size_t n = next - begin;
size_t status = fwrite(begin, 1, n, file);

if(status != n)
{
return std::char_traits<char>::eof();
}

return c;
}

return std::char_traits<char>::eof();
}

不幸的是,每当我使用(例如)temp >> readVar; 时,它都不会使用我的任何重载函数 - 调用堆栈显示调用了 STL 原始实现 - 相反,只是读入垃圾。每this question ,我需要为 ofstream 定义 overflow(并且可能为 ifstream 定义 underflow),我已经完成了。我是否正确定义了 xsputnxsgetn?为什么我的重载函数没有被调用?

最佳答案

似乎尝试使用 std::ifstream 执行此操作将不起作用,我需要更改它 std::istream。进行此更改后,将调用重载函数并且一切正常。

关于c++ - 创建自定义 std::streambuf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30853370/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com