First commit
This commit is contained in:
42
src/Nazara/Core/Win32/ClockImpl.cpp
Normal file
42
src/Nazara/Core/Win32/ClockImpl.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/ClockImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
LARGE_INTEGER frequency; // La fréquence ne varie pas pas au cours de l'exécution
|
||||
}
|
||||
|
||||
bool NzClockImplInitializeHighPrecision()
|
||||
{
|
||||
return QueryPerformanceFrequency(&frequency) != 0;
|
||||
}
|
||||
|
||||
nzUInt64 NzClockImplGetMicroseconds()
|
||||
{
|
||||
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
|
||||
HANDLE thread = GetCurrentThread();
|
||||
DWORD oldMask = SetThreadAffinityMask(thread, 1);
|
||||
|
||||
LARGE_INTEGER time;
|
||||
QueryPerformanceCounter(&time);
|
||||
|
||||
SetThreadAffinityMask(thread, oldMask);
|
||||
|
||||
return time.QuadPart * 1000000ULL / frequency.QuadPart;
|
||||
}
|
||||
|
||||
nzUInt64 NzClockImplGetMilliseconds()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWS_VISTA
|
||||
return GetTickCount64();
|
||||
#else
|
||||
return GetTickCount();
|
||||
#endif
|
||||
}
|
||||
16
src/Nazara/Core/Win32/ClockImpl.hpp
Normal file
16
src/Nazara/Core/Win32/ClockImpl.hpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_CLOCKIMPL_WINDOWS_HPP
|
||||
#define NAZARA_CLOCKIMPL_WINDOWS_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
|
||||
bool NzClockImplInitializeHighPrecision();
|
||||
nzUInt64 NzClockImplGetMicroseconds();
|
||||
nzUInt64 NzClockImplGetMilliseconds();
|
||||
|
||||
#endif // NAZARA_CLOCKIMPL_WINDOWS_HPP
|
||||
137
src/Nazara/Core/Win32/DirectoryImpl.cpp
Normal file
137
src/Nazara/Core/Win32/DirectoryImpl.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/DirectoryImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzDirectoryImpl::NzDirectoryImpl(const NzDirectory* parent)
|
||||
{
|
||||
NazaraUnused(parent);
|
||||
}
|
||||
|
||||
NzDirectoryImpl::~NzDirectoryImpl()
|
||||
{
|
||||
}
|
||||
|
||||
void NzDirectoryImpl::Close()
|
||||
{
|
||||
FindClose(m_handle);
|
||||
}
|
||||
|
||||
NzString NzDirectoryImpl::GetResultName() const
|
||||
{
|
||||
return NzString::Unicode(m_result.cFileName);
|
||||
}
|
||||
|
||||
nzUInt64 NzDirectoryImpl::GetResultSize() const
|
||||
{
|
||||
LARGE_INTEGER size;
|
||||
size.HighPart = m_result.nFileSizeHigh;
|
||||
size.LowPart = m_result.nFileSizeLow;
|
||||
|
||||
return size.QuadPart;
|
||||
}
|
||||
|
||||
bool NzDirectoryImpl::IsResultDirectory() const
|
||||
{
|
||||
if (m_result.dwFileAttributes != INVALID_FILE_ATTRIBUTES)
|
||||
return (m_result.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NzDirectoryImpl::NextResult()
|
||||
{
|
||||
if (m_firstCall) // Nous devons ignorer le premier appel car FindFirstFile nous a déjà renvoyé des résultats
|
||||
{
|
||||
m_firstCall = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FindNextFileW(m_handle, &m_result))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
if (GetLastError() != ERROR_NO_MORE_FILES)
|
||||
NazaraError("Unable to get next result: " + NzGetLastSystemError());
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzDirectoryImpl::Open(const NzString& dirPath)
|
||||
{
|
||||
NzString searchPath = dirPath + "\\*";
|
||||
wchar_t* path = searchPath.GetWideBuffer();
|
||||
m_handle = FindFirstFileW(path, &m_result);
|
||||
delete[] path;
|
||||
|
||||
if (m_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
NazaraError("Unable to open directory: " + NzGetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_firstCall = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzDirectoryImpl::Create(const NzString& dirPath)
|
||||
{
|
||||
wchar_t* path = dirPath.GetWideBuffer();
|
||||
bool success = CreateDirectoryW(path, nullptr) != 0;
|
||||
delete[] path;
|
||||
|
||||
return success || GetLastError() == ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
bool NzDirectoryImpl::Exists(const NzString& dirPath)
|
||||
{
|
||||
wchar_t* path = dirPath.GetWideBuffer();
|
||||
DWORD attributes = GetFileAttributesW(path);
|
||||
delete[] path;
|
||||
|
||||
if (attributes != INVALID_FILE_ATTRIBUTES)
|
||||
return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
NzString NzDirectoryImpl::GetCurrent()
|
||||
{
|
||||
NzString currentPath;
|
||||
wchar_t* path = new wchar_t[MAX_PATH];
|
||||
|
||||
unsigned int size = GetCurrentDirectoryW(MAX_PATH, path);
|
||||
if (size > MAX_PATH) // La taille prends en compte le caractère nul
|
||||
{
|
||||
delete[] path;
|
||||
|
||||
path = new wchar_t[size];
|
||||
if (GetCurrentDirectoryW(size, path) == 0)
|
||||
NazaraError("Unable to get current directory: " + NzGetLastSystemError());
|
||||
else
|
||||
currentPath = NzString::Unicode(path);
|
||||
}
|
||||
else if (size == 0)
|
||||
NazaraError("Unable to get current directory: " + NzGetLastSystemError());
|
||||
else
|
||||
currentPath = NzString::Unicode(path);
|
||||
|
||||
delete[] path;
|
||||
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
bool NzDirectoryImpl::Remove(const NzString& dirPath)
|
||||
{
|
||||
wchar_t* path = dirPath.GetWideBuffer();
|
||||
bool success = RemoveDirectoryW(path) != 0;
|
||||
delete[] path;
|
||||
|
||||
DWORD error = GetLastError();
|
||||
return success || error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND;
|
||||
}
|
||||
45
src/Nazara/Core/Win32/DirectoryImpl.hpp
Normal file
45
src/Nazara/Core/Win32/DirectoryImpl.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_DIRECTORYIMPL_HPP
|
||||
#define NAZARA_DIRECTORYIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Utility/NonCopyable.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
class NzDirectory;
|
||||
class NzString;
|
||||
|
||||
class NzDirectoryImpl : NzNonCopyable
|
||||
{
|
||||
public:
|
||||
NzDirectoryImpl(const NzDirectory* parent);
|
||||
~NzDirectoryImpl();
|
||||
|
||||
void Close();
|
||||
|
||||
NzString GetResultName() const;
|
||||
nzUInt64 GetResultSize() const;
|
||||
|
||||
bool IsResultDirectory() const;
|
||||
|
||||
bool NextResult();
|
||||
|
||||
bool Open(const NzString& dirPath);
|
||||
|
||||
static bool Create(const NzString& dirPath);
|
||||
static bool Exists(const NzString& dirPath);
|
||||
static NzString GetCurrent();
|
||||
static bool Remove(const NzString& dirPath);
|
||||
|
||||
private:
|
||||
HANDLE m_handle;
|
||||
WIN32_FIND_DATAW m_result;
|
||||
bool m_firstCall;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DIRECTORYIMPL_HPP
|
||||
51
src/Nazara/Core/Win32/DynLibImpl.cpp
Normal file
51
src/Nazara/Core/Win32/DynLibImpl.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/DynLibImpl.hpp>
|
||||
#include <Nazara/Core/DynLib.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzDynLibImpl::NzDynLibImpl(NzDynLib* parent) :
|
||||
m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzDynLibImpl::~NzDynLibImpl()
|
||||
{
|
||||
}
|
||||
|
||||
NzDynLibFunc NzDynLibImpl::GetSymbol(const NzString& symbol) const
|
||||
{
|
||||
NzDynLibFunc sym = reinterpret_cast<NzDynLibFunc>(GetProcAddress(m_handle, symbol.GetConstBuffer()));
|
||||
if (!sym)
|
||||
m_parent->SetLastError(NzGetLastSystemError());
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
bool NzDynLibImpl::Load(const NzString& libraryPath)
|
||||
{
|
||||
NzString path = libraryPath;
|
||||
if (!path.EndsWith(".dll"))
|
||||
path += ".dll";
|
||||
|
||||
wchar_t* pathW = path.GetWideBuffer();
|
||||
m_handle = LoadLibraryExW(pathW, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
delete[] pathW;
|
||||
|
||||
if (m_handle)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
m_parent->SetLastError(NzGetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void NzDynLibImpl::Unload()
|
||||
{
|
||||
FreeLibrary(m_handle);
|
||||
}
|
||||
31
src/Nazara/Core/Win32/DynLibImpl.hpp
Normal file
31
src/Nazara/Core/Win32/DynLibImpl.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_DYNLIBIMPL_HPP
|
||||
#define NAZARA_DYNLIBIMPL_HPP
|
||||
|
||||
#include <Nazara/Core/DynLib.hpp>
|
||||
#include <Nazara/Utility/NonCopyable.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
class NzString;
|
||||
|
||||
class NzDynLibImpl : NzNonCopyable
|
||||
{
|
||||
public:
|
||||
NzDynLibImpl(NzDynLib* m_parent);
|
||||
~NzDynLibImpl();
|
||||
|
||||
NzDynLibFunc GetSymbol(const NzString& symbol) const;
|
||||
bool Load(const NzString& libraryPath);
|
||||
void Unload();
|
||||
|
||||
private:
|
||||
HMODULE m_handle;
|
||||
NzDynLib* m_parent;
|
||||
};
|
||||
|
||||
#endif // NAZARA_DYNLIBIMPL_HPP
|
||||
309
src/Nazara/Core/Win32/FileImpl.cpp
Normal file
309
src/Nazara/Core/Win32/FileImpl.cpp
Normal file
@@ -0,0 +1,309 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/FileImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/Win32/Time.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzFileImpl::NzFileImpl(const NzFile* parent) :
|
||||
m_endOfFile(false)
|
||||
{
|
||||
NazaraUnused(parent);
|
||||
}
|
||||
|
||||
NzFileImpl::~NzFileImpl()
|
||||
{
|
||||
}
|
||||
|
||||
void NzFileImpl::Close()
|
||||
{
|
||||
CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
bool NzFileImpl::EndOfFile() const
|
||||
{
|
||||
return m_endOfFile;
|
||||
}
|
||||
|
||||
void NzFileImpl::Flush()
|
||||
{
|
||||
if (!FlushFileBuffers(m_handle))
|
||||
NazaraError("Unable to flush file: " + NzGetLastSystemError());
|
||||
}
|
||||
|
||||
nzUInt64 NzFileImpl::GetCursorPos() const
|
||||
{
|
||||
LARGE_INTEGER zero;
|
||||
zero.QuadPart = 0;
|
||||
|
||||
LARGE_INTEGER position;
|
||||
SetFilePointerEx(m_handle, zero, &position, FILE_CURRENT);
|
||||
|
||||
return position.QuadPart;
|
||||
}
|
||||
|
||||
bool NzFileImpl::Open(const NzString& filePath, unsigned int mode)
|
||||
{
|
||||
DWORD access;
|
||||
DWORD shareMode = FILE_SHARE_READ;
|
||||
DWORD openMode;
|
||||
if (mode & NzFile::ReadOnly)
|
||||
{
|
||||
access = GENERIC_READ;
|
||||
openMode = OPEN_EXISTING;
|
||||
}
|
||||
else if (mode & NzFile::ReadWrite)
|
||||
{
|
||||
if (mode & NzFile::Append)
|
||||
access = FILE_APPEND_DATA;
|
||||
else
|
||||
access = GENERIC_READ | GENERIC_WRITE;
|
||||
|
||||
if (mode & NzFile::Truncate)
|
||||
openMode = CREATE_ALWAYS;
|
||||
else
|
||||
openMode = OPEN_ALWAYS;
|
||||
}
|
||||
else if (mode & NzFile::WriteOnly)
|
||||
{
|
||||
if (mode & NzFile::Append)
|
||||
access = FILE_APPEND_DATA;
|
||||
else
|
||||
access = GENERIC_WRITE;
|
||||
|
||||
if (mode & NzFile::Truncate)
|
||||
openMode = CREATE_ALWAYS;
|
||||
else
|
||||
openMode = OPEN_ALWAYS;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
if ((mode & NzFile::Lock) == 0)
|
||||
shareMode |= FILE_SHARE_WRITE;
|
||||
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
m_handle = CreateFileW(path, access, shareMode, nullptr, openMode, 0, nullptr);
|
||||
delete[] path;
|
||||
|
||||
return m_handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
std::size_t NzFileImpl::Read(void* buffer, std::size_t size)
|
||||
{
|
||||
DWORD read = 0;
|
||||
if (ReadFile(m_handle, buffer, size, &read, nullptr))
|
||||
{
|
||||
m_endOfFile = (size != read);
|
||||
return read;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool NzFileImpl::SetCursorPos(NzFile::CursorPosition pos, nzInt64 offset)
|
||||
{
|
||||
DWORD moveMethod;
|
||||
switch (pos)
|
||||
{
|
||||
case NzFile::AtBegin:
|
||||
moveMethod = FILE_BEGIN;
|
||||
break;
|
||||
|
||||
case NzFile::AtCurrent:
|
||||
moveMethod = FILE_CURRENT;
|
||||
break;
|
||||
|
||||
case NzFile::AtEnd:
|
||||
moveMethod = FILE_END;
|
||||
break;
|
||||
|
||||
default:
|
||||
NazaraInternalError("Cursor position not handled (0x" + NzString::Number(pos, 16) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
m_endOfFile = false;
|
||||
|
||||
LARGE_INTEGER distance;
|
||||
distance.QuadPart = offset;
|
||||
|
||||
return SetFilePointerEx(m_handle, distance, nullptr, moveMethod) != 0;
|
||||
}
|
||||
|
||||
std::size_t NzFileImpl::Write(const void* buffer, std::size_t size)
|
||||
{
|
||||
DWORD written = 0;
|
||||
|
||||
LARGE_INTEGER cursorPos;
|
||||
cursorPos.QuadPart = GetCursorPos();
|
||||
|
||||
LockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0);
|
||||
WriteFile(m_handle, buffer, size, &written, nullptr);
|
||||
UnlockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath)
|
||||
{
|
||||
wchar_t* path = sourcePath.GetWideBuffer();
|
||||
wchar_t* newPath = targetPath.GetWideBuffer();
|
||||
|
||||
if (CopyFileW(path, newPath, false))
|
||||
{
|
||||
delete[] path;
|
||||
delete[] newPath;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Unable to copy file: " + NzGetLastSystemError());
|
||||
delete[] path;
|
||||
delete[] newPath;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzFileImpl::Delete(const NzString& filePath)
|
||||
{
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
|
||||
if (DeleteFileW(path))
|
||||
{
|
||||
delete[] path;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Unable to delete file (" + filePath + "): " + NzGetLastSystemError());
|
||||
delete[] path;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzFileImpl::Exists(const NzString& filePath)
|
||||
{
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
HANDLE handle = CreateFileW(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
delete[] path;
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
time_t NzFileImpl::GetCreationTime(const NzString& filePath)
|
||||
{
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
HANDLE handle = CreateFileW(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
delete[] path;
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
FILETIME creationTime;
|
||||
if (!GetFileTime(handle, &creationTime, nullptr, nullptr))
|
||||
{
|
||||
NazaraError("Unable to get creation time: " + NzGetLastSystemError());
|
||||
|
||||
CloseHandle(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return FileTimeToTime(&creationTime);
|
||||
}
|
||||
|
||||
time_t NzFileImpl::GetLastAccessTime(const NzString& filePath)
|
||||
{
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
HANDLE handle = CreateFileW(path, 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
delete[] path;
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
FILETIME accessTime;
|
||||
if (!GetFileTime(handle, nullptr, &accessTime, nullptr))
|
||||
{
|
||||
NazaraError("Unable to get last access time: " + NzGetLastSystemError());
|
||||
|
||||
CloseHandle(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return FileTimeToTime(&accessTime);
|
||||
}
|
||||
|
||||
time_t NzFileImpl::GetLastWriteTime(const NzString& filePath)
|
||||
{
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
HANDLE handle = CreateFileW(path, 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
delete[] path;
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
FILETIME writeTime;
|
||||
if (!GetFileTime(handle, nullptr, nullptr, &writeTime))
|
||||
{
|
||||
NazaraError("Unable to get last write time: " + NzGetLastSystemError());
|
||||
CloseHandle(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return FileTimeToTime(&writeTime);
|
||||
}
|
||||
|
||||
nzUInt64 NzFileImpl::GetSize(const NzString& filePath)
|
||||
{
|
||||
wchar_t* path = filePath.GetWideBuffer();
|
||||
HANDLE handle = CreateFileW(path, 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
delete[] path;
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!GetFileSizeEx(handle, &fileSize))
|
||||
fileSize.QuadPart = 0;
|
||||
|
||||
CloseHandle(handle);
|
||||
|
||||
return fileSize.QuadPart;
|
||||
}
|
||||
|
||||
bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath)
|
||||
{
|
||||
wchar_t* path = sourcePath.GetWideBuffer();
|
||||
wchar_t* newPath = targetPath.GetWideBuffer();
|
||||
|
||||
bool success = MoveFileExW(path, newPath, MOVEFILE_COPY_ALLOWED) != 0;
|
||||
|
||||
delete[] path;
|
||||
delete[] newPath;
|
||||
|
||||
if (success)
|
||||
return true;
|
||||
else
|
||||
{
|
||||
NazaraError("Unable to rename file: " + NzGetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
48
src/Nazara/Core/Win32/FileImpl.hpp
Normal file
48
src/Nazara/Core/Win32/FileImpl.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_FILEIMPL_HPP
|
||||
#define NAZARA_FILEIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/File.hpp>
|
||||
#include <Nazara/Utility/NonCopyable.hpp>
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
|
||||
class NzFile;
|
||||
class NzString;
|
||||
|
||||
class NzFileImpl : NzNonCopyable
|
||||
{
|
||||
public:
|
||||
NzFileImpl(const NzFile* parent);
|
||||
~NzFileImpl();
|
||||
|
||||
void Close();
|
||||
bool EndOfFile() const;
|
||||
void Flush();
|
||||
nzUInt64 GetCursorPos() const;
|
||||
bool Open(const NzString& filePath, unsigned int mode);
|
||||
std::size_t Read(void* buffer, std::size_t size);
|
||||
bool SetCursorPos(NzFile::CursorPosition pos, nzInt64 offset);
|
||||
std::size_t Write(const void* buffer, std::size_t size);
|
||||
|
||||
static bool Copy(const NzString& sourcePath, const NzString& targetPath);
|
||||
static bool Delete(const NzString& filePath);
|
||||
static bool Exists(const NzString& filePath);
|
||||
static time_t GetCreationTime(const NzString& filePath);
|
||||
static time_t GetLastAccessTime(const NzString& filePath);
|
||||
static time_t GetLastWriteTime(const NzString& filePath);
|
||||
static nzUInt64 GetSize(const NzString& filePath);
|
||||
static bool Rename(const NzString& sourcePath, const NzString& targetPath);
|
||||
|
||||
private:
|
||||
HANDLE m_handle;
|
||||
bool m_endOfFile;
|
||||
};
|
||||
|
||||
#endif // NAZARA_FILEIMPL_HPP
|
||||
31
src/Nazara/Core/Win32/MutexImpl.cpp
Normal file
31
src/Nazara/Core/Win32/MutexImpl.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/MutexImpl.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzMutexImpl::NzMutexImpl()
|
||||
{
|
||||
InitializeCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
NzMutexImpl::~NzMutexImpl()
|
||||
{
|
||||
DeleteCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
void NzMutexImpl::Lock()
|
||||
{
|
||||
EnterCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
bool NzMutexImpl::TryLock()
|
||||
{
|
||||
return TryEnterCriticalSection(&m_criticalSection) != 0;
|
||||
}
|
||||
|
||||
void NzMutexImpl::Unlock()
|
||||
{
|
||||
LeaveCriticalSection(&m_criticalSection);
|
||||
}
|
||||
30
src/Nazara/Core/Win32/MutexImpl.hpp
Normal file
30
src/Nazara/Core/Win32/MutexImpl.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_MUTEXIMPL_HPP
|
||||
#define NAZARA_MUTEXIMPL_HPP
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
class NzThreadConditionImpl;
|
||||
|
||||
class NzMutexImpl
|
||||
{
|
||||
friend class NzThreadConditionImpl;
|
||||
|
||||
public:
|
||||
NzMutexImpl();
|
||||
~NzMutexImpl();
|
||||
|
||||
void Lock();
|
||||
bool TryLock();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
};
|
||||
|
||||
#endif // NAZARA_MUTEXIMPL_HPP
|
||||
65
src/Nazara/Core/Win32/SemaphoreImpl.cpp
Normal file
65
src/Nazara/Core/Win32/SemaphoreImpl.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Core/Win32/SemaphoreImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <limits>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzSemaphoreImpl::NzSemaphoreImpl(unsigned int count)
|
||||
{
|
||||
m_semaphore = CreateSemaphore(nullptr, count, std::numeric_limits<LONG>::max(), nullptr);
|
||||
#if NAZARA_CORE_SAFE ///FIXME: Ne peut échouer qu'à cause de mauvais paramètres ?
|
||||
if (!m_semaphore)
|
||||
NazaraError("Failed to create semaphore: " + NzGetLastSystemError());
|
||||
#endif
|
||||
}
|
||||
|
||||
NzSemaphoreImpl::~NzSemaphoreImpl()
|
||||
{
|
||||
CloseHandle(m_semaphore);
|
||||
}
|
||||
|
||||
unsigned int NzSemaphoreImpl::GetCount() const
|
||||
{
|
||||
LONG count;
|
||||
ReleaseSemaphore(m_semaphore, 0, &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
void NzSemaphoreImpl::Post()
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (!ReleaseSemaphore(m_semaphore, 1, nullptr))
|
||||
NazaraError("Failed to release semaphore: " + NzGetLastSystemError());
|
||||
#else
|
||||
ReleaseSemaphore(m_semaphore, 1, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NzSemaphoreImpl::Wait()
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
if (WaitForSingleObject(m_semaphore, INFINITE) == WAIT_FAILED)
|
||||
NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError());
|
||||
#else
|
||||
WaitForSingleObject(m_semaphore, INFINITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool NzSemaphoreImpl::Wait(nzUInt32 timeout)
|
||||
{
|
||||
#if NAZARA_CORE_SAFE
|
||||
DWORD result = WaitForSingleObject(m_semaphore, timeout);
|
||||
if (result == WAIT_FAILED)
|
||||
{
|
||||
NazaraError("Failed to wait for semaphore: " + NzGetLastSystemError());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return result == WAIT_OBJECT_0;
|
||||
#else
|
||||
return WaitForSingleObject(m_semaphore, timeout) == WAIT_OBJECT_0;
|
||||
#endif
|
||||
}
|
||||
28
src/Nazara/Core/Win32/SemaphoreImpl.hpp
Normal file
28
src/Nazara/Core/Win32/SemaphoreImpl.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_SEMAPHOREIMPL_HPP
|
||||
#define NAZARA_SEMAPHOREIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
class NzSemaphoreImpl
|
||||
{
|
||||
public:
|
||||
NzSemaphoreImpl(unsigned int count);
|
||||
~NzSemaphoreImpl();
|
||||
|
||||
unsigned int GetCount() const;
|
||||
void Post();
|
||||
void Wait();
|
||||
bool Wait(nzUInt32 timeout);
|
||||
|
||||
private:
|
||||
HANDLE m_semaphore;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SEMAPHOREIMPL_HPP
|
||||
98
src/Nazara/Core/Win32/ThreadConditionImpl.cpp
Normal file
98
src/Nazara/Core/Win32/ThreadConditionImpl.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Source: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||
|
||||
#include <Nazara/Core/Win32/ThreadConditionImpl.hpp>
|
||||
#include <Nazara/Core/Win32/MutexImpl.hpp>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzThreadConditionImpl::NzThreadConditionImpl()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
InitializeConditionVariable(&m_cv);
|
||||
#else
|
||||
m_count = 0;
|
||||
InitializeCriticalSection(&m_countLock);
|
||||
m_events[SIGNAL] = CreateEvent(nullptr, false, false, nullptr); // auto-reset event
|
||||
m_events[BROADCAST] = CreateEvent(nullptr, true, false, nullptr); // manual-reset event
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
NzThreadConditionImpl::~NzThreadConditionImpl()
|
||||
{
|
||||
DeleteCriticalSection(&m_countLock);
|
||||
}
|
||||
#endif
|
||||
|
||||
void NzThreadConditionImpl::Signal()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
WakeConditionVariable(&m_cv);
|
||||
#else
|
||||
// Avoid race conditions.
|
||||
EnterCriticalSection(&m_countLock);
|
||||
bool haveWaiters = (m_count > 0);
|
||||
LeaveCriticalSection(&m_countLock);
|
||||
|
||||
if (haveWaiters)
|
||||
SetEvent(m_events[SIGNAL]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NzThreadConditionImpl::SignalAll()
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
WakeAllConditionVariable(&m_cv);
|
||||
#else
|
||||
// Avoid race conditions.
|
||||
EnterCriticalSection(&m_countLock);
|
||||
bool haveWaiters = (m_count > 0);
|
||||
LeaveCriticalSection (&m_countLock);
|
||||
|
||||
if (haveWaiters)
|
||||
SetEvent(m_events[BROADCAST]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void NzThreadConditionImpl::Wait(NzMutexImpl* mutex)
|
||||
{
|
||||
Wait(mutex, INFINITE);
|
||||
}
|
||||
|
||||
bool NzThreadConditionImpl::Wait(NzMutexImpl* mutex, nzUInt32 timeout)
|
||||
{
|
||||
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
return SleepConditionVariableCS(&m_cv, mutex->m_criticalSection, timeout);
|
||||
#else
|
||||
// Avoid race conditions.
|
||||
EnterCriticalSection(&m_countLock);
|
||||
m_count++;
|
||||
LeaveCriticalSection(&m_countLock);
|
||||
|
||||
// It's ok to release the mutex here since Win32
|
||||
// manual-reset events maintain state when used with SetEvent.
|
||||
// This avoids the "lost wakeup" bug...
|
||||
LeaveCriticalSection(&mutex->m_criticalSection);
|
||||
|
||||
// Wait for either event to become signaled due to Signal being called or SignalAll being called.
|
||||
int result = WaitForMultipleObjects(2, m_events, false, timeout);
|
||||
|
||||
EnterCriticalSection(&m_countLock);
|
||||
m_count--;
|
||||
bool lastWaiter = (result == WAIT_OBJECT_0 + BROADCAST && m_count == 0);
|
||||
LeaveCriticalSection(&m_countLock);
|
||||
|
||||
// Some thread called SignalAll
|
||||
if (lastWaiter)
|
||||
// We're the last waiter to be notified or to stop waiting, so reset the manual event.
|
||||
ResetEvent(m_events[BROADCAST]);
|
||||
|
||||
// Reacquire the mutex.
|
||||
EnterCriticalSection(&mutex->m_criticalSection);
|
||||
|
||||
return result != WAIT_TIMEOUT;
|
||||
#endif
|
||||
}
|
||||
51
src/Nazara/Core/Win32/ThreadConditionImpl.hpp
Normal file
51
src/Nazara/Core/Win32/ThreadConditionImpl.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_THREADCONDITIONIMPL_HPP
|
||||
#define NAZARA_THREADCONDITIONIMPL_HPP
|
||||
|
||||
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
class NzMutexImpl;
|
||||
|
||||
class NzThreadConditionImpl
|
||||
{
|
||||
public:
|
||||
NzThreadConditionImpl();
|
||||
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
~NzThreadConditionImpl() = default;
|
||||
#else
|
||||
~NzThreadConditionImpl();
|
||||
#endif
|
||||
|
||||
void Signal();
|
||||
void SignalAll();
|
||||
|
||||
void Wait(NzMutexImpl* mutex);
|
||||
bool Wait(NzMutexImpl* mutex, nzUInt32 timeout);
|
||||
|
||||
private:
|
||||
#ifdef NAZARA_PLATFORM_WINDOWSVISTA
|
||||
CONDITION_VARIABLE m_cv;
|
||||
#else
|
||||
enum
|
||||
{
|
||||
SIGNAL = 0,
|
||||
BROADCAST = 1,
|
||||
MAX_EVENTS = 2
|
||||
};
|
||||
|
||||
CRITICAL_SECTION m_countLock;
|
||||
HANDLE m_events[MAX_EVENTS];
|
||||
unsigned int m_count;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // NAZARA_THREADCONDITIONIMPL_HPP
|
||||
94
src/Nazara/Core/Win32/ThreadImpl.cpp
Normal file
94
src/Nazara/Core/Win32/ThreadImpl.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Inspiré du code de la SFML par Laurent Gomila
|
||||
|
||||
#include <Nazara/Core/Win32/ThreadImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Utility/Functor.hpp>
|
||||
#include <process.h>
|
||||
#include <Nazara/Core/Debug.hpp>
|
||||
|
||||
NzThread::Id::Id(const NzThreadImpl* thread)
|
||||
{
|
||||
if (thread->m_thread)
|
||||
m_handle = reinterpret_cast<void*>(thread->m_threadId); // Un entier transformé en pointeur : Hacky
|
||||
else
|
||||
m_handle = nullptr;
|
||||
}
|
||||
|
||||
NzThread::Id::~Id()
|
||||
{
|
||||
}
|
||||
|
||||
bool NzThread::Id::operator==(const Id& rhs) const
|
||||
{
|
||||
return m_handle == rhs.m_handle;
|
||||
}
|
||||
|
||||
bool NzThread::Id::operator!=(const Id& rhs) const
|
||||
{
|
||||
return m_handle != rhs.m_handle;
|
||||
}
|
||||
|
||||
NzThreadImpl::NzThreadImpl(NzThread* thread)
|
||||
{
|
||||
m_thread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, &NzThreadImpl::ThreadProc, thread, 0, &m_threadId));
|
||||
if (!m_thread)
|
||||
NazaraError("Failed to create thread: " + NzGetLastSystemError());
|
||||
}
|
||||
|
||||
NzThreadImpl::~NzThreadImpl()
|
||||
{
|
||||
}
|
||||
|
||||
NzThread::Id NzThreadImpl::GetId() const
|
||||
{
|
||||
return NzThread::Id(reinterpret_cast<void*>(m_threadId)); // Hacky
|
||||
}
|
||||
|
||||
bool NzThreadImpl::IsCurrent() const
|
||||
{
|
||||
return m_threadId == GetCurrentThreadId();
|
||||
}
|
||||
|
||||
void NzThreadImpl::Join()
|
||||
{
|
||||
if (m_thread)
|
||||
WaitForSingleObject(m_thread, INFINITE);
|
||||
}
|
||||
|
||||
void NzThreadImpl::Terminate()
|
||||
{
|
||||
if (m_thread)
|
||||
TerminateThread(m_thread, 0);
|
||||
}
|
||||
|
||||
unsigned int _stdcall NzThreadImpl::ThreadProc(void* userdata)
|
||||
{
|
||||
NzThread* owner = static_cast<NzThread*>(userdata);
|
||||
NzFunctor* func = owner->m_func;
|
||||
HANDLE myHandle = owner->m_impl->m_thread;
|
||||
func->Run();
|
||||
delete func;
|
||||
|
||||
// http://stackoverflow.com/questions/418742/is-it-reasonable-to-call-closehandle-on-a-thread-before-it-terminates
|
||||
CloseHandle(myHandle);
|
||||
|
||||
/*
|
||||
En C++, il vaut mieux retourner depuis la fonction que de quitter le thread explicitement
|
||||
Source : http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659(v=vs.85).aspx
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
NzThread::Id NzThread::GetCurrentId()
|
||||
{
|
||||
return NzThread::Id(reinterpret_cast<void*>(GetCurrentThreadId())); // Hacky
|
||||
}
|
||||
|
||||
void NzThread::Sleep(nzUInt32 time)
|
||||
{
|
||||
::Sleep(time);
|
||||
}
|
||||
38
src/Nazara/Core/Win32/ThreadImpl.hpp
Normal file
38
src/Nazara/Core/Win32/ThreadImpl.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// Inspiré du code de la SFML par Laurent Gomila
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_THREADIMPL_HPP
|
||||
#define NAZARA_THREADIMPL_HPP
|
||||
|
||||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Thread.hpp>
|
||||
#include <windows.h>
|
||||
|
||||
class NzThread;
|
||||
|
||||
class NzThreadImpl
|
||||
{
|
||||
friend class NzThread::Id;
|
||||
|
||||
public:
|
||||
NzThreadImpl(NzThread* threadFunc);
|
||||
~NzThreadImpl();
|
||||
|
||||
NzThread::Id GetId() const;
|
||||
bool IsCurrent() const;
|
||||
void Join();
|
||||
void Terminate();
|
||||
|
||||
private:
|
||||
static unsigned int _stdcall ThreadProc(void* userdata);
|
||||
|
||||
HANDLE m_thread;
|
||||
unsigned int m_threadId;
|
||||
};
|
||||
|
||||
#endif // NAZARA_THREADIMPL_HPP
|
||||
32
src/Nazara/Core/Win32/Time.hpp
Normal file
32
src/Nazara/Core/Win32/Time.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2012 Jérôme Leclercq
|
||||
// This file is part of the "Nazara Engine".
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_WINDOWS_TIME_HPP
|
||||
#define NAZARA_WINDOWS_TIME_HPP
|
||||
|
||||
#include <ctime>
|
||||
#include <windows.h>
|
||||
|
||||
time_t FileTimeToTime(FILETIME* time)
|
||||
{
|
||||
SYSTEMTIME stUTC, stLocal;
|
||||
|
||||
FileTimeToSystemTime(time, &stUTC);
|
||||
SystemTimeToTzSpecificLocalTime(nullptr, &stUTC, &stLocal);
|
||||
|
||||
std::tm timeinfo;
|
||||
timeinfo.tm_sec = stLocal.wSecond;
|
||||
timeinfo.tm_min = stLocal.wMinute;
|
||||
timeinfo.tm_hour = stLocal.wHour;
|
||||
timeinfo.tm_mday = stLocal.wDay;
|
||||
timeinfo.tm_mon = stLocal.wMonth-1;
|
||||
timeinfo.tm_year = stLocal.wYear-1900;
|
||||
timeinfo.tm_isdst = -1;
|
||||
|
||||
return std::mktime(&timeinfo);
|
||||
}
|
||||
|
||||
#endif // NAZARA_WINDOWS_TIME_HPP
|
||||
Reference in New Issue
Block a user