First commit

This commit is contained in:
Lynix
2012-05-01 16:43:48 +02:00
commit 71b4262c51
208 changed files with 46084 additions and 0 deletions

View File

@@ -0,0 +1,187 @@
/*#include <Nazara/Core/ByteArray.hpp>
#include <algorithm>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
NzByteArray::NzByteArray() :
m_sharedArray(&emptyArray)
{
}
NzByteArray::NzByteArray(const nzUInt8* buffer, unsigned int bufferLength)
{
if (bufferLength > 0)
{
m_sharedArray = new SharedArray;
m_sharedArray->allocatedSize = bufferLength;
m_sharedArray->buffer = new nzUInt8[bufferLength];
m_sharedArray->size = bufferLength;
std::memcpy(m_sharedArray->buffer, buffer, bufferLength*sizeof(nzUInt8));
}
else
m_sharedArray = &emptyArray;
}
NzByteArray::NzByteArray(const NzByteArray& buffer) :
m_sharedArray(buffer.m_sharedArray)
{
if (m_sharedArray != &emptyArray)
{
NazaraMutexLock(m_sharedArray->mutex);
m_sharedArray->refCount++;
NazaraMutexUnlock(m_sharedArray->mutex);
}
}
NzByteArray::NzByteArray(NzByteArray&& buffer) :
m_sharedArray(buffer.m_sharedArray)
{
buffer.m_sharedArray = &emptyArray;
}
NzByteArray::NzByteArray(SharedArray* sharedArray) :
m_sharedArray(sharedArray)
{
}
NzByteArray::~NzByteArray()
{
ReleaseArray();
}
unsigned int NzByteArray::Capacity() const
{
return m_sharedArray->allocatedSize;
}
void NzByteArray::Clear()
{
ReleaseArray();
}
const nzUInt8* NzByteArray::GetBuffer() const
{
return m_sharedArray->buffer;
}
unsigned int NzByteArray::GetSize() const
{
return m_sharedArray->size;
}
NzByteArray& NzByteArray::Insert(int pos, const nzUInt8* buffer, unsigned int bufferLength)
{
if (bufferLength == 0)
return *this;
if (m_sharedArray->size == 0)
return operator=(string);
if (pos < 0)
pos = std::max(static_cast<int>(m_sharedArray->size + pos), 0);
unsigned int start = std::min(static_cast<unsigned int>(pos), m_sharedArray->size);
// Si le buffer est déjà suffisamment grand
if (m_sharedArray->allocatedSize >= m_sharedArray->size + bufferLength)
{
EnsureOwnership();
std::memmove(&m_sharedArray->buffer[start+bufferLength], &m_sharedArray->buffer[start], m_sharedArray->size*sizeof(nzUInt8));
std::memcpy(&m_sharedArray->buffer[start], buffer, bufferLength*sizeof(nzUInt8));
m_sharedArray->size += bufferLength;
}
else
{
unsigned int newSize = m_sharedArray->size+bufferLength;
nzUInt8* newBuffer = new nzUInt8[newSize+1];
nzUInt8* ptr = newBuffer;
const nzUInt8* s = m_sharedArray->buffer;
while (ptr != &newBuffer[start])
*ptr++ = *s++;
while (ptr != &newBuffer[start+bufferLength])
*ptr++ = *buffer++;
std::strcpy(ptr, s);
ReleaseString();
m_sharedArray = new SharedString;
m_sharedArray->allocatedSize = newSize;
m_sharedArray->buffer = newBuffer;
m_sharedArray->size = newSize;
}
return *this;
}
NzByteArray& NzByteArray::Insert(int pos, const NzByteArray& byteArray);
bool NzByteArray::IsEmpty() const
{
return m_sharedArray->size == 0;
}
void NzByteArray::Reserve(unsigned int bufferSize)
{
if (m_sharedArray->allocatedSize >= bufferSize)
return;
char* ptr = new char[bufferSize+1];
if (m_sharedArray->size > 0)
std::strcpy(ptr, m_sharedArray->buffer);
unsigned int size = m_sharedArray->size;
ReleaseArray();
m_sharedArray = new SharedString;
m_sharedArray->allocatedSize = bufferSize;
m_sharedArray->buffer = ptr;
m_sharedArray->size = size;
}
NzByteArray& NzByteArray::Resize(int size, nzUInt8 byte = '\0');
NzByteArray NzByteArray::Resized(int size, nzUInt8 byte = '\0') const;
NzByteArray SubArray(int startPos, int endPos = -1) const;
void Swap(NzByteArray& byteArray);
NzByteArray& Trim(nzUInt8 byte = '\0');
NzByteArray Trimmed(nzUInt8 byte = '\0') const;
// Méthodes compatibles STD
nzUInt8* begin();
const nzUInt8* begin() const;
nzUInt8* end();
const nzUInt8* end() const;
void push_front(nzUInt8 c);
void push_back(nzUInt8 c);
typedef const nzUInt8& const_reference;
typedef nzUInt8* iterator;
//typedef nzUInt8* reverse_iterator;
typedef nzUInt8 value_type;
// Méthodes compatibles STD
nzUInt8& operator[](unsigned int pos);
nzUInt8 operator[](unsigned int pos) const;
NzByteArray& operator=(const NzByteArray& byteArray);
NzByteArray& operator=(NzByteArray&& byteArray);
NzByteArray operator+(const NzByteArray& byteArray) const;
NzByteArray& operator+=(const NzByteArray& byteArray);
static int Compare(const NzByteArray& first, const NzByteArray& second);
static SharedArray emptyArray;
private:
void EnsureOwnership();
bool FillHash(NzHashImpl* hash) const;
void ReleaseArray();
*/

103
src/Nazara/Core/Clock.cpp Normal file
View File

@@ -0,0 +1,103 @@
// 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
#define NAZARA_CLOCK_CPP
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Core/Error.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/ClockImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/ClockImpl.hpp>
#else
#error OS not handled
#endif
#include <Nazara/Core/ThreadSafety.hpp>
#include <Nazara/Core/Debug.hpp>
NzClock::NzClock() :
m_elapsedTime(0),
m_refTime(NzGetMicroseconds()),
m_paused(false)
{
}
float NzClock::GetSeconds() const
{
return GetMicroseconds()/1000000.f;
}
nzUInt64 NzClock::GetMicroseconds() const
{
NazaraMutex(m_mutex);
return m_elapsedTime + (NzGetMicroseconds()-m_refTime);
}
nzUInt64 NzClock::GetMilliseconds() const
{
return GetMicroseconds()/1000;
}
bool NzClock::IsPaused() const
{
NazaraMutex(m_mutex);
return m_paused;
}
void NzClock::Pause()
{
NazaraMutex(m_mutex);
if (!m_paused)
{
m_elapsedTime += NzGetMicroseconds()-m_refTime;
m_paused = true;
}
else
NazaraWarning("Clock is already paused, ignoring...");
}
void NzClock::Restart()
{
NazaraMutex(m_mutex);
m_elapsedTime = 0;
m_refTime = NzGetMicroseconds();
m_paused = false;
}
void NzClock::Unpause()
{
NazaraMutex(m_mutex);
if (m_paused)
{
m_refTime = NzGetMicroseconds();
m_paused = false;
}
else
NazaraWarning("Clock is not paused, ignoring...");
}
nzUInt64 NzGetMicrosecondsLowPrecision()
{
return NzClockImplGetMilliseconds()*1000ULL;
}
nzUInt64 NzGetMicrosecondsFirstRun()
{
if (NzClockImplInitializeHighPrecision())
NzGetMicroseconds = NzClockImplGetMicroseconds;
else
NzGetMicroseconds = NzGetMicrosecondsLowPrecision;
return NzGetMicroseconds();
}
NzClockFunction NzGetMicroseconds = NzGetMicrosecondsFirstRun;
NzClockFunction NzGetMilliseconds = NzClockImplGetMilliseconds;

View File

@@ -0,0 +1,29 @@
// 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/Config.hpp>
#if NAZARA_CORE_MEMORYLEAKTRACKER || defined(NAZARA_DEBUG)
#include <Nazara/Core/Debug/MemoryLeakTracker.hpp>
#include <new>
void* operator new(std::size_t size) throw(std::bad_alloc)
{
return NzMemoryManager::Allocate(size, false);
}
void* operator new[](std::size_t size) throw(std::bad_alloc)
{
return NzMemoryManager::Allocate(size, true);
}
void operator delete(void* pointer) throw()
{
NzMemoryManager::Free(pointer, false);
}
void operator delete[](void* pointer) throw()
{
NzMemoryManager::Free(pointer, true);
}
#endif

