core/smn_adt_array.cpp
author Scott Ehlert <ds@alliedmods.net>
Wed Nov 19 02:16:45 2008 -0600 (2008-11-19)
changeset 2415 9ac720a36ce4
parent 2289 44045ead61cd
child 2471 194be299b700
permissions -rw-r--r--
Merge.
dvander@1156
     1
/**
dvander@1156
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
ds@1947
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@1156
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@1156
    28
 *
dvander@1156
    29
 * Version: $Id$
dvander@1156
    30
 */
dvander@1156
    31
dvander@1156
    32
#include <malloc.h>
dvander@1156
    33
#include "sm_globals.h"
dvander@1156
    34
#include "sm_stringutil.h"
dvander@1156
    35
#include "CellArray.h"
dvander@1156
    36
#include "HandleSys.h"
dvander@1156
    37
dvander@1156
    38
HandleType_t htCellArray;
dvander@1156
    39
dvander@1156
    40
class CellArrayHelpers : 
dvander@1156
    41
	public SMGlobalClass,
dvander@1156
    42
	public IHandleTypeDispatch
dvander@1156
    43
{
dvander@1156
    44
public: //SMGlobalClass
dvander@1156
    45
	void OnSourceModAllInitialized()
dvander@1156
    46
	{
dvander@1156
    47
		htCellArray = g_HandleSys.CreateType("CellArray", this, 0, NULL, NULL, g_pCoreIdent, NULL);
dvander@1156
    48
	}
dvander@1156
    49
	void OnSourceModShutdown()
dvander@1156
    50
	{
dvander@1156
    51
		g_HandleSys.RemoveType(htCellArray, g_pCoreIdent);
dvander@1156
    52
	}
dvander@1156
    53
public: //IHandleTypeDispatch
dvander@1156
    54
	void OnHandleDestroy(HandleType_t type, void *object)
dvander@1156
    55
	{
dvander@1156
    56
		CellArray *array = (CellArray *)object;
dvander@1156
    57
		delete array;
dvander@1156
    58
	}
dvander@1766
    59
	bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
dvander@1766
    60
	{
dvander@1766
    61
		CellArray *pArray = (CellArray *)object;
dvander@1766
    62
		*pSize = sizeof(CellArray) + pArray->mem_usage();
dvander@1766
    63
		return true;
dvander@1766
    64
	}
dvander@1156
    65
} s_CellArrayHelpers;
dvander@1156
    66
dvander@1156
    67
static cell_t CreateArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
    68
{
dvander@1156
    69
	if (!params[1])
dvander@1156
    70
	{
dvander@1156
    71
		return pContext->ThrowNativeError("Invalid block size (must be > 0)");
dvander@1156
    72
	}
dvander@1156
    73
dvander@1156
    74
	CellArray *array = new CellArray(params[1]);
dvander@1156
    75
dvander@1156
    76
	if (params[2])
dvander@1156
    77
	{
dvander@1156
    78
		array->resize(params[2]);
dvander@1156
    79
	}
dvander@1156
    80
	
dvander@1156
    81
	Handle_t hndl = g_HandleSys.CreateHandle(htCellArray, array, pContext->GetIdentity(), g_pCoreIdent, NULL);
dvander@1156
    82
	if (!hndl)
dvander@1156
    83
	{
dvander@1156
    84
		delete array;
dvander@1156
    85
	}
dvander@1156
    86
dvander@1156
    87
	return hndl;
dvander@1156
    88
}
dvander@1156
    89
dvander@1156
    90
static cell_t ClearArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
    91
{
dvander@1156
    92
	CellArray *array;
dvander@1156
    93
	HandleError err;
dvander@1156
    94
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
    95
dvander@1156
    96
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
    97
		!= HandleError_None)
dvander@1156
    98
	{
dvander@1156
    99
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   100
	}
dvander@1156
   101
dvander@1156
   102
	array->clear();
dvander@1156
   103
	
dvander@1156
   104
	return 1;
dvander@1156
   105
}
dvander@1156
   106
dvander@1156
   107
