diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 6b905fbac..59b2b5457 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -65,6 +65,7 @@ namespace Nz bool SetCursorPos(CursorPosition pos, Int64 offset = 0); bool SetCursorPos(UInt64 offset) override; bool SetFile(const String& filePath); + bool SetSize(UInt64 size); File& operator=(const String& filePath); File& operator=(const File&) = delete; diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index c03fb7b7f..8505e42f9 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -454,6 +454,25 @@ namespace Nz return true; } + /*! + * \brief Sets the size of the file + * \return true if the file size has correctly changed + * + * \param size The size the file should have after this call + * + * \remark The cursor position is not affected by this call + * \remark The file must be open in write mode + */ + bool File::SetSize(UInt64 size) + { + NazaraLock(m_mutex) + + NazaraAssert(IsOpen(), "File is not open"); + NazaraAssert(IsWritable(), "File is not writable"); + + return m_impl->SetSize(size); + } + /*! * \brief Sets the file path * \return A reference to this diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index 688b87c99..dcce3d29a 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -158,6 +159,31 @@ namespace Nz return SetFilePointerEx(m_handle, distance, nullptr, moveMethod) != 0; } + bool FileImpl::SetSize(UInt64 size) + { + UInt64 cursorPos = GetCursorPos(); + + CallOnExit resetCursor([this, cursorPos] () + { + if (!SetCursorPos(CursorPosition_AtBegin, cursorPos)) + NazaraWarning("Failed to reset cursor position to previous position: " + Error::GetLastSystemError()); + }); + + if (!SetCursorPos(CursorPosition_AtBegin, size)) + { + NazaraError("Failed to set file size: failed to move cursor position: " + Error::GetLastSystemError()); + return false; + } + + if (!SetEndOfFile(m_handle)) + { + NazaraError("Failed to set file size: " + Error::GetLastSystemError()); + return false; + } + + return true; + } + std::size_t FileImpl::Write(const void* buffer, std::size_t size) { DWORD written = 0; diff --git a/src/Nazara/Core/Win32/FileImpl.hpp b/src/Nazara/Core/Win32/FileImpl.hpp index 0f3745abc..9a669cb19 100644 --- a/src/Nazara/Core/Win32/FileImpl.hpp +++ b/src/Nazara/Core/Win32/FileImpl.hpp @@ -32,6 +32,7 @@ namespace Nz bool Open(const String& filePath, UInt32 mode); std::size_t Read(void* buffer, std::size_t size); bool SetCursorPos(CursorPosition pos, Int64 offset); + bool SetSize(UInt64 size); std::size_t Write(const void* buffer, std::size_t size); FileImpl& operator=(const FileImpl&) = delete;