added usage of the Handle System to begin experimenting

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40257
This commit is contained in:
David Anderson 2007-01-01 19:50:16 +00:00
parent a4363dfa4f
commit 2fc806542a
13 changed files with 190 additions and 6 deletions

View File

@ -17,6 +17,8 @@ namespace SourceMod
typedef unsigned int HandleType_t; typedef unsigned int HandleType_t;
typedef unsigned int Handle_t; typedef unsigned int Handle_t;
class SourcePawn::IPluginContext;
/** /**
* About type checking: * About type checking:
* Types can be inherited - a Parent type ("Supertype") can have child types. * Types can be inherited - a Parent type ("Supertype") can have child types.
@ -179,13 +181,13 @@ namespace SourceMod
* *
* @param type Type to use on the handle. * @param type Type to use on the handle.
* @param object Object to bind to the handle. * @param object Object to bind to the handle.
* @param ctx Plugin context that will own this handle. NULL for none. * @param pOwner Plugin context that will own this handle. NULL for none.
* @param ident Identity token if any security rights are needed. * @param ident Identity token if any security rights are needed.
* @return A new Handle_t. * @return A new Handle_t.
*/ */
virtual Handle_t CreateScriptHandle(HandleType_t type, virtual Handle_t CreateScriptHandle(HandleType_t type,
void *object, void *object,
sp_context_t *ctx, SourcePawn::IPluginContext *pOwner,
IdentityToken_t *ident) =0; IdentityToken_t *ident) =0;
/** /**

View File

@ -64,6 +64,12 @@ namespace SourceMod
* @brief Returns whether the current entry is a file. * @brief Returns whether the current entry is a file.
*/ */
virtual bool IsEntryFile() =0; virtual bool IsEntryFile() =0;
/**
* @brief Returns true if the current entry is valid
* (Used similarly to MoreFiles).
*/
virtual bool IsEntryValid() =0;
}; };
/** /**

View File

@ -211,6 +211,10 @@
RelativePath="..\sm_trie.cpp" RelativePath="..\sm_trie.cpp"
> >
</File> </File>
<File
RelativePath="..\smn_filesystem.cpp"
>
</File>
<File <File
RelativePath="..\smn_float.cpp" RelativePath="..\smn_float.cpp"
> >

View File

@ -49,6 +49,7 @@ private:
extern ISourcePawnEngine *g_pSourcePawn; extern ISourcePawnEngine *g_pSourcePawn;
extern IVirtualMachine *g_pVM; extern IVirtualMachine *g_pVM;
extern IdentityToken_t *g_pCoreIdent;
#include "sm_autonatives.h" #include "sm_autonatives.h"

114
core/smn_filesystem.cpp Normal file
View File

@ -0,0 +1,114 @@
#include "sm_globals.h"
#include "HandleSys.h"
#include "LibrarySys.h"
HandleType_t g_FileType;
HandleType_t g_DirType;
class FileNatives :
public SMGlobalClass,
public IHandleTypeDispatch
{
public:
virtual void OnSourceModAllInitialized()
{
HandleSecurity sec;
sec.owner = g_pCoreIdent;
sec.access[HandleAccess_Inherit] = false;
sec.access[HandleAccess_Create] = false;
g_FileType = g_HandleSys.CreateTypeEx("File", this, 0, &sec, NULL);
g_DirType = g_HandleSys.CreateTypeEx("Directory", this, 0, &sec, NULL);
}
virtual void OnSourceModShutdown()
{
g_HandleSys.RemoveType(g_DirType, g_pCoreIdent);
g_HandleSys.RemoveType(g_FileType, g_pCoreIdent);
g_DirType = 0;
g_FileType = 0;
}
virtual void OnHandleDestroy(HandleType_t type, void *object)
{
if (type == g_FileType)
{
FILE *fp = (FILE *)object;
fclose(fp);
} else if (type == g_DirType) {
IDirectory *pDir = (IDirectory *)object;
g_LibSys.CloseDirectory(pDir);
}
}
};
cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
{
char *path;
int err;
if ((err=pContext->LocalToString(params[1], &path)) != SP_ERROR_NONE)
{
pContext->ThrowNativeErrorEx(err, NULL);
return 0;
}
IDirectory *pDir = g_LibSys.OpenDirectory(path);
if (!pDir)
{
return 0;
}
return g_HandleSys.CreateScriptHandle(g_DirType, pDir, pContext, g_pCoreIdent);
}
cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
{
Handle_t hndl = static_cast<Handle_t>(params[1]);
IDirectory *pDir;
HandleError herr;
int err;
if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, g_pCoreIdent, (void **)&pDir))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
}
if (!pDir->MoreFiles())
{
return false;
}
cell_t *filetype;
if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
{
pContext->ThrowNativeErrorEx(err, NULL);
return 0;
}
if (pDir->IsEntryDirectory())
{
*filetype = 1;
} else if (pDir->IsEntryFile()) {
*filetype = 2;
} else {
*filetype = 0;
}
const char *path = pDir->GetEntryName();
if ((err=pContext->StringToLocalUTF8(params[2], params[3],path, NULL))
!= SP_ERROR_NONE)
{
pContext->ThrowNativeErrorEx(err, NULL);
return 0;
}
return true;
}
REGISTER_NATIVES(filesystem)
{
{"OpenDirectory", sm_OpenDirectory},
{"ReadDirEntry", sm_ReadDirEntry},
{NULL, NULL},
};

View File

@ -69,4 +69,5 @@ REGISTER_NATIVES(handles)
{"IsValidHandle", sm_IsValidHandle}, {"IsValidHandle", sm_IsValidHandle},
{"CloseHandle", sm_CloseHandle}, {"CloseHandle", sm_CloseHandle},
{"CloneHandle", sm_CloneHandle}, {"CloneHandle", sm_CloneHandle},
{NULL, NULL},
}; };

View File

@ -5,7 +5,7 @@
#include "vm/sp_vm_engine.h" #include "vm/sp_vm_engine.h"
#include <sh_string.h> #include <sh_string.h>
#include "PluginSys.h" #include "PluginSys.h"
#include "ForwardSys.h" #include "ShareSys.h"
SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool);
@ -16,6 +16,7 @@ ILibrary *g_pJIT = NULL;
SourceHook::String g_BaseDir; SourceHook::String g_BaseDir;
ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn; ISourcePawnEngine *g_pSourcePawn = &g_SourcePawn;
IVirtualMachine *g_pVM; IVirtualMachine *g_pVM;
IdentityToken_t *g_pCoreIdent = NULL;
typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *); typedef int (*GIVEENGINEPOINTER)(ISourcePawnEngine *);
typedef unsigned int (*GETEXPORTCOUNT)(); typedef unsigned int (*GETEXPORTCOUNT)();
@ -139,6 +140,9 @@ void SourceModBase::StartSourceMod(bool late)
pBase = pBase->m_pGlobalClassNext; pBase = pBase->m_pGlobalClassNext;
} }
/* Make the global core identity */
g_pCoreIdent = g_ShareSys.CreateCoreIdentity();
/* Notify! */ /* Notify! */
pBase = SMGlobalClass::head; pBase = SMGlobalClass::head;
while (pBase) while (pBase)

View File

@ -302,10 +302,10 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
Handle_t HandleSystem::CreateScriptHandle(HandleType_t type, Handle_t HandleSystem::CreateScriptHandle(HandleType_t type,
void *object, void *object,
sp_context_t *ctx, IPluginContext *pContext,
IdentityToken_t *ident) IdentityToken_t *ident)
{ {
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(ctx); IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
return CreateHandle(type, object, pPlugin->GetIdentity(), ident); return CreateHandle(type, object, pPlugin->GetIdentity(), ident);
} }

View File

@ -90,7 +90,7 @@ public: //IHandleSystem
void *object, void *object,
IdentityToken_t *source, IdentityToken_t *source,
IdentityToken_t *ident); IdentityToken_t *ident);
Handle_t CreateScriptHandle(HandleType_t type, void *object, sp_context_t *ctx, IdentityToken_t *ident); Handle_t CreateScriptHandle(HandleType_t type, void *object, IPluginContext *pContext, IdentityToken_t *ident);
HandleError FreeHandle(Handle_t handle, IdentityToken_t *ident); HandleError FreeHandle(Handle_t handle, IdentityToken_t *ident);
HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *source, IdentityToken_t *ident); HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *source, IdentityToken_t *ident);
HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object); HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object);

View File

@ -93,6 +93,11 @@ void CDirectory::NextEntry()
#endif #endif
} }
bool CDirectory::IsEntryValid()
{
return IsValid();
}
bool CDirectory::IsEntryDirectory() bool CDirectory::IsEntryDirectory()
{ {
#if defined PLATFORM_WINDOWS #if defined PLATFORM_WINDOWS

View File

@ -23,6 +23,7 @@ public:
virtual const char *GetEntryName(); virtual const char *GetEntryName();
virtual bool IsEntryDirectory(); virtual bool IsEntryDirectory();
virtual bool IsEntryFile(); virtual bool IsEntryFile();
virtual bool IsEntryValid();
public: public:
bool IsValid(); bool IsValid();
private: private:

42
plugins/include/files.inc Normal file
View File

@ -0,0 +1,42 @@
/**
* :TODO: license info
*/
#if defined _files_included
#endinput
#endif
#define _files_included
/* @note All paths in SourceMod natives are relative to the mod folder unless otherwise noted. */
enum FileType
{
FileType_Unknown = 0, /* Unknown file type (device/socket) */
FileType_Directory = 1, /* File is a directory */
FileType_File = 2, /* File is a file */
};
/**
* @brief Opens a directory/folder for contents enumeration.
* @note Directories are closed with CloseHandle().
* @note Directories Handles can be cloned.
*
* @param path Path to open.
* @return A Handle to the directory, INVALID_HANDLE on open error.
*/
native Handle:OpenDirectory(const String:path[]);
/**
* @brief Reads the current directory entry as a local filename, then moves to the next file.
* @note Contents of buffers are undefined when returning false.
* @note Both the '.' and '..' automatic directory entries will be retrieved for Windows and Linux.
*
* @param dir Handle to a directory.
* @param buffer String buffer to hold directory name.
* @param maxlength Maximum size of string buffer.
* @param type Optional variable to store the file type.
* @return True on success, false if there are no more files to read.
* @error Invalid or corrupt Handle.
*/
native bool:ReadDirEntry(Handle:dir, String:buffer[], maxlength, &FileType:type=0);

View File

@ -16,6 +16,10 @@ struct Plugin
const String:url[], /* Plugin URL */ const String:url[], /* Plugin URL */
}; };
#include <float>
#include <handles>
#include <string>
/** /**
* Declare this as a struct in your plugin to expose its information. * Declare this as a struct in your plugin to expose its information.
* Example: * Example: