Permalink
Browse files

Rewrite C options to use StringsBuffer instead

  • Loading branch information...
UnknownShadow200 committed Nov 12, 2017
1 parent b2ba84f commit 128920589b0a61c30e1723e9319ecd14cbc82833
Showing with 70 additions and 81 deletions.
  1. +42 −56 src/Client/Options.c
  2. +5 −9 src/Client/Options.h
  3. +15 −9 src/Client/String.c
  4. +8 −7 src/Client/String.h
View
@@ -2,54 +2,47 @@
#include "ExtMath.h"
#include "ErrorHandler.h"
#include "Utils.h"
#include "Funcs.h"
#define OPT_NOT_FOUND UInt32_MaxValue
UInt8 Options_KeysBuffer[String_BufferSize(26) * OPTIONS_COUNT];
UInt8 Options_ValuesBuffer[
String_BufferSize(8) * OPTIONS_TINYSTRS +
String_BufferSize(16) * OPTIONS_SMALLSTRS +
String_BufferSize(32) * OPTIONS_MEDSTRS +
String_BufferSize(512) * OPTIONS_LARGESTRS
];
#define Options_InitStrs(strArray, count, elemLen)\
for (i = 0; i < count; i++, j++) {\
strArray[j] = String_FromEmptyBuffer(buffer, elemLen);\
buffer += String_BufferSize(elemLen);\
void Options_Init(void) {
StringBuffers_Init(&Options_Keys);
StringBuffers_Init(&Options_Values);
}
void Options_Init(void) {
Int32 i, j = 0;
UInt8* buffer = Options_KeysBuffer;
Options_InitStrs(Options_Keys, OPTIONS_COUNT, 24);
j = 0;
buffer = Options_ValuesBuffer;
Options_InitStrs(Options_Values, OPTIONS_TINYSTRS, 8);
Options_InitStrs(Options_Values, OPTIONS_SMALLSTRS, 16);
Options_InitStrs(Options_Values, OPTIONS_MEDSTRS, 32);
Options_InitStrs(Options_Values, OPTIONS_LARGESTRS, 512);
void Options_Free(void) {
StringsBuffer_Free(&Options_Keys);
StringsBuffer_Free(&Options_Values);
}
Int32 Options_Find(String key) {
Int32 i;
for (i = 0; i < OPTIONS_COUNT; i++) {
if (String_CaselessEquals(&Options_Keys[i], &key)) return i;
UInt32 Options_Find(String key) {
UInt32 i;
for (i = 0; i < Options_Keys.Count; i++) {
String curKey = StringsBuffer_UNSAFE_Get(&Options_Keys, i);
if (String_CaselessEquals(&curKey, &key)) return i;
}
return -1;
return OPT_NOT_FOUND;
}
bool Options_TryGetValue(const UInt8* keyRaw, String* value) {
bool Options_TryGetValue(const UInt8* keyRaw, STRING_TRANSIENT String* value) {
String key = String_FromReadonly(keyRaw);
*value = String_MakeNull();
Int32 i = Options_Find(key);
if (i >= 0) { *value = Options_Values[i]; return true; }
UInt32 i = Options_Find(key);
if (i != OPT_NOT_FOUND) {
*value = StringsBuffer_UNSAFE_Get(&Options_Values, i);
return true;
}
Int32 sepIndex = String_IndexOf(&key, '-', 0);
if (sepIndex == -1) return false;
key = String_UNSAFE_SubstringAt(&key, sepIndex + 1);
i = Options_Find(key);
if (i >= 0) { *value = Options_Values[i]; return true; }
if (i != OPT_NOT_FOUND) {
*value = StringsBuffer_UNSAFE_Get(&Options_Values, i);
return true;
}
return false;
}
@@ -94,48 +87,41 @@ UInt32 Options_GetEnum(const UInt8* key, UInt32 defValue, const UInt8** names, U
return Utils_ParseEnum(&str, defValue, names, namesCount);
}
void Options_Remove(Int32 i) {
String_Clear(&Options_Keys[i]);
String_Clear(&Options_Values[i]);
void Options_Remove(UInt32 i) {
StringsBuffer_Remove(&Options_Keys, i);
StringsBuffer_Remove(&Options_Values, i);
}
Int32 Options_Insert(String key, String value) {
Int32 i = Options_Find(key);
/* The new value may not fit in the old slot, always insert into a new slot. */
if (i >= 0) {
UInt32 i = Options_Find(key);
if (i != OPT_NOT_FOUND) {
Options_Remove(i);
Options_Changed[i] = false;
}
for (i = 0; i < OPTIONS_COUNT; i++) {
if (Options_Keys[i].length > 0) continue;
if (Options_Values[i].capacity < value.length) continue;
String_AppendString(&Options_Keys[i], &key);
String_AppendString(&Options_Values[i], &value);
return i;
/* Reset Changed state for this option */
for (; i < Array_NumElements(Options_Changed) - 1; i++) {
Options_Changed[i] = Options_Changed[i + 1];
}
}
ErrorHandler_Fail("No free slot left to save option");
return -1;
StringsBuffer_Add(&Options_Keys, &key);
StringsBuffer_Add(&Options_Values, &value);
return Options_Keys.Count;
}
void Options_SetInt32(const UInt8* keyRaw, Int32 value) {
UInt8 numBuffer[String_BufferSize(STRING_INT32CHARS)];
UInt8* ptr = numBuffer;
String numStr = String_FromRawBuffer(ptr, STRING_INT32CHARS);
String numStr = String_FromRawBuffer(numBuffer, STRING_INT32CHARS);
String_AppendInt32(&numStr, value);
Options_Set(keyRaw, numStr);
}
void Options_Set(const UInt8* keyRaw, STRING_PURE String value) {
String key = String_FromReadonly(keyRaw);
Int32 i;
UInt32 i;
if (value.buffer == NULL) {
i = Options_Find(key);
if (i >= 0) Options_Remove(i);
if (i != OPT_NOT_FOUND) Options_Remove(i);
} else {
i = Options_Insert(key, value);
}
if (i >= 0) Options_Changed[i] = true;
if (i != OPT_NOT_FOUND) Options_Changed[i] = true;
}
View
@@ -70,18 +70,14 @@ typedef UInt8 FpsLimitMethod;
#define OptionsKey_AllowClassicHacks "nostalgia-hacks"
#define OptionsKey_ClassicArmModel "nostalgia-classicarm"
#define OPTIONS_LARGESTRS 4
#define OPTIONS_MEDSTRS 16
#define OPTIONS_SMALLSTRS 32
#define OPTIONS_TINYSTRS 64
#define OPTIONS_COUNT (OPTIONS_LARGESTRS + OPTIONS_MEDSTRS + OPTIONS_SMALLSTRS + OPTIONS_TINYSTRS)
String Options_Keys[OPTIONS_COUNT];
String Options_Values[OPTIONS_COUNT];
bool Options_Changed[OPTIONS_COUNT];
StringsBuffer Options_Keys;
StringsBuffer Options_Values;
bool Options_Changed[256];
void Options_Init(void);
void Options_Free(void);
/* TODO: eliminate this and use STRING_TRANSIENT ARG */
String Options_Get(const UInt8* key);
Int32 Options_GetInt(const UInt8* key, Int32 min, Int32 max, Int32 defValue);
bool Options_GetBool(const UInt8* key, bool defValue);
View
@@ -2,15 +2,15 @@
#include "Funcs.h"
#include "ErrorHandler.h"
String String_FromEmptyBuffer(UInt8* buffer, UInt16 capacity) {
String String_FromEmptyBuffer(STRING_REF UInt8* buffer, UInt16 capacity) {
String str;
str.buffer = buffer;
str.capacity = capacity;
str.length = 0;
return str;
}
String String_FromRawBuffer(UInt8* buffer, UInt16 capacity) {
String String_FromRawBuffer(STRING_REF UInt8* buffer, UInt16 capacity) {
String str = String_FromEmptyBuffer(buffer, capacity);
Int32 i;
@@ -19,7 +19,7 @@ String String_FromRawBuffer(UInt8* buffer, UInt16 capacity) {
return str;
}
String String_FromReadonly(const UInt8* buffer) {
String String_FromReadonly(STRING_REF const UInt8* buffer) {
UInt16 length = 0;
UInt8* cur = buffer;
while ((*cur) != NULL) { cur++; length++; }
@@ -385,14 +385,20 @@ bool Convert_TryParseBool(STRING_PURE String* str, bool* value) {
#define STRINGSBUFFER_LEN_SHIFT 10
#define STRINGSBUFFER_LEN_MASK 0x3FFUL
void StringsBuffer_Get(StringsBuffer* buffer, UInt32 index, STRING_TRANSIENT String* text) {
if (index >= buffer->Count) ErrorHandler_Fail("Tried to get String past StringsBuffer end");
String raw = StringsBuffer_UNSAFE_Get(buffer, index);
String_Clear(text);
String_AppendString(text, &raw);
}
UInt32 flags = buffer->FlagsBuffer[index];
String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, UInt32 index) {
if (index >= buffer->Count) ErrorHandler_Fail("Tried to get String past StringsBuffer end");
UInt32 flags = buffer->FlagsBuffer[index];
UInt32 offset = flags >> STRINGSBUFFER_LEN_SHIFT;
UInt32 len = flags & STRINGSBUFFER_LEN_MASK;
UInt32 len = flags & STRINGSBUFFER_LEN_MASK;
UInt8* src = &buffer->FlagsBuffer[offset];
UInt32 i;
for (i = 0; i < len; i++) { String_Append(text, src[i]); }
String raw;
raw.buffer = &buffer->TextBuffer[offset];
raw.length = len; raw.capacity = len;
return raw;
}
View
@@ -26,12 +26,12 @@ typedef struct String_ {
} String;
/* Constructs a new string, pointing a buffer consisting purely of NULL characters. */
String String_FromEmptyBuffer(UInt8* buffer, UInt16 capacity);
String String_FromEmptyBuffer(STRING_REF UInt8* buffer, UInt16 capacity);
/* Constructs a new string, pointing a buffer consisting of arbitary data.
NOTE: This method sets the bytes occupied by the string to NUL. */
String String_FromRawBuffer(UInt8* buffer, UInt16 capacity);
NOTE: This method sets the bytes occupied by the string to NULL. */
String String_FromRawBuffer(STRING_REF UInt8* buffer, UInt16 capacity);
/* Constructs a new string from a constant readonly buffer. */
String String_FromReadonly(const UInt8* buffer);
String String_FromReadonly(STRING_REF const UInt8* buffer);
/* Makes an empty string that points to nowhere. */
String String_MakeNull(void);
/* Constructs a new string from a compile time string constant. */
@@ -48,9 +48,7 @@ NOTE: THIS IS UNSAFE - IT MAINTAINS A REFERENCE TO THE ORIGINAL BUFFER, AND THE
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)))
/* Returns whether two strings have same contents. */
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b);
/* Returns whether two strings have same case-insensitive contents. */
bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b);
/* Attempts to append a character to the end of a string. */
@@ -100,7 +98,10 @@ typedef struct StringsBuffer_ {
UInt32 Count;
} StringsBuffer;
void StringBuffers_Init(StringsBuffer* buffer);
void StringsBuffer_Free(StringsBuffer* buffer);
void StringsBuffer_Get(StringsBuffer* buffer, UInt32 index, STRING_TRANSIENT String* text);
STRING_REF String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, UInt32 index);
void StringsBuffer_Add(StringsBuffer* buffer, STRING_PURE String* text);
void StringsBuffer_Free(StringsBuffer* buffer);
void StringsBuffer_Remove(StringsBuffer* buffer, UInt32 index);
#endif

0 comments on commit 1289205

Please sign in to comment.