began platform support

initial import of platform library code
tested on win32

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40146
This commit is contained in:
David Anderson 2006-11-05 02:47:13 +00:00
parent c63d26e1c5
commit f83a597e49
6 changed files with 422 additions and 6 deletions

View File

@ -10,6 +10,11 @@ namespace SourceMod
class ILibrary
{
public:
virtual ~ILibrary()
{
/* Calling delete will call CloseLibrary! */
};
public:
/**
* @brief Closes dynamic library and invalidates pointer.
@ -30,6 +35,10 @@ namespace SourceMod
*/
class IDirectory
{
public:
virtual ~IDirectory()
{
}
public:
/**
* @brief Returns true if there are more files to read, false otherwise.
@ -90,7 +99,7 @@ namespace SourceMod
* @param err_max Maximum length of error buffer.
* @return Pointer to an IDirectory, NULL if failed.
*/
virtual IDirectory *OpenDirectory(const char *path, char *error, size_t err_max) =0;
virtual IDirectory *OpenDirectory(const char *path) =0;
/**
* @brief Closes a directory and frees its handle.
@ -99,6 +108,11 @@ namespace SourceMod
*/
virtual void CloseDirectory(IDirectory *dir) =0;
/**
* @brief Returns true if a path exists.
*/
virtual bool PathExists(const char *path) =0;
/**
* @brief Returns true if the path is a normal file.
*/
@ -108,6 +122,17 @@ namespace SourceMod
* @brief Returns true if the path is a normal directory.
*/
virtual bool IsPathDirectory(const char *path) =0;
/**
* @brief Gets a platform-specific error message.
* This should only be called when an ILibrary function fails.
* Win32 equivalent: GetLastError() + FormatMessage()
* POSIX equivalent: errno + strerror()
*
* @param error Error message buffer.
* @param err_max Maximum length of error buffer.
*/
virtual void GetPlatformError(char *error, size_t err_max) =0;
};
};

View File

@ -1,6 +1,7 @@
#include <oslink.h>
#include "mm_api.h"
#include "sm_version.h"
#include "systems/LibrarySys.h"
SourceMod_Core g_SourceMod;

View File

@ -40,8 +40,8 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\interfaces"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS"
AdditionalIncludeDirectories="..\interfaces;..\"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@ -117,8 +117,8 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\interfaces"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS"
AdditionalIncludeDirectories="..\interfaces;..\"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
@ -192,6 +192,10 @@
RelativePath="..\mm_api.h"
>
</File>
<File
RelativePath="..\sm_platform.h"
>
</File>
<File
RelativePath="..\sm_version.h"
>
@ -215,7 +219,7 @@
>
</File>
<File
RelativePath="..\interfaces\IPluginMngr.h"
RelativePath="..\interfaces\IPluginSys.h"
>
</File>
<File
@ -223,6 +227,26 @@
>
</File>
</Filter>
<Filter
Name="Systems"
>
<Filter
Name="Header Files"
>
<File
RelativePath="..\systems\LibrarySys.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
>
<File
RelativePath="..\systems\LibrarySys.cpp"
>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>

23
core/sm_platform.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef _INCLUDE_SOURCEMOD_PLATFORM_H_
#define _INCLUDE_SOURCEMOD_PLATFORM_H_
#if defined WIN32 || defined WIN64
#define PLATFORM_WINDOWS
#if !defined WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#if !defined snprintf
#define snprintf _snprintf
#endif
#include <windows.h>
#include <direct.h>
#define PLATFORM_MAX_PATH MAX_PATH
#else if defined __linux__
#define PLATFORM_LINUX
#define PLATFORM_POSIX
#include <dirent.h>
#include <errno.h>
#define PLATFORM_MAX_PATH PATH_MAX
#endif
#endif //_INCLUDE_SOURCEMOD_PLATFORM_H_

278
core/systems/LibrarySys.cpp Normal file
View File