View File

@@ -0,0 +1,227 @@
// 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/Debug/MemoryLeakTracker.hpp>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <stdexcept>
namespace
{
struct Block
{
std::size_t size;
const char* file;
Block* prev;
Block* next;
bool array;
unsigned int line;
unsigned int magic;
};
bool initialized = false;
const unsigned int magic = 0x51429EE;
const char* MLTFileName = "NazaraLeaks.log";
const char* nextFreeFile = "Internal error";
unsigned int nextFreeLine = 0;
static Block ptrList =
{
0,
nullptr,
&ptrList,
&ptrList,
false,
0,
magic
};
}
NzMemoryManager::NzMemoryManager()
{
}
NzMemoryManager::~NzMemoryManager()
{
Uninitialize();
}
void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line)
{
EnsureInitialization();
Block* ptr = reinterpret_cast<Block*>(std::malloc(size+sizeof(Block)));
if (!ptr)
return nullptr;
ptr->array = multi;
ptr->file = file;
ptr->line = line;
ptr->size = size;
ptr->magic = magic;
ptr->prev = ptrList.prev;
ptr->next = &ptrList;
ptrList.prev->next = ptr;
ptrList.prev = ptr;
return reinterpret_cast<char*>(ptr)+sizeof(Block);
}
void NzMemoryManager::Free(void* pointer, bool multi)
{
if (!pointer)
return;
Block* ptr = reinterpret_cast<Block*>(reinterpret_cast<char*>(pointer)-sizeof(Block));
if (ptr->magic != magic)
return;
if (ptr->array != multi)
{
char* time = TimeInfo();
FILE* log = std::fopen(MLTFileName, "a");
if (nextFreeFile)
{
if (multi)
std::fprintf(log, "%s Warning: delete[] on new at %s:%d\n", time, nextFreeFile, nextFreeLine);
else
std::fprintf(log, "%s Warning: delete on new[] at %s:%d\n", time, nextFreeFile, nextFreeLine);
nextFreeFile = nullptr;
nextFreeLine = 0;
}
else
{
if (multi)
std::fprintf(log, "%s Warning: delete[] on new at unknown position\n", time);
else
std::fprintf(log, "%s Warning: delete on new[] at unknown position\n", time);
}
std::fclose(log);
std::free(time);
}
ptr->magic = 0;
ptr->prev->next = ptr->next;
ptr->next->prev = ptr->prev;
std::free(ptr);
}
void NzMemoryManager::NextFree(const char* file, unsigned int line)
{
nextFreeFile = file;
nextFreeLine = line;
}
void NzMemoryManager::EnsureInitialization()
{
if (!initialized)
{
Initialize();
if (std::atexit(Uninitialize) != 0)
{
static NzMemoryManager manager;
}
initialized = true;
}
}
void NzMemoryManager::Initialize()
{
char* time = TimeInfo();
FILE* file = std::fopen(MLTFileName, "w");
std::fprintf(file, "%s ==============================\n", time);
std::fprintf(file, "%s Nazara Memory Leak Tracker \n", time);
std::fprintf(file, "%s ==============================\n", time);
std::fclose(file);
std::free(time);
}
char* NzMemoryManager::TimeInfo()
{
char* buffer = reinterpret_cast<char*>(std::malloc(23*sizeof(char)));
time_t currentTime = std::time(nullptr);
std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(&currentTime));
return buffer;
}
void NzMemoryManager::Uninitialize()
{
FILE* log = std::fopen(MLTFileName, "a");
char* time = TimeInfo();
std::fprintf(log, "%s Application finished, checking leaks...\n", time);
if (ptrList.next == &ptrList)
{
std::fprintf(log, "%s ==============================\n", time);
std::fprintf(log, "%s No leak detected \n", time);
std::fprintf(log, "%s ==============================", time);
}
else
{
std::fprintf(log, "%s ==============================\n", time);
std::fprintf(log, "%s Leaks have been detected \n", time);
std::fprintf(log, "%s ==============================\n\n", time);
std::fputs("Leak list:\n", log);
Block* ptr = ptrList.next;
unsigned int count = 0;
unsigned int totalSize = 0;
while (ptr != &ptrList)
{
count++;
totalSize += ptr->size;
if (ptr->file)
std::fprintf(log, "-0x%p -> %d bytes allocated at %s:%d\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size, ptr->file, ptr->line);
else
std::fprintf(log, "-0x%p -> %d bytes allocated at unknown position\n", reinterpret_cast<char*>(ptr)+sizeof(Block), ptr->size);
void* pointer = ptr;
ptr = ptr->next;
std::free(pointer);
}
std::fprintf(log, "\n%d blocks leaked (%d bytes)", count, totalSize);
}
std::free(time);
std::fclose(log);
}
void* operator new(std::size_t size, const char* file, unsigned int line)
{
return NzMemoryManager::Allocate(size, false, file, line);
}
void* operator new[](std::size_t size, const char* file, unsigned int line)
{
return NzMemoryManager::Allocate(size, true, file, line);
}
void operator delete(void* ptr, const char* file, unsigned int line) throw()
{
NzMemoryManager::NextFree(file, line);
NzMemoryManager::Free(ptr, false);
}
void operator delete[](void* ptr, const char* file, unsigned int line) throw()
{
NzMemoryManager::NextFree(file, line);
NzMemoryManager::Free(ptr, true);
}

View 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
#define NAZARA_DIRECTORY_CPP
#include <Nazara/Core/Directory.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
//#include <Nazara/ThreadLocalVar.h>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/DirectoryImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/DirectoryImpl.hpp>
#else
#error OS not handled
#endif
#include <Nazara/Core/ThreadSafety.hpp>
#include <Nazara/Core/Debug.hpp>
namespace
{
NzString currentPath(NzDirectoryImpl::GetCurrent());
//static ThreadLocalVar<NzString> currentPath(NzDirectoryImpl::GetCurrent());
}
NzDirectory::NzDirectory() :
m_impl(nullptr)
{
}
NzDirectory::NzDirectory(const NzString& dirPath) :
m_impl(nullptr)
{
SetDirectory(dirPath);
}
NzDirectory::~NzDirectory()
{
Close();
}
void NzDirectory::Close()
{
if (m_impl)
{
m_impl->Close();
delete m_impl;
m_impl = nullptr;
NazaraMutexUnlock(m_mutex);
}
}
NzString NzDirectory::GetResultName() const
{
#if NAZARA_CORE_SAFE
if (!m_impl)
{
NazaraError("Directory not opened");
return NzString();
}
#endif
return m_impl->GetResultName();
}
NzString NzDirectory::GetResultPath() const
{
#if NAZARA_CORE_SAFE
if (!m_impl)
{
NazaraError("Directory not opened");
return NzString();
}
#endif
return m_dirPath + NAZARA_DIRECTORY_SEPARATOR + m_impl->GetResultName();
}
nzUInt64 NzDirectory::GetResultSize() const
{
#if NAZARA_CORE_SAFE
if (!m_impl)
{
NazaraError("Directory not opened");
return 0;
}
#endif
return m_impl->GetResultSize();
}
bool NzDirectory::IsResultDirectory() const
{
#if NAZARA_CORE_SAFE
if (!m_impl)
{
NazaraError("Directory not opened");
return false;
}
#endif
return m_impl->IsResultDirectory();
}
bool NzDirectory::NextResult(bool skipDots)
{
#if NAZARA_CORE_SAFE
if (!m_impl)
{
NazaraError("Directory not opened");
return false;
}
#endif
if (skipDots)
{
NzString name;
do
{
if (!m_impl->NextResult())
return false;
name = m_impl->GetResultName();
}
while (name == '.' || name == "..");
return true;
}
else
return m_impl->NextResult();
}
bool NzDirectory::Open()
{
Close();
if (!Exists(m_dirPath))
return false;
NazaraMutexLock(m_mutex);
m_impl = new NzDirectoryImpl(this);
if (!m_impl->Open(m_dirPath))
{
delete m_impl;
m_impl = nullptr;
NazaraMutexUnlock(m_mutex);
return false;
}
return true;
}
void NzDirectory::SetDirectory(const NzString& dirPath)
{
Close();
m_dirPath = NzFile::AbsolutePath(dirPath);
}
bool NzDirectory::Copy(const NzString& sourcePath, const NzString& destPath)
{
if (sourcePath.IsEmpty() || destPath.IsEmpty())
return false;
NzString dirPath(sourcePath);
NzString dest(NzFile::NormalizePath(destPath));
if (!Create(destPath, true))
{
NazaraError("Unable to create \"" + destPath + '"');
return false;
}
NzDirectory dir(dirPath);
if (!dir.Open())
{
NazaraError("Unable to open \"" + destPath + '"');
return false;
}
while (dir.NextResult(true));
{
if (dir.IsResultDirectory())
{
if (!Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
return false;
}
else if (!NzFile::Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName()))
{
NazaraError("Unable to copy \"" + dir.GetResultPath() + "\" to \"" + dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName() + '"');
return false;
}
}
dir.Close();
return true;
}
bool NzDirectory::Create(const NzString& dirPath, bool recursive)
{
if (dirPath.IsEmpty())
return false;
if (recursive)
{
NzString path = NzFile::NormalizePath(dirPath);
unsigned int foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR);
if (foundPos == NzString::npos)
return false;
#ifdef NAZARA_PLATFORM_WINDOWS
// Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop")
if (path.Match("\\\\*"))
{
foundPos = path.Find('\\', 2);
if (foundPos == NzString::npos)
return false;
foundPos = path.Find('\\', foundPos+1);
if (foundPos == NzString::npos)
return false;
}
#endif
do
{
NzString p = path.Substr(0, foundPos);
if (p.EndsWith(NAZARA_DIRECTORY_SEPARATOR))
p = p.Substr(0, -2);
if (!NzDirectoryImpl::Exists(p) && !NzDirectoryImpl::Create(p))
return false;
if (foundPos == NzString::npos)
break;
foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR, foundPos+1);
}
while (true);
return true;
}
else
return NzDirectoryImpl::Create(NzFile::NormalizePath(dirPath));
}
bool NzDirectory::Exists(const NzString& dirPath)
{
if (dirPath.IsEmpty())
return false;
return NzDirectoryImpl::Exists(NzFile::NormalizePath(dirPath));
}
NzString NzDirectory::GetCurrent()
{
return currentPath;
}
bool NzDirectory::Remove(const NzString& dirPath, bool emptyDirectory)
{
if (dirPath.IsEmpty())
return false;
if (emptyDirectory)
{
NzDirectory dir(dirPath);
if (!dir.Open())
return NzDirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer
while (dir.NextResult(true))
{
if (dir.IsResultDirectory())
{
if (!Remove(dir.GetResultPath(), true))
return false;
}
else if (!NzFile::Delete(dir.GetResultPath()))
{
NazaraError(dir.GetResultPath());
return false;
}
}
dir.Close();
}
return NzDirectoryImpl::Remove(NzFile::NormalizePath(dirPath));
}
bool NzDirectory::SetCurrent(const NzString& dirPath)
{
NzString path = NzFile::AbsolutePath(dirPath);
if (NzDirectoryImpl::Exists(path))
{
currentPath = path;
return true;
}
else
return false;
}

