mirror of
https://github.com/alliedmodders/sourcemod.git
synced 2025-12-06 18:08:36 +00:00
Add new options to ArrayList FindString, FindValue (#2216)
This commit is contained in:
parent
eb3b4d9822
commit
84f67fcd2d
@ -587,29 +587,70 @@ static cell_t FindStringInArray(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||
}
|
||||
|
||||
// the blocknumber is not guaranteed to always be passed
|
||||
// The parameters above 2 are optional
|
||||
|
||||
size_t blocknumber = 0;
|
||||
if (params[0] >= 3)
|
||||
{
|
||||
blocknumber = (size_t)params[3];
|
||||
}
|
||||
|
||||
if (blocknumber >= array->blocksize())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize());
|
||||
}
|
||||
}
|
||||
|
||||
int startidx = -1;
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
startidx = params[4];
|
||||
if (startidx > 0 && startidx > array->size())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid start index %d (max: %d)", startidx, array->size());
|
||||
}
|
||||
}
|
||||
|
||||
bool reverse = false;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
reverse = params[5];
|
||||
}
|
||||
|
||||
typedef int (*STRCOMPARE)(const char *, const char *);
|
||||
STRCOMPARE comparefn = (params[0] < 6 || params[6]) ? strcmp : strcasecmp;
|
||||
|
||||
char *str;
|
||||
pContext->LocalToString(params[2], &str);
|
||||
|
||||
for (unsigned int i = 0; i < array->size(); i++)
|
||||
if (reverse)
|
||||
{
|
||||
if (startidx < 0)
|
||||
{
|
||||
startidx = array->size();
|
||||
}
|
||||
for (int i = (startidx - 1); i >= 0; i--)
|
||||
{
|
||||
const char *array_str = (const char *)&array->base()[i * array->blocksize() + blocknumber];
|
||||
if (strcmp(str, array_str) == 0)
|
||||
if (comparefn(str, array_str) == 0)
|
||||
{
|
||||
return (cell_t) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startidx < -1)
|
||||
{
|
||||
startidx = -1;
|
||||
}
|
||||
for (unsigned int i = (startidx + 1); i < array->size(); i++)
|
||||
{
|
||||
const char *array_str = (const char *)&array->base()[i * array->blocksize() + blocknumber];
|
||||
if (comparefn(str, array_str) == 0)
|
||||
{
|
||||
return (cell_t) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -626,19 +667,41 @@ static cell_t FindValueInArray(IPluginContext *pContext, const cell_t *params)
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
|
||||
}
|
||||
|
||||
// the blocknumber is not guaranteed to always be passed
|
||||
// The parameters above 2 are optional
|
||||
|
||||
size_t blocknumber = 0;
|
||||
if (params[0] >= 3)
|
||||
{
|
||||
blocknumber = (size_t) params[3];
|
||||
}
|
||||
|
||||
blocknumber = (size_t)params[3];
|
||||
if (blocknumber >= array->blocksize())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize());
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < array->size(); i++)
|
||||
int startidx = -1;
|
||||
if (params[0] >= 4)
|
||||
{
|
||||
startidx = params[4];
|
||||
if (startidx > 0 && startidx > array->size())
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid start index %d (max: %d)", startidx, array->size());
|
||||
}
|
||||
}
|
||||
|
||||
bool reverse = false;
|
||||
if (params[0] >= 5)
|
||||
{
|
||||
reverse = params[5];
|
||||
}
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
if (startidx < 0)
|
||||
{
|
||||
startidx = array->size();
|
||||
}
|
||||
for (int i = (startidx - 1); i >= 0; i--)
|
||||
{
|
||||
cell_t *blk = array->at(i);
|
||||
if (params[2] == blk[blocknumber])
|
||||
@ -646,6 +709,22 @@ static cell_t FindValueInArray(IPluginContext *pContext, const cell_t *params)
|
||||
return (cell_t) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startidx < -1)
|
||||
{
|
||||
startidx = -1;
|
||||
}
|
||||
for (unsigned int i = (startidx + 1); i < array->size(); i++)
|
||||
{
|
||||
cell_t *blk = array->at(i);
|
||||
if (params[2] == blk[blocknumber])
|
||||
{
|
||||
return (cell_t) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -207,19 +207,28 @@ methodmap ArrayList < Handle {
|
||||
// Returns the index for the first occurrence of the provided string. If
|
||||
// the string cannot be located, -1 will be returned.
|
||||
//
|
||||
// @param item String to search for
|
||||
// @param block Optionally which block to search in
|
||||
// @param item String to search for.
|
||||
// @param block Optionally which block to search in.
|
||||
// @param start Index to start searching from (exclusive), or -1 for direction default.
|
||||
// Valid numbers are in the interval [-1..Length].
|
||||
// @param reverse Whether the search direction should be reversed.
|
||||
// @param caseSensitive If true (default), comparison is case sensitive.
|
||||
// If false, comparison is case insensitive.
|
||||
// @return Array index, or -1 on failure
|
||||
public native int FindString(const char[] item, int block=0);
|
||||
// @error Invalid block, or invalid start index.
|
||||
public native int FindString(const char[] item, int block=0, int start=-1, bool reverse=false, bool caseSensitive=true);
|
||||
|
||||
// Returns the index for the first occurrence of the provided value. If the
|
||||
// value cannot be located, -1 will be returned.
|
||||
//
|
||||
// @param item Value to search for
|
||||
// @param block Optionally which block to search in
|
||||
// @return Array index, or -1 on failure
|
||||
// @error Invalid block index
|
||||
public native int FindValue(any item, int block=0);
|
||||
// @param item Value to search for.
|
||||
// @param block Optionally which block to search in.
|
||||
// @param start Index to start searching from (exclusive), or -1 for direction default.
|
||||
// Valid numbers are in the interval [-1..Length].
|
||||
// @param reverse Whether the search direction should be reversed.
|
||||
// @return Array index, or -1 on failure.
|
||||
// @error Invalid block, or invalid start index.
|
||||
public native int FindValue(any item, int block=0, int start=-1, bool reverse=false);
|
||||
|
||||
// Sort an ADT Array. Specify the type as Integer, Float, or String.
|
||||
//
|
||||
|
||||
141
plugins/testsuite/mock/test_arraylist_find.sp
Normal file
141
plugins/testsuite/mock/test_arraylist_find.sp
Normal file
@ -0,0 +1,141 @@
|
||||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
#include <testing>
|
||||
|
||||
enum struct TestStruct
|
||||
{
|
||||
int intval;
|
||||
char strval[32];
|
||||
}
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
ArrayList list = new ArrayList(sizeof(TestStruct));
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
SetTestContext("EmptyArrayTest");
|
||||
|
||||
AssertEq("test_forward", list.FindString("index3", TestStruct::strval, -1, false), -1);
|
||||
AssertEq("test_reverse", list.FindString("index3", TestStruct::strval, -1, true), -1);
|
||||
AssertEq("test_forward", list.FindValue(3, TestStruct::intval, -1, false), -1);
|
||||
AssertEq("test_reverse", list.FindValue(3, TestStruct::intval, -1, true), -1);
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
// Fill
|
||||
TestStruct ts;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
ts.intval = i;
|
||||
Format(ts.strval, sizeof(ts.strval), "index%d", i);
|
||||
list.PushArray(ts);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
SetTestContext("FindString");
|
||||
|
||||
AssertEq("test_defaults", list.FindString("index3", TestStruct::strval), 3);
|
||||
|
||||
AssertEq("test_forward", list.FindString("index3", TestStruct::strval, -1, false), 3);
|
||||
AssertEq("test_forward", list.FindString("index3", TestStruct::strval, 0, false), 3);
|
||||
AssertEq("test_forward", list.FindString("index3", TestStruct::strval, 2, false), 3);
|
||||
AssertEq("test_forward", list.FindString("index3", TestStruct::strval, 3, false), -1);
|
||||
AssertEq("test_forward", list.FindString("index3", TestStruct::strval, 10, false), -1);
|
||||
|
||||
AssertEq("test_reverse", list.FindString("index3", TestStruct::strval, -1, true), 3);
|
||||
AssertEq("test_reverse", list.FindString("index3", TestStruct::strval, 0, true), -1);
|
||||
AssertEq("test_reverse", list.FindString("index3", TestStruct::strval, 3, true), -1);
|
||||
AssertEq("test_reverse", list.FindString("index3", TestStruct::strval, 4, true), 3);
|
||||
AssertEq("test_reverse", list.FindString("index3", TestStruct::strval, 10, true), 3);
|
||||
|
||||
AssertEq("test_bottom", list.FindString("index0", TestStruct::strval, -1, false), 0);
|
||||
AssertEq("test_bottom", list.FindString("index0", TestStruct::strval, -1, true), 0);
|
||||
AssertEq("test_bottom", list.FindString("index0", TestStruct::strval, 1, true), 0);
|
||||
AssertEq("test_bottom", list.FindString("index0", TestStruct::strval, 10, false), -1);
|
||||
AssertEq("test_bottom", list.FindString("index0", TestStruct::strval, 10, true), 0);
|
||||
|
||||
AssertEq("test_top", list.FindString("index9", TestStruct::strval, -1, false), 9);
|
||||
AssertEq("test_top", list.FindString("index9", TestStruct::strval, -1, true), 9);
|
||||
AssertEq("test_top", list.FindString("index9", TestStruct::strval, 8, false), 9);
|
||||
AssertEq("test_top", list.FindString("index9", TestStruct::strval, 10, false), -1);
|
||||
AssertEq("test_top", list.FindString("index9", TestStruct::strval, 10, true), 9);
|
||||
|
||||
AssertEq("test_case_sensitive", list.FindString("INDEX0", TestStruct::strval, .caseSensitive = true), -1);
|
||||
AssertEq("test_case_sensitive", list.FindString("INDEX0", TestStruct::strval, .caseSensitive = false), 0);
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
SetTestContext("FindValue");
|
||||
|
||||
AssertEq("test_defaults", list.FindValue(3, TestStruct::intval), 3);
|
||||
|
||||
AssertEq("test_forward", list.FindValue(3, TestStruct::intval, -1, false), 3);
|
||||
AssertEq("test_forward", list.FindValue(3, TestStruct::intval, 0, false), 3);
|
||||
AssertEq("test_forward", list.FindValue(3, TestStruct::intval, 2, false), 3);
|
||||
AssertEq("test_forward", list.FindValue(3, TestStruct::intval, 3, false), -1);
|
||||
AssertEq("test_forward", list.FindValue(3, TestStruct::intval, 10, false), -1);
|
||||
|
||||
AssertEq("test_reverse", list.FindValue(3, TestStruct::intval, -1, true), 3);
|
||||
AssertEq("test_reverse", list.FindValue(3, TestStruct::intval, 0, true), -1);
|
||||
AssertEq("test_reverse", list.FindValue(3, TestStruct::intval, 3, true), -1);
|
||||
AssertEq("test_reverse", list.FindValue(3, TestStruct::intval, 4, true), 3);
|
||||
AssertEq("test_reverse", list.FindValue(3, TestStruct::intval, 10, true), 3);
|
||||
|
||||
AssertEq("test_bottom", list.FindValue(0, TestStruct::intval, -1, false), 0);
|
||||
AssertEq("test_bottom", list.FindValue(0, TestStruct::intval, -1, true), 0);
|
||||
AssertEq("test_bottom", list.FindValue(0, TestStruct::intval, 1, true), 0);
|
||||
AssertEq("test_bottom", list.FindValue(0, TestStruct::intval, 10, false), -1);
|
||||
AssertEq("test_bottom", list.FindValue(0, TestStruct::intval, 10, true), 0);
|
||||
|
||||
AssertEq("test_top", list.FindValue(9, TestStruct::intval, -1, false), 9);
|
||||
AssertEq("test_top", list.FindValue(9, TestStruct::intval, -1, true), 9);
|
||||
AssertEq("test_top", list.FindValue(9, TestStruct::intval, 8, false), 9);
|
||||
AssertEq("test_top", list.FindValue(9, TestStruct::intval, 10, false), -1);
|
||||
AssertEq("test_top", list.FindValue(9, TestStruct::intval, 10, true), 9);
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
SetTestContext("IterateOverFindString");
|
||||
int found, index;
|
||||
|
||||
// Duplicate last entry
|
||||
list.PushArray(ts);
|
||||
|
||||
found = 0; index = -1;
|
||||
while ((index = list.FindString("index9", TestStruct::strval, index, false)) != -1)
|
||||
{
|
||||
found++;
|
||||
}
|
||||
AssertEq("test_find_all_strings_forward", found, 2);
|
||||
|
||||
found = 0; index = -1;
|
||||
while ((index = list.FindString("index9", TestStruct::strval, index, true)) != -1)
|
||||
{
|
||||
found++;
|
||||
}
|
||||
AssertEq("test_find_all_strings_reverse", found, 2);
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
SetTestContext("IterateOverFindValue");
|
||||
|
||||
found = 0, index = -1;
|
||||
while ((index = list.FindValue(9, TestStruct::intval, index, false)) != -1)
|
||||
{
|
||||
found++;
|
||||
}
|
||||
AssertEq("test_find_all_values_forward", found, 2);
|
||||
|
||||
found = 0; index = -1;
|
||||
while ((index = list.FindValue(9, TestStruct::intval, index, true)) != -1)
|
||||
{
|
||||
found++;
|
||||
}
|
||||
AssertEq("test_find_all_values_reverse", found, 2);
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
PrintToServer("OK");
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user