C client: simplify key-value splitting

This commit is contained in:
UnknownShadow200 2018-08-30 05:00:01 +10:00
parent 26081a0074
commit e3905c9a3f
10 changed files with 38 additions and 52 deletions

View File

@ -125,14 +125,10 @@ void Entity_SetModel(struct Entity* entity, STRING_PURE String* model) {
entity->ModelScale = Vector3_Create1(1.0f); entity->ModelScale = Vector3_Create1(1.0f);
entity->ModelBlock = BLOCK_AIR; entity->ModelBlock = BLOCK_AIR;
Int32 sep = String_IndexOf(model, '|', 0);
String name, scale; String name, scale;
if (sep == -1) { if (!String_UNSAFE_Split_KV(model, '|', &name, &scale)) {
name = *model; name = *model;
scale = String_MakeNull(); scale = String_MakeNull();
} else {
name = String_UNSAFE_Substring(model, 0, sep);
scale = String_UNSAFE_SubstringAt(model, sep + 1);
} }
/* 'giant' model kept for backwards compatibility */ /* 'giant' model kept for backwards compatibility */

View File

@ -305,26 +305,21 @@ void Hotkeys_Init(void) {
for (i = 0; i < Options_Keys.Count; i++) { for (i = 0; i < Options_Keys.Count; i++) {
String key = StringsBuffer_UNSAFE_Get(&Options_Keys, i); String key = StringsBuffer_UNSAFE_Get(&Options_Keys, i);
if (!String_CaselessStarts(&key, &prefix)) continue; if (!String_CaselessStarts(&key, &prefix)) continue;
Int32 keySplit = String_IndexOf(&key, '&', prefix.length);
if (keySplit < 0) continue; /* invalid key */
String strKey = String_UNSAFE_Substring(&key, prefix.length, keySplit - prefix.length);
String strFlags = String_UNSAFE_SubstringAt(&key, keySplit + 1);
/* key&modifiers = more-input&text */
key.length -= prefix.length; key.buffer += prefix.length;
String value = StringsBuffer_UNSAFE_Get(&Options_Values, i); String value = StringsBuffer_UNSAFE_Get(&Options_Values, i);
Int32 valueSplit = String_IndexOf(&value, '&', 0);
if (valueSplit < 0) continue; /* invalid value */
String strMoreInput = String_UNSAFE_Substring(&value, 0, valueSplit - 0); String strKey, strFlags, strMore, strText;
String strText = String_UNSAFE_SubstringAt(&value, valueSplit + 1); if (!String_UNSAFE_Split_KV(&key, '&', &strKey, &strFlags)) continue;
if (!String_UNSAFE_Split_KV(&value, '&', &strMore, &strText)) continue;
/* Then try to parse the key and value */
Key hotkey = Utils_ParseEnum(&strKey, Key_None, Key_Names, Array_Elems(Key_Names)); Key hotkey = Utils_ParseEnum(&strKey, Key_None, Key_Names, Array_Elems(Key_Names));
UInt8 flags; bool moreInput; UInt8 flags; bool more;
if (hotkey == Key_None || !strText.length || !Convert_TryParseUInt8(&strFlags, &flags) if (hotkey == Key_None || !Convert_TryParseUInt8(&strFlags, &flags)
|| !Convert_TryParseBool(&strMoreInput, &moreInput)) { continue; } || !Convert_TryParseBool(&strMore, &more)) { continue; }
Hotkeys_Add(hotkey, flags, &strText, moreInput); Hotkeys_Add(hotkey, flags, &strText, more);
} }
} }

View File