View File

@@ -0,0 +1,90 @@
// 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
#define NAZARA_DYNLIB_CPP
#include <Nazara/Core/DynLib.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/DynLibImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/DynLibImpl.hpp>
#else
#error No implementation for this platform
#endif
#include <Nazara/Core/ThreadSafety.hpp>
#include <Nazara/Core/Debug.hpp>
NzDynLib::NzDynLib(const NzString& libraryPath) :
m_path(libraryPath),
m_impl(nullptr)
{
}
NzDynLib::~NzDynLib()
{
Unload();
}
NzString NzDynLib::GetLastError() const
{
NazaraLock(m_mutex)
return m_lastError;
}
NzDynLibFunc NzDynLib::GetSymbol(const NzString& symbol) const
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!m_impl)
{
NazaraError("Library not opened");
return nullptr;
}
#endif
return m_impl->GetSymbol(symbol);
}
bool NzDynLib::Load()
{
NazaraLock(m_mutex)
Unload();
m_impl = new NzDynLibImpl(this);
if (!m_impl->Load(m_path))
{
delete m_impl;
m_impl = nullptr;
return false;
}
return true;
}
void NzDynLib::Unload()
{
NazaraLock(m_mutex)
if (m_impl)
{
m_impl->Unload();
delete m_impl;
m_impl = nullptr;
}
}
void NzDynLib::SetLastError(const NzString& error)
{
NazaraLock(m_mutex)
m_lastError = error;
}

67
src/Nazara/Core/Error.cpp Normal file
View File

@@ -0,0 +1,67 @@
// 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
#define NAZARA_ERROR_CPP
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <cstdlib>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <windows.h>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <cstring>
#endif
#include <Nazara/Core/Debug.hpp>
void NzError(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function)
{
NazaraLog->WriteError(type, error, line, file, function);
#if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE
if (type == nzErrorType_AssertFailed)
exit(EXIT_FAILURE);
#endif
}
unsigned int NzGetLastSystemErrorCode()
{
#if defined(NAZARA_PLATFORM_WINDOWS)
return GetLastError();
#elif defined(NAZARA_PLATFORM_POSIX)
return errno;
#else
#error GetLastSystemErrorCode is not implemented on this platform
#endif
return 0;
}
NzString NzGetLastSystemError(unsigned int code)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
wchar_t* buffer = nullptr;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
0,
code,
0,
reinterpret_cast<LPWSTR>(&buffer),
0,
nullptr);
NzString error(NzString::Unicode(buffer));
LocalFree(buffer);
error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message
return error;
#elif defined(NAZARA_PLATFORM_POSIX)
return strerror(code);
#else
#error GetLastSystemError is not implemented on this platform
return "GetLastSystemError is not implemented on this platform";
#endif
}

784
src/Nazara/Core/File.cpp Normal file
View File

