3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
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
16 #include "sm_globals.h"
17 #include "sm_stringutil.h"
18 #include "CellArray.h"
19 #include "HandleSys.h"
21 HandleType_t htCellArray;
23 class CellArrayHelpers :
25 public IHandleTypeDispatch
27 public: //SMGlobalClass
28 void OnSourceModAllInitialized()
30 htCellArray = g_HandleSys.CreateType("CellArray", this, 0, NULL, NULL, g_pCoreIdent, NULL);
32 void OnSourceModShutdown()
34 g_HandleSys.RemoveType(htCellArray, g_pCoreIdent);
36 public: //IHandleTypeDispatch
37 void OnHandleDestroy(HandleType_t type, void *object)
39 CellArray *array = (CellArray *)object;
44 static cell_t CreateArray(IPluginContext *pContext, const cell_t *params)
48 return pContext->ThrowNativeError("Invalid block size (must be > 0)");
51 CellArray *array = new CellArray(params[1]);
55 array->resize(params[2]);
58 Handle_t hndl = g_HandleSys.CreateHandle(htCellArray, array, pContext->GetIdentity(), g_pCoreIdent, NULL);
67 static cell_t ClearArray(IPluginContext *pContext, const cell_t *params)
71 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
73 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
76 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
84 static cell_t ResizeArray(IPluginContext *pContext, const cell_t *params)
88 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
90 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
93 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
96 if (!array->resize(params[2]))
98 return pContext->ThrowNativeError("Unable to resize array to \"%u\"", params[2]);
104 static cell_t GetArraySize(IPluginContext *pContext, const cell_t *params)
108 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
110 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
113 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
116 return (cell_t)array->size();
119 static cell_t PushArrayCell(IPluginContext *pContext, const cell_t *params)
123 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
125 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
128 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
131 cell_t *blk = array->push();
134 return pContext->ThrowNativeError("Failed to grow array");
139 return (cell_t)(array->size() - 1);
142 static cell_t PushArrayString(IPluginContext *pContext, const cell_t *params)
146 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
148 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
151 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
154 cell_t *blk = array->push();
157 return pContext->ThrowNativeError("Failed to grow array");
161 pContext->LocalToString(params[2], &str);
163 strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
165 return (cell_t)(array->size() - 1);
168 static cell_t PushArrayArray(IPluginContext *pContext, const cell_t *params)
172 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
174 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
177 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
180 cell_t *blk = array->push();
183 return pContext->ThrowNativeError("Failed to grow array");
187 pContext->LocalToPhysAddr(params[2], &addr);
189 size_t indexes = array->blocksize();
190 if (params[3] != -1 && (size_t)params[3] <= array->blocksize())
195 memcpy(blk, addr, sizeof(cell_t) * indexes);
197 return (cell_t)(array->size() - 1);
200 static cell_t GetArrayCell(IPluginContext *pContext, const cell_t *params)
204 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
206 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
209 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
212 size_t idx = (size_t)params[2];
213 if (idx >= array->size())
215 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
218 cell_t *blk = array->at(idx);
220 idx = (size_t)params[3];
223 if (idx >= array->blocksize())
225 return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
229 if (idx >= array->blocksize() * 4)
231 return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
233 return (cell_t)*((char *)blk + idx);
239 static cell_t GetArrayString(IPluginContext *pContext, const cell_t *params)
243 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
245 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
248 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
251 size_t idx = (size_t)params[2];
252 if (idx >= array->size())
254 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
257 cell_t *blk = array->at(idx);
258 size_t numWritten = 0;
260 pContext->StringToLocalUTF8(params[3], params[4], (char *)blk, &numWritten);
265 static cell_t GetArrayArray(IPluginContext *pContext, const cell_t *params)
269 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
271 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
274 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
277 size_t idx = (size_t)params[2];
278 if (idx >= array->size())
280 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
283 cell_t *blk = array->at(idx);
284 size_t indexes = array->blocksize();
285 if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
291 pContext->LocalToPhysAddr(params[3], &addr);
293 memcpy(addr, blk, sizeof(cell_t) * indexes);
298 static cell_t SetArrayCell(IPluginContext *pContext, const cell_t *params)
302 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
304 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
307 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
310 size_t idx = (size_t)params[2];
311 if (idx >= array->size())
313 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
316 cell_t *blk = array->at(idx);
318 idx = (size_t)params[4];
321 if (idx >= array->blocksize())
323 return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", idx, array->blocksize());
325 blk[idx] = params[3];
327 if (idx >= array->blocksize() * 4)
329 return pContext->ThrowNativeError("Invalid byte %d (blocksize: %d bytes)", idx, array->blocksize() * 4);
331 *((char *)blk + idx) = (char)params[3];
337 static cell_t SetArrayString(IPluginContext *pContext, const cell_t *params)
341 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
343 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
346 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
349 size_t idx = (size_t)params[2];
350 if (idx >= array->size())
352 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
355 cell_t *blk = array->at(idx);
358 pContext->LocalToString(params[3], &str);
360 return strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t));
363 static cell_t SetArrayArray(IPluginContext *pContext, const cell_t *params)
367 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
369 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
372 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
375 size_t idx = (size_t)params[2];
376 if (idx >= array->size())
378 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
381 cell_t *blk = array->at(idx);
382 size_t indexes = array->blocksize();
383 if (params[4] != -1 && (size_t)params[4] <= array->blocksize())
389 pContext->LocalToPhysAddr(params[3], &addr);
391 memcpy(blk, addr, sizeof(cell_t) * indexes);
396 static cell_t ShiftArrayUp(IPluginContext *pContext, const cell_t *params)
400 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
402 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
405 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
408 size_t idx = (size_t)params[2];
409 if (idx >= array->size())
411 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
414 array->insert_at(idx);
419 static cell_t RemoveFromArray(IPluginContext *pContext, const cell_t *params)
423 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
425 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
428 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
431 size_t idx = (size_t)params[2];
432 if (idx >= array->size())
434 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size());
442 static cell_t SwapArrayItems(IPluginContext *pContext, const cell_t *params)
446 HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
448 if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&array))
451 return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
454 size_t idx1 = (size_t)params[2];
455 size_t idx2 = (size_t)params[3];
456 if (idx1 >= array->size())
458 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx1, array->size());
460 if (idx2 >= array->size())
462 return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx2, array->size());
465 array->swap(idx1, idx2);
470 REGISTER_NATIVES(cellArrayNatives)
472 {"ClearArray", ClearArray},
473 {"CreateArray", CreateArray},
474 {"GetArrayArray", GetArrayArray},
475 {"GetArrayCell", GetArrayCell},
476 {"GetArraySize", GetArraySize},
477 {"GetArrayString", GetArrayString},
478 {"ResizeArray", ResizeArray},
479 {"PushArrayArray", PushArrayArray},
480 {"PushArrayCell", PushArrayCell},
481 {"PushArrayString", PushArrayString},
482 {"RemoveFromArray", RemoveFromArray},
483 {"SetArrayCell", SetArrayCell},
484 {"SetArrayString", SetArrayString},
485 {"SetArrayArray", SetArrayArray},
486 {"ShiftArrayUp", ShiftArrayUp},
487 {"SwapArrayItems", SwapArrayItems},