diff --git a/include/tlibc/collections/Array.h b/include/tlibc/collections/Array.h index 70b529e..33857ca 100755 --- a/include/tlibc/collections/Array.h +++ b/include/tlibc/collections/Array.h @@ -27,9 +27,10 @@ static inline void Array_realloc_size(Array_* ar, u32 new_size){ ar->size = new_size; } -static inline Array_ Array_copy(Array_ src){ +static inline Array_ Array_copy(const Array_ src){ Array_ copy = Array_alloc_size(src.size); - memcpy(copy.data, src.data, src.size); + if(copy.data != NULL) + memcpy(copy.data, src.data, src.size); return copy; } @@ -39,11 +40,11 @@ static inline Array_ Array_copy(Array_ src){ #define struct_castTo_Array(STRUCT_PTR) Array_construct_size((STRUCT_PTR), sizeof(*STRUCT_PTR)) ///@return a[0..i-1] -static inline Array(u8) Array_sliceTo(Array(u8) a, u32 i){ +static inline Array(u8) Array_sliceTo(const Array(u8) a, u32 i){ return Array_construct_size(a.data, i); } ///@return a[i...] -static inline Array(u8) Array_sliceFrom(Array(u8) a, u32 i){ +static inline Array(u8) Array_sliceFrom(const Array(u8) a, u32 i){ return Array_construct_size((u8*)a.data + i, a.size - i); } diff --git a/include/tlibc/collections/List.h b/include/tlibc/collections/List.h index 2095920..fc4370d 100755 --- a/include/tlibc/collections/List.h +++ b/include/tlibc/collections/List.h @@ -19,7 +19,9 @@ static inline List_ List_construct_size(void* data_ptr, u32 occupied_size, u32 a #define List_alloc(T, INITIAL_COUNT) List_alloc_size((INITIAL_COUNT) * sizeof(T)) List_ List_alloc_size(u32 initial_size); -void* List_expand_size(List_* ptr, u32 expansion_size); +List_ List_copy(List_ src); + +void* List_expand_size(List_* ptr, u32 size_to_add); #define List_push(L, T, VALUE) *(T*)(List_expand_size(L, sizeof(T))) = VALUE #define List_pushMany(L, T, VALUES_PTR, COUNT) List_push_size(L, VALUES_PTR, (COUNT) * sizeof(T)) void List_push_size(List_* ptr, void* values, u32 size); diff --git a/include/tlibc/string/StringBuilder.h b/include/tlibc/string/StringBuilder.h index 799dc78..8e46689 100755 --- a/include/tlibc/string/StringBuilder.h +++ b/include/tlibc/string/StringBuilder.h @@ -13,6 +13,14 @@ static inline StringBuilder StringBuilder_alloc(u32 initial_size) { } void StringBuilder_destroy(StringBuilder* b); +static inline StringBuilder StringBuilder_copy(const StringBuilder* b){ + return (StringBuilder) { .buffer = List_copy(b->buffer) }; +} +static inline void StringBuilder_expand(StringBuilder* b, u32 size_to_add){ + List_expand_size(&b->buffer, size_to_add); +} + + /// @param count set to -1 to clear StringBuilder void StringBuilder_removeFromEnd(StringBuilder* b, u32 count); void StringBuilder_append_char(StringBuilder* b, char c); @@ -25,3 +33,5 @@ void StringBuilder_append_memory(StringBuilder* b, Array(u8) mem, bool uppercase // adds '\0' to the buffer and returns pointer to buffer content str StringBuilder_getStr(StringBuilder* b); + +bool StringBuilder_equals(const StringBuilder* a, const StringBuilder* b); diff --git a/include/tlibc/string/str.h b/include/tlibc/string/str.h index 43903ee..88d9741 100755 --- a/include/tlibc/string/str.h +++ b/include/tlibc/string/str.h @@ -20,6 +20,10 @@ static inline str str_from_cstr(cstr s_ptr){ return str_construct((void*)s_ptr, strlen(s_ptr), true); } +static inline void str_destroy(str s){ + free(s.data); +} + static inline Array_ str_castTo_Array(str s) { return Array_construct_size(s.data, s.size); } @@ -31,29 +35,29 @@ static inline str Array_castTo_str(Array_ a, bool isZeroTerminated) { static const str str_null = str_construct(NULL, 0, 0); /// copies src content to new string and adds \0 at the end -str str_copy(str src); +str str_copy(const str self); /// compares two strings, NullPtr-friendly -bool str_equals(str str0, str str1); +bool str_equals(const str self, const str other); /// allocates new string which is reversed variant of str str_reverse(str s); -i32 str_seek(str src, str fragment, u32 startIndex); -i32 str_seekReverse(str src, str fragment, u32 startIndex); +i32 str_seek(const str src, const str fragment, u32 startIndex); +i32 str_seekReverse(const str src, const str fragment, u32 startIndex); -i32 str_seekChar(str src, char c, u32 startIndex); -i32 str_seekCharReverse(str src, char c, u32 startIndex); +i32 str_seekChar(const str src, char c, u32 startIndex); +i32 str_seekCharReverse(const str src, char c, u32 startIndex); -bool str_startsWith(str src, str fragment); -bool str_endsWith(str src, str fragment); +bool str_startsWith(const str src, const str fragment); +bool str_endsWith(const str src, const str fragment); /// @brief calculates string hash using sdbm32 algorythm (something like lightweight crc32) /// @return non-cryptografic hash of the string -u32 str_hash32(str s); +u32 str_hash32(const str s); -str str_toUpper(str src); -str str_toLower(str src); +str str_toUpper(const str src); +str str_toLower(const str src); str hex_to_str(Array(u8) buf, bool uppercase); diff --git a/src/collections/List.c b/src/collections/List.c index 18dffaa..c04f242 100755 --- a/src/collections/List.c +++ b/src/collections/List.c @@ -7,12 +7,19 @@ List_ List_alloc_size(u32 initial_size){ return List_construct_size(malloc(allocated_size), 0, allocated_size); } -void* List_expand_size(List_* ptr, u32 expansion_size){ +List_ List_copy(const List_ src){ + List_ copy = List_alloc_size(src.allocated_size); + if(copy.data != NULL) + memcpy(copy.data, src.data, src.size); + return copy; +} + +void* List_expand_size(List_* ptr, u32 size_to_add){ u32 occupied_size = ptr->size; u32 expanded_alloc_size = ptr->allocated_size; if(expanded_alloc_size == 0) expanded_alloc_size = 64; - ptr->size += expansion_size; + ptr->size += size_to_add; while(ptr->size > expanded_alloc_size){ expanded_alloc_size *= 2; } diff --git a/src/string/StringBuilder.c b/src/string/StringBuilder.c index 79ffed9..5de448e 100755 --- a/src/string/StringBuilder.c +++ b/src/string/StringBuilder.c @@ -5,16 +5,24 @@ void StringBuilder_destroy(StringBuilder* b){ return; free(b->buffer.data); - b->buffer = List_construct_size(NULL, 0, 0); } str StringBuilder_getStr(StringBuilder* b){ - if(b->buffer.size == 0 || ((char*)b->buffer.data)[b->buffer.size - 1] != '\0') + if(b->buffer.size == 0 || ((char*)b->buffer.data)[b->buffer.size - 1] != '\0'){ List_push(&b->buffer, u8, '\0'); - str result = str_construct((char*)b->buffer.data, b->buffer.size - 1, true); + // '\0' at the end doesn't increase buffer.size + b->buffer.size -= 1; + } + str result = str_construct((char*)b->buffer.data, b->buffer.size, true); return result; } +bool StringBuilder_equals(const StringBuilder* a, const StringBuilder* b){ + str a_str = str_construct((char*)a->buffer.data, a->buffer.size, false); + str b_str = str_construct((char*)b->buffer.data, b->buffer.size, false); + return str_equals(a_str, b_str); +} + void StringBuilder_removeFromEnd(StringBuilder* b, u32 count){ if(count < b->buffer.size){ b->buffer.size -= count; diff --git a/src/string/str.c b/src/string/str.c index 26b58c9..b0bee62 100755 --- a/src/string/str.c +++ b/src/string/str.c @@ -1,19 +1,21 @@ #include "tlibc/string/str.h" #include "tlibc/string/StringBuilder.h" -str str_copy(str src){ - if(src.data == NULL || src.size == 0) - return src; +str str_copy(const str self){ + if(self.data == NULL || self.size == 0) + return self; - str nstr = str_construct((char*)malloc(src.size + 1), src.size, true); - memcpy(nstr.data, src.data, src.size); - nstr.data[nstr.size] = '\0'; - return nstr; + str copy = str_construct((char*)malloc(self.size + 1), self.size, true); + memcpy(copy.data, self.data, self.size); + copy.data[copy.size] = '\0'; + return copy; } -bool str_equals(str s0, str s1){ - if(s0.size != s1.size) +bool str_equals(const str self, const str other){ + if(self.size != other.size) return false; + if(self.data == other.data) + return true; /* BENCHMARK: str_equals64: 2.967s @@ -21,7 +23,7 @@ bool str_equals(str s0, str s1){ strncmp: 1.611s memcmp: 0.710s */ - return memcmp(s0.data, s1.data, s0.size) == 0; + return memcmp(self.data, other.data, self.size) == 0; } str str_reverse(str s){ @@ -34,7 +36,7 @@ str str_reverse(str s){ return r; } -i32 str_seek(str src, str fragment, u32 startIndex){ +i32 str_seek(const str src, const str fragment, u32 startIndex){ if(src.size == 0 || fragment.size == 0) return -1; @@ -49,7 +51,7 @@ i32 str_seek(str src, str fragment, u32 startIndex){ return -1; } -i32 str_seekReverse(str src, str fragment, u32 startIndex){ +i32 str_seekReverse(const str src, const str fragment, u32 startIndex){ if(src.size == 0 || fragment.size == 0) return -1; @@ -66,7 +68,7 @@ i32 str_seekReverse(str src, str fragment, u32 startIndex){ return -1; } -i32 str_seekChar(str src, char c, u32 startIndex){ +i32 str_seekChar(const str src, char c, u32 startIndex){ for(u32 i = startIndex; i < src.size; i++){ if(src.data[i] == c) return i; @@ -74,7 +76,7 @@ i32 str_seekChar(str src, char c, u32 startIndex){ return -1; } -i32 str_seekCharReverse(str src, char c, u32 startIndex){ +i32 str_seekCharReverse(const str src, char c, u32 startIndex){ if(startIndex > src.size - 1) startIndex = src.size - 1; for(u32 i = startIndex; i != (u32)-1; i--){ @@ -84,24 +86,27 @@ i32 str_seekCharReverse(str src, char c, u32 startIndex){ return -1; } -bool str_startsWith(str src, str fragment){ +bool str_startsWith(const str src, const str fragment){ if(src.size < fragment.size) return false; - src.size = fragment.size; - return str_equals(src, fragment); + str src_fragment = str_null; + src_fragment.data = src.data; + src_fragment.size = fragment.size; + return str_equals(src_fragment, fragment); } -bool str_endsWith(str src, str fragment){ +bool str_endsWith(const str src, const str fragment){ if(src.size < fragment.size) return false; - src.data = (char*)(src.data + src.size - fragment.size); - src.size = fragment.size; - return str_equals(src, fragment); + str src_fragment = str_null; + src_fragment.data = (char*)(src.data + src.size - fragment.size); + src_fragment.size = fragment.size; + return str_equals(src_fragment, fragment); } -u32 str_hash32(str s){ +u32 str_hash32(const str s){ u8* ubuf = (u8*)s.data; u32 hash=0; for (u32 i = 0; i < s.size; i++) @@ -109,7 +114,7 @@ u32 str_hash32(str s){ return hash; } -str str_toUpper(str src){ +str str_toUpper(const str src){ str r = str_copy(src); for (u32 i = 0; i < r.size; i++){ if(isAlphabeticalLower(r.data[i])) @@ -118,7 +123,7 @@ str str_toUpper(str src){ return r; } -str str_toLower(str src){ +str str_toLower(const str src){ str r = str_copy(src); for (u32 i = 0; i < r.size; i++){ if(isAlphabeticalUpper(r.data[i]))