@@ -0,0 +1,784 @@
// 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
#define NAZARA_FILE_CPP
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/Config.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Hash.hpp>
#include <Nazara/Core/HashImpl.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <cstring>
#include <utility>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/FileImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/FileImpl.hpp>
#else
#error OS not handled
#endif
#include <Nazara/Core/ThreadSafety.hpp>
#include <Nazara/Core/Debug.hpp>
NzFile::NzFile() :
m_endianness(nzEndianness_Unknown),
m_impl(nullptr),
m_openMode(0)
{
}
NzFile::NzFile(const NzString& filePath) :
m_endianness(nzEndianness_Unknown),
m_impl(nullptr),
m_openMode(0)
{
SetFile(filePath);
}
NzFile::NzFile(const NzString& filePath, unsigned long openMode) :
m_endianness(nzEndianness_Unknown),
m_impl(nullptr),
m_openMode(0)
{
SetFile(filePath);
Open(openMode);
}
NzFile::NzFile(NzFile&& file) :
m_endianness(file.m_endianness),
m_filePath(std::move(file.m_filePath)),
m_impl(file.m_impl),
m_openMode(file.m_openMode)
{
file.m_impl = nullptr;
}
NzFile::~NzFile()
{
Close();
}
bool NzFile::Copy(const NzString& newFilePath)
{
return Copy(m_filePath, newFilePath);
}
void NzFile::Close()
{
NazaraLock(m_mutex)
if (m_impl)
{
m_impl->Close();
delete m_impl;
m_impl = nullptr;
}
}
bool NzFile::Delete()
{
NazaraLock(m_mutex)
Close();
return Delete(m_filePath);
}
bool NzFile::EndOfFile() const
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return false;
}
#endif
return m_impl->EndOfFile();
}
bool NzFile::Exists() const
{
NazaraLock(m_mutex)
if (IsOpen())
return true; // Le fichier est ouvert, donc il existe
else
return Exists(m_filePath);
}
void NzFile::Flush()
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return;
}
if ((m_openMode & ReadWrite) == 0 && (m_openMode & WriteOnly) == 0)
{
NazaraError("Cannot flush file without write access");
return;
}
#endif
m_impl->Flush();
}
time_t NzFile::GetCreationTime() const
{
NazaraLock(m_mutex)
return GetCreationTime(m_filePath);
}
nzUInt64 NzFile::GetCursorPos() const
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return false;
}
#endif
return m_impl->GetCursorPos();
}
NzString NzFile::GetDirectoryPath() const
{
NazaraLock(m_mutex)
return m_filePath.SubstrTo(NAZARA_DIRECTORY_SEPARATOR, -1, true);
}
NzString NzFile::GetFilePath() const
{
NazaraLock(m_mutex)
return m_filePath;
}
NzString NzFile::GetFileName() const
{
NazaraLock(m_mutex)
return m_filePath.SubstrFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true);
}
time_t NzFile::GetLastAccessTime() const
{
NazaraLock(m_mutex)
return GetLastAccessTime(m_filePath);
}
time_t NzFile::GetLastWriteTime() const
{
NazaraLock(m_mutex)
return GetLastWriteTime(m_filePath);
}
NzString NzFile::GetLine(unsigned int lineSize)
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return NzString();
}
if ((m_openMode & ReadOnly) == 0 && (m_openMode & ReadWrite) == 0)
{
NazaraError("File not opened with read access");
return NzString();
}
#endif
NzString line;
if (lineSize == 0) // Taille maximale indéterminée
{
while (!m_impl->EndOfFile())
{
char c;
if (m_impl->Read(&c, sizeof(char)) == sizeof(char))
{
if (c == '\n')
{
if (m_openMode & Text && line.EndsWith('\r'))
line.Resize(-1);
break;
}
line += c;
}
else
break;
}
}
else
{
line.Reserve(lineSize);
for (unsigned int i = 0; i < lineSize; ++i)
{
char c;
if (m_impl->Read(&c, sizeof(char)) == sizeof(char))
{
if (c == '\n')
{
if (m_openMode & Text && line.EndsWith('\r'))
line.Resize(-1);
break;
}
line += c;
}
else
break;
}
}
return line;
}
nzUInt64 NzFile::GetSize() const
{
NazaraLock(m_mutex)
return GetSize(m_filePath);
}
bool NzFile::IsOpen() const
{
NazaraLock(m_mutex)
return m_impl != nullptr;
}
std::size_t NzFile::Read(void* buffer, std::size_t typeSize, unsigned int count)
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return 0;
}
if ((m_openMode & ReadOnly) == 0 && (m_openMode & ReadWrite) == 0)
{
NazaraError("File not opened with read access");
return 0;
}
#endif
if (!buffer || count == 0 || typeSize == 0)
return 0;
std::size_t byteRead = m_impl->Read(buffer, typeSize*count);
if (byteRead == 0)
return 0;
if (m_endianness != nzEndianness_Unknown && m_endianness != NzGetPlatformEndianness() && typeSize != 1)
{
unsigned int typeCount = byteRead/typeSize;
for (unsigned int i = 0; i < typeCount; ++i)
NzByteSwap(static_cast<char*>(buffer) + i*typeSize, typeSize);
}
return byteRead;
}
bool NzFile::Rename(const NzString& newFilePath)
{
NazaraLock(m_mutex)
bool opened = IsOpen();
Close();
bool success = Rename(m_filePath, newFilePath);
if (success)
m_filePath = NormalizePath(newFilePath);
if (opened)
Open();
return success;
}
bool NzFile::Open(unsigned long openMode)
{
NazaraLock(m_mutex)
Close();
if (m_filePath.IsEmpty())
return false;
if (openMode != 0)
m_openMode = openMode;
if (m_openMode == 0)
return false;
m_impl = new NzFileImpl(this);
if (!m_impl->Open(m_filePath, m_openMode))
{
delete m_impl;
m_impl = nullptr;
return false;
}
return true;
}
bool NzFile::SetCursorPos(CursorPosition pos, nzInt64 offset)
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return false;
}
#endif
return m_impl->SetCursorPos(pos, offset);
}
bool NzFile::SetCursorPos(nzUInt64 offset)
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return false;
}
#endif
return m_impl->SetCursorPos(AtBegin, offset);
}
void NzFile::SetEndianness(nzEndianness endianness)
{
NazaraLock(m_mutex)
m_endianness = endianness;
}
bool NzFile::SetFile(const NzString& filePath)
{
NazaraLock(m_mutex)
if (IsOpen())
{
if (filePath.IsEmpty())
return false;
NzFileImpl* impl = new NzFileImpl(this);
if (!impl->Open(filePath, m_openMode))
{
delete impl;
return false;
}
m_impl->Close();
delete m_impl;
m_impl = impl;
}
m_filePath = AbsolutePath(filePath);
return true;
}
bool NzFile::SetOpenMode(unsigned int openMode)
{
NazaraLock(m_mutex)
if (openMode == 0 || openMode == m_openMode)
return true;
if (IsOpen())
{
NzFileImpl* impl = new NzFileImpl(this);
if (!impl->Open(m_filePath, openMode))
{
delete impl;
return false;
}
m_impl->Close();
delete m_impl;
m_impl = impl;
}
m_openMode = openMode;
return true;
}
bool NzFile::Write(const NzString& string)
{
NazaraLock(m_mutex)
NzString temp(string);
if (m_openMode & Text)
{
#if defined(NAZARA_PLATFORM_WINDOWS)
temp.Replace("\n", "\r\n");
#elif defined(NAZARA_PLATFORM_LINUX)
// Rien à faire
#elif defined(NAZARA_PLATFORM_MACOS)
temp.Replace('\n', '\r');
#else
#error OS not handled
#endif
}
unsigned int size = temp.GetSize();
std::size_t bytesWritten = Write(temp.GetBuffer(), sizeof(char), size);
return bytesWritten == size*sizeof(char);
}
std::size_t NzFile::Write(const void* buffer, std::size_t typeSize, unsigned int count)
{
NazaraLock(m_mutex)
#if NAZARA_CORE_SAFE
if (!IsOpen())
{
NazaraError("File not opened");
return 0;
}
if ((m_openMode & ReadWrite) == 0 && (m_openMode & WriteOnly) == 0)
{
NazaraError("File not opened with write access");
return 0;
}
#endif
if (!buffer || count == 0 || typeSize == 0)
return 0;
std::size_t bytesWritten;
if (m_endianness != nzEndianness_Unknown && m_endianness != NzGetPlatformEndianness() && typeSize != 1)
{
char* buf = new char[count*typeSize];
std::memcpy(buf, buffer, count*typeSize);
for (unsigned int i = 0; i < count; ++i)
NzByteSwap(&buf[i*typeSize], typeSize);
bytesWritten = m_impl->Write(buf, count*typeSize);
delete[] buf;
}
else
bytesWritten = m_impl->Write(buffer, count*typeSize);
return bytesWritten;
}
NzFile& NzFile::operator=(const NzString& filePath)
{
SetFile(filePath);
return *this;
}
NzFile& NzFile::operator=(NzFile&& file)
{
NazaraLock(m_mutex)
std::swap(m_endianness, file.m_endianness);
std::swap(m_filePath, file.m_filePath);
std::swap(m_impl, file.m_impl);
std::swap(m_openMode, file.m_openMode);
return *this;
}
NzString NzFile::AbsolutePath(const NzString& filePath)
{
// Je n'utilise pas les fonctions de l'OS car elles ne fonctionnent que pour un chemin existant
NzString path = NormalizePath(filePath);
if (path.IsEmpty())
return NzString();
NzString base;
unsigned int start;
#ifdef NAZARA_PLATFORM_WINDOWS
if (path.Match("?:*"))
start = 1;
else if (path.Match("\\\\*"))
{
base = "\\\\";
start = 2;
}
else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
{
NzString drive = NzDirectory::GetCurrent().SubstrTo('\\');
NzString end = path.Substr(1, -1);
if (end.IsEmpty())
path = drive;
else
path = drive + '\\' + end;
start = 1;
}
else
{
NazaraError("Path unrecognized");
return path;
}
#elif NAZARA_PLATEFORM_LINUX
base = '/';
start = 0;
#else
#error OS case not implemented
#endif
static NzString upDir = NAZARA_DIRECTORY_SEPARATOR + NzString('.');
if (path.Find(upDir) == NzString::npos)
return path;
std::vector<NzString> sep;
if (path.Split(sep, NAZARA_DIRECTORY_SEPARATOR) <= 1)
return path;
// Nous avons un chemin absolu, mais il nous faut un peu le nettoyer
unsigned int pathLen = base.GetSize();
for (unsigned int i = 0; i < sep.size(); ++i)
{
if (sep[i] == '.')
sep.erase(sep.begin() + i--);
else if (sep[i] == "..")
{
if (i > start) // Si nous ne sommes pas dans la partie protégée
sep.erase(sep.begin() + i--);
sep.erase(sep.begin() + i--);
}
else
pathLen += sep[i].GetSize();
}
pathLen += sep.size()-1;
///FIXME: Le destructeur de NzStringStream provoque un bug lors de la libération de son vector
//NzStringStream stream(base);
NzString stream;
stream.Reserve(pathLen);
stream.Append(base);
for (unsigned int i = 0; i < sep.size(); ++i)
{
stream.Append(sep[i]);
if (i != sep.size()-1)
stream.Append(NAZARA_DIRECTORY_SEPARATOR);
/*if (i != sep.size()-1)
stream << sep[i] << NAZARA_DIRECTORY_SEPARATOR;
else
stream << sep[i];*/
}
return stream;
}
bool NzFile::Copy(const NzString& sourcePath, const NzString& targetPath)
{
if (sourcePath.IsEmpty() || targetPath.IsEmpty())
return false;
return NzFileImpl::Copy(NormalizePath(sourcePath), NormalizePath(targetPath));
}
bool NzFile::Delete(const NzString& filePath)
{
if (filePath.IsEmpty())
return false;
return NzFileImpl::Delete(NormalizePath(filePath));
}
bool NzFile::Exists(const NzString& filePath)
{
if (filePath.IsEmpty())
return false;
return NzFileImpl::Exists(NormalizePath(filePath));
}
time_t NzFile::GetCreationTime(const NzString& filePath)
{
if (filePath.IsEmpty())
return 0;
return NzFileImpl::GetCreationTime(NormalizePath(filePath));
}
time_t NzFile::GetLastAccessTime(const NzString& filePath)
{
if (filePath.IsEmpty())
return 0;
return NzFileImpl::GetLastAccessTime(NormalizePath(filePath));
}
time_t NzFile::GetLastWriteTime(const NzString& filePath)
{
if (filePath.IsEmpty())
return 0;
return NzFileImpl::GetLastWriteTime(NormalizePath(filePath));
}
NzHashDigest NzFile::GetHash(const NzString& filePath, nzHash hash)
{
NzFile file(filePath);
NzHash h(hash);
return h.Hash(file);
}
NzHashDigest NzFile::GetHash(const NzString& filePath, NzHashImpl* hash)
{
NzFile file(filePath);
NzHash h(hash);
return h.Hash(file);
}
nzUInt64 NzFile::GetSize(const NzString& filePath)
{
if (filePath.IsEmpty())
return 0;
return NzFileImpl::GetSize(NormalizePath(filePath));
}
bool NzFile::IsAbsolute(const NzString& path)
{
NzString wpath(path);
wpath.Trim();
if (wpath.IsEmpty())
return false;
#if NAZARA_CORE_NORMALIZE_DIRECTORY_SEPARATORS
wpath = NormalizeSeparators(wpath);
#endif
#ifdef NAZARA_PLATFORM_WINDOWS
if (path.Match("?:*"))
return true;
else if (path.Match("\\\\*"))
return true;
else if (wpath.StartsWith('\\')) // Spécial : '\' fait référence au disque racine
return true;
else
return false;
#elif NAZARA_PLATEFORM_LINUX
return wpath.StartsWith('/');
#else
#error OS case not implemented
#endif
}
NzString NzFile::NormalizePath(const NzString& filePath)
{
NzString path(filePath);
path.Trim();
#if NAZARA_CORE_NORMALIZE_DIRECTORY_SEPARATORS
path = NormalizeSeparators(path);
#endif
if (!IsAbsolute(path))
path = NzDirectory::GetCurrent() + NAZARA_DIRECTORY_SEPARATOR + path;
while (path.EndsWith(NAZARA_DIRECTORY_SEPARATOR))
path.Resize(-1);
return path;
}
NzString NzFile::NormalizeSeparators(const NzString& filePath)
{
NzString path(filePath);
#if defined(NAZARA_PLATFORM_WINDOWS)
path.Replace('/', '\\');
#elif defined(NAZARA_PLATFORM_LINUX)
path.Replace('\\', '/');
#else
#error OS not handled
#endif
return path;
}
bool NzFile::Rename(const NzString& sourcePath, const NzString& targetPath)
{
if (sourcePath.IsEmpty() || targetPath.IsEmpty())
return false;
return NzFileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath));
}
bool NzFile::FillHash(NzHashImpl* hash) const
{
NzFile file(m_filePath);
if (!file.Open(NzFile::ReadOnly))
{
NazaraError("Unable to open file");
return false;
}
nzUInt64 remainingSize = file.GetSize();
char buffer[NAZARA_CORE_FILE_BUFFERSIZE];
unsigned int size;
while (remainingSize > 0)
{
size = (remainingSize >= NAZARA_CORE_FILE_BUFFERSIZE) ? NAZARA_CORE_FILE_BUFFERSIZE : static_cast<unsigned int>(remainingSize);
if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size)
{
NazaraError("Unable to read file");
return false;
}
remainingSize -= size;
hash->Append(reinterpret_cast<nzUInt8*>(&buffer[0]), size);
}
return true;
} // Fermeture auttomatique du fichier