@ -1548,14 +1548,10 @@ static void HotkeyListScreen_EntryClick(struct GuiElem* elem, struct GuiElem* w)
Gui_ReplaceActive(EditHotkeyScreen_MakeInstance(original)); return; Gui_ReplaceActive(EditHotkeyScreen_MakeInstance(original)); return;
} }
Int32 sepIndex = String_IndexOf(&text, '+', 0);
String key = text, value; String key = text, value;
UInt8 flags = 0; UInt8 flags = 0;
if (sepIndex >= 0) { if (String_UNSAFE_Split_KV(&text, '+', &key, &value)) {
key = String_UNSAFE_Substring(&text, 0, sepIndex - 1);
value = String_UNSAFE_SubstringAt(&text, sepIndex + 1);
String ctrl = String_FromConst("Ctrl"); String ctrl = String_FromConst("Ctrl");
String shift = String_FromConst("Shift"); String shift = String_FromConst("Shift");
String alt = String_FromConst("Alt"); String alt = String_FromConst("Alt");

View File

@ -173,6 +173,7 @@ void Options_Load(void) {
/* ReadLine reads single byte at a time */ /* ReadLine reads single byte at a time */
UInt8 buffer[2048]; struct Stream buffered; UInt8 buffer[2048]; struct Stream buffered;
Stream_ReadonlyBuffered(&buffered, &stream, buffer, sizeof(buffer)); Stream_ReadonlyBuffered(&buffered, &stream, buffer, sizeof(buffer));
String key, value;
for (;;) { for (;;) {
res = Stream_ReadLine(&buffered, &line); res = Stream_ReadLine(&buffered, &line);
@ -180,13 +181,7 @@ void Options_Load(void) {
if (res) { Chat_LogError(res, "reading from", &path); break; } if (res) { Chat_LogError(res, "reading from", &path); break; }
if (!line.length || line.buffer[0] == '#') continue; if (!line.length || line.buffer[0] == '#') continue;
Int32 sepIndex = String_IndexOf(&line, '=', 0); if (!String_UNSAFE_Split_KV(&line, '=', &key, &value)) continue;
if (sepIndex <= 0) continue;
String key = String_UNSAFE_Substring(&line, 0, sepIndex);
sepIndex++;
if (sepIndex == line.length) continue;
String value = String_UNSAFE_SubstringAt(&line, sepIndex);
if (!Options_HasChanged(&key)) { if (!Options_HasChanged(&key)) {
Options_Insert(&key, &value); Options_Insert(&key, &value);

View File

@ -240,18 +240,12 @@ static bool WoM_ReadLine(STRING_REF String* page, Int32* start, STRING_TRANSIENT
} }
static void WoM_ParseConfig(STRING_PURE String* page) { static void WoM_ParseConfig(STRING_PURE String* page) {
String line; String line, key, value;
Int32 start = 0; Int32 start = 0;
while (WoM_ReadLine(page, &start, &line)) { while (WoM_ReadLine(page, &start, &line)) {
Platform_Log(&line); Platform_Log(&line);
Int32 sepIndex = String_IndexOf(&line, '=', 0); if (!String_UNSAFE_Split_KV(&line, '=', &key, &value)) continue;
if (sepIndex == -1) continue;
String key = String_UNSAFE_Substring(&line, 0, sepIndex);
String_UNSAFE_TrimEnd(&key);
String value = String_UNSAFE_SubstringAt(&line, sepIndex + 1);
String_UNSAFE_TrimStart(&value);
if (String_CaselessEqualsConst(&key, "environment.cloud")) { if (String_CaselessEqualsConst(&key, "environment.cloud")) {
PackedCol col = WoM_ParseCol(&value, WorldEnv_DefaultCloudsCol); PackedCol col = WoM_ParseCol(&value, WorldEnv_DefaultCloudsCol);

View File

@ -115,7 +115,7 @@ int main(void) {
} }
UInt16 port; UInt16 port;
if (!Convert_TryParseUInt16(&args[3], &Game_Port)) { if (!Convert_TryParseUInt16(&args[3], &port)) {
Platform_LogConst("Invalid port"); return 1; Platform_LogConst("Invalid port"); return 1;
} }
Game_Port = port; Game_Port = port;

View File

@ -154,7 +154,7 @@ static void SPConnection_BeginConnect(void) {
} }
Event_RaiseVoid(&BlockEvents_PermissionsChanged); Event_RaiseVoid(&BlockEvents_PermissionsChanged);
/* For when user drops a map file onto ClassicalSharp.exe */ /* For when user drops a map file onto ClassiCube.exe */
String path = Game_Username; String path = Game_Username;
if (String_IndexOf(&path, Directory_Separator, 0) >= 0 && File_Exists(&path)) { if (String_IndexOf(&path, Directory_Separator, 0) >= 0 && File_Exists(&path)) {
LoadLevelScreen_LoadMap(&path); LoadLevelScreen_LoadMap(&path);

View File

@ -82,6 +82,20 @@ void String_UNSAFE_Split(STRING_REF String* str, char c, STRING_TRANSIENT String
for (; i < maxSubs; i++) { subs[i] = String_MakeNull(); } for (; i < maxSubs; i++) { subs[i] = String_MakeNull(); }
} }
bool String_UNSAFE_Split_KV(STRING_REF String* str, char c, STRING_TRANSIENT String* key, STRING_TRANSIENT String* value) {
/* key [c] value or key[c]value */
Int32 idx = String_IndexOf(str, c, 0);
if (idx <= 0) return false; /* missing [c] or no key */
if ((idx + 1) >= str->length) return false; /* missing value */
*key = String_UNSAFE_Substring(str, 0, idx); idx++;
*value = String_UNSAFE_SubstringAt(str, idx);
String_UNSAFE_TrimEnd(key);
String_UNSAFE_TrimStart(value);
return true;
}
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b) { bool String_Equals(STRING_PURE String* a, STRING_PURE String* b) {
if (a->length != b->length) return false; if (a->length != b->length) return false;

View File

@ -43,13 +43,10 @@ String String_FromReadonly(STRING_REF const char* buffer);
void String_StripCols(STRING_TRANSIENT String* str); void String_StripCols(STRING_TRANSIENT String* str);
void String_Copy(STRING_TRANSIENT String* dst, STRING_PURE String* src); void String_Copy(STRING_TRANSIENT String* dst, STRING_PURE String* src);
/* Returns a string that points directly to a substring of the given string.
NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE SUBSTRING IS NOT NULL TERMINATED */
String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length); String String_UNSAFE_Substring(STRING_REF String* str, Int32 offset, Int32 length);
#define String_UNSAFE_SubstringAt(str, offset) (String_UNSAFE_Substring(str, offset, (str)->length - (offset))) #define String_UNSAFE_SubstringAt(str, offset) (String_UNSAFE_Substring(str, offset, (str)->length - (offset)))
/* Splits a string into a sequence of substrings
NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE SUBSTRING IS NOT NULL TERMINATED */
void String_UNSAFE_Split(STRING_REF String* str, char c, STRING_TRANSIENT String* subs, Int32* subsCount); void String_UNSAFE_Split(STRING_REF String* str, char c, STRING_TRANSIENT String* subs, Int32* subsCount);
bool String_UNSAFE_Split_KV(STRING_REF String* str, char c, STRING_TRANSIENT String* key, STRING_TRANSIENT String* value);
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b); bool String_Equals(STRING_PURE String* a, STRING_PURE String* b);
bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b); bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b);

View File

@ -323,14 +323,13 @@ bool TextureCache_GetStream(STRING_PURE String* url, struct Stream* stream) {
void TexturePack_GetFromTags(STRING_PURE String* url, STRING_TRANSIENT String* result, struct EntryList* list) { void TexturePack_GetFromTags(STRING_PURE String* url, STRING_TRANSIENT String* result, struct EntryList* list) {
TexCache_Crc32(url); TexCache_Crc32(url);
Int32 i; Int32 i;
for (i = 0; i < list->Entries.Count; i++) { String line, key, value;
String entry = StringsBuffer_UNSAFE_Get(&list->Entries, i);
if (!String_CaselessStarts(&entry, &crc32)) continue;
Int32 sepIndex = String_IndexOf(&entry, ' ', 0); for (i = 0; i < list->Entries.Count; i++) {
if (sepIndex == -1) continue; line = StringsBuffer_UNSAFE_Get(&list->Entries, i);
if (!String_UNSAFE_Split_KV(&line, ' ', &key, &value)) continue;
String value = String_UNSAFE_SubstringAt(&entry, sepIndex + 1);
if (!String_CaselessEquals(&key, &crc32)) continue;
String_AppendString(result, &value); String_AppendString(result, &value);
} }
} }