Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: loadFromStream() - read() exceeds file size  (Read 3495 times)

0 Members and 1 Guest are viewing this topic.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
loadFromStream() - read() exceeds file size
« on: April 28, 2012, 11:50:32 am »
When I load a sf::SoundBuffer or sf::Music through a stream, read() is passed a size which leads to reading past the end of the stream.

#include <SFML/Audio.hpp>
#include <fstream>
#include <iostream>

class MyStream : public sf::InputStream
{
        public:
                MyStream(const char* filename)
                : stream(filename, std::ios::in | std::ios::binary)
                {
                }

                virtual sf::Int64 read(void* data, sf::Int64 size)
                {
                        std::cout << "Begin      " << tell() << "\n";
                        std::cout << "End        " << tell() + size << "\n";
                        std::cout << "Total size " << getSize() << "\n\n";

                        stream.read(static_cast<char*>(data), size);
                        if (!stream)
                        {
                                std::cout << "FAIL\n";
                                std::exit(0);
                        }

                        return stream.gcount();
                }

                virtual sf::Int64 seek(sf::Int64 position)
                {
                        stream.seekg(position);
                        return tell();
                }

                virtual sf::Int64 tell()
                {
                        return stream.tellg();
                }

                virtual sf::Int64 getSize()
                {
                        sf::Int64 backup = tell();
                        stream.seekg(0, std::ios::end);

                        sf::Int64 size = tell();
                        seek(backup);

                        return size;
                }

        private:
                std::ifstream stream;
};

int main()
{
        MyStream stream("Music.ogg");

        sf::SoundBuffer buffer;
        bool success = buffer.loadFromStream(stream);

        sf::Sound sound(buffer);
        sound.play();
        sf::sleep(buffer.getDuration());
}
success is false in some cases (for wav, it seemed to work), but there is no SFML error output on the console.

Instead of size, one can write std::min(size, getSize() - tell()), but I suggest to handle this on SFML side if possible. I don't know however how well you can influence the low-level library callbacks, maybe this is given.

In case you cannot reproduce the problem, I'll upload an OGG file.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: loadFromStream() - read() exceeds file size
« Reply #1 on: April 28, 2012, 12:21:22 pm »
You should rather open an issue in the tracker, otherwise I'll forget it :)
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: loadFromStream() - read() exceeds file size
« Reply #3 on: April 29, 2012, 04:25:41 pm »
Hey, another question: Are read() accesses of sf::Music concurrent?

I have an archive from which I load different resources on demand through sf::InputStream, and at the same time a music is playing (also streaming from that same archive). The archive accesses aren't threadsafe.

Some resources fail to load without an error message, and I couldn't reproduce the behavior. Really annoying bug, but it would make sense now...
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: loadFromStream() - read() exceeds file size
« Reply #4 on: April 29, 2012, 04:33:22 pm »
Yep, sf::Music calls read in its own thread.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: loadFromStream() - read() exceeds file size
« Reply #5 on: April 29, 2012, 05:37:13 pm »
Okay, thank you.

Can you add an advice concerning race conditions to the sf::Music::loadFromStream() function and maybe also to sf::InputStream? Archives are probably the main use case of sf::InputStream, but one doesn't immediately think about the threading implications of having a single archive file from which multiple resources are read.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: loadFromStream() - read() exceeds file size
« Reply #6 on: April 29, 2012, 07:27:36 pm »
Sure :)
Laurent Gomila - SFML developer