57
src/Nazara/Core/Hash.cpp Normal file
View File

@@ -0,0 +1,57 @@
// 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
#define NAZARA_HASH_CPP
#include <Nazara/Core/Hash.hpp>
#include <Nazara/Core/Hash/CRC32.hpp>
#include <Nazara/Core/Hash/Fletcher16.hpp>
#include <Nazara/Core/Hash/MD5.hpp>
#include <Nazara/Core/Hash/Whirlpool.hpp>
#include <Nazara/Core/Debug.hpp>
NzHash::NzHash(nzHash hash)
{
switch (hash)
{
case nzHash_Fletcher16:
m_impl = new NzHashFletcher16;
break;
case nzHash_CRC32:
m_impl = new NzHashCRC32;
break;
case nzHash_MD5:
m_impl = new NzHashMD5;
break;
case nzHash_Whirlpool:
m_impl = new NzHashWhirlpool;
break;
}
}
NzHash::NzHash(NzHashImpl* hashImpl) :
m_impl(hashImpl)
{
}
NzHash::~NzHash()
{
delete m_impl;
}
NzHashDigest NzHash::Hash(const NzHashable& hashable)
{
m_impl->Begin();
if (hashable.FillHash(m_impl))
return m_impl->End();
else
{
m_impl->End();
return NzHashDigest();
}
}

View File

@@ -0,0 +1,129 @@
// 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/Hash/CRC32.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Debug.hpp>
struct NzHashCRC32_state
{
nzUInt32 crc;
const nzUInt32* table;
};
namespace
{
nzUInt32 crc32_reflect(nzUInt32 ref, unsigned int j)
{
nzUInt32 value = 0;
for (unsigned int i = 1; i <= j; ++i)
{
if (ref & 1)
value |= 1 << (j - i);
ref >>= 1;
}
return value;
}
static const nzUInt32 crc32_table[256] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
}
NzHashCRC32::NzHashCRC32(nzUInt32 polynomial)
{
m_state = new NzHashCRC32_state;
if (polynomial == 0x04c11db7)
m_state->table = crc32_table; // Table précalculée (Bien plus rapide)
else
{
nzUInt32* table = new nzUInt32[256];
for (unsigned int i = 0; i < 256; ++i)
{
table[i] = crc32_reflect(i, 8) << 24;
for (unsigned int j = 0; j < 8; ++j)
table[i] = (table[i] << 1) ^ (table[i] & (1 << 31) ? polynomial : 0);
table[i] = crc32_reflect(table[i], 32);
}
m_state->table = table;
}
}
NzHashCRC32::~NzHashCRC32()
{
if (m_state->table != crc32_table)
delete[] m_state->table;
delete m_state;
}
void NzHashCRC32::Append(const nzUInt8* data, unsigned int len)
{
while (len--)
m_state->crc = m_state->table[(m_state->crc ^ *data++) & 0xFF] ^ (m_state->crc >> 8);
}
void NzHashCRC32::Begin()
{
m_state->crc = 0xFFFFFFFF;
}
NzHashDigest NzHashCRC32::End()
{
m_state->crc ^= 0xFFFFFFFF;
if (NazaraEndianness == nzEndianness_LittleEndian)
NzByteSwap(&m_state->crc, sizeof(nzUInt32));
return NzHashDigest(GetHashName(), reinterpret_cast<nzUInt8*>(&m_state->crc), 4);
}
unsigned int NzHashCRC32::GetDigestLength()
{
return 4;
}
NzString NzHashCRC32::GetHashName()
{
static NzString hashName = "CRC32";
return hashName;
}

View File