static cell_t ResizeArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
   108
{
dvander@1156
   109
	CellArray *array;
dvander@1156
   110
	HandleError err;
dvander@1156
   111
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   112
dvander@1156
   113
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   114
		!= HandleError_None)
dvander@1156
   115
	{
dvander@1156
   116
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   117
	}
dvander@1156
   118
dvander@1156
   119
	if (!array->resize(params[2]))
dvander@1156
   120
	{
dvander@1156
   121
		return pContext->ThrowNativeError("Unable to resize array to \"%u\"", params[2]);
dvander@1156
   122
	}
dvander@1156
   123
dvander@1156
   124
	return 1;
dvander@1156
   125
}
dvander@1156
   126
dvander@1156
   127
static cell_t GetArraySize(IPluginContext *pContext, const cell_t *params)
dvander@1156
   128
{
dvander@1156
   129
	CellArray *array;
dvander@1156
   130
	HandleError err;
dvander@1156
   131
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   132
dvander@1156
   133
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   134
		!= HandleError_None)
dvander@1156
   135
	{
dvander@1156
   136
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   137
	}
dvander@1156
   138
dvander@1156
   139
	return (cell_t)array->size();
dvander@1156
   140
}
dvander@1156
   141
dvander@1156
   142
static cell_t PushArrayCell(IPluginContext *pContext, const cell_t *params)
dvander@1156
   143
{
dvander@1156
   144
	CellArray *array;
dvander@1156
   145
	HandleError err;
dvander@1156
   146
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   147
dvander@1156
   148
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   149
		!= HandleError_None)
dvander@1156
   150
	{
dvander@1156
   151
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   152
	}
dvander@1156
   153
dvander@1156
   154
	cell_t *blk = array->push();
dvander@1156
   155
	if (!blk)
dvander@1156
   156
	{
dvander@1156
   157
		return pContext->ThrowNativeError("Failed to grow array");
dvander@1156
   158
	}
dvander@1156
   159
dvander@1156
   160
	*blk = params[2];
dvander@1156
   161
dvander@1156
   162
	return (cell_t)(array->size() - 1);
dvander@1156
   163
}
dvander@1156
   164
dvander@1156
   165
static cell_t PushArrayString(IPluginContext *pContext, const cell_t *params)
dvander@1156
   166
{
dvander@1156
   167
	CellArray *array;
dvander@1156
   168
	HandleError err;
dvander@1156
   169
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   170
dvander@1156
   171
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   172
		!= HandleError_None)
dvander@1156
   173
	{
dvander@1156
   174
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   175
	}
dvander@1156
   176
dvander@1156
   177
	cell_t *blk = array->push();
dvander@1156
   178
	if (!blk)
dvander@1156
   179
	{
dvander@1156
   180
		return pContext->ThrowNativeError("Failed to grow array");
dvander@1156
   181
	}
dvander@1156
   182
dvander@1156
   183
	char *str;
dvander@1156
   184
	pContext->LocalToString(params[2], &str);
dvander@1156
   185
dvander@1156
   186
	strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
dvander@1156
   187
dvander@1156
   188
	return (cell_t)(array->size() - 1);
dvander@1156
   189
}
dvander@1156
   190
dvander@1156
   191
static cell_t PushArrayArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
   192
{
dvander@1156
   193
	CellArray *array;
dvander@1156
   194
	HandleError err;
dvander@1156
   195
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   196
dvander@1156
   197
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   198
		!= HandleError_None)
dvander@1156
   199
	{
dvander@1156
   200
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   201
	}
dvander@1156
   202
dvander@1156
   203
	cell_t *blk = array->push();
dvander@1156
   204
	if (!blk)
dvander@1156
   205
	{
dvander@1156
   206
		return pContext->ThrowNativeError("Failed to grow array");
dvander@1156
   207
	}
dvander@1156
   208
dvander@1156
   209
	cell_t *addr;
dvander@1156
   210
	pContext->LocalToPhysAddr(params[2], &addr);
dvander@1156
   211
dvander@1156
   212
	size_t indexes = array->blocksize();
dvander@1156
   213
	if (params[3] != -1 && (size_t)params[3] <= array->blocksize())
