我很惊讶谷歌没有找到解决方案。我正在寻找一种解决方案,允许将SDL_RWops与std::istream一起使用。SDL_RWops是在SDL中读取/写入数据的替代机制。
有没有处理这个问题的网站链接?
一个明显的解决方案是预先读取足够的数据到内存中,然后使用SDL_RWFromMem。但是,这样做的缺点是我需要预先知道文件大小。
似乎可以通过“覆盖”SDL_RWops函数来解决该问题...
我很惊讶谷歌没有找到解决方案。我正在寻找一种解决方案,允许将SDL_RWops与std::istream一起使用。SDL_RWops是在SDL中读取/写入数据的替代机制。
有没有处理这个问题的网站链接?
一个明显的解决方案是预先读取足够的数据到内存中,然后使用SDL_RWFromMem。但是,这样做的缺点是我需要预先知道文件大小。
似乎可以通过“覆盖”SDL_RWops函数来解决该问题...
我觉得回答自己的问题有点不好意思,但这个问题困扰了我一段时间,这是我想出的解决方案:
int istream_seek( struct SDL_RWops *context, int offset, int whence)
{
std::istream* stream = (std::istream*) context->hidden.unknown.data1;
if ( whence == SEEK_SET )
stream->seekg ( offset, std::ios::beg );
else if ( whence == SEEK_CUR )
stream->seekg ( offset, std::ios::cur );
else if ( whence == SEEK_END )
stream->seekg ( offset, std::ios::end );
return stream->fail() ? -1 : stream->tellg();
}
int istream_read(SDL_RWops *context, void *ptr, int size, int maxnum)
{
if ( size == 0 ) return -1;
std::istream* stream = (std::istream*) context->hidden.unknown.data1;
stream->read( (char*)ptr, size * maxnum );
return stream->bad() ? -1 : stream->gcount() / size;
}
int istream_close( SDL_RWops *context )
{
if ( context ) {
SDL_FreeRW( context );
}
return 0;
}
SDL_RWops *SDL_RWFromIStream( std::istream& stream )
{
SDL_RWops *rwops;
rwops = SDL_AllocRW();
if ( rwops != NULL )
{
rwops->seek = istream_seek;
rwops->read = istream_read;
rwops->write = NULL;
rwops->close = istream_close;
rwops->hidden.unknown.data1 = &stream;
}
return rwops;
}
本程序假设SDL不会释放istream,并且它们会在操作中一直存在。目前仅支持istream,对于ostream需要编写单独的函数。我知道可以传递iostream,但这不允许将istream传递到转换函数:/。
欢迎提供任何错误或升级的建议。
// Open a bitmap
std::ifstream bitmap("bitmap.bmp");
// Find the bitmap file's size
bitmap.seekg(0, std::ios_base::end);
std::istream::pos_tye fileSize = bitmap.tellg();
bitmap.seekg(0);
// Allocate a buffer to store the file in
std::vector<unsigned char> buffer(fileSize);
// Copy the istream into the buffer
std::copy(std::istreambuf_iterator<unsigned char>(bitmap), std::istreambuf_iterator<unsigned char>(), buffer.begin());
// Get an SDL_RWops struct for the file
SDL_RWops* rw = SDL_RWFromMem(&buffer[0], buffer.size());
// Do stuff with the SDL_RWops struct