@@ -0,0 +1,70 @@
// 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/Hash/Fletcher16.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Debug.hpp>
struct NzHashFletcher16_state
{
nzUInt16 sum1;
nzUInt16 sum2;
};
NzHashFletcher16::NzHashFletcher16()
{
m_state = new NzHashFletcher16_state;
}
NzHashFletcher16::~NzHashFletcher16()
{
delete m_state;
}
void NzHashFletcher16::Append(const nzUInt8* data, unsigned int len)
{
while (len)
{
unsigned int tlen = std::min(len, 21U);
len -= tlen;
do
{
m_state->sum1 += *data++;
m_state->sum2 += m_state->sum1;
}
while (--tlen);
m_state->sum1 = (m_state->sum1 & 0xff) + (m_state->sum1 >> 8);
m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8);
}
}
void NzHashFletcher16::Begin()
{
m_state->sum1 = 0xff;
m_state->sum2 = 0xff;
}
NzHashDigest NzHashFletcher16::End()
{
m_state->sum1 = (m_state->sum1 & 0xff) + (m_state->sum1 >> 8);
m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8);
nzUInt32 fletcher = (m_state->sum2 << 8) | m_state->sum1;
if (NazaraEndianness == nzEndianness_BigEndian)
NzByteSwap(&fletcher, sizeof(nzUInt32));
return NzHashDigest(GetHashName(), reinterpret_cast<nzUInt8*>(&fletcher), 2);
}
unsigned int NzHashFletcher16::GetDigestLength()
{
return 2;
}
NzString NzHashFletcher16::GetHashName()
{
static NzString hashName = "Fletcher16";
return hashName;
}

View File

@@ -0,0 +1,363 @@
// 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
/*
Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
L. Peter Deutsch
ghost@aladdin.com
*/
#include <Nazara/Core/Hash/MD5.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <cstring>
#include <Nazara/Core/Debug.hpp>
#define T_MASK (static_cast<nzUInt32>(~0))
#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
#define T3 0x242070db
#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
#define T6 0x4787c62a
#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
#define T9 0x698098d8
#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
#define T13 0x6b901122
#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
#define T16 0x49b40821
#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
#define T19 0x265e5a51
#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
#define T22 0x02441453
#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
#define T25 0x21e1cde6
#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
#define T28 0x455a14ed
#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
#define T31 0x676f02d9
#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
#define T35 0x6d9d6122
#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
#define T38 0x4bdecfa9
#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
#define T41 0x289b7ec6
#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
#define T44 0x04881d05
#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
#define T47 0x1fa27cf8
#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
#define T50 0x432aff97
#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
#define T53 0x655b59c3
#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
#define T57 0x6fa87e4f
#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
#define T60 0x4e0811a1
#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
#define T63 0x2ad7d2bb
#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
struct NzHashMD5_state
{
nzUInt32 count[2]; /* message length in bits, lsw first */
nzUInt32 abcd[4]; /* digest buffer */
nzUInt8 buf[64]; /* accumulate block */
};
namespace
{
void md5_process(NzHashMD5_state* state, const nzUInt8* data)
{
nzUInt32 a = state->abcd[0];
nzUInt32 b = state->abcd[1];
nzUInt32 c = state->abcd[2];
nzUInt32 d = state->abcd[3];
nzUInt32 t;
#ifdef NAZARA_ENDIANNESS_BIGENDIAN
/* Define storage only for big-endian CPUs. */
nzUInt32 X[16];
/*
* On big-endian machines, we must arrange the bytes in the
* right order.
*/
const nzUInt8* xp = data;
int i;
for (i = 0; i < 16; ++i, xp += 4)
X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
#else
/* Define storage for little-endian or both types of CPUs. */
nzUInt32 xbuf[16];
const nzUInt32* X;
/*
* On little-endian machines, we can process properly aligned
* data without copying it.
*/
if (!((data - reinterpret_cast<const nzUInt8*>(0)) & 3))
{
/* data are properly aligned */
X = reinterpret_cast<const nzUInt32*>(data);
}
else
{
/* not aligned */
std::memcpy(xbuf, data, 64);
X = xbuf;
}
#endif
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
/* Round 1. */
/* Let [abcd k s i] denote the operation
a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + F(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 7, T1);
SET(d, a, b, c, 1, 12, T2);
SET(c, d, a, b, 2, 17, T3);
SET(b, c, d, a, 3, 22, T4);
SET(a, b, c, d, 4, 7, T5);
SET(d, a, b, c, 5, 12, T6);
SET(c, d, a, b, 6, 17, T7);
SET(b, c, d, a, 7, 22, T8);
SET(a, b, c, d, 8, 7, T9);
SET(d, a, b, c, 9, 12, T10);
SET(c, d, a, b, 10, 17, T11);
SET(b, c, d, a, 11, 22, T12);
SET(a, b, c, d, 12, 7, T13);
SET(d, a, b, c, 13, 12, T14);
SET(c, d, a, b, 14, 17, T15);
SET(b, c, d, a, 15, 22, T16);
#undef SET
/* Round 2. */
/* Let [abcd k s i] denote the operation
a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + G(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 1, 5, T17);
SET(d, a, b, c, 6, 9, T18);
SET(c, d, a, b, 11, 14, T19);
SET(b, c, d, a, 0, 20, T20);
SET(a, b, c, d, 5, 5, T21);
SET(d, a, b, c, 10, 9, T22);
SET(c, d, a, b, 15, 14, T23);
SET(b, c, d, a, 4, 20, T24);
SET(a, b, c, d, 9, 5, T25);
SET(d, a, b, c, 14, 9, T26);
SET(c, d, a, b, 3, 14, T27);
SET(b, c, d, a, 8, 20, T28);
SET(a, b, c, d, 13, 5, T29);
SET(d, a, b, c, 2, 9, T30);
SET(c, d, a, b, 7, 14, T31);
SET(b, c, d, a, 12, 20, T32);
#undef SET
/* Round 3. */
/* Let [abcd k s t] denote the operation
a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define SET(a, b, c, d, k, s, Ti)\
t = a + H(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 5, 4, T33);
SET(d, a, b, c, 8, 11, T34);
SET(c, d, a, b, 11, 16, T35);
SET(b, c, d, a, 14, 23, T36);
SET(a, b, c, d, 1, 4, T37);
SET(d, a, b, c, 4, 11, T38);
SET(c, d, a, b, 7, 16, T39);
SET(b, c, d, a, 10, 23, T40);
SET(a, b, c, d, 13, 4, T41);
SET(d, a, b, c, 0, 11, T42);
SET(c, d, a, b, 3, 16, T43);
SET(b, c, d, a, 6, 23, T44);
SET(a, b, c, d, 9, 4, T45);
SET(d, a, b, c, 12, 11, T46);
SET(c, d, a, b, 15, 16, T47);
SET(b, c, d, a, 2, 23, T48);
#undef SET
/* Round 4. */
/* Let [abcd k s t] denote the operation
a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define SET(a, b, c, d, k, s, Ti)\
t = a + I(b,c,d) + X[k] + Ti;\
a = ROTATE_LEFT(t, s) + b
/* Do the following 16 operations. */
SET(a, b, c, d, 0, 6, T49);
SET(d, a, b, c, 7, 10, T50);
SET(c, d, a, b, 14, 15, T51);
SET(b, c, d, a, 5, 21, T52);
SET(a, b, c, d, 12, 6, T53);
SET(d, a, b, c, 3, 10, T54);
SET(c, d, a, b, 10, 15, T55);
SET(b, c, d, a, 1, 21, T56);
SET(a, b, c, d, 8, 6, T57);
SET(d, a, b, c, 15, 10, T58);
SET(c, d, a, b, 6, 15, T59);
SET(b, c, d, a, 13, 21, T60);
SET(a, b, c, d, 4, 6, T61);
SET(d, a, b, c, 11, 10, T62);
SET(c, d, a, b, 2, 15, T63);
SET(b, c, d, a, 9, 21, T64);
#undef SET
/* Then perform the following additions. (That is increment each
of the four registers by the value it had before this block
was started.) */
state->abcd[0] += a;
state->abcd[1] += b;
state->abcd[2] += c;
state->abcd[3] += d;
}
}
NzHashMD5::NzHashMD5()
{
m_state = new NzHashMD5_state;
}
NzHashMD5::~NzHashMD5()
{
delete m_state;
}
void NzHashMD5::Append(const nzUInt8* data, unsigned int len)
{
const nzUInt8 *p = data;
int left = len;
int offset = (m_state->count[0] >> 3) & 63;
nzUInt32 nbits = len << 3;
if (len <= 0)
return;
/* Update the message length. */
m_state->count[1] += len >> 29;
m_state->count[0] += nbits;
if (m_state->count[0] < nbits)
m_state->count[1]++;
/* Process an initial partial block. */
if (offset)
{
int copy = (offset + len > 64 ? 64 - offset : len);
std::memcpy(m_state->buf + offset, p, copy);
if (offset + copy < 64)
return;
p += copy;
left -= copy;
md5_process(m_state, m_state->buf);
}
/* Process full blocks. */
for (; left >= 64; p += 64, left -= 64)
md5_process(m_state, p);
/* Process a final partial block. */
if (left)
std::memcpy(m_state->buf, p, left);
}
void NzHashMD5::Begin()
{
m_state->count[0] = m_state->count[1] = 0;
m_state->abcd[0] = 0x67452301;
m_state->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
m_state->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
m_state->abcd[3] = 0x10325476;
}
NzHashDigest NzHashMD5::End()
{
static const unsigned char pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
nzUInt8 data[8];
int i;
/* Save the length before padding. */
for (i = 0; i < 8; ++i)
data[i] = static_cast<nzUInt8>(m_state->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
Append(pad, ((55 - (m_state->count[0] >> 3)) & 63) + 1);
/* Append the length. */
Append(data, 8);
nzUInt8 digest[16];
for (i = 0; i < 16; ++i)
digest[i] = static_cast<nzUInt8>(m_state->abcd[i >> 2] >> ((i & 3) << 3));
return NzHashDigest(GetHashName(), &digest[0], 16);
}
unsigned int NzHashMD5::GetDigestLength()
{
return 16;
}
NzString NzHashMD5::GetHashName()
{
static NzString hashName = "MD5";
return hashName;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,189 @@
// 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
#define NAZARA_HASHDIGEST_CPP
#include <Nazara/Core/HashDigest.hpp>
#include <Nazara/Core/Error.hpp>
#include <cstdio>
#include <cstring>
#include <utility>
#include <Nazara/Core/ThreadSafety.hpp>
#include <Nazara/Core/Debug.hpp>
NzHashDigest::NzHashDigest() :
m_digest(nullptr),
m_digestLength(0)
{
}
NzHashDigest::NzHashDigest(NzString hashName, const nzUInt8* digest, unsigned int length) :
m_hashName(hashName),
m_digestLength(length)
{
if (m_digestLength > 0)
{
m_digest = new nzUInt8[length];
std::memcpy(m_digest, digest, length);
}
else
m_digest = nullptr;
}
NzHashDigest::NzHashDigest(const NzHashDigest& rhs) :
m_hashName(rhs.m_hashName),
m_digestLength(rhs.m_digestLength)
{
if (m_digestLength > 0)
{
m_digest = new nzUInt8[m_digestLength];
std::memcpy(m_digest, rhs.m_digest, m_digestLength);
}
else
m_digest = nullptr;
}
NzHashDigest::NzHashDigest(NzHashDigest&& rhs) :
m_hashName(std::move(rhs.m_hashName)),
m_digest(rhs.m_digest),
m_digestLength(rhs.m_digestLength)
{
rhs.m_digest = nullptr;
rhs.m_digestLength = 0;
}
NzHashDigest::~NzHashDigest()
{
delete[] m_digest;
}
bool NzHashDigest::IsValid() const
{
return m_digestLength > 0;
}
const nzUInt8* NzHashDigest::GetDigest() const
{
return m_digest;
}
unsigned int NzHashDigest::GetDigestLength() const
{
return m_digestLength;
}
NzString NzHashDigest::GetHashName() const
{
return m_hashName;
}
NzString NzHashDigest::ToHex() const
{
if (m_digestLength == 0)
return NzString();
unsigned int length = m_digestLength*2;
char* hex_output = new char[length+1];
for (unsigned int i = 0; i < m_digestLength; ++i)
std::sprintf(hex_output + i*2, "%02x", m_digest[i]);
return NzString(new NzString::SharedString(length, length, 1, hex_output));
}
nzUInt8 NzHashDigest::operator[](unsigned short pos) const
{
#if NAZARA_CORE_SAFE
if (pos >= m_digestLength)
{
NazaraError("Position out of range");
return 0;
}
#endif
return m_digest[pos];
}
NzHashDigest& NzHashDigest::operator=(const NzHashDigest& rhs)
{
m_hashName = rhs.m_hashName;
m_digestLength = rhs.m_digestLength;
if (m_digestLength > 0)
{
m_digest = new nzUInt8[m_digestLength];
std::memcpy(m_digest, rhs.m_digest, m_digestLength);
}
else
m_digest = nullptr;
return *this;
}
NzHashDigest& NzHashDigest::operator=(NzHashDigest&& rhs)
{
std::swap(m_hashName, rhs.m_hashName);
std::swap(m_digest, rhs.m_digest);
std::swap(m_digestLength, rhs.m_digestLength);
return *this;
}
bool NzHashDigest::operator==(const NzHashDigest& rhs) const
{
if (m_digest == nullptr || rhs.m_digest == nullptr)
return m_digest == rhs.m_digest;
if (m_digestLength != rhs.m_digestLength)
return false;
return m_hashName == rhs.m_hashName && std::memcmp(m_digest, rhs.m_digest, m_digestLength) == 0;
}
bool NzHashDigest::operator!=(const NzHashDigest& rhs) const
{
return !operator==(rhs);
}
bool NzHashDigest::operator<(const NzHashDigest& rhs) const
{
if (rhs.m_digest == nullptr)
return false;
if (m_digest == nullptr)
return true;
int cmp = NzString::Compare(m_hashName, rhs.m_hashName);
if (cmp == 0)
{
cmp = std::memcmp(m_digest, rhs.m_digest, std::min(m_digestLength, rhs.m_digestLength));
if (cmp == 0)
return m_digestLength < rhs.m_digestLength;
else
return cmp < 0;
}
else
return cmp < 0;
}
bool NzHashDigest::operator<=(const NzHashDigest& rhs) const
{
return !rhs.operator<(*this);
}
bool NzHashDigest::operator>(const NzHashDigest& rhs) const
{
return rhs.operator<(*this);
}
bool NzHashDigest::operator>=(const NzHashDigest& rhs) const
{
return !operator<(rhs);
}
std::ostream& operator<<(std::ostream& out, const NzHashDigest& hashstring)
{
out << hashstring.ToHex();
return out;
}

View File

@@ -0,0 +1,21 @@
// 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
#define NAZARA_HASHABLE_CPP
#include <Nazara/Core/Hashable.hpp>
#include <Nazara/Core/Hash.hpp>
#include <Nazara/Core/Debug.hpp>
NzHashDigest NzHashable::GetHash(nzHash hash) const
{
NzHash h(hash);
return h.Hash(*this);
}
NzHashDigest NzHashable::GetHash(NzHashImpl* impl) const
{
NzHash h(impl);
return h.Hash(*this);
}

20
src/Nazara/Core/Lock.cpp Normal file
View File

@@ -0,0 +1,20 @@
// 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
#define NAZARA_LOCK_CPP
#include <Nazara/Core/Lock.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/Debug.hpp>
NzLock::NzLock(NzMutex& mutex) :
m_mutex(mutex)
{
m_mutex.Lock();
}
NzLock::~NzLock()
{
m_mutex.Unlock();
}

161
src/Nazara/Core/Log.cpp Normal file
View File

@@ -0,0 +1,161 @@
// 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
#define NAZARA_LOG_CPP
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Math/Basic.hpp>
#include <ctime>
#if NAZARA_CORE_REDIRECT_TO_CERR_ON_LOG_FAILURE
#include <cstdio>
#endif
#include <Nazara/Core/ThreadSafety.hpp>
#include <Nazara/Core/Debug.hpp>
namespace
{
NzString errorType[] = {
"Assert failed: ", // nzErrorType_AssertFailed
"Internal error: ", // nzErrorType_Internal
"Error: ", // nzErrorType_Normal
"Warning: " // nzErrorType_Warning
};
}
NzLog::NzLog() :
m_filePath("NazaraLog.log"),
m_file(nullptr),
m_append(false),
m_enabled(true),
m_writeTime(true)
{
}
NzLog::~NzLog()
{
delete m_file;
}
void NzLog::Enable(bool enable)
{
NazaraLock(m_mutex)
if (m_enabled == enable)
return;
m_enabled = enable;
if (!m_enabled && m_file)
{
delete m_file;
m_file = nullptr;
}
}
void NzLog::EnableAppend(bool enable)
{
NazaraLock(m_mutex)
m_append = enable;
if (!m_append && m_file)
{
m_file->Delete();
m_file = nullptr;
}
}
void NzLog::EnableDateTime(bool enable)
{
NazaraLock(m_mutex)
m_writeTime = enable;
}
NzString NzLog::GetFile() const
{
NazaraLock(m_mutex)
if (m_file)
return m_file->GetFilePath();
else
return NzString();
}
bool NzLog::IsEnabled() const
{
NazaraLock(m_mutex)
return m_enabled;
}
void NzLog::SetFile(const NzString& filePath)
{
NazaraLock(m_mutex)
m_filePath = filePath;
if (m_file)
m_file->SetFile(filePath);
}
void NzLog::Write(const NzString& string)
{
NazaraLock(m_mutex)
if (m_enabled)
{
if (!m_file)
m_file = new NzFile(m_filePath, NzFile::Text | NzFile::WriteOnly | ((m_append) ? NzFile::Append : NzFile::Truncate));
NzString line;
if (m_writeTime)
{
line.Reserve(23 + string.GetSize() + 1);
line.Resize(23);
time_t currentTime = std::time(nullptr);
std::strftime(&line[0], 24, "%d/%m/%Y - %H:%M:%S: ", std::localtime(&currentTime));
}
else
line.Reserve(string.GetSize() + 1);
line += string;
line += '\n';
#if NAZARA_CORE_REDIRECT_TO_CERR_ON_LOG_FAILURE
if (!m_file->IsOpen() || !m_file->Write(line))
std::fputs(line.GetBuffer(), stderr);
#else
if (m_file->IsOpen())
m_file->Write(line);
#endif
}
}
void NzLog::WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func)
{
NzString stream;
stream.Reserve(errorType[type].GetSize() + error.GetSize() + 2 + file.GetSize() + 1 + NzGetNumberLength(line) +2 + func.GetSize() + 1);
stream += errorType[type];
stream += error;
stream += " (";
stream += file;
stream += ':';
stream += line;
stream += ": ";
stream += func;
stream += ')';
/*NzStringStream stream;
stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')';*/
Write(stream);
}
NzLog* NzLog::Instance()
{
static NzLog log;
return &log;
}

42
src/Nazara/Core/Mutex.cpp Normal file
View 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
#define NAZARA_MUTEX_CPP
#include <Nazara/Core/Mutex.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/MutexImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/MutexImpl.hpp>
#else
#error Lack of implementation: Mutex
#endif
#include <Nazara/Core/Debug.hpp>
NzMutex::NzMutex()
{
m_impl = new NzMutexImpl;
}
NzMutex::~NzMutex()
{
delete m_impl;
}
void NzMutex::Lock()
{
m_impl->Lock();
}
bool NzMutex::TryLock()
{
return m_impl->TryLock();
}
void NzMutex::Unlock()
{
m_impl->Unlock();
}

View File

@@ -0,0 +1,47 @@
// 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
#define NAZARA_SEMAPHORE_CPP
#include <Nazara/Core/Semaphore.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/SemaphoreImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/SemaphoreImpl.hpp>
#else
#error Lack of implementation: Semaphore
#endif
#include <Nazara/Core/Debug.hpp>
NzSemaphore::NzSemaphore(unsigned int count)
{
m_impl = new NzSemaphoreImpl(count);
}
NzSemaphore::~NzSemaphore()
{
delete m_impl;
}
unsigned int NzSemaphore::GetCount() const
{
return m_impl->GetCount();
}
void NzSemaphore::Post()
{
m_impl->Post();
}
void NzSemaphore::Wait()
{
m_impl->Wait();
}
bool NzSemaphore::Wait(nzUInt32 timeout)
{
return m_impl->Wait(timeout);
}

5113
src/Nazara/Core/String.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,217 @@
// 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
#define NAZARA_STRINGSTREAM_CPP
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Core/Debug.hpp>
NzStringStream::NzStringStream() :
m_bufferSize(0)
{
}
NzStringStream::NzStringStream(const NzString& str) :
m_bufferSize(str.GetSize())
{
m_strings.push_back(str);
}
NzString NzStringStream::ToString() const
{
NazaraLock(m_mutex)
NzString string;
string.Reserve(m_bufferSize);
for (const NzString& str : m_strings)
string += str;
return string;
}
NzStringStream& NzStringStream::operator<<(bool boolean)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Boolean(boolean));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(short number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(unsigned short number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(int number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(unsigned int number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(long number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(unsigned long number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(long long number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(unsigned long long number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(float number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(double number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(long double number)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Number(number));
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(char character)
{
NazaraLock(m_mutex)
m_strings.push_back(character);
m_bufferSize++;
return *this;
}
NzStringStream& NzStringStream::operator<<(unsigned char character)
{
NazaraLock(m_mutex)
m_strings.push_back(character);
m_bufferSize++;
return *this;
}
NzStringStream& NzStringStream::operator<<(const char* string)
{
NazaraLock(m_mutex)
m_strings.push_back(string);
m_bufferSize += m_strings.back().GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(const std::string& string)
{
NazaraLock(m_mutex)
m_strings.push_back(string);
m_bufferSize += string.size();
return *this;
}
NzStringStream& NzStringStream::operator<<(const NzString& string)
{
NazaraLock(m_mutex)
m_strings.push_back(string);
m_bufferSize += string.GetSize();
return *this;
}
NzStringStream& NzStringStream::operator<<(const void* ptr)
{
NazaraLock(m_mutex)
m_strings.push_back(NzString::Pointer(ptr));
m_bufferSize += sizeof(void*)*2;
return *this;
}
NzStringStream::operator NzString() const
{
return ToString();
}

View File

@@ -0,0 +1,80 @@
// 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
#define NAZARA_THREAD_CPP
#include <Nazara/Core/Thread.hpp>
#include <Nazara/Core/Error.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/ThreadImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/ThreadImpl.hpp>
#else
#error Thread has no implementation
#endif
#include <Nazara/Core/Debug.hpp>
NzThread::~NzThread()
{
if (!m_independent)
Join();
else
delete m_impl;
}
NzThread::Id NzThread::GetId() const
{
if (m_impl)
return m_impl->GetId();
else
return NzThread::Id();
}
bool NzThread::IsCurrent() const
{
if (m_impl)
return m_impl->IsCurrent();
else
return false;
}
void NzThread::Launch(bool independent)
{
Join();
m_independent = independent;
m_impl = new NzThreadImpl(this);
}
void NzThread::Join()
{
if (m_impl)
{
#if NAZARA_CORE_SAFE
if (m_impl->IsCurrent())
{
NazaraError("A thread cannot join itself");
return;
}
#endif
m_impl->Join();
delete m_impl;
m_impl = nullptr;
}
}
void NzThread::Terminate()
{
if (m_impl)
{
m_impl->Terminate();
delete m_impl;
m_impl = nullptr;
}
}

View 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
#define NAZARA_THREADCONDITION_CPP
#include <Nazara/Core/ThreadCondition.hpp>
#include <Nazara/Core/Mutex.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Core/Win32/ThreadConditionImpl.hpp>
#elif defined(NAZARA_PLATFORM_POSIX)
#include <Nazara/Core/Posix/ThreadConditionImpl.hpp>
#else
#error Thread condition has no implementation
#endif
#include <Nazara/Core/Debug.hpp>
NzThreadCondition::NzThreadCondition()
{
m_impl = new NzThreadConditionImpl;
}
NzThreadCondition::~NzThreadCondition()
{
delete m_impl;
}
void NzThreadCondition::Signal()
{
m_impl->Signal();
}
void NzThreadCondition::SignalAll()
{
m_impl->SignalAll();
}
void NzThreadCondition::Wait(NzMutex* mutex)
{
m_impl->Wait(mutex->m_impl);
}
bool NzThreadCondition::Wait(NzMutex* mutex, nzUInt32 timeout)
{
return m_impl->Wait(mutex->m_impl, timeout);
}

View File

@@ -0,0 +1,55 @@
// 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
#define NAZARA_UNICODE_CPP
#include <Nazara/Core/Unicode.hpp>
#include <Nazara/Core/Debug.hpp>
namespace NzUnicode
{
#if NAZARA_CORE_INCLUDE_UNICODEDATA
struct Character
{
nzUInt16 category; // Le type du caractère
nzUInt8 direction; // Le sens de lecure du caractère
nzUInt32 lowerCase; // Le caractère correspondant en minuscule
nzUInt32 titleCase; // Le caractère correspondant en titre
nzUInt32 upperCase; // Le caractère correspondant en majuscule
};
#include <Nazara/Core/UnicodeData.hpp>
#else // Implémentation bidon
Category GetCategory(char32_t character)
{
NazaraUnused(character);
return Category_NoCategory;
}
Direction GetDirection(char32_t character)
{
NazaraUnused(character);
return Direction_Boundary_Neutral;
}
char32_t GetLowercase(char32_t character)
{
return character;
}
char32_t GetTitlecase(char32_t character)
{
return character;
}
char32_t GetUppercase(char32_t character)
{
return character;
}
#endif
}

View 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
}

View 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

View 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;
}

View 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

View 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);
}

View 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

View 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;
}
}

View 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

View 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);
}

View 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

View 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
}

View 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

View 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
}

View 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

View 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);
}

View 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

View 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