mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Prefer std::optional
return types over output parameters
This commit is contained in:
parent
fe0785769e
commit
c6919e28fc
@ -29,6 +29,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Audio/Export.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
@ -68,12 +70,11 @@ public:
|
||||
/// during the whole lifetime of the reader.
|
||||
///
|
||||
/// \param stream Source stream to read from
|
||||
/// \param info Structure to fill with the properties of the loaded sound
|
||||
///
|
||||
/// \return True if the file was successfully opened
|
||||
/// \return Properties of the loaded sound if the file was successfully opened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] virtual bool open(InputStream& stream, Info& info) = 0;
|
||||
[[nodiscard]] virtual std::optional<Info> open(InputStream& stream) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current read position to the given sample offset
|
||||
@ -132,7 +133,7 @@ public:
|
||||
/// // return true if the reader can handle the format
|
||||
/// }
|
||||
///
|
||||
/// [[nodiscard]] bool open(sf::InputStream& stream, Info& info) override
|
||||
/// [[nodiscard]] std::optional<sf::SoundFileReader::Info> open(sf::InputStream& stream) override
|
||||
/// {
|
||||
/// // read the sound file header and fill the sound attributes
|
||||
/// // (channel count, sample count and sample rate)
|
||||
|
@ -81,8 +81,8 @@ bool InputSoundFile::openFromFile(const std::filesystem::path& filename)
|
||||
return false;
|
||||
|
||||
// Pass the stream to the reader
|
||||
SoundFileReader::Info info;
|
||||
if (!reader->open(*file, info))
|
||||
const auto info = reader->open(*file);
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
// Take ownership of successfully opened reader and stream
|
||||
@ -90,9 +90,9 @@ bool InputSoundFile::openFromFile(const std::filesystem::path& filename)
|
||||
m_stream = std::move(file);
|
||||
|
||||
// Retrieve the attributes of the open sound file
|
||||
m_sampleCount = info.sampleCount;
|
||||
m_channelCount = info.channelCount;
|
||||
m_sampleRate = info.sampleRate;
|
||||
m_sampleCount = info->sampleCount;
|
||||
m_channelCount = info->channelCount;
|
||||
m_sampleRate = info->sampleRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -116,8 +116,8 @@ bool InputSoundFile::openFromMemory(const void* data, std::size_t sizeInBytes)
|
||||
memory->open(data, sizeInBytes);
|
||||
|
||||
// Pass the stream to the reader
|
||||
SoundFileReader::Info info;
|
||||
if (!reader->open(*memory, info))
|
||||
const auto info = reader->open(*memory);
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
// Take ownership of successfully opened reader and stream
|
||||
@ -125,9 +125,9 @@ bool InputSoundFile::openFromMemory(const void* data, std::size_t sizeInBytes)
|
||||
m_stream = std::move(memory);
|
||||
|
||||
// Retrieve the attributes of the open sound file
|
||||
m_sampleCount = info.sampleCount;
|
||||
m_channelCount = info.channelCount;
|
||||
m_sampleRate = info.sampleRate;
|
||||
m_sampleCount = info->sampleCount;
|
||||
m_channelCount = info->channelCount;
|
||||
m_sampleRate = info->sampleRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -152,8 +152,8 @@ bool InputSoundFile::openFromStream(InputStream& stream)
|
||||
}
|
||||
|
||||
// Pass the stream to the reader
|
||||
SoundFileReader::Info info;
|
||||
if (!reader->open(stream, info))
|
||||
const auto info = reader->open(stream);
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
// Take ownership of reader and store a reference to the stream without taking ownership
|
||||
@ -161,9 +161,9 @@ bool InputSoundFile::openFromStream(InputStream& stream)
|
||||
m_stream = {&stream, false};
|
||||
|
||||
// Retrieve the attributes of the open sound file
|
||||
m_sampleCount = info.sampleCount;
|
||||
m_channelCount = info.channelCount;
|
||||
m_sampleRate = info.sampleRate;
|
||||
m_sampleCount = info->sampleCount;
|
||||
m_channelCount = info->channelCount;
|
||||
m_sampleRate = info->sampleRate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -227,14 +227,14 @@ bool SoundFileReaderFlac::check(InputStream& stream)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
|
||||
std::optional<SoundFileReader::Info> SoundFileReaderFlac::open(InputStream& stream)
|
||||
{
|
||||
// Create the decoder
|
||||
m_decoder.reset(FLAC__stream_decoder_new());
|
||||
if (!m_decoder)
|
||||
{
|
||||
err() << "Failed to open FLAC file (failed to allocate the decoder)" << std::endl;
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Initialize the decoder with our callbacks
|
||||
@ -255,13 +255,11 @@ bool SoundFileReaderFlac::open(InputStream& stream, Info& info)
|
||||
{
|
||||
m_decoder.reset();
|
||||
err() << "Failed to open FLAC file (failed to read metadata)" << std::endl;
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Retrieve the sound properties
|
||||
info = m_clientData.info; // was filled in the "metadata" callback
|
||||
|
||||
return true;
|
||||
return m_clientData.info; // was filled in the "metadata" callback
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,10 +57,11 @@ public:
|
||||
/// \brief Open a sound file for reading
|
||||
///
|
||||
/// \param stream Stream to open
|
||||
/// \param info Structure to fill with the attributes of the loaded sound
|
||||
///
|
||||
/// \return Properties of the loaded sound if the file was successfully opened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] bool open(sf::InputStream& stream, Info& info) override;
|
||||
[[nodiscard]] std::optional<Info> open(sf::InputStream& stream) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current read position to the given sample offset
|
||||
|
@ -118,7 +118,7 @@ SoundFileReaderMp3::~SoundFileReaderMp3()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderMp3::open(InputStream& stream, Info& info)
|
||||
std::optional<SoundFileReader::Info> SoundFileReaderMp3::open(InputStream& stream)
|
||||
{
|
||||
// Init IO callbacks
|
||||
m_io.read_data = &stream;
|
||||
@ -127,15 +127,16 @@ bool SoundFileReaderMp3::open(InputStream& stream, Info& info)
|
||||
// Init mp3 decoder
|
||||
mp3dec_ex_open_cb(&m_decoder, &m_io, MP3D_SEEK_TO_SAMPLE);
|
||||
if (!m_decoder.samples)
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Retrieve the music attributes
|
||||
Info info;
|
||||
info.channelCount = static_cast<unsigned int>(m_decoder.info.channels);
|
||||
info.sampleRate = static_cast<unsigned int>(m_decoder.info.hz);
|
||||
info.sampleCount = m_decoder.samples;
|
||||
|
||||
m_numSamples = info.sampleCount;
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,12 +86,11 @@ public:
|
||||
/// \brief Open a sound file for reading
|
||||
///
|
||||
/// \param stream Source stream to read from
|
||||
/// \param info Structure to fill with the properties of the loaded sound
|
||||
///
|
||||
/// \return True if the file was successfully opened
|
||||
/// \return Properties of the loaded sound if the file was successfully opened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] bool open(InputStream& stream, Info& info) override;
|
||||
[[nodiscard]] std::optional<Info> open(InputStream& stream) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current read position to the given sample offset
|
||||
|
@ -95,26 +95,27 @@ SoundFileReaderOgg::~SoundFileReaderOgg()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderOgg::open(InputStream& stream, Info& info)
|
||||
std::optional<SoundFileReader::Info> SoundFileReaderOgg::open(InputStream& stream)
|
||||
{
|
||||
// Open the Vorbis stream
|
||||
const int status = ov_open_callbacks(&stream, &m_vorbis, nullptr, 0, callbacks);
|
||||
if (status < 0)
|
||||
{
|
||||
err() << "Failed to open Vorbis file for reading" << std::endl;
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Retrieve the music attributes
|
||||
vorbis_info* vorbisInfo = ov_info(&m_vorbis, -1);
|
||||
info.channelCount = static_cast<unsigned int>(vorbisInfo->channels);
|
||||
info.sampleRate = static_cast<unsigned int>(vorbisInfo->rate);
|
||||
info.sampleCount = static_cast<std::size_t>(ov_pcm_total(&m_vorbis, -1) * vorbisInfo->channels);
|
||||
Info info;
|
||||
info.channelCount = static_cast<unsigned int>(vorbisInfo->channels);
|
||||
info.sampleRate = static_cast<unsigned int>(vorbisInfo->rate);
|
||||
info.sampleCount = static_cast<std::size_t>(ov_pcm_total(&m_vorbis, -1) * vorbisInfo->channels);
|
||||
|
||||
// We must keep the channel count for the seek function
|
||||
m_channelCount = info.channelCount;
|
||||
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,12 +61,11 @@ public:
|
||||
/// \brief Open a sound file for reading
|
||||
///
|
||||
/// \param stream Source stream to read from
|
||||
/// \param info Structure to fill with the properties of the loaded sound
|
||||
///
|
||||
/// \return True if the file was successfully opened
|
||||
/// \return Properties of the loaded sound if the file was successfully opened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] bool open(InputStream& stream, Info& info) override;
|
||||
[[nodiscard]] std::optional<Info> open(InputStream& stream) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current read position to the given sample offset
|
||||
|
@ -120,17 +120,15 @@ bool SoundFileReaderWav::check(InputStream& stream)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderWav::open(InputStream& stream, Info& info)
|
||||
std::optional<SoundFileReader::Info> SoundFileReaderWav::open(InputStream& stream)
|
||||
{
|
||||
m_stream = &stream;
|
||||
|
||||
if (!parseHeader(info))
|
||||
{
|
||||
const auto info = parseHeader();
|
||||
if (!info)
|
||||
err() << "Failed to open WAV sound file (invalid or unsupported file)" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
@ -213,7 +211,7 @@ std::uint64_t SoundFileReaderWav::read(std::int16_t* samples, std::uint64_t maxC
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
std::optional<SoundFileReader::Info> SoundFileReaderWav::parseHeader()
|
||||
{
|
||||
assert(m_stream && "Input stream cannot be null. Call SoundFileReaderWav::open() to initialize it.");
|
||||
|
||||
@ -222,9 +220,10 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
char mainChunk[mainChunkSize];
|
||||
if (static_cast<std::size_t>(m_stream->read(mainChunk, static_cast<std::int64_t>(sizeof(mainChunk)))) !=
|
||||
sizeof(mainChunk))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Parse all the sub-chunks
|
||||
Info info;
|
||||
bool dataChunkFound = false;
|
||||
while (!dataChunkFound)
|
||||
{
|
||||
@ -232,13 +231,13 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
char subChunkId[4];
|
||||
if (static_cast<std::size_t>(m_stream->read(subChunkId, static_cast<std::int64_t>(sizeof(subChunkId)))) !=
|
||||
sizeof(subChunkId))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
std::uint32_t subChunkSize = 0;
|
||||
if (!decode(*m_stream, subChunkSize))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
const std::int64_t subChunkStart = m_stream->tell();
|
||||
if (subChunkStart == -1)
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Check which chunk it is
|
||||
if ((subChunkId[0] == 'f') && (subChunkId[1] == 'm') && (subChunkId[2] == 't') && (subChunkId[3] == ' '))
|
||||
@ -248,41 +247,41 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
// Audio format
|
||||
std::uint16_t format = 0;
|
||||
if (!decode(*m_stream, format))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
if ((format != waveFormatPcm) && (format != waveFormatExtensible))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Channel count
|
||||
std::uint16_t channelCount = 0;
|
||||
if (!decode(*m_stream, channelCount))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
info.channelCount = channelCount;
|
||||
|
||||
// Sample rate
|
||||
std::uint32_t sampleRate = 0;
|
||||
if (!decode(*m_stream, sampleRate))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
info.sampleRate = sampleRate;
|
||||
|
||||
// Byte rate
|
||||
std::uint32_t byteRate = 0;
|
||||
if (!decode(*m_stream, byteRate))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Block align
|
||||
std::uint16_t blockAlign = 0;
|
||||
if (!decode(*m_stream, blockAlign))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Bits per sample
|
||||
std::uint16_t bitsPerSample = 0;
|
||||
if (!decode(*m_stream, bitsPerSample))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
if (bitsPerSample != 8 && bitsPerSample != 16 && bitsPerSample != 24 && bitsPerSample != 32)
|
||||
{
|
||||
err() << "Unsupported sample size: " << bitsPerSample
|
||||
<< " bit (Supported sample sizes are 8/16/24/32 bit)" << std::endl;
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
m_bytesPerSample = bitsPerSample / 8;
|
||||
|
||||
@ -291,28 +290,28 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
// Extension size
|
||||
std::uint16_t extensionSize = 0;
|
||||
if (!decode(*m_stream, extensionSize))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Valid bits per sample
|
||||
std::uint16_t validBitsPerSample = 0;
|
||||
if (!decode(*m_stream, validBitsPerSample))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Channel mask
|
||||
std::uint32_t channelMask = 0;
|
||||
if (!decode(*m_stream, channelMask))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
// Subformat
|
||||
char subformat[16];
|
||||
if (static_cast<std::size_t>(m_stream->read(subformat, static_cast<std::int64_t>(sizeof(subformat)))) !=
|
||||
sizeof(subformat))
|
||||
return false;
|
||||
return std::nullopt;
|
||||
|
||||
if (std::memcmp(subformat, waveSubformatPcm, sizeof(subformat)) != 0)
|
||||
{
|
||||
err() << "Unsupported format: extensible format with non-PCM subformat" << std::endl;
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (validBitsPerSample != bitsPerSample)
|
||||
@ -321,13 +320,13 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
<< " bits) and "
|
||||
"sample container size ("
|
||||
<< bitsPerSample << " bits) differ" << std::endl;
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip potential extra information
|
||||
if (m_stream->seek(subChunkStart + subChunkSize) == -1)
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
else if ((subChunkId[0] == 'd') && (subChunkId[1] == 'a') && (subChunkId[2] == 't') && (subChunkId[3] == 'a'))
|
||||
{
|
||||
@ -346,11 +345,11 @@ bool SoundFileReaderWav::parseHeader(Info& info)
|
||||
{
|
||||
// unknown chunk, skip it
|
||||
if (m_stream->seek(m_stream->tell() + subChunkSize) == -1)
|
||||
return false;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return info;
|
||||
}
|
||||
|
||||
} // namespace sf::priv
|
||||
|
@ -53,12 +53,11 @@ public:
|
||||
/// \brief Open a sound file for reading
|
||||
///
|
||||
/// \param stream Stream to open
|
||||
/// \param info Structure to fill with the attributes of the loaded sound
|
||||
///
|
||||
/// \return True if the file was successfully opened
|
||||
/// \return Properties of the loaded sound if the file was successfully opened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] bool open(sf::InputStream& stream, Info& info) override;
|
||||
[[nodiscard]] std::optional<Info> open(sf::InputStream& stream) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current read position to the given sample offset
|
||||
@ -95,7 +94,7 @@ private:
|
||||
/// \return True on success, false on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool parseHeader(Info& info);
|
||||
std::optional<Info> parseHeader();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
|
Loading…
Reference in New Issue
Block a user