从std :: istream中读取SDL_RWops

Kor*_*icz 4 c++ sdl istream

我很惊讶Google没有找到解决方案.我正在寻找一种允许SDL_RWops与std :: istream一起使用的解决方案.SDL_RWops是在SDL中读/写数据的替代机制.

是否有指向解决问题的网站的链接?

一个明显的解决方案是预先读取足够的数据到内存,然后使用SDL_RWFromMem.但是,这有一个缺点,我需要事先知道文件大小.

似乎可以通过"覆盖"SDL_RWops函数以某种方式解决问题......

Kor*_*icz 5

我回答自己的问题感觉很糟糕,但是我已经花了好一些时间,这是我提出的解决方案:

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;
}
Run Code Online (Sandbox Code Playgroud)

在假设的情况下工作从未被SDL释放(并且他们通过操作生活).也只有istream支持,ostream会有一个单独的函数 - 我知道我可以传递iostream,但是这不允许将istream传递给转换函数:/.

有关错误或升级的任何提示都欢迎.

  • 使用rwops-> type你可以允许istream,ostream或iostream. (4认同)
  • 使用NULL作为写函数似乎很可怕.创建一个使用SDL_SetError并返回-1的函数可能更好. (3认同)