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