Skip to content
This repository was archived by the owner on Sep 24, 2023. It is now read-only.

Commit 0efc58d

Browse files
committed
Use string functions optimized for use-case
strcopy has to seek through the char array each time it's performed, making it really slow on longer lines. SplitString used a more exhaustive check than was necessary for single character matches.
1 parent 617590e commit 0efc58d

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

scripting/level_keyvalues.sp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
#pragma newdecls required
1919

20-
#define PLUGIN_VERSION "0.3.1"
20+
#define PLUGIN_VERSION "0.3.2"
2121
public Plugin myinfo = {
2222
name = "Level KeyValues",
2323
author = "nosoop",
@@ -165,7 +165,7 @@ static ArrayList ParseEntityList(const char mapEntities[2097152]) {
165165

166166
int i, n;
167167
char lineBuffer[4096];
168-
while ((n = SplitString(mapEntities[i], "\n", lineBuffer, sizeof(lineBuffer))) != -1) {
168+
while ((n = SplitStringOnNewLine(mapEntities[i], lineBuffer, sizeof(lineBuffer))) != -1) {
169169
switch(lineBuffer[0]) {
170170
case '{': {
171171
currentEntityMap = new StringMultiMap();
@@ -206,6 +206,31 @@ static ArrayList ParseEntityList(const char mapEntities[2097152]) {
206206
return mapEntityList;
207207
}
208208

209+
/**
210+
* Semi-optimized `SplitString` for linebreaks.
211+
*
212+
*/
213+
int SplitStringOnNewLine(const char[] str, char[] buffer, int maxlen) {
214+
int b;
215+
char c;
216+
while ((c = str[b]) != '\0' && c != '\n') {
217+
b++;
218+
}
219+
if (!str[b]) {
220+
return -1;
221+
}
222+
b++;
223+
strcopy(buffer, b, str);
224+
return b;
225+
}
226+
227+
/**
228+
* Replacement for StrCat that takes in a position to copy to.
229+
*/
230+
int strcopypos(char[] dest, int destLen, const char[] source, int index = 0) {
231+
return strcopy(dest[index], destLen - index, source) + index;
232+
}
233+
209234
Action ForwardOnEntityKeysParsed(StringMultiMap entity) {
210235
Action result;
211236
Call_StartForward(g_OnEntityKeysParsed);
@@ -219,8 +244,9 @@ Action ForwardOnEntityKeysParsed(StringMultiMap entity) {
219244
* Writes the entity list back out in level string format.
220245
*/
221246
void WriteEntityList(ArrayList entityList, char[] buffer, int maxlen) {
247+
int bufpos;
222248
for (int i = 0; i < entityList.Length; i++) {
223-
StrCat(buffer, maxlen, "{\n");
249+
bufpos = strcopypos(buffer, maxlen, "{\n", bufpos);
224250

225251
StringMultiMapIterator keyiter = view_as<StringMultiMap>(entityList.Get(i)).GetIterator();
226252
while (keyiter.Next()) {
@@ -230,11 +256,11 @@ void WriteEntityList(ArrayList entityList, char[] buffer, int maxlen) {
230256

231257
char lineBuffer[512];
232258
Format(lineBuffer, sizeof(lineBuffer), "\"%s\" \"%s\"\n", key, value);
233-
StrCat(buffer, maxlen, lineBuffer);
259+
bufpos = strcopypos(buffer, maxlen, lineBuffer, bufpos);
234260
}
235261
delete keyiter;
236262

237-
StrCat(buffer, maxlen, "}\n");
263+
bufpos = strcopypos(buffer, maxlen, "}\n", bufpos);
238264
}
239265
}
240266

0 commit comments

Comments
 (0)