core/systems/LibrarySys.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jan 27 09:25:07 2007 +0000 (2007-01-27)
changeset 401 18fc0da83775
parent 370 d3a484f98f6d
child 651 7129f1566129
permissions -rw-r--r--
fixed this using /MD in release mode
     1 /**
     2  * ===============================================================
     3  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     4  * ===============================================================
     5  *
     6  * This file is not open source and may not be copied without explicit
     7  * written permission of AlliedModders LLC.  This file may not be redistributed 
     8  * in whole or significant part.
     9  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    10  *
    11  * Version: $Id$
    12  */
    13 
    14 #include <stdio.h>
    15 #include <stdarg.h>
    16 #include <string.h>
    17 #include <sm_platform.h>
    18 #include "LibrarySys.h"
    19 
    20 LibrarySystem g_LibSys;
    21 
    22 CLibrary::~CLibrary()
    23 {
    24 	if (m_lib)
    25 	{
    26 #if defined PLATFORM_WINDOWS
    27 		FreeLibrary(m_lib);
    28 #elif defined PLATFORM_POSIX
    29 		dlclose(m_lib);
    30 #endif
    31 		m_lib = NULL;
    32 	}
    33 }
    34 
    35 CLibrary::CLibrary(LibraryHandle me)
    36 {
    37 	m_lib = me;
    38 }
    39 
    40 void CLibrary::CloseLibrary()
    41 {
    42 	delete this;
    43 }
    44 
    45 void *CLibrary::GetSymbolAddress(const char *symname)
    46 {
    47 #if defined PLATFORM_WINDOWS
    48 	return GetProcAddress(m_lib, symname);
    49 #elif defined PLATFORM_POSIX
    50 	return dlsym(m_lib, symname);
    51 #endif
    52 }
    53 
    54 
    55 /********************
    56  ** Directory Code **
    57  ********************/
    58 
    59 
    60 CDirectory::CDirectory(const char *path)
    61 {
    62 #if defined PLATFORM_WINDOWS
    63 	char newpath[PLATFORM_MAX_PATH];
    64 	snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
    65 	m_dir = FindFirstFileA(newpath, &m_fd);
    66 	if (!IsValid())
    67 	{
    68 		m_fd.cFileName[0] = '\0';
    69 	}
    70 #elif defined PLATFORM_POSIX
    71 	m_dir = opendir(path);
    72 	if (IsValid())
    73 	{
    74 		/* :TODO: we need to read past "." and ".."! */
    75 		ep = readdir(m_dir);
    76 		snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
    77 	} else {
    78 		ep = NULL;
    79 	}
    80 #endif
    81 }
    82 
    83 CDirectory::~CDirectory()
    84 {
    85 	if (IsValid())
    86 	{
    87 #if defined PLATFORM_WINDOWS
    88 		FindClose(m_dir);
    89 #elif defined PLATFORM_POSIX
    90 		closedir(m_dir);
    91 #endif
    92 	}
    93 }
    94 
    95 void CDirectory::NextEntry()
    96 {
    97 #if defined PLATFORM_WINDOWS
    98 	if (FindNextFile(m_dir, &m_fd) == 0)
    99 	{
   100 		FindClose(m_dir);
   101 		m_dir = INVALID_HANDLE_VALUE;
   102 	}
   103 #elif defined PLATFORM_POSIX
   104 	if ((ep=readdir(m_dir)) == NULL)
   105 	{
   106 		closedir(m_dir);
   107 		m_dir = NULL;
   108 	}
   109 #endif
   110 }
   111 
   112 bool CDirectory::IsEntryValid()
   113 {
   114 	return IsValid();
   115 }
   116 
   117 bool CDirectory::IsEntryDirectory()
   118 {
   119 #if defined PLATFORM_WINDOWS
   120 	return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
   121 #elif defined PLATFORM_LINUX
   122 	char temppath[PLATFORM_MAX_PATH];
   123 	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
   124 	return g_LibSys.IsPathDirectory(temppath);
   125 #endif
   126 }
   127 
   128 bool CDirectory::IsEntryFile()
   129 {
   130 #if defined PLATFORM_WINDOWS
   131 	return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
   132 #elif defined PLATFORM_POSIX
   133 	char temppath[PLATFORM_MAX_PATH];
   134 	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
   135 	return g_LibSys.IsPathFile(temppath);
   136 #endif
   137 }
   138 
   139 const char *CDirectory::GetEntryName()
   140 {
   141 #if defined PLATFORM_WINDOWS
   142 	return m_fd.cFileName;
   143 #elif defined PLATFORM_LINUX
   144 	return ep ? ep->d_name : "";
   145 #endif
   146 }
   147 
   148 bool CDirectory::MoreFiles()
   149 {
   150 	return IsValid();
   151 }
   152 
   153 bool CDirectory::IsValid()
   154 {
   155 #if defined PLATFORM_WINDOWS
   156 	return (m_dir != INVALID_HANDLE_VALUE);
   157 #elif defined PLATFORM_LINUX
   158 	return (m_dir != NULL);
   159 #endif
   160 }
   161 
   162 
   163 /*************************
   164  ** Library System Code **
   165  *************************/
   166 
   167 
   168 bool LibrarySystem::PathExists(const char *path)
   169 {
   170 #if defined PLATFORM_WINDOWS
   171 	DWORD attr = GetFileAttributesA(path);
   172 
   173 	return (attr != INVALID_FILE_ATTRIBUTES);
   174 #elif defined PLATFORM_POSIX
   175 	struct stat s;
   176 
   177 	return (stat(path, &s) == 0);
   178 #endif
   179 }
   180 
   181 bool LibrarySystem::IsPathFile(const char *path)
   182 {
   183 #if defined PLATFORM_WINDOWS
   184 	DWORD attr = GetFileAttributes(path);
   185 
   186 	if (attr == INVALID_FILE_ATTRIBUTES)
   187 	{
   188 		return false;
   189 	}
   190 
   191 	if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
   192 	{
   193 		return false;
   194 	}
   195 
   196 	return true;
   197 #elif defined PLATFORM_LINUX
   198 	struct stat s;
   199 
   200 	if (stat(path, &s) != 0)
   201 	{
   202 		return false;
   203 	}
   204 
   205 	return S_ISREG(s.st_mode) ? true : false;
   206 #endif
   207 }
   208 
   209 bool LibrarySystem::IsPathDirectory(const char *path)
   210 {
   211 #if defined PLATFORM_WINDOWS
   212 	DWORD attr = GetFileAttributes(path);
   213 
   214 	if (attr == INVALID_FILE_ATTRIBUTES)
   215 	{
   216 		return false;
   217 	}
   218 
   219 	if (attr & FILE_ATTRIBUTE_DIRECTORY)
   220 	{
   221 		return true;
   222 	}
   223 
   224 #elif defined PLATFORM_LINUX
   225 	struct stat s;
   226 
   227 	if (stat(path, &s) != 0)
   228 	{
   229 		return false;
   230 	}
   231 
   232 	if (S_ISDIR(s.st_mode))
   233 	{
   234 		return true;
   235 	}
   236 #endif
   237 
   238 	return false;
   239 }
   240 
   241 IDirectory *LibrarySystem::OpenDirectory(const char *path)
   242 {
   243 	CDirectory *dir = new CDirectory(path);
   244 
   245 	if (!dir->IsValid())
   246 	{
   247 		delete dir;
   248 		return NULL;
   249 	}
   250 
   251 	return dir;
   252 }
   253 
   254 void LibrarySystem::GetPlatformError(char *error, size_t err_max)
   255 {
   256 	if (error && err_max)
   257 	{
   258 #if defined PLATFORM_WINDOWS
   259 		DWORD dw = GetLastError();
   260 		FormatMessageA(
   261 			FORMAT_MESSAGE_FROM_SYSTEM,
   262 			NULL,
   263 			dw,
   264 			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   265 			(LPSTR)error,
   266 			err_max,
   267 			NULL);
   268 #elif defined PLATFORM_POSIX
   269 		snprintf(error, err_max, "%s", strerror(errno));
   270 #endif
   271 	}
   272 }
   273 
   274 void LibrarySystem::CloseDirectory(IDirectory *dir)
   275 {
   276 	delete dir;
   277 }
   278 
   279 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t err_max)
   280 {
   281 	LibraryHandle lib;
   282 #if defined PLATFORM_WINDOWS
   283 	lib = LoadLibraryA(path);
   284 	if (!lib)
   285 	{
   286 		GetPlatformError(error, err_max);
   287 		return false;
   288 	}
   289 #elif defined PLATFORM_POSIX
   290 	lib = dlopen(path, RTLD_NOW);
   291 	if (!lib)
   292 	{
   293 		GetPlatformError(error, err_max);
   294 		return false;
   295 	}
   296 #endif
   297 
   298 	return new CLibrary(lib);
   299 }
   300 
   301 size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
   302 {
   303 	va_list ap;
   304 	va_start(ap,fmt);
   305 	size_t mylen = vsnprintf(buffer, len, fmt, ap);
   306 	va_end(ap);
   307 
   308 	mylen = (mylen >= len) ? (len - 1) : mylen;
   309 
   310 	for (size_t i=0; i<mylen; i++)
   311 	{
   312 		if (buffer[i] == PLATFORM_SEP_ALTCHAR)
   313 		{
   314 			buffer[i] = PLATFORM_SEP_CHAR;
   315 		}
   316 	}
   317 
   318 	return mylen;
   319 }