dvander@1156
   214
	{
dvander@1156
   215
		indexes = params[3];
dvander@1156
   216
	}
dvander@1156
   217
dvander@1156
   218
	memcpy(blk, addr, sizeof(cell_t) * indexes);
dvander@1156
   219
dvander@1156
   220
	return (cell_t)(array->size() - 1);
dvander@1156
   221
}
dvander@1156
   222
dvander@1156
   223
static cell_t GetArrayCell(IPluginContext *pContext, const cell_t *params)
dvander@1156
   224
{
dvander@1156
   225
	CellArray *array;
dvander@1156
   226
	HandleError err;
dvander@1156
   227
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   228
dvander@1156
   229
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   230
		!= HandleError_None)
dvander@1156
   231
	{
dvander@1156
   232
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   233
	}
dvander@1156
   234
dvander@1156
   235
	size_t idx = (size_t)params[2];
dvander@1156
   236
	if (idx >= array->size())
dvander@1156
   237
	{
dvander@1156
   238
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   239
	}
dvander@1156
   240
dvander@1156
   241
	cell_t *blk = array->at(idx);
dvander@1156
   242
dvander@1156
   243
	idx = (size_t)params[3];
dvander@1159
   244
	if (params[4] == 0)
dvander@1156
   245
	{
dvander@1156
   246
		if (idx >= array->blocksize())
dvander@1156
   247
		{
dvander@1156
   248
			return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
dvander@1156
   249
		}
dvander@1156
   250
		return blk[idx];
dvander@1156
   251
	} else {
dvander@1156
   252
		if (idx >= array->blocksize() * 4)
dvander@1156
   253
		{
dvander@1156
   254
			return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
dvander@1156
   255
		}
dvander@1156
   256
		return (cell_t)*((char *)blk + idx);
dvander@1156
   257
	}
dvander@1156
   258
dvander@1156
   259
	return 0;
dvander@1156
   260
}
dvander@1156
   261
dvander@1156
   262
static cell_t GetArrayString(IPluginContext *pContext, const cell_t *params)
dvander@1156
   263
{
dvander@1156
   264
	CellArray *array;
dvander@1156
   265
	HandleError err;
dvander@1156
   266
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   267
dvander@1156
   268
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   269
		!= HandleError_None)
dvander@1156
   270
	{
dvander@1156
   271
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   272
	}
dvander@1156
   273
dvander@1156
   274
	size_t idx = (size_t)params[2];
dvander@1156
   275
	if (idx >= array->size())
dvander@1156
   276
	{
dvander@1156
   277
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   278
	}
dvander@1156
   279
dvander@1156
   280
	cell_t *blk = array->at(idx);
dvander@1156
   281
	size_t numWritten = 0;
dvander@1156
   282
dvander@1156
   283
	pContext->StringToLocalUTF8(params[3], params[4], (char *)blk, &numWritten);
dvander@1156
   284
dvander@1156
   285
	return numWritten;
dvander@1156
   286
}
dvander@1156
   287
dvander@1156
   288
static cell_t GetArrayArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
   289
{
dvander@1156
   290
	CellArray *array;
dvander@1156
   291
	HandleError err;
dvander@1156
   292
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   293
dvander@1156
   294
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   295
		!= HandleError_None)
dvander@1156
   296
	{
dvander@1156
   297
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   298
	}
dvander@1156
   299
dvander@1156
   300
	size_t idx = (size_t)params[2];
dvander@1156
   301
	if (idx >= array->size())
dvander@1156
   302
	{
dvander@1156
   303
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   304
	}
dvander@1156
   305
dvander@1156
   306
	cell_t *blk = array->at(idx);
dvander@1156
   307
	size_t indexes = array->blocksize();
dvander@1156
   308
	if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
dvander@1156
   309
	{
dvander@1156
   310
		indexes = params[4];
dvander@1156
   311
	}
dvander@1156
   312
dvander@1156
   313
	cell_t *addr;
dvander@1156
   314
	pContext->LocalToPhysAddr(params[3], &addr);
dvander@1156
   315
