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