@ -0,0 +1,278 @@
#include <stdio.h>
#include "LibrarySys.h"
LibrarySystem g_LibSys;
CLibrary::~CLibrary()
{
if (m_lib)
{
#if defined PLATFORM_WINDOWS
FreeLibrary(m_lib);
#else if defined PLATFORM_POSIX
dlclose(m_lib);
#endif
m_lib = NULL;
}
}
CLibrary::CLibrary(LibraryHandle me)
{
m_lib = me;
}
void CLibrary::CloseLibrary()
{
delete this;
}
void *CLibrary::GetSymbolAddress(const char *symname)
{
#if defined PLATFORM_WINDOWS
return GetProcAddress(m_lib, symname);
#else if defined PLATFORM_POSIX
return dlsym(m_lib, symname);
#endif
}
/********************
** Directory Code **
********************/
CDirectory::CDirectory(const char *path)
{
#if defined PLATFORM_WINDOWS
char newpath[PLATFORM_MAX_PATH];
snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
m_dir = FindFirstFileA(newpath, &m_fd);
if (!IsValid())
{
m_fd.cFileName[0] = '\0';
}
#else if defined PLATFORM_POSIX
m_dir = opendir(path);
if (IsValid())
{
/* :TODO: we need to read past "." and ".."! */
ep = readdir(dp);
snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
} else {
ep = NULL;
}
#endif
}
CDirectory::~CDirectory()
{
if (IsValid())
{
#if defined PLATFORM_WINDOWS
FindClose(m_dir);
#else if defined PLATFORM_POSIX
closedir(m_dir);
#endif
}
}
void CDirectory::NextEntry()
{
#if defined PLATFORM_WINDOWS
if (FindNextFile(m_dir, &m_fd) == 0)
{
FindClose(m_dir);
m_dir = INVALID_HANDLE_VALUE;
}
#else if defined PLATFORM_POSIX
if ((ep=readdir(m_dir) == NULL)
{
closedir(m_dir);
m_dir = NULL;
}
#endif
}
bool CDirectory::IsEntryDirectory()
{
#if defined PLATFORM_WINDOWS
return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
#else if defined PLATFORM_LINUX
char temppath[PLATFORM_MAX_PATH];
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
return g_LibrarySys.IsPathDirectory(temppath);
#endif
}
bool CDirectory::IsEntryFile()
{
#if defined PLATFORM_WINDOWS
return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
#else if defined PLATFORM_POSIX
char temppath[PLATFORM_MAX_PATH];
snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
return g_LibrarySys.IsPathFile(temppath);
#endif
}
const char *CDirectory::GetEntryName()
{
#if defined PLATFORM_WINDOWS
return m_fd.cFileName;
#else if defined PLATFORM_LINUX
return ep ? ep->d_name : "";
#endif
}
bool CDirectory::MoreFiles()
{
return IsValid();
}
bool CDirectory::IsValid()
{
#if defined PLATFORM_WINDOWS
return (m_dir != INVALID_HANDLE_VALUE);
#else if defined PLATFORM_LINUX
return (m_dir != NULL);
#endif
}
/*************************
** Library System Code **
*************************/
bool LibrarySystem::PathExists(const char *path)
{
#if defined PLATFORM_WINDOWS
DWORD attr = GetFileAttributesA(path);
return (attr != INVALID_FILE_ATTRIBUTES);
#else if defined PLATFORM_POSIX
struct stat s;
return (stat(path, &s) == 0);
#endif
}
bool LibrarySystem::IsPathFile(const char *path)
{
#if defined PLATFORM_WINDOWS
DWORD attr = GetFileAttributes(path);
if (attr == INVALID_FILE_ATTRIBUTES)
{
return false;
}
if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
{
return false;
}
return true;
#else if defined PLATFORM_LINUX
struct stat s;
if (stat(path, &s) != 0)
{
return false;
}
return S_ISREG(s.st_mode) ? true : false;
#endif
}
bool LibrarySystem::IsPathDirectory(const char *path)
{
#if defined PLATFORM_WINDOWS
DWORD attr = GetFileAttributes(path);
if (attr == INVALID_FILE_ATTRIBUTES)
{
return false;
}
if (attr & FILE_ATTRIBUTE_DIRECTORY)
{
return true;
}
#else if defined PLATFORM_LINUX
struct stat s;
if (stat(path, &s) != 0)
{
return false;
}
if (S_ISDIR(s.st_mode))
{
return true;
}
#endif
return false;
}
IDirectory *LibrarySystem::OpenDirectory(const char *path)
{
CDirectory *dir = new CDirectory(path);
if (!dir->IsValid())
{
delete dir;
return NULL;
}
return dir;
}
void LibrarySystem::GetPlatformError(char *error, size_t err_max)
{
if (error && err_max)
{
#if defined PLATFORM_WINDOWS
DWORD dw = GetLastError();
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)error,
err_max,
NULL);
#else if defined PLATFORM_POSIX
snprintf(error, err_max, "%s", strerror(errno));
#endif
}
}
void LibrarySystem::CloseDirectory(IDirectory *dir)
{
delete dir;
}
ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t err_max)
{
LibraryHandle lib;
#if defined PLATFORM_WINDOWS
lib = LoadLibraryA(path);
if (!lib)
{
GetPlatformError(error, err_max);
return false;
}
#else if defined PLATFORM_POSIX
lib = dlopen(path, RTLD_NOW);
if (!lib)
{
GetPlatformError(error, err_max);
return false;
}
#endif
return new CLibrary(lib);
}

65
core/systems/LibrarySys.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef _INCLUDE_SOURCEMOD_SYSTEM_LIBRARY_H_
#define _INCLUDE_SOURCEMOD_SYSTEM_LIBRARY_H_
#include <ILibrarySys.h>
#include "sm_platform.h"
using namespace SourceMod;
#if defined PLATFORM_WINDOWS
typedef HMODULE LibraryHandle;
#else if defined PLATFORM_POSIX
typedef void * LibraryHandle;
#endif
class CDirectory : public IDirectory
{
public:
CDirectory(const char *path);
~CDirectory();
public:
virtual bool MoreFiles();
virtual void NextEntry();
virtual const char *GetEntryName();
virtual bool IsEntryDirectory();
virtual bool IsEntryFile();
public:
bool IsValid();
private:
#if defined PLATFORM_WINDOWS
HANDLE m_dir;
WIN32_FIND_DATAA m_fd;
#else if defined PLATFORM_LINUX
DIR *m_dir;
struct dirent *ep;
char m_origpath[PLATFORM_MAX_PATH];
#endif
};
class CLibrary : public ILibrary
{
public:
CLibrary(LibraryHandle me);
~CLibrary();
public:
virtual void CloseLibrary();
virtual void *GetSymbolAddress(const char *symname);
private:
LibraryHandle m_lib;
};
class LibrarySystem
{
public:
virtual ILibrary *OpenLibrary(const char *path, char *error, size_t err_max);
virtual IDirectory *OpenDirectory(const char *path);
virtual void CloseDirectory(IDirectory *dir);
virtual bool PathExists(const char *path);
virtual bool IsPathFile(const char *path);
virtual bool IsPathDirectory(const char *path);
virtual void GetPlatformError(char *error, size_t err_max);
};
extern LibrarySystem g_LibSys;
#endif //_INCLUDE_SOURCEMOD_SYSTEM_LIBRARY_H_