From 90181ed4db205f939ed29ff121c2c53b9e147505 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Fri, 12 May 2017 19:46:33 +1000 Subject: [PATCH] Add more stuff to C string API --- src/Client/Block.c | 2 +- src/Client/String.c | 212 +++++++++++++++++++++++++------------------- src/Client/String.h | 109 ++++++++++++----------- 3 files changed, 183 insertions(+), 140 deletions(-) diff --git a/src/Client/Block.c b/src/Client/Block.c index e9ee95acd..c79bdd65d 100644 --- a/src/Client/Block.c +++ b/src/Client/Block.c @@ -107,7 +107,7 @@ void Block_ResetProps(BlockID block) { Int32 Block_FindID(String* name) { Int32 block; for (block = BlockID_Air; block < Block_Count; block++) { - if (String_CaselessEquals(&Block_Name[block], name)) return i; + if (String_CaselessEquals(&Block_Name[block], name)) return block; } return -1; } diff --git a/src/Client/String.c b/src/Client/String.c index 4abed7093..923ab4d76 100644 --- a/src/Client/String.c +++ b/src/Client/String.c @@ -1,90 +1,124 @@ -#include "String.h" -#include "Funcs.h" - -String String_FromEmptyBuffer(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 str = String_FromEmptyBuffer(buffer, capacity); - // Need to set region occupied by string to NUL for interop with native APIs - for (Int32 i = 0; i < capacity + 1; i++) { - buffer[i] = 0; - } - return str; -} - -String String_FromConstant(const UInt8* buffer) { - UInt16 length = 0; - UInt8 cur = 0; - UInt8* ptr = buffer; - - while ((cur = *buffer) != 0) { - length++; buffer++; - } - - String str; - str.buffer = ptr; - str.capacity = length; - str.length = length; - return str; -} - -String String_MakeNull() { - String str; - str.buffer = NULL; - str.capacity = 0; - str.length = 0; - return str; -} - - -bool String_Equals(String* a, String* b) { - if (a->length != b->length) return false; - - for (Int32 i = 0; i < a->length; i++) { - if (a->buffer[i] != b->buffer[i]) return false; - } - return true; -} - -bool String_CaselessEquals(String* a, String* b) { - if (a->length != b->length) return false; - - for (Int32 i = 0; i < a->length; i++) { - UInt8 aCur = a->buffer[i]; - UInt8 bCur = b->buffer[i]; - - if (Char_IsUpper(aCur)) aCur = Char_ToLower(aCur); - if (Char_IsUpper(bCur)) bCur = Char_ToLower(bCur); - - if (aCur != bCur) return false; - } - return true; -} - - -bool String_Append(String* str, UInt8 c) { - if (str->length == str->capacity) return false; - - str->buffer[str->length] = c; - str->length++; - return true; -} - - -Int32 String_IndexOf(String* str, UInt8 c, Int32 offset) { - for (Int32 i = offset; i < str->length; i++) { - if (str->buffer[i] == c) return i; - } - return -1; -} - -UInt8 String_CharAt(String* str, Int32 offset) { - if (offset < 0 || offset >= str->length) return 0; - return str->buffer[offset]; +#include "String.h" +#include "Funcs.h" + +String String_FromEmptyBuffer(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 str = String_FromEmptyBuffer(buffer, capacity); + // Need to set region occupied by string to NUL for interop with native APIs + for (Int32 i = 0; i < capacity + 1; i++) { + buffer[i] = 0; + } +} + +String String_FromConstant(const UInt8* buffer) { + UInt16 length = 0; + UInt8 cur = 0; + UInt8* ptr = buffer; + + while ((cur = *buffer) != 0) { + length++; buffer++; + } + + String str; + str.buffer = ptr; + str.capacity = length; + str.length = length; + return str; +} + +String String_MakeNull() { + String str; + str.buffer = NULL; + str.capacity = 0; + str.length = 0; + return str; +} + + +bool String_Equals(String* a, String* b) { + if (a->length != b->length) return false; + + for (Int32 i = 0; i < a->length; i++) { + if (a->buffer[i] != b->buffer[i]) return false; + } + return true; +} + +bool String_CaselessEquals(String* a, String* b) { + if (a->length != b->length) return false; + + for (Int32 i = 0; i < a->length; i++) { + UInt8 aCur = a->buffer[i]; + UInt8 bCur = b->buffer[i]; + + if (Char_IsUpper(aCur)) aCur = Char_ToLower(aCur); + if (Char_IsUpper(bCur)) bCur = Char_ToLower(bCur); + + if (aCur != bCur) return false; + } + return true; +} + + +bool String_Append(String* str, UInt8 c) { + if (str->length == str->capacity) return false; + + str->buffer[str->length] = c; + str->length++; + return true; +} + +bool String_AppendNum(String* str, Int64 num) { + UInt8 numBuffer[20]; + Int32 numLen = MakeNum(num, numBuffer); + + for (Int32 i = numLen - 1; i >= 0; i--) { + if (!String_Append(str, numBuffer[i])) return false; + } + return true; +} + +bool String_AppendPaddedNum(String* str, Int64 num, Int32 minDigits) { + UInt8 numBuffer[20]; + for (Int32 i = 0; i < minDigits; i++) { + numBuffer[i] = '0'; + } + + Int32 numLen = MakeNum(num, numBuffer); + if (numLen < minDigits) numLen = minDigits; + + for (Int32 i = numLen - 1; i >= 0; i--) { + if (!String_Append(str, numBuffer[i])) return false; + } + return true; +} + +static Int32 String_MakeNum(Int64 num, UInt8* numBuffer) { + Int32 len = 0; + + do { + numBuffer[len] = (char)('0' + (num % 10)); num /= 10; + len++; + } while (num > 0); + return len; +} + + +Int32 String_IndexOf(String* str, UInt8 c, Int32 offset) { + for (Int32 i = offset; i < str->length; i++) { + if (str->buffer[i] == c) return i; + } + return -1; +} + +UInt8 String_CharAt(String* str, Int32 offset) { + if (offset < 0 || offset >= str->length) return 0; + return str->buffer[offset]; } \ No newline at end of file diff --git a/src/Client/String.h b/src/Client/String.h index d160ec223..d8b592991 100644 --- a/src/Client/String.h +++ b/src/Client/String.h @@ -1,51 +1,60 @@ -#ifndef CS_STRING_H -#define CS_STRING_H -#include "Typedefs.h" -/* Implements operations for a string. - Copyright 2017 ClassicalSharp | Licensed under BSD-3 -*/ - -#define String_BufferSize(n) (n + 1) - -typedef struct String { - /* Pointer to raw characters. Size is capacity + 1, as buffer is null terminated. */ - UInt8* buffer; - - /* Number of characters used. */ - UInt16 length; - - /* Max number of characters that can be in buffer. */ - UInt16 capacity; -} String; - -/* Constructs a new string, pointing a buffer consisting purely of NULL characters. */ -String String_FromEmptyBuffer(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); - -/* Constructs a new string from a constant readonly string. */ -String String_FromConstant(const UInt8* buffer); - -/* Makes an empty string that points to nowhere. */ -String String_MakeNull(); - - -/* Returns whether two strings have same contents. */ -bool String_Equals(String* a, String* b); - -/* Returns whether two strings have same case-insensitive contents. */ -bool String_CaselessEquals(String* a, String* b); - - -/* Attempts to append a character to the end of a string. */ -bool String_Append(String* str, UInt8 c); - -/* Finds the first index of c in given string, -1 if not found. */ -int String_IndexOf(String* str, UInt8 c, Int32 offset); - -/* Gets the character at the given index in the string. */ -UInt8 String_CharAt(String* str, Int32 offset); - +#ifndef CS_STRING_H +#define CS_STRING_H +#include "Typedefs.h" +/* Implements operations for a string. +Copyright 2017 ClassicalSharp | Licensed under BSD-3 +*/ + +#define String_BufferSize(n) (n + 1) + +typedef struct String { + /* Pointer to raw characters. Size is capacity + 1, as buffer is null terminated. */ + UInt8* buffer; + + /* Number of characters used. */ + UInt16 length; + + /* Max number of characters that can be in buffer. */ + UInt16 capacity; +} String; + +/* Constructs a new string, pointing a buffer consisting purely of NULL characters. */ +String String_FromEmptyBuffer(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); + +/* Constructs a new string from a constant readonly string. */ +String String_FromConstant(const UInt8* buffer); + +/* Makes an empty string that points to nowhere. */ +String String_MakeNull(); + + +/* Returns whether two strings have same contents. */ +bool String_Equals(String* a, String* b); + +/* Returns whether two strings have same case-insensitive contents. */ +bool String_CaselessEquals(String* a, String* b); + + +/* Attempts to append a character to the end of a string. */ +bool String_Append(String* str, UInt8 c); + +/* Attempts to append an integer value to the end of a string. */ +bool String_AppendNum(String* str, Int64 num); + +/* Attempts to append an integer value to the end of a string, padding left with 0. */ +bool String_AppendPaddedNum(String* str, Int64 num, Int32 minDigits); + +static Int32 String_MakeNum(Int64 num, UInt8* numBuffer); + + +/* Finds the first index of c in given string, -1 if not found. */ +int String_IndexOf(String* str, UInt8 c, Int32 offset); + +/* Gets the character at the given index in the string. */ +UInt8 String_CharAt(String* str, Int32 offset); + #endif \ No newline at end of file