Question

Je suis assez surpris que Google n'a pas trouvé une solution. Je cherche une solution qui permet SDL_RWops à utiliser avec std :: istream. SDL_RWops est le mécanisme alternatif pour la lecture / écriture de données dans SDL.

Tous les liens vers des sites qui abordent le problème?

Une solution évidente serait de suffisamment de données pré-lecture à la mémoire puis utilisez SDL_RWFromMem. Cependant, qui a l'inconvénient que je avais besoin de connaître la taille du fichier au préalable.

On dirait que le problème pourrait être résolu en quelque sorte par « impérieuses » fonctions SDL_RWops ...

Était-ce utile?

La solution

Je me sens mal répondre à ma propre question, mais il me preocupied pendant un certain temps, et c'est la solution que je suis venu avec:

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;
}

Fonctionne sous les hypothèses des années IStream ne sont jamais libérés par SDL (et qu'ils vivent à travers l'opération). seulement un soutien istream est, une fonction distincte serait fait pour ostream - Je sais que je pourrais passer iostream, mais cela ne permettrait pas à faire passer un istream à la fonction de conversion:. /

Des conseils sur les erreurs ou les mises à jour bienvenue.

Autres conseils

Si vous essayez d'obtenir une struct SDL_RWops d'un istream, vous pouvez le faire en lisant l'ensemble istream en mémoire, puis en utilisant SDL_RWFromMem pour obtenir un struct pour le représenter.

Voici un exemple rapide; notez qu'il est dangereux, car aucun contrôle de santé d'esprit sont faits. Par exemple, si la taille du fichier est 0, tampon accès [0] peut lancer une exception ou affirmer dans debug.

// 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top