core/systems/LibrarySys.cpp
author Scott Ehlert <ds@alliedmods.net>
Fri Jun 01 06:33:54 2007 +0000 (2007-06-01)
changeset 873 a2136b3be10d
parent 829 3746e673414e
child 978 54782a83a1ef
permissions -rw-r--r--
- Added natives: PrintToChat() and PrintCenterText()
- Bit of reorganization with moving some natives from sourcemod.inc to halflife.inc
     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 "LibrarySys.h"
    20 
    21 LibrarySystem g_LibSys;
    22 
    23 CLibrary::~CLibrary()
    24 {
    25 	if (m_lib)
    26 	{
    27 #if defined PLATFORM_WINDOWS
    28 		FreeLibrary(m_lib);
    29 #elif defined PLATFORM_POSIX
    30 		dlclose(m_lib);
    31 #endif
    32 		m_lib = NULL;
    33 	}
    34 }
    35 
    36 CLibrary::CLibrary(LibraryHandle me)
    37 {
    38 	m_lib = me;
    39 }
    40 
    41 void CLibrary::CloseLibrary()
    42 {
    43 	delete this;
    44 }
    45 
    46 void *CLibrary::GetSymbolAddress(const char *symname)
    47 {
    48 #if defined PLATFORM_WINDOWS
    49 	return GetProcAddress(m_lib, symname);
    50 #elif defined PLATFORM_POSIX
    51 	return dlsym(m_lib, symname);
    52 #endif
    53 }
    54 
    55 
    56 /********************
    57  ** Directory Code **
    58  ********************/
    59 
    60 
    61 CDirectory::CDirectory(const char *path)
    62 {
    63 #if defined PLATFORM_WINDOWS
    64 	char newpath[PLATFORM_MAX_PATH];
    65 	snprintf(newpath, sizeof(newpath), "%s\\*.*", path);
    66 	m_dir = FindFirstFileA(newpath, &m_fd);
    67 	if (!IsValid())
    68 	{
    69 		m_fd.cFileName[0] = '\0';
    70 	}
    71 #elif defined PLATFORM_POSIX
    72 	m_dir = opendir(path);
    73 	if (IsValid())
    74 	{
    75 		/* :TODO: we need to read past "." and ".."! */
    76 		ep = readdir(m_dir);
    77 		snprintf(m_origpath, PLATFORM_MAX_PATH, "%s", path);
    78 	} else {
    79 		ep = NULL;
    80 	}
    81 #endif
    82 }
    83 
    84 CDirectory::~CDirectory()
    85 {
    86 	if (IsValid())
    87 	{
    88 #if defined PLATFORM_WINDOWS
    89 		FindClose(m_dir);
    90 #elif defined PLATFORM_POSIX
    91 		closedir(m_dir);
    92 #endif
    93 	}
    94 }
    95 
    96 void CDirectory::NextEntry()
    97 {
    98 #if defined PLATFORM_WINDOWS
    99 	if (FindNextFile(m_dir, &m_fd) == 0)
   100 	{
   101 		FindClose(m_dir);
   102 		m_dir = INVALID_HANDLE_VALUE;
   103 	}
   104 #elif defined PLATFORM_POSIX
   105 	if ((ep=readdir(m_dir)) == NULL)
   106 	{
   107 		closedir(m_dir);
   108 		m_dir = NULL;
   109 	}
   110 #endif
   111 }
   112 
   113 bool CDirectory::IsEntryValid()
   114 {
   115 	return IsValid();
   116 }
   117 
   118 bool CDirectory::IsEntryDirectory()
   119 {
   120 #if defined PLATFORM_WINDOWS
   121 	return ((m_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
   122 #elif defined PLATFORM_LINUX
   123 	char temppath[PLATFORM_MAX_PATH];
   124 	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
   125 	return g_LibSys.IsPathDirectory(temppath);
   126 #endif
   127 }
   128 
   129 bool CDirectory::IsEntryFile()
   130 {
   131 #if defined PLATFORM_WINDOWS
   132 	return !(m_fd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE));
   133 #elif defined PLATFORM_POSIX
   134 	char temppath[PLATFORM_MAX_PATH];
   135 	snprintf(temppath, sizeof(temppath), "%s/%s", m_origpath, GetEntryName());
   136 	return g_LibSys.IsPathFile(temppath);
   137 #endif
   138 }
   139 
   140 const char *CDirectory::GetEntryName()
   141 {
   142 #if defined PLATFORM_WINDOWS
   143 	return m_fd.cFileName;
   144 #elif defined PLATFORM_LINUX
   145 	return ep ? ep->d_name : "";
   146 #endif
   147 }
   148 
   149 bool CDirectory::MoreFiles()
   150 {
   151 	return IsValid();
   152 }
   153 
   154 bool CDirectory::IsValid()
   155 {
   156 #if defined PLATFORM_WINDOWS
   157 	return (m_dir != INVALID_HANDLE_VALUE);
   158 #elif defined PLATFORM_LINUX
   159 	return (m_dir != NULL);
   160 #endif
   161 }
   162 
   163 
   164 /*************************
   165  ** Library System Code **
   166  *************************/
   167 
   168 
   169 bool LibrarySystem::PathExists(const char *path)
   170 {
   171 #if defined PLATFORM_WINDOWS
   172 	DWORD attr = GetFileAttributesA(path);
   173 
   174 	return (attr != INVALID_FILE_ATTRIBUTES);
   175 #elif defined PLATFORM_POSIX
   176 	struct stat s;
   177 
   178 	return (stat(path, &s) == 0);
   179 #endif
   180 }
   181 
   182 bool LibrarySystem::IsPathFile(const char *path)
   183 {
   184 #if defined PLATFORM_WINDOWS
   185 	DWORD attr = GetFileAttributes(path);
   186 
   187 	if (attr == INVALID_FILE_ATTRIBUTES)
   188 	{
   189 		return false;
   190 	}
   191 
   192 	if (attr & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))
   193 	{
   194 		return false;
   195 	}
   196 
   197 	return true;
   198 #elif defined PLATFORM_LINUX
   199 	struct stat s;
   200 
   201 	if (stat(path, &s) != 0)
   202 	{
   203 		return false;
   204 	}
   205 
   206 	return S_ISREG(s.st_mode) ? true : false;
   207 #endif
   208 }
   209 
   210 bool LibrarySystem::IsPathDirectory(const char *path)
   211 {
   212 #if defined PLATFORM_WINDOWS
   213 	DWORD attr = GetFileAttributes(path);
   214 
   215 	if (attr == INVALID_FILE_ATTRIBUTES)
   216 	{
   217 		return false;
   218 	}
   219 
   220 	if (attr & FILE_ATTRIBUTE_DIRECTORY)
   221 	{
   222 		return true;
   223 	}
   224 
   225 #elif defined PLATFORM_LINUX
   226 	struct stat s;
   227 
   228 	if (stat(path, &s) != 0)
   229 	{
   230 		return false;
   231 	}
   232 
   233 	if (S_ISDIR(s.st_mode))
   234 	{
   235 		return true;
   236 	}
   237 #endif
   238 
   239 	return false;
   240 }
   241 
   242 IDirectory *LibrarySystem::OpenDirectory(const char *path)
   243 {
   244 	CDirectory *dir = new CDirectory(path);
   245 
   246 	if (!dir->IsValid())
   247 	{
   248 		delete dir;
   249 		return NULL;
   250 	}
   251 
   252 	return dir;
   253 }
   254 
   255 void LibrarySystem::GetPlatformError(char *error, size_t maxlength)
   256 {
   257 	if (error && maxlength)
   258 	{
   259 #if defined PLATFORM_WINDOWS
   260 		DWORD dw = GetLastError();
   261 		FormatMessageA(
   262 			FORMAT_MESSAGE_FROM_SYSTEM,
   263 			NULL,
   264 			dw,
   265 			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   266 			(LPSTR)error,
   267 			maxlength,
   268 			NULL);
   269 #elif defined PLATFORM_POSIX
   270 		snprintf(error, maxlength, "%s", strerror(errno));
   271 #endif
   272 	}
   273 }
   274 
   275 void LibrarySystem::CloseDirectory(IDirectory *dir)
   276 {
   277 	delete dir;
   278 }
   279 
   280 ILibrary *LibrarySystem::OpenLibrary(const char *path, char *error, size_t maxlength)
   281 {
   282 	LibraryHandle lib;
   283 #if defined PLATFORM_WINDOWS
   284 	lib = LoadLibraryA(path);
   285 	if (!lib)
   286 	{
   287 		GetPlatformError(error, maxlength);
   288 		return false;
   289 	}
   290 #elif defined PLATFORM_POSIX
   291 	lib = dlopen(path, RTLD_NOW);
   292 	if (!lib)
   293 	{
   294 		GetPlatformError(error, maxlength);
   295 		return false;
   296 	}
   297 #endif
   298 
   299 	return new CLibrary(lib);
   300 }
   301 
   302 size_t LibrarySystem::PathFormat(char *buffer, size_t len, const char *fmt, ...)
   303 {
   304 	va_list ap;
   305 	va_start(ap, fmt);
   306 	size_t mylen = vsnprintf(buffer, len, fmt, ap);
   307 	va_end(ap);
   308 
   309 	if (mylen >= len)
   310 	{
   311 		mylen = len - 1;
   312 		buffer[mylen] = '\0';
   313 	}
   314 
   315 	for (size_t i=0; i<mylen; i++)
   316 	{
   317 		if (buffer[i] == PLATFORM_SEP_ALTCHAR)
   318 		{
   319 			buffer[i] = PLATFORM_SEP_CHAR;
   320 		}
   321 	}
   322 
   323 	return mylen;
   324 }
   325 
   326 const char *LibrarySystem::GetFileExtension(const char *filename)
   327 {
   328 	size_t end = strlen(filename) - 1;
   329 
   330 	for (size_t i = end; i >= 0; i--)
   331 	{
   332 		if (i > end)
   333 		{
   334 			break;
   335 		}
   336 
   337 		if (filename[i] == PLATFORM_SEP_CHAR || filename[i] == PLATFORM_SEP_ALTCHAR)
   338 		{
   339 			break;
   340 		}
   341 
   342 		if (filename[i] == '.' && i != end)
   343 		{
   344 			return &filename[++i];
   345 		}
   346 	}
   347 
   348 	return NULL;
   349 }