Reading SDL_RWops from std :: istream

I am very surprised that Google did not find a solution. I am looking for a solution that allows using SDL_RWops with std :: istream. SDL_RWops is an alternative mechanism for reading / writing data to SDL.

Any links to sites that solve the problem?

The obvious solution would be to pre-read enough data into memory and then use SDL_RWFromMem. However, this has the disadvantage that I need to know the file size in advance.

It seems that the problem can be somehow solved by "overriding" the SDL_RWops functions ...

+4
source share
2 answers

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.

+5
source

If you are trying to get the SDL_RWops structure from istream, you can do this by reading the entire istream in memory, and then using SDL_RWFromMem to get the structure to represent it.

The following is a brief example; Please note that this is not safe, as health checks are not performed. For example, if the file size is 0, access to the buffer [0] may throw an exception or assert in debug builds.

 // Open a bitmap std::ifstream bitmap("bitmap.bmp"); // Find the bitmap file 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 
+1
source

All Articles