diff --git a/include/SFML/System/FileInputStream.hpp b/include/SFML/System/FileInputStream.hpp index fb3faf74b..9b15263b9 100644 --- a/include/SFML/System/FileInputStream.hpp +++ b/include/SFML/System/FileInputStream.hpp @@ -36,13 +36,10 @@ #include #ifdef SFML_SYSTEM_ANDROID -namespace sf -{ -namespace priv +namespace sf::priv { class SFML_SYSTEM_API ResourceStream; } -} #endif @@ -79,6 +76,18 @@ public: //////////////////////////////////////////////////////////// FileInputStream& operator=(const FileInputStream&) = delete; + //////////////////////////////////////////////////////////// + /// \brief Move constructor + /// + //////////////////////////////////////////////////////////// + FileInputStream(FileInputStream&&); + + //////////////////////////////////////////////////////////// + /// \brief Move assignment + /// + //////////////////////////////////////////////////////////// + FileInputStream& operator=(FileInputStream&&); + //////////////////////////////////////////////////////////// /// \brief Open the stream from a file path /// diff --git a/include/SFML/System/SuspendAwareClock.hpp b/include/SFML/System/SuspendAwareClock.hpp index 2328ee582..aba879805 100644 --- a/include/SFML/System/SuspendAwareClock.hpp +++ b/include/SFML/System/SuspendAwareClock.hpp @@ -31,7 +31,6 @@ //////////////////////////////////////////////////////////// #include #include -#include namespace sf diff --git a/src/SFML/System/FileInputStream.cpp b/src/SFML/System/FileInputStream.cpp index 46c1a6c43..43434e12c 100644 --- a/src/SFML/System/FileInputStream.cpp +++ b/src/SFML/System/FileInputStream.cpp @@ -42,6 +42,7 @@ void FileInputStream::FileCloser::operator()(std::FILE* file) } #endif + //////////////////////////////////////////////////////////// FileInputStream::FileInputStream() = default; @@ -50,6 +51,14 @@ FileInputStream::FileInputStream() = default; FileInputStream::~FileInputStream() = default; +//////////////////////////////////////////////////////////// +FileInputStream::FileInputStream(FileInputStream&&) = default; + + +//////////////////////////////////////////////////////////// +FileInputStream& FileInputStream::operator=(FileInputStream&&) = default; + + //////////////////////////////////////////////////////////// bool FileInputStream::open(const std::string& filename) { diff --git a/src/SFML/System/Lock.cpp b/src/SFML/System/Lock.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a36f1e1c5..65ac2b736 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -8,6 +8,7 @@ target_compile_features(sfml-test-main PRIVATE cxx_std_17) # System is always built SET(SYSTEM_SRC + "${SRCROOT}/System/FileInputStream.cpp" "${SRCROOT}/System/Time.cpp" "${SRCROOT}/System/Vector2.cpp" "${SRCROOT}/System/Vector3.cpp" diff --git a/test/System/FileInputStream.cpp b/test/System/FileInputStream.cpp new file mode 100644 index 000000000..22f29f5f8 --- /dev/null +++ b/test/System/FileInputStream.cpp @@ -0,0 +1,42 @@ +#include +#include "SystemUtil.hpp" +#include +#include + +TEST_CASE("sf::FileInputStream class - [system]") +{ + SUBCASE("Empty stream") + { + sf::FileInputStream fis; + + CHECK(fis.read(nullptr, 0) == -1); + CHECK(fis.seek(0) == -1); + CHECK(fis.tell() == -1); + } + +// Work around GCC 8.x bug with ``. +#if !defined(__GNUC__) || (__GNUC__ >= 9) + SUBCASE("Temporary file stream") + { + const std::string fileContents = "hello world"; + + sf::Testing::TemporaryFile tmpFile(fileContents); + sf::FileInputStream fis; + + REQUIRE(fis.open(tmpFile.getPath())); + + char buffer[32]; + + CHECK(fis.read(buffer, 5) == 5); + CHECK(std::string_view(buffer, 5) == std::string_view(fileContents.c_str(), 5)); + + SUBCASE("Move semantics") + { + sf::FileInputStream fis2 = std::move(fis); + + CHECK(fis2.read(buffer, 6) == 6); + CHECK(std::string_view(buffer, 6) == std::string_view(fileContents.c_str() + 5, 6)); + } + } +#endif // !defined(__GNUC__) || (__GNUC__ >= 9) +} diff --git a/test/TestUtilities/SystemUtil.cpp b/test/TestUtilities/SystemUtil.cpp index 99819161d..7306e1a98 100644 --- a/test/TestUtilities/SystemUtil.cpp +++ b/test/TestUtilities/SystemUtil.cpp @@ -1,7 +1,16 @@ -// Note: No need to increase compile time by including TestUtilities/System.hpp +#include "SystemUtil.hpp" + #include #include + +// Work around GCC 8.x bug with ``. +#if !defined(__GNUC__) || (__GNUC__ >= 9) +#include +#endif // !defined(__GNUC__) || (__GNUC__ >= 9) + +#include #include +#include #include @@ -19,3 +28,45 @@ namespace sf return stream.str().c_str(); } } + +// Work around GCC 8.x bug with ``. +#if !defined(__GNUC__) || (__GNUC__ >= 9) +namespace sf::Testing +{ + static std::string getTemporaryFilePath() + { + static int counter = 0; + + std::ostringstream oss; + oss << "sfmltemp" << counter << ".tmp"; + ++counter; + + std::filesystem::path result; + result /= std::filesystem::temp_directory_path(); + result /= oss.str(); + + return result.string(); + } + + TemporaryFile::TemporaryFile(const std::string& contents) + : m_path(getTemporaryFilePath()) + { + std::ofstream ofs(m_path); + assert(ofs); + + ofs << contents; + assert(ofs); + } + + TemporaryFile::~TemporaryFile() + { + [[maybe_unused]] const bool removed = std::filesystem::remove(m_path); + assert(removed); + } + + const std::string& TemporaryFile::getPath() const + { + return m_path; + } +} +#endif // !defined(__GNUC__) || (__GNUC__ >= 9) diff --git a/test/TestUtilities/SystemUtil.hpp b/test/TestUtilities/SystemUtil.hpp index d4c06e0e8..c5eb989f4 100644 --- a/test/TestUtilities/SystemUtil.hpp +++ b/test/TestUtilities/SystemUtil.hpp @@ -11,6 +11,7 @@ #include #include #include +#include // String conversions for doctest framework namespace sf @@ -38,4 +39,30 @@ namespace sf } } +// Work around GCC 8.x bug with ``. +#if !defined(__GNUC__) || (__GNUC__ >= 9) +namespace sf::Testing +{ + class TemporaryFile + { + private: + std::string m_path; + + public: + // Create a temporary file with a randomly generated path, containing 'contents'. + TemporaryFile(const std::string& contents); + + // Close and delete the generated file. + ~TemporaryFile(); + + // Prevent copies. + TemporaryFile(const TemporaryFile&) = delete; + TemporaryFile& operator=(const TemporaryFile&) = delete; + + // Return the randomly generated path. + const std::string& getPath() const; + }; +} +#endif // !defined(__GNUC__) || (__GNUC__ >= 9) + #endif // SFML_TESTUTILITIES_SYSTEM_HPP