Skip to content

Add block parameter to various ArrayList functions#1656

Merged
peace-maker merged 6 commits intoalliedmodders:masterfrom
Mikusch:findstring-block
Sep 27, 2023
Merged

Add block parameter to various ArrayList functions#1656
peace-maker merged 6 commits intoalliedmodders:masterfrom
Mikusch:findstring-block

Conversation

@Mikusch
Copy link
Contributor

@Mikusch Mikusch commented Nov 28, 2021

This PR adds the block parameter to the following functions:

  • ArrayList.FindString
  • ArrayList.GetArray
  • ArrayList.SetArray
  • ArrayList.GetString
  • ArrayList.SetString

Default value is 0.

This can be useful especially when operating on enum structs:

enum struct MyStruct
{
	int intValue;
	int arrValue[3];
	char strValue[64];
}

public void OnPluginStart()
{
	MyStruct struct1;
	struct1.intValue = 42;
	struct1.arrValue[0] = 1;
	struct1.arrValue[1] = 2;
	struct1.arrValue[2] = 3;
	strcopy(struct1.strValue, sizeof(struct1.strValue), "foo");
	
	MyStruct struct2;
	struct2.intValue = 1337;
	struct2.arrValue[0] = 4;
	struct2.arrValue[1] = 5;
	struct2.arrValue[2] = 6;
	strcopy(struct2.strValue, sizeof(struct2.strValue), "bar");
	
	int arrBuffer[3];
	char strBuffer[64];
	
	ArrayList list = new ArrayList(sizeof(MyStruct));
	list.PushArray(struct1);
	list.PushArray(struct2);
	
	// ArrayList.FindString
	int index = list.FindString("bar", MyStruct::strValue);
	PrintToServer("bar is at index: %d", index); // "1"
	
	// ArrayList.GetArray
	list.GetArray(1, arrBuffer, sizeof(arrBuffer), MyStruct::arrValue);
	PrintToServer("arrValue at index 1 contains: (%d, %d, %d)", arrBuffer[0], arrBuffer[1], arrBuffer[2]);	// "(4, 5, 6)"
	
	// ArrayList.SetArray
	arrBuffer[2] = 322;
	list.SetArray(1, arrBuffer, sizeof(arrBuffer), MyStruct::arrValue);
	list.GetArray(1, arrBuffer, sizeof(arrBuffer), MyStruct::arrValue);
	PrintToServer("arrValue at index 1 contains: (%d, %d, %d)", arrBuffer[0], arrBuffer[1], arrBuffer[2]);	// "(4, 5, 322)"
	
	// ArrayList.GetString
	list.GetString(0, strBuffer, sizeof(strBuffer), MyStruct::strValue);
	PrintToServer("strValue at index 0: %s", strBuffer);	// "foo"
	
	// ArrayList.SetString
	list.SetString(0, "the grass was greener", MyStruct::strValue);
	list.GetString(0, strBuffer, sizeof(strBuffer), MyStruct::strValue);
	PrintToServer("strValue at index 0: %s", strBuffer);	// "the grass was greener"
	
	delete list;
}

@JoinedSenses
Copy link
Contributor

I like this. Would also be nice to have block param for (G/S)et(String/Array), too

@Mikusch
Copy link
Contributor Author

Mikusch commented Nov 28, 2021

Would also be nice to have block param for (G/S)et(String/Array), too

That sounds like a great addition. I'll get around to it in the coming days. I don't really mind if it's in this PR or another.

I should probably add an offset parameter to CellArray::at to make this look a bit cleaner.
Would require an interface version bump, so I'll hold off of it for now.

@Mikusch Mikusch changed the title Add block parameter to ArrayList.FindString Add block parameter to various ArrayList functions Nov 28, 2021
@Mikusch
Copy link
Contributor Author

Mikusch commented Nov 28, 2021

I've added the block parameter to (G/S)et(String/Array) and updated the PR name/description.

@sirdigbot
Copy link
Contributor

If I'm not missing something, your code has a major bug. For SetString you don't prevent actually prevent writing past the string's buffer.
Which was something I addressed in my pr #1678

enum struct SomeStruct
{
    int a;
    char textLong[16];
    int b;
    char textShort[4];
    int c;
}
// ...
list.SetString(0, "Some string that is very much too large for this buffer", SomeStruct::textLong);

@peace-maker
Copy link
Member

@Mikusch can you rebase and fix the buffer overflow @sirdigbot mentioned please?

@Mikusch
Copy link
Contributor Author

Mikusch commented Jul 30, 2023

Hi @peace-maker, I apologize for how long it's taken me to update this PR.

bb918f2 adds an optional size parameter to SetString which will ensure you can't overflow the buffer.

Copy link
Member

@peace-maker peace-maker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@Mikusch Mikusch requested a review from peace-maker September 27, 2023 13:40
@peace-maker peace-maker merged commit 29694ec into alliedmodders:master Sep 27, 2023
@Mikusch Mikusch deleted the findstring-block branch September 27, 2023 14:06
@Alienmario
Copy link
Contributor

Alienmario commented Oct 28, 2024

I think the last thing missing to really get off of the wasteful iteration of struct arrays is a start index parameter for FindString/FindValue -- to handle the instances where members can have identical values.

(along with case insensivity option for FindString perhaps)

Edit: Looking into it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants