mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 14:21:04 +08:00
Use std::optional
rather than sentinel values
This commit is contained in:
parent
8acb9d9ab1
commit
de8430bb29
@ -931,9 +931,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::uint32_t> buffer(static_cast<std::size_t>(file.getSize()) / sizeof(std::uint32_t));
|
||||
const auto fileSize = file.getSize().value();
|
||||
std::vector<std::uint32_t> buffer(fileSize / sizeof(std::uint32_t));
|
||||
|
||||
if (file.read(buffer.data(), file.getSize()) != file.getSize())
|
||||
if (file.read(buffer.data(), fileSize) != file.getSize())
|
||||
{
|
||||
vulkanAvailable = false;
|
||||
return;
|
||||
@ -959,9 +960,10 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::uint32_t> buffer(static_cast<std::size_t>(file.getSize()) / sizeof(std::uint32_t));
|
||||
const auto fileSize = file.getSize().value();
|
||||
std::vector<std::uint32_t> buffer(fileSize / sizeof(std::uint32_t));
|
||||
|
||||
if (file.read(buffer.data(), file.getSize()) != file.getSize())
|
||||
if (file.read(buffer.data(), fileSize) != file.getSize())
|
||||
{
|
||||
vulkanAvailable = false;
|
||||
return;
|
||||
|
@ -111,36 +111,36 @@ public:
|
||||
/// \param data Buffer where to copy the read data
|
||||
/// \param size Desired number of bytes to read
|
||||
///
|
||||
/// \return The number of bytes actually read, or -1 on error
|
||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::int64_t read(void* data, std::int64_t size) override;
|
||||
[[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current reading position
|
||||
///
|
||||
/// \param position The position to seek to, from the beginning
|
||||
///
|
||||
/// \return The position actually sought to, or -1 on error
|
||||
/// \return The position actually sought to, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::int64_t seek(std::int64_t position) override;
|
||||
[[nodiscard]] std::optional<std::size_t> seek(std::size_t position) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current reading position in the stream
|
||||
///
|
||||
/// \return The current position, or -1 on error.
|
||||
/// \return The current position, or `std::nullopt` on error.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::int64_t tell() override;
|
||||
[[nodiscard]] std::optional<std::size_t> tell() override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the size of the stream
|
||||
///
|
||||
/// \return The total number of bytes available in the stream, or -1 on error
|
||||
/// \return The total number of bytes available in the stream, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t getSize() override;
|
||||
std::optional<std::size_t> getSize() override;
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#include <SFML/System/Export.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
@ -58,36 +60,36 @@ public:
|
||||
/// \param data Buffer where to copy the read data
|
||||
/// \param size Desired number of bytes to read
|
||||
///
|
||||
/// \return The number of bytes actually read, or -1 on error
|
||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] virtual std::int64_t read(void* data, std::int64_t size) = 0;
|
||||
[[nodiscard]] virtual std::optional<std::size_t> read(void* data, std::size_t size) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current reading position
|
||||
///
|
||||
/// \param position The position to seek to, from the beginning
|
||||
///
|
||||
/// \return The position actually sought to, or -1 on error
|
||||
/// \return The position actually sought to, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] virtual std::int64_t seek(std::int64_t position) = 0;
|
||||
[[nodiscard]] virtual std::optional<std::size_t> seek(std::size_t position) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current reading position in the stream
|
||||
///
|
||||
/// \return The current position, or -1 on error.
|
||||
/// \return The current position, or `std::nullopt` on error.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] virtual std::int64_t tell() = 0;
|
||||
[[nodiscard]] virtual std::optional<std::size_t> tell() = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the size of the stream
|
||||
///
|
||||
/// \return The total number of bytes available in the stream, or -1 on error
|
||||
/// \return The total number of bytes available in the stream, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual std::int64_t getSize() = 0;
|
||||
virtual std::optional<std::size_t> getSize() = 0;
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
@ -119,13 +121,13 @@ public:
|
||||
///
|
||||
/// [[nodiscard]] bool open(const std::filesystem::path& filename);
|
||||
///
|
||||
/// [[nodiscard]] std::int64_t read(void* data, std::int64_t size);
|
||||
/// [[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size);
|
||||
///
|
||||
/// [[nodiscard]] std::int64_t seek(std::int64_t position);
|
||||
/// [[nodiscard]] std::optional<std::size_t> seek(std::size_t position);
|
||||
///
|
||||
/// [[nodiscard]] std::int64_t tell();
|
||||
/// [[nodiscard]] std::optional<std::size_t> tell();
|
||||
///
|
||||
/// std::int64_t getSize();
|
||||
/// std::optional<std::size_t> getSize();
|
||||
///
|
||||
/// private:
|
||||
///
|
||||
|
@ -64,44 +64,44 @@ public:
|
||||
/// \param data Buffer where to copy the read data
|
||||
/// \param size Desired number of bytes to read
|
||||
///
|
||||
/// \return The number of bytes actually read, or -1 on error
|
||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::int64_t read(void* data, std::int64_t size) override;
|
||||
[[nodiscard]] std::optional<std::size_t> read(void* data, std::size_t size) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current reading position
|
||||
///
|
||||
/// \param position The position to seek to, from the beginning
|
||||
///
|
||||
/// \return The position actually sought to, or -1 on error
|
||||
/// \return The position actually sought to, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::int64_t seek(std::int64_t position) override;
|
||||
[[nodiscard]] std::optional<std::size_t> seek(std::size_t position) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current reading position in the stream
|
||||
///
|
||||
/// \return The current position, or -1 on error.
|
||||
/// \return The current position, or `std::nullopt` on error.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
[[nodiscard]] std::int64_t tell() override;
|
||||
[[nodiscard]] std::optional<std::size_t> tell() override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the size of the stream
|
||||
///
|
||||
/// \return The total number of bytes available in the stream, or -1 on error
|
||||
/// \return The total number of bytes available in the stream, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t getSize() override;
|
||||
std::optional<std::size_t> getSize() override;
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
const std::byte* m_data{}; //!< Pointer to the data in memory
|
||||
std::int64_t m_size{}; //!< Total size of the data
|
||||
std::int64_t m_offset{}; //!< Current reading position
|
||||
std::size_t m_size{}; //!< Total size of the data
|
||||
std::size_t m_offset{}; //!< Current reading position
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -213,7 +213,7 @@ void InputSoundFile::seek(std::uint64_t sampleOffset)
|
||||
////////////////////////////////////////////////////////////
|
||||
void InputSoundFile::seek(Time timeOffset)
|
||||
{
|
||||
seek(static_cast<std::uint64_t>(timeOffset.asSeconds() * static_cast<float>(m_sampleRate)) * m_channelMap.size());
|
||||
seek(static_cast<std::size_t>(timeOffset.asSeconds() * static_cast<float>(m_sampleRate)) * m_channelMap.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,7 +58,7 @@ std::unique_ptr<SoundFileReader> SoundFileFactory::createReaderFromFilename(cons
|
||||
// Test the filename in all the registered factories
|
||||
for (const auto& [fpCreate, fpCheck] : getReaderFactoryMap())
|
||||
{
|
||||
if (stream.seek(0) == -1)
|
||||
if (!stream.seek(0).has_value())
|
||||
{
|
||||
err() << "Failed to seek sound stream" << std::endl;
|
||||
return nullptr;
|
||||
@ -84,7 +84,7 @@ std::unique_ptr<SoundFileReader> SoundFileFactory::createReaderFromMemory(const
|
||||
// Test the stream for all the registered factories
|
||||
for (const auto& [fpCreate, fpCheck] : getReaderFactoryMap())
|
||||
{
|
||||
if (stream.seek(0) == -1)
|
||||
if (!stream.seek(0).has_value())
|
||||
{
|
||||
err() << "Failed to seek sound stream" << std::endl;
|
||||
return nullptr;
|
||||
@ -106,7 +106,7 @@ std::unique_ptr<SoundFileReader> SoundFileFactory::createReaderFromStream(InputS
|
||||
// Test the stream for all the registered factories
|
||||
for (const auto& [fpCreate, fpCheck] : getReaderFactoryMap())
|
||||
{
|
||||
if (stream.seek(0) == -1)
|
||||
if (!stream.seek(0).has_value())
|
||||
{
|
||||
err() << "Failed to seek sound stream" << std::endl;
|
||||
return nullptr;
|
||||
|
@ -44,15 +44,17 @@ FLAC__StreamDecoderReadStatus streamRead(const FLAC__StreamDecoder*, FLAC__byte
|
||||
{
|
||||
auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);
|
||||
|
||||
const std::int64_t count = data->stream->read(buffer, static_cast<std::int64_t>(*bytes));
|
||||
if (count > 0)
|
||||
if (const std::optional count = data->stream->read(buffer, *bytes))
|
||||
{
|
||||
*bytes = static_cast<std::size_t>(count);
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
}
|
||||
else if (count == 0)
|
||||
{
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
if (*count > 0)
|
||||
{
|
||||
*bytes = *count;
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -64,8 +66,7 @@ FLAC__StreamDecoderSeekStatus streamSeek(const FLAC__StreamDecoder*, FLAC__uint6
|
||||
{
|
||||
auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);
|
||||
|
||||
const std::int64_t position = data->stream->seek(static_cast<std::int64_t>(absoluteByteOffset));
|
||||
if (position >= 0)
|
||||
if (data->stream->seek(static_cast<std::size_t>(absoluteByteOffset)).has_value())
|
||||
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
|
||||
else
|
||||
return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
|
||||
@ -75,10 +76,9 @@ FLAC__StreamDecoderTellStatus streamTell(const FLAC__StreamDecoder*, FLAC__uint6
|
||||
{
|
||||
auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);
|
||||
|
||||
const std::int64_t position = data->stream->tell();
|
||||
if (position >= 0)
|
||||
if (const std::optional position = data->stream->tell())
|
||||
{
|
||||
*absoluteByteOffset = static_cast<FLAC__uint64>(position);
|
||||
*absoluteByteOffset = *position;
|
||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||
}
|
||||
else
|
||||
@ -91,10 +91,9 @@ FLAC__StreamDecoderLengthStatus streamLength(const FLAC__StreamDecoder*, FLAC__u
|
||||
{
|
||||
auto* data = static_cast<sf::priv::SoundFileReaderFlac::ClientData*>(clientData);
|
||||
|
||||
const std::int64_t count = data->stream->getSize();
|
||||
if (count >= 0)
|
||||
if (const std::optional count = data->stream->getSize())
|
||||
{
|
||||
*streamLength = static_cast<FLAC__uint64>(count);
|
||||
*streamLength = *count;
|
||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
|
||||
}
|
||||
else
|
||||
|
@ -68,14 +68,14 @@ namespace
|
||||
std::size_t readCallback(void* ptr, std::size_t size, void* data)
|
||||
{
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
return static_cast<std::size_t>(stream->read(ptr, static_cast<std::int64_t>(size)));
|
||||
return stream->read(ptr, size).value_or(-1);
|
||||
}
|
||||
|
||||
int seekCallback(std::uint64_t offset, void* data)
|
||||
{
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
const std::int64_t position = stream->seek(static_cast<std::int64_t>(offset));
|
||||
return position < 0 ? -1 : 0;
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
const std::optional position = stream->seek(static_cast<std::size_t>(offset));
|
||||
return position ? 0 : -1;
|
||||
}
|
||||
|
||||
bool hasValidId3Tag(const std::uint8_t* header)
|
||||
@ -92,7 +92,7 @@ bool SoundFileReaderMp3::check(InputStream& stream)
|
||||
{
|
||||
std::uint8_t header[10];
|
||||
|
||||
if (static_cast<std::size_t>(stream.read(header, static_cast<std::int64_t>(sizeof(header)))) < sizeof(header))
|
||||
if (stream.read(header, sizeof(header)) != sizeof(header))
|
||||
return false;
|
||||
|
||||
if (hasValidId3Tag(header))
|
||||
|
@ -41,29 +41,32 @@ namespace
|
||||
std::size_t read(void* ptr, std::size_t size, std::size_t nmemb, void* data)
|
||||
{
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
return static_cast<std::size_t>(stream->read(ptr, static_cast<std::int64_t>(size * nmemb)));
|
||||
return stream->read(ptr, size * nmemb).value_or(-1);
|
||||
}
|
||||
|
||||
int seek(void* data, ogg_int64_t offset, int whence)
|
||||
int seek(void* data, ogg_int64_t signedOffset, int whence)
|
||||
{
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
auto offset = static_cast<std::size_t>(signedOffset);
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
offset += stream->tell();
|
||||
offset += stream->tell().value();
|
||||
break;
|
||||
case SEEK_END:
|
||||
offset = stream->getSize() - offset;
|
||||
offset = stream->getSize().value() - offset;
|
||||
}
|
||||
return static_cast<int>(stream->seek(offset));
|
||||
const std::optional position = stream->seek(offset);
|
||||
return position ? static_cast<int>(*position) : -1;
|
||||
}
|
||||
|
||||
long tell(void* data)
|
||||
{
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
return static_cast<long>(stream->tell());
|
||||
auto* stream = static_cast<sf::InputStream*>(data);
|
||||
const std::optional position = stream->tell();
|
||||
return position ? static_cast<long>(*position) : -1;
|
||||
}
|
||||
|
||||
ov_callbacks callbacks = {&read, &seek, nullptr, &tell};
|
||||
|
@ -43,13 +43,13 @@ namespace
|
||||
{
|
||||
ma_result onRead(ma_decoder* decoder, void* buffer, size_t bytesToRead, size_t* bytesRead)
|
||||
{
|
||||
auto* stream = static_cast<sf::InputStream*>(decoder->pUserData);
|
||||
const auto count = stream->read(buffer, static_cast<std::int64_t>(bytesToRead));
|
||||
auto* stream = static_cast<sf::InputStream*>(decoder->pUserData);
|
||||
const std::optional count = stream->read(buffer, bytesToRead);
|
||||
|
||||
if (count < 0)
|
||||
if (!count.has_value())
|
||||
return MA_ERROR;
|
||||
|
||||
*bytesRead = static_cast<size_t>(count);
|
||||
*bytesRead = static_cast<std::size_t>(*count);
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
@ -61,19 +61,17 @@ ma_result onSeek(ma_decoder* decoder, ma_int64 byteOffset, ma_seek_origin origin
|
||||
{
|
||||
case ma_seek_origin_start:
|
||||
{
|
||||
if (stream->seek(byteOffset) < 0)
|
||||
if (!stream->seek(static_cast<std::size_t>(byteOffset)).has_value())
|
||||
return MA_ERROR;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
case ma_seek_origin_current:
|
||||
{
|
||||
const auto currentPosition = stream->tell();
|
||||
|
||||
if (currentPosition < 0)
|
||||
if (!stream->tell().has_value())
|
||||
return MA_ERROR;
|
||||
|
||||
if (stream->seek(stream->tell() + byteOffset) < 0)
|
||||
if (!stream->seek(stream->tell().value() + static_cast<std::size_t>(byteOffset)).has_value())
|
||||
return MA_ERROR;
|
||||
|
||||
return MA_SUCCESS;
|
||||
|
@ -55,13 +55,11 @@ namespace
|
||||
// FreeType callbacks that operate on a sf::InputStream
|
||||
unsigned long read(FT_Stream rec, unsigned long offset, unsigned char* buffer, unsigned long count)
|
||||
{
|
||||
const auto convertedOffset = static_cast<std::int64_t>(offset);
|
||||
auto* stream = static_cast<sf::InputStream*>(rec->descriptor.pointer);
|
||||
if (stream->seek(convertedOffset) == convertedOffset)
|
||||
auto* stream = static_cast<sf::InputStream*>(rec->descriptor.pointer);
|
||||
if (stream->seek(offset) == offset)
|
||||
{
|
||||
if (count > 0)
|
||||
return static_cast<unsigned long>(
|
||||
stream->read(reinterpret_cast<char*>(buffer), static_cast<std::int64_t>(count)));
|
||||
return static_cast<unsigned long>(stream->read(reinterpret_cast<char*>(buffer), count).value());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -244,7 +242,7 @@ std::optional<Font> Font::loadFromStream(InputStream& stream)
|
||||
}
|
||||
|
||||
// Make sure that the stream's reading position is at the beginning
|
||||
if (stream.seek(0) == -1)
|
||||
if (!stream.seek(0).has_value())
|
||||
{
|
||||
err() << "Failed to seek font stream" << std::endl;
|
||||
return std::nullopt;
|
||||
@ -252,7 +250,7 @@ std::optional<Font> Font::loadFromStream(InputStream& stream)
|
||||
|
||||
// Prepare a wrapper for our stream, that we'll pass to FreeType callbacks
|
||||
fontHandles->streamRec.base = nullptr;
|
||||
fontHandles->streamRec.size = static_cast<unsigned long>(stream.getSize());
|
||||
fontHandles->streamRec.size = static_cast<unsigned long>(stream.getSize().value());
|
||||
fontHandles->streamRec.pos = 0;
|
||||
fontHandles->streamRec.descriptor.pointer = &stream;
|
||||
fontHandles->streamRec.read = &read;
|
||||
|
@ -55,14 +55,15 @@ namespace
|
||||
// stb_image callbacks that operate on a sf::InputStream
|
||||
int read(void* user, char* data, int size)
|
||||
{
|
||||
auto& stream = *static_cast<sf::InputStream*>(user);
|
||||
return static_cast<int>(stream.read(data, size));
|
||||
auto& stream = *static_cast<sf::InputStream*>(user);
|
||||
const std::optional count = stream.read(data, static_cast<std::size_t>(size));
|
||||
return count ? static_cast<int>(*count) : -1;
|
||||
}
|
||||
|
||||
void skip(void* user, int size)
|
||||
{
|
||||
auto& stream = *static_cast<sf::InputStream*>(user);
|
||||
if (stream.seek(stream.tell() + size) == -1)
|
||||
if (!stream.seek(stream.tell().value() + static_cast<std::size_t>(size)).has_value())
|
||||
sf::err() << "Failed to seek image loader input stream" << std::endl;
|
||||
}
|
||||
|
||||
@ -233,7 +234,7 @@ std::optional<Image> Image::loadFromMemory(const void* data, std::size_t size)
|
||||
std::optional<Image> Image::loadFromStream(InputStream& stream)
|
||||
{
|
||||
// Make sure that the stream's reading position is at the beginning
|
||||
if (stream.seek(0) == -1)
|
||||
if (!stream.seek(0).has_value())
|
||||
{
|
||||
err() << "Failed to seek image stream" << std::endl;
|
||||
return std::nullopt;
|
||||
|
@ -104,20 +104,20 @@ bool getFileContents(const std::filesystem::path& filename, std::vector<char>& b
|
||||
// Read the contents of a stream into an array of char
|
||||
bool getStreamContents(sf::InputStream& stream, std::vector<char>& buffer)
|
||||
{
|
||||
bool success = false;
|
||||
const std::int64_t size = stream.getSize();
|
||||
if (size > 0)
|
||||
bool success = false;
|
||||
const std::optional size = stream.getSize();
|
||||
if (size > std::size_t{0})
|
||||
{
|
||||
buffer.resize(static_cast<std::size_t>(size));
|
||||
buffer.resize(*size);
|
||||
|
||||
if (stream.seek(0) == -1)
|
||||
if (!stream.seek(0).has_value())
|
||||
{
|
||||
sf::err() << "Failed to seek shader stream" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::int64_t read = stream.read(buffer.data(), size);
|
||||
success = (read == size);
|
||||
const std::optional read = stream.read(buffer.data(), *size);
|
||||
success = (read == size);
|
||||
}
|
||||
buffer.push_back('\0');
|
||||
return success;
|
||||
|
@ -41,62 +41,41 @@ ResourceStream::ResourceStream(const std::filesystem::path& filename)
|
||||
ActivityStates& states = getActivity();
|
||||
const std::lock_guard lock(states.mutex);
|
||||
m_file.reset(AAssetManager_open(states.activity->assetManager, filename.c_str(), AASSET_MODE_UNKNOWN));
|
||||
assert(m_file && "Failed to initialize ResourceStream file");
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t ResourceStream::read(void* data, std::int64_t size)
|
||||
std::optional<std::size_t> ResourceStream::read(void* data, std::size_t size)
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
return AAsset_read(m_file.get(), data, static_cast<std::size_t>(size));
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
const auto numBytesRead = AAsset_read(m_file.get(), data, size);
|
||||
if (numBytesRead < 0)
|
||||
return std::nullopt;
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t ResourceStream::seek(std::int64_t position)
|
||||
std::optional<std::size_t> ResourceStream::seek(std::size_t position)
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
return AAsset_seek(m_file.get(), static_cast<off_t>(position), SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
const auto newPosition = AAsset_seek(m_file.get(), static_cast<off_t>(position), SEEK_SET);
|
||||
if (newPosition < 0)
|
||||
return std::nullopt;
|
||||
return newPosition;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t ResourceStream::tell()
|
||||
std::optional<std::size_t> ResourceStream::tell()
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
return getSize() - AAsset_getRemainingLength(m_file.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return getSize().value() - static_cast<std::size_t>(AAsset_getRemainingLength(m_file.get()));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t ResourceStream::getSize()
|
||||
std::optional<std::size_t> ResourceStream::getSize()
|
||||
{
|
||||
if (m_file)
|
||||
{
|
||||
return AAsset_getLength(m_file.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return AAsset_getLength(m_file.get());
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,36 +60,36 @@ public:
|
||||
/// \param data Buffer where the asset data is copied
|
||||
/// \param size Number of bytes read
|
||||
///
|
||||
/// \return The number of bytes actually read, or -1 on error
|
||||
/// \return The number of bytes actually read, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t read(void* data, std::int64_t size) override;
|
||||
std::optional<std::size_t> read(void* data, std::size_t size) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the current reading position in the asset file
|
||||
///
|
||||
/// \param position The position to seek to, from the beginning
|
||||
///
|
||||
/// \return The position actually sought to, or -1 on error
|
||||
/// \return The position actually sought to, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t seek(std::int64_t position) override;
|
||||
std::optional<std::size_t> seek(std::size_t position) override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the current reading position in the asset file
|
||||
///
|
||||
/// \return The current position, or -1 on error.
|
||||
/// \return The current position, or `std::nullopt` on error.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t tell() override;
|
||||
std::optional<std::size_t> tell() override;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Return the size of the asset file
|
||||
///
|
||||
/// \return The total number of bytes available in the asset, or -1 on error
|
||||
/// \return The total number of bytes available in the asset, or `std::nullopt` on error
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t getSize() override;
|
||||
std::optional<std::size_t> getSize() override;
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -79,78 +79,79 @@ bool FileInputStream::open(const std::filesystem::path& filename)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t FileInputStream::read(void* data, std::int64_t size)
|
||||
std::optional<std::size_t> FileInputStream::read(void* data, std::size_t size)
|
||||
{
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
if (priv::getActivityStatesPtr() != nullptr)
|
||||
{
|
||||
if (!m_androidFile)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
return m_androidFile->read(data, size);
|
||||
}
|
||||
#endif
|
||||
if (!m_file)
|
||||
return -1;
|
||||
return static_cast<std::int64_t>(std::fread(data, 1, static_cast<std::size_t>(size), m_file.get()));
|
||||
return std::nullopt;
|
||||
return std::fread(data, 1, size, m_file.get());
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t FileInputStream::seek(std::int64_t position)
|
||||
std::optional<std::size_t> FileInputStream::seek(std::size_t position)
|
||||
{
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
if (priv::getActivityStatesPtr() != nullptr)
|
||||
{
|
||||
if (!m_androidFile)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
return m_androidFile->seek(position);
|
||||
}
|
||||
#endif
|
||||
if (!m_file)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
if (std::fseek(m_file.get(), static_cast<long>(position), SEEK_SET))
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
|
||||
return tell();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t FileInputStream::tell()
|
||||
std::optional<std::size_t> FileInputStream::tell()
|
||||
{
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
if (priv::getActivityStatesPtr() != nullptr)
|
||||
{
|
||||
if (!m_androidFile)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
return m_androidFile->tell();
|
||||
}
|
||||
#endif
|
||||
if (!m_file)
|
||||
return -1;
|
||||
return std::ftell(m_file.get());
|
||||
return std::nullopt;
|
||||
const auto position = std::ftell(m_file.get());
|
||||
return position < 0 ? std::nullopt : std::optional<std::size_t>(position);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t FileInputStream::getSize()
|
||||
std::optional<std::size_t> FileInputStream::getSize()
|
||||
{
|
||||
#ifdef SFML_SYSTEM_ANDROID
|
||||
if (priv::getActivityStatesPtr() != nullptr)
|
||||
{
|
||||
if (!m_androidFile)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
return m_androidFile->getSize();
|
||||
}
|
||||
#endif
|
||||
if (!m_file)
|
||||
return -1;
|
||||
const std::int64_t position = tell();
|
||||
return std::nullopt;
|
||||
const auto position = tell().value();
|
||||
std::fseek(m_file.get(), 0, SEEK_END);
|
||||
const std::int64_t size = tell();
|
||||
const std::optional size = tell();
|
||||
|
||||
if (seek(position) == -1)
|
||||
return -1;
|
||||
if (!seek(position).has_value())
|
||||
return std::nullopt;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
@ -27,6 +27,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/MemoryInputStream.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
|
||||
@ -36,20 +38,18 @@ namespace sf
|
||||
void MemoryInputStream::open(const void* data, std::size_t sizeInBytes)
|
||||
{
|
||||
m_data = static_cast<const std::byte*>(data);
|
||||
m_size = static_cast<std::int64_t>(sizeInBytes);
|
||||
m_size = sizeInBytes;
|
||||
m_offset = 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t MemoryInputStream::read(void* data, std::int64_t size)
|
||||
std::optional<std::size_t> MemoryInputStream::read(void* data, std::size_t size)
|
||||
{
|
||||
if (!m_data)
|
||||
return -1;
|
||||
|
||||
const std::int64_t endPosition = m_offset + size;
|
||||
const std::int64_t count = endPosition <= m_size ? size : m_size - m_offset;
|
||||
return std::nullopt;
|
||||
|
||||
const std::size_t count = std::min(size, m_size - m_offset);
|
||||
if (count > 0)
|
||||
{
|
||||
std::memcpy(data, m_data + m_offset, static_cast<std::size_t>(count));
|
||||
@ -61,10 +61,10 @@ std::int64_t MemoryInputStream::read(void* data, std::int64_t size)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t MemoryInputStream::seek(std::int64_t position)
|
||||
std::optional<std::size_t> MemoryInputStream::seek(std::size_t position)
|
||||
{
|
||||
if (!m_data)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
|
||||
m_offset = position < m_size ? position : m_size;
|
||||
return m_offset;
|
||||
@ -72,20 +72,20 @@ std::int64_t MemoryInputStream::seek(std::int64_t position)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t MemoryInputStream::tell()
|
||||
std::optional<std::size_t> MemoryInputStream::tell()
|
||||
{
|
||||
if (!m_data)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::int64_t MemoryInputStream::getSize()
|
||||
std::optional<std::size_t> MemoryInputStream::getSize()
|
||||
{
|
||||
if (!m_data)
|
||||
return -1;
|
||||
return std::nullopt;
|
||||
|
||||
return m_size;
|
||||
}
|
||||
|
@ -75,10 +75,10 @@ TEST_CASE("[System] sf::FileInputStream")
|
||||
SECTION("Default constructor")
|
||||
{
|
||||
sf::FileInputStream fileInputStream;
|
||||
CHECK(fileInputStream.read(nullptr, 0) == -1);
|
||||
CHECK(fileInputStream.seek(0) == -1);
|
||||
CHECK(fileInputStream.tell() == -1);
|
||||
CHECK(fileInputStream.getSize() == -1);
|
||||
CHECK(fileInputStream.read(nullptr, 0) == std::nullopt);
|
||||
CHECK(fileInputStream.seek(0) == std::nullopt);
|
||||
CHECK(fileInputStream.tell() == std::nullopt);
|
||||
CHECK(fileInputStream.getSize() == std::nullopt);
|
||||
}
|
||||
|
||||
const TemporaryFile temporaryFile("Hello world");
|
||||
|
@ -16,28 +16,73 @@ TEST_CASE("[System] sf::MemoryInputStream")
|
||||
STATIC_CHECK(std::is_nothrow_move_assignable_v<sf::MemoryInputStream>);
|
||||
}
|
||||
|
||||
SECTION("Empty stream")
|
||||
SECTION("Default constructor")
|
||||
{
|
||||
sf::MemoryInputStream mis;
|
||||
|
||||
CHECK(mis.read(nullptr, 0) == -1);
|
||||
CHECK(mis.seek(0) == -1);
|
||||
CHECK(mis.tell() == -1);
|
||||
CHECK(mis.getSize() == -1);
|
||||
sf::MemoryInputStream memoryInputStream;
|
||||
CHECK(memoryInputStream.read(nullptr, 0) == std::nullopt);
|
||||
CHECK(memoryInputStream.seek(0) == std::nullopt);
|
||||
CHECK(memoryInputStream.tell() == std::nullopt);
|
||||
CHECK(memoryInputStream.getSize() == std::nullopt);
|
||||
}
|
||||
|
||||
SECTION("Open memory stream")
|
||||
{
|
||||
using namespace std::literals::string_view_literals;
|
||||
constexpr auto memoryContents = "hello world"sv;
|
||||
sf::MemoryInputStream mis;
|
||||
mis.open(memoryContents.data(), sizeof(char) * memoryContents.size());
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
std::array<char, 32> buffer{};
|
||||
CHECK(mis.read(buffer.data(), 5) == 5);
|
||||
CHECK(std::string_view(buffer.data(), 5) == std::string_view(memoryContents.data(), 5));
|
||||
CHECK(mis.seek(10) == 10);
|
||||
CHECK(mis.tell() == 10);
|
||||
CHECK(mis.getSize() == 11);
|
||||
SECTION("open()")
|
||||
{
|
||||
sf::MemoryInputStream memoryInputStream;
|
||||
memoryInputStream.open(nullptr, 0);
|
||||
CHECK(memoryInputStream.tell() == std::nullopt);
|
||||
CHECK(memoryInputStream.getSize() == std::nullopt);
|
||||
|
||||
static constexpr auto input = "hello world"sv;
|
||||
memoryInputStream.open(input.data(), input.size());
|
||||
CHECK(memoryInputStream.tell().value() == 0);
|
||||
CHECK(memoryInputStream.getSize().value() == input.size());
|
||||
}
|
||||
|
||||
SECTION("read()")
|
||||
{
|
||||
static constexpr auto input = "hello world"sv;
|
||||
sf::MemoryInputStream memoryInputStream;
|
||||
memoryInputStream.open(input.data(), input.size());
|
||||
CHECK(memoryInputStream.tell().value() == 0);
|
||||
CHECK(memoryInputStream.getSize().value() == input.size());
|
||||
|
||||
// Read within input
|
||||
std::array<char, 32> output{};
|
||||
CHECK(memoryInputStream.read(output.data(), 5).value() == 5);
|
||||
CHECK(std::string_view(output.data(), 5) == "hello"sv);
|
||||
CHECK(memoryInputStream.tell().value() == 5);
|
||||
CHECK(memoryInputStream.getSize().value() == input.size());
|
||||
|
||||
// Read beyond input
|
||||
CHECK(memoryInputStream.read(output.data(), 100).value() == 6);
|
||||
CHECK(std::string_view(output.data(), 6) == " world"sv);
|
||||
CHECK(memoryInputStream.tell().value() == 11);
|
||||
CHECK(memoryInputStream.getSize().value() == input.size());
|
||||
}
|
||||
|
||||
SECTION("seek()")
|
||||
{
|
||||
static constexpr auto input = "We Love SFML!"sv;
|
||||
sf::MemoryInputStream memoryInputStream;
|
||||
memoryInputStream.open(input.data(), input.size());
|
||||
CHECK(memoryInputStream.tell().value() == 0);
|
||||
CHECK(memoryInputStream.getSize().value() == input.size());
|
||||
|
||||
SECTION("Seek within input")
|
||||
{
|
||||
CHECK(memoryInputStream.seek(0).value() == 0);
|
||||
CHECK(memoryInputStream.tell().value() == 0);
|
||||
|
||||
CHECK(memoryInputStream.seek(5).value() == 5);
|
||||
CHECK(memoryInputStream.tell().value() == 5);
|
||||
}
|
||||
|
||||
SECTION("Seek beyond input")
|
||||
{
|
||||
CHECK(memoryInputStream.seek(1'000).value() == input.size());
|
||||
CHECK(memoryInputStream.tell().value() == input.size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user