I feel bad when I answer my question, but he bothered me for a while, and this is the solution I came across:
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; }
It works under the assumption that istream is never freed from SDLs (and that they live through operation). Only istream support is also supported, a separate function will be executed for ostream - I know that I can pass iostream, but this would not allow passing istream to the conversion function: /.
Any advice on bugs or updates is welcome.
source share