dvander@1156
   316
	memcpy(addr, blk, sizeof(cell_t) * indexes);
dvander@1156
   317
dvander@1156
   318
	return indexes;
dvander@1156
   319
}
dvander@1156
   320
dvander@1156
   321
static cell_t SetArrayCell(IPluginContext *pContext, const cell_t *params)
dvander@1156
   322
{
dvander@1156
   323
	CellArray *array;
dvander@1156
   324
	HandleError err;
dvander@1156
   325
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   326
dvander@1156
   327
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   328
		!= HandleError_None)
dvander@1156
   329
	{
dvander@1156
   330
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   331
	}
dvander@1156
   332
dvander@1156
   333
	size_t idx = (size_t)params[2];
dvander@1156
   334
	if (idx >= array->size())
dvander@1156
   335
	{
dvander@1156
   336
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   337
	}
dvander@1156
   338
dvander@1156
   339
	cell_t *blk = array->at(idx);
dvander@1156
   340
dvander@1156
   341
	idx = (size_t)params[4];
dvander@1159
   342
	if (params[5] == 0)
dvander@1156
   343
	{
dvander@1156
   344
		if (idx >= array->blocksize())
dvander@1156
   345
		{
dvander@1156
   346
			return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
dvander@1156
   347
		}
dvander@1156
   348
		blk[idx] = params[3];
dvander@1156
   349
	} else {
dvander@1156
   350
		if (idx >= array->blocksize() * 4)
dvander@1156
   351
		{
dvander@1156
   352
			return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
dvander@1156
   353
		}
dvander@1156
   354
		*((char *)blk + idx) = (char)params[3];
dvander@1156
   355
	}
dvander@1156
   356
dvander@1156
   357
	return 1;
dvander@1156
   358
}
dvander@1156
   359
dvander@1156
   360
static cell_t SetArrayString(IPluginContext *pContext, const cell_t *params)
dvander@1156
   361
{
dvander@1156
   362
	CellArray *array;
dvander@1156
   363
	HandleError err;
dvander@1156
   364
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   365
dvander@1156
   366
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   367
		!= HandleError_None)
dvander@1156
   368
	{
dvander@1156
   369
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   370
	}
dvander@1156
   371
dvander@1156
   372
	size_t idx = (size_t)params[2];
dvander@1156
   373
	if (idx >= array->size())
dvander@1156
   374
	{
dvander@1156
   375
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   376
	}
dvander@1156
   377
dvander@1156
   378
	cell_t *blk = array->at(idx);
dvander@1156
   379
dvander@1156
   380
	char *str;
dvander@1156
   381
	pContext->LocalToString(params[3], &str);
dvander@1156
   382
dvander@1156
   383
	return strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
dvander@1156
   384
}
dvander@1156
   385
dvander@1156
   386
static cell_t SetArrayArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
   387
{
dvander@1156
   388
	CellArray *array;
dvander@1156
   389
	HandleError err;
dvander@1156
   390
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   391
dvander@1156
   392
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   393
		!= HandleError_None)
dvander@1156
   394
	{
dvander@1156
   395
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   396
	}
dvander@1156
   397
dvander@1156
   398
	size_t idx = (size_t)params[2];
dvander@1156
   399
	if (idx >= array->size())
dvander@1156
   400
	{
dvander@1156
   401
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   402
	}
dvander@1156
   403
dvander@1156
   404
	cell_t *blk = array->at(idx);
dvander@1156
   405
	size_t indexes = array->blocksize();
dvander@1156
   406
	if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
dvander@1156
   407
	{
dvander@1156
   408
		indexes = params[4];
dvander@1156
   409
	}
dvander@1156
   410
dvander@1156
   411
	cell_t *addr;
dvander@1156
   412
	pContext->LocalToPhysAddr(params[3], &addr);
dvander@1156
   413
dvander@1156
   414
	memcpy(blk, addr, sizeof(cell_t) * indexes);
dvander@1156
   415
dvander@1156
   416
	return indexes;
dvander@1156
   417
}
dvander@1156
   418
dvander@1156
   419
