sourcemod/core/smn_adt_array.cpp
Scott Ehlert 251cced1f8 Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401971
2008-03-30 07:00:22 +00:00

589 lines
16 KiB
C++

/**
* vim: set ts=4 :
* =============================================================================
* SourceMod
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id$
*/
#include <malloc.h>
#include "sm_globals.h"
#include "sm_stringutil.h"
#include "CellArray.h"
#include "HandleSys.h"
HandleType_t htCellArray;
class CellArrayHelpers :
public SMGlobalClass,
public IHandleTypeDispatch
{
public: //SMGlobalClass
void OnSourceModAllInitialized()
{
htCellArray = g_HandleSys.CreateType("CellArray", this, 0, NULL, NULL, g_pCoreIdent, NULL);
}
void OnSourceModShutdown()
{
g_HandleSys.RemoveType(htCellArray, g_pCoreIdent);
}
public: //IHandleTypeDispatch
void OnHandleDestroy(HandleType_t type, void *object)
{
CellArray *array = (CellArray *)object;
delete array;
}
bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
{
CellArray *pArray = (CellArray *)object;
*pSize = sizeof(CellArray) + pArray->mem_usage();
return true;
}
} s_CellArrayHelpers;
static cell_t CreateArray(IPluginContext *pContext, const cell_t *params)
{
if (!params[1])
{
return pContext->ThrowNativeError("Invalid block size (must be > 0)");
}
CellArray *array = new CellArray(params[1]);
if (params[2])
{
array->resize(params[2]);
}
Handle_t hndl = g_HandleSys.CreateHandle(htCellArray, array, pContext->GetIdentity(), g_pCoreIdent, NULL);
if (!hndl)
{
delete array;
}
return hndl;
}
static cell_t ClearArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
array->clear();
return 1;
}
static cell_t ResizeArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
if (!array->resize(params[2]))
{
return pContext->ThrowNativeError("Unable to resize array to \"%u\"", params[2]);
}
return 1;
}
static cell_t GetArraySize(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
return (cell_t)array->size();
}
static cell_t PushArrayCell(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
cell_t *blk = array->push();
if (!blk)
{
return pContext->ThrowNativeError("Failed to grow array");
}
*blk = params[2];
return (cell_t)(array->size() - 1);
}
static cell_t PushArrayString(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
cell_t *blk = array->push();
if (!blk)
{
return pContext->ThrowNativeError("Failed to grow array");
}
char *str;
pContext->LocalToString(params[2], &str);
strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
return (cell_t)(array->size() - 1);
}
static cell_t PushArrayArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
cell_t *blk = array->push();
if (!blk)
{
return pContext->ThrowNativeError("Failed to grow array");
}
cell_t *addr;
pContext->LocalToPhysAddr(params[2], &addr);
size_t indexes = array->blocksize();
if (params[3] != -1 && (size_t)params[3] <= array->blocksize())
{
indexes = params[3];
}
memcpy(blk, addr, sizeof(cell_t) * indexes);
return (cell_t)(array->size() - 1);
}
static cell_t GetArrayCell(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
cell_t *blk = array->at(idx);
idx = (size_t)params[3];
if (params[4] == 0)
{
if (idx >= array->blocksize())
{
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
}
return blk[idx];
} else {
if (idx >= array->blocksize() * 4)
{
return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
}
return (cell_t)*((char *)blk + idx);
}
return 0;
}
static cell_t GetArrayString(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
cell_t *blk = array->at(idx);
size_t numWritten = 0;
pContext->StringToLocalUTF8(params[3], params[4], (char *)blk, &numWritten);
return numWritten;
}
static cell_t GetArrayArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
cell_t *blk = array->at(idx);
size_t indexes = array->blocksize();
if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
{
indexes = params[4];
}
cell_t *addr;
pContext->LocalToPhysAddr(params[3], &addr);
memcpy(addr, blk, sizeof(cell_t) * indexes);
return indexes;
}
static cell_t SetArrayCell(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
cell_t *blk = array->at(idx);
idx = (size_t)params[4];
if (params[5] == 0)
{
if (idx >= array->blocksize())
{
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
}
blk[idx] = params[3];
} else {
if (idx >= array->blocksize() * 4)
{
return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
}
*((char *)blk + idx) = (char)params[3];
}
return 1;
}
static cell_t SetArrayString(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
cell_t *blk = array->at(idx);
char *str;
pContext->LocalToString(params[3], &str);
return strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
}
static cell_t SetArrayArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
cell_t *blk = array->at(idx);
size_t indexes = array->blocksize();
if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
{
indexes = params[4];
}
cell_t *addr;
pContext->LocalToPhysAddr(params[3], &addr);
memcpy(blk, addr, sizeof(cell_t) * indexes);
return indexes;
}
static cell_t ShiftArrayUp(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
array->insert_at(idx);
return 1;
}
static cell_t RemoveFromArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx = (size_t)params[2];
if (idx >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
}
array->remove(idx);
return 1;
}
static cell_t SwapArrayItems(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
size_t idx1 = (size_t)params[2];
size_t idx2 = (size_t)params[3];
if (idx1 >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx1, array->size());
}
if (idx2 >= array->size())
{
return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx2, array->size());
}
array->swap(idx1, idx2);
return 1;
}
static cell_t CloneArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *oldArray;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&oldArray))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
CellArray *array = oldArray->clone();
Handle_t hndl = g_HandleSys.CreateHandle(htCellArray, array, pContext->GetIdentity(), g_pCoreIdent, NULL);
if (!hndl)
{
delete array;
}
return hndl;
}
static cell_t FindStringInArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
char *str;
pContext->LocalToString(params[2], &str);
for (unsigned int i = 0; i < array->size(); i++)
{
const char *array_str = (const char *)array->at(i);
if (strcmp(str, array_str) == 0)
{
return (cell_t) i;
}
}
return -1;
}
static cell_t FindValueInArray(IPluginContext *pContext, const cell_t *params)
{
CellArray *array;
HandleError err;
HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
!= HandleError_None)
{
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
}
for (unsigned int i = 0; i < array->size(); i++)
{
if (params[2] == *array->at(i))
{
return (cell_t) i;
}
}
return -1;
}
REGISTER_NATIVES(cellArrayNatives)
{
{"ClearArray", ClearArray},
{"CreateArray", CreateArray},
{"GetArrayArray", GetArrayArray},
{"GetArrayCell", GetArrayCell},
{"GetArraySize", GetArraySize},
{"GetArrayString", GetArrayString},
{"ResizeArray", ResizeArray},
{"PushArrayArray", PushArrayArray},
{"PushArrayCell", PushArrayCell},
{"PushArrayString", PushArrayString},
{"RemoveFromArray", RemoveFromArray},
{"SetArrayCell", SetArrayCell},
{"SetArrayString", SetArrayString},
{"SetArrayArray", SetArrayArray},
{"ShiftArrayUp", ShiftArrayUp},
{"SwapArrayItems", SwapArrayItems},
{"CloneArray", CloneArray},
{"FindStringInArray", FindStringInArray},
{"FindValueInArray", FindValueInArray},
{NULL, NULL},
};