static cell_t ShiftArrayUp(IPluginContext *pContext, const cell_t *params)
dvander@1156
   420
{
dvander@1156
   421
	CellArray *array;
dvander@1156
   422
	HandleError err;
dvander@1156
   423
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   424
dvander@1156
   425
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   426
		!= HandleError_None)
dvander@1156
   427
	{
dvander@1156
   428
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   429
	}
dvander@1156
   430
dvander@1156
   431
	size_t idx = (size_t)params[2];
dvander@1156
   432
	if (idx >= array->size())
dvander@1156
   433
	{
dvander@1156
   434
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   435
	}
dvander@1156
   436
dvander@1156
   437
	array->insert_at(idx);
dvander@1156
   438
dvander@1156
   439
	return 1;
dvander@1156
   440
}
dvander@1156
   441
dvander@1156
   442
static cell_t RemoveFromArray(IPluginContext *pContext, const cell_t *params)
dvander@1156
   443
{
dvander@1156
   444
	CellArray *array;
dvander@1156
   445
	HandleError err;
dvander@1156
   446
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   447
dvander@1156
   448
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   449
		!= HandleError_None)
dvander@1156
   450
	{
dvander@1156
   451
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   452
	}
dvander@1156
   453
dvander@1156
   454
	size_t idx = (size_t)params[2];
dvander@1156
   455
	if (idx >= array->size())
dvander@1156
   456
	{
dvander@1156
   457
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
dvander@1156
   458
	}
dvander@1156
   459
dvander@1156
   460
	array->remove(idx);
dvander@1156
   461
dvander@1156
   462
	return 1;
dvander@1156
   463
}
dvander@1156
   464
dvander@1156
   465
static cell_t SwapArrayItems(IPluginContext *pContext, const cell_t *params)
dvander@1156
   466
{
dvander@1156
   467
	CellArray *array;
dvander@1156
   468
	HandleError err;
dvander@1156
   469
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
dvander@1156
   470
dvander@1156
   471
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
dvander@1156
   472
		!= HandleError_None)
dvander@1156
   473
	{
dvander@1156
   474
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
dvander@1156
   475
	}
dvander@1156
   476
dvander@1156
   477
	size_t idx1 = (size_t)params[2];
dvander@1156
   478
	size_t idx2 = (size_t)params[3];
dvander@1156
   479
	if (idx1 >= array->size())
dvander@1156
   480
	{
dvander@1156
   481
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx1, array->size());
dvander@1156
   482
	}
dvander@1156
   483
	if (idx2 >= array->size())
dvander@1156
   484
	{
dvander@1156
   485
		return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx2, array->size());
dvander@1156
   486
	}
dvander@1156
   487
dvander@1156
   488
	array->swap(idx1, idx2);
dvander@1156
   489
dvander@1156
   490
	return 1;
dvander@1156
   491
}
dvander@1156
   492
ferret99gt@1664
   493
static cell_t CloneArray(IPluginContext *pContext, const cell_t *params)
ferret99gt@1664
   494
{
ferret99gt@1664
   495
	CellArray *oldArray;
ferret99gt@1664
   496
	HandleError err;
ferret99gt@1664
   497
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
ferret99gt@1664
   498
ferret99gt@1664
   499
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&oldArray)) 
ferret99gt@1664
   500
		!= HandleError_None)
ferret99gt@1664
   501
	{
ferret99gt@1664
   502
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
ferret99gt@1664
   503
	}
ferret99gt@1664
   504
ferret99gt@1664
   505
	CellArray *array = oldArray->clone();
ferret99gt@1664
   506
	
ferret99gt@1664
   507
	Handle_t hndl = g_HandleSys.CreateHandle(htCellArray, array, pContext->GetIdentity(), g_pCoreIdent, NULL);
ferret99gt@1664
   508
	if (!hndl)
ferret99gt@1664
   509
	{
ferret99gt@1664
   510
		delete array;
ferret99gt@1664
   511
	}
ferret99gt@1664
   512
ferret99gt@1664
   513
	return hndl;
ferret99gt@1664
   514
}
ferret99gt@1664
   515
ferret99gt@1664
   516
static cell_t FindStringInArray(IPluginContext *pContext, const cell_t *params)
ferret99gt@1664
   517
{
ferret99gt@1664
   518
	CellArray *array;
ferret99gt@1664
   519
	HandleError err;
ferret99gt@1664
   520
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
ferret99gt@1664
   521
ferret99gt@1664
   522
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
ferret99gt@1664
   523
		!= HandleError_None)
ferret99gt@1664
   524
	{
ferret99gt@1664
   525
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
ferret99gt@1664
   526
	}
ferret99gt@1664
   527
ferret99gt@1664
   528
	char *str;
ferret99gt@1664
   529
	pContext->LocalToString(params[2], &str);
ferret99gt@1664
   530
ferret99gt@1664
   531
	for (unsigned int i = 0; i < array->size(); i++)
ferret99gt@1664
   532
	{
ferret99gt@1664
   533
		const char *array_str = (const char *)array->at(i);
ferret99gt@1664
   534
		if (strcmp(str, array_str) == 0)
ferret99gt@1664
   535
		{
ferret99gt@1664
   536
			return (cell_t) i;
ferret99gt@1664
   537
		}
ferret99gt@1664
   538
	}
ferret99gt@1664
   539
ferret99gt@1664
   540
	return -1;
ferret99gt@1664
   541
}
ferret99gt@1664
   542
ferret99gt@1664
   543
static cell_t FindValueInArray(IPluginContext *pContext, const cell_t *params)
ferret99gt@1664
   544
{
ferret99gt@1664
   545
	CellArray *array;
ferret99gt@1664
   546
	HandleError err;
ferret99gt@1664
   547
	HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
ferret99gt@1664
   548
ferret99gt@1664
   549
	if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array)) 
ferret99gt@1664
   550
		!= HandleError_None)
ferret99gt@1664
   551
	{
ferret99gt@1664
   552
		return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
ferret99gt@1664
   553
	}
ferret99gt@1664
   554
ferret99gt@1664
   555
	for (unsigned int i = 0; i < array->size(); i++)
ferret99gt@1664
   556
	{
ferret99gt@1664
   557
		if (params[2] == *array->at(i))
ferret99gt@1664
   558
		{
ferret99gt@1664
   559
			return (cell_t) i;
ferret99gt@1664
   560
		}
ferret99gt@1664
   561
	}
ferret99gt@1664
   562
ferret99gt@1664
   563
	return -1;
ferret99gt@1664
   564
}
ferret99gt@1664
   565
dvander@1156
   566
REGISTER_NATIVES(cellArrayNatives)
dvander@1156
   567
{
dvander@1156
   568
	{"ClearArray",					ClearArray},
dvander@1156
   569
	{"CreateArray",					CreateArray},
dvander@1156
   570
	{"GetArrayArray",				GetArrayArray},
dvander@1156
   571
	{"GetArrayCell",				GetArrayCell},
dvander@1156
   572
	{"GetArraySize",				GetArraySize},
dvander@1156
   573
	{"GetArrayString",				GetArrayString},
dvander@1156
   574
	{"ResizeArray",					ResizeArray},
dvander@1156
   575
	{"PushArrayArray",				PushArrayArray},
dvander@1156
   576
	{"PushArrayCell",				PushArrayCell},
dvander@1156
   577
	{"PushArrayString",				PushArrayString},
dvander@1156
   578
	{"RemoveFromArray",				RemoveFromArray},
dvander@1156
   579
	{"SetArrayCell",				SetArrayCell},
dvander@1156
   580
	{"SetArrayString",				SetArrayString},
dvander@1156
   581
	{"SetArrayArray",				SetArrayArray},
dvander@1156
   582
	{"ShiftArrayUp",				ShiftArrayUp},
dvander@1156
   583
	{"SwapArrayItems",				SwapArrayItems},
ferret99gt@1664
   584
	{"CloneArray",					CloneArray},
ferret99gt@1664
   585
	{"FindStringInArray",			FindStringInArray},
ferret99gt@1664
   586
	{"FindValueInArray",			FindValueInArray},
dvander@1156
   587
	{NULL,							NULL},
dvander@1156
   588
};