diff --git a/czi/source_code/azgra_lib/CMakeLists.txt b/czi/source_code/azgra_lib/CMakeLists.txt index cec0079e319d6c6c5078af3699a6f416769159e8..4c4723d32645ff12fa47caba2fbb7902a0e85153 100644 --- a/czi/source_code/azgra_lib/CMakeLists.txt +++ b/czi/source_code/azgra_lib/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.0.0) project(azgra) +set(CMAKE_CXX_FLAGS "-Wall") + add_library(${PROJECT_NAME} STATIC src/stream/binary_converter.cpp src/stream/binary_file_stream.cpp @@ -10,8 +12,9 @@ add_library(${PROJECT_NAME} STATIC src/stream/memory_bit_stream.cpp src/utilities/Stopwatch.cpp src/utilities/z_order.cpp + src/azgra_string.cpp ) add_library(sub::azgra ALIAS ${PROJECT_NAME}) -target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) \ No newline at end of file +target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/include) diff --git a/czi/source_code/azgra_lib/include/azgra/azgra_string.h b/czi/source_code/azgra_lib/include/azgra/azgra_string.h new file mode 100644 index 0000000000000000000000000000000000000000..47c0885b3b33fa7a359bf57dd659fcb0e726761f --- /dev/null +++ b/czi/source_code/azgra_lib/include/azgra/azgra_string.h @@ -0,0 +1,324 @@ +#pragma once + +#include <stddef.h> +#include <vector> +#include <assert.h> + +namespace azgra +{ +constexpr char AsciiCaseOffset = 'a' - 'A'; +class SimpleString +{ +private: + /** + * @brief Internal string memory. + */ + char *_string = nullptr; + /** + * @brief Length of this string. + */ + size_t _length = 0; + + /** + * @brief Allocates memory for string, with size of sizeof(char) * length + */ + static char *alloc_string(const size_t &length); + /** + * @brief Reallocates memory, to bigger size, copying old content. + */ + static char *realloc_string(const size_t &length, const char* oldString, const size_t oldLen); + /** + * @brief Free string memory block. + */ + static void free_string(char *memory); + + /** + * @brief Get size of c string. + * + * @param cString String to get size of. + * @return size_t Size of cString + */ + static size_t c_string_length(const char *cString); + + /** + * @brief Internal concatenation function. + * + * @param string String to add to current string. + * @param length Length of String. + */ + void internal_concat(const char *string, const size_t length); + + /** + * @brief Initalize this string memory and fields. + * + * @param string String to initialize from. + */ + void internal_initalize(const char *string); + + /** + * @brief Construct a new Simple String with already allocated memory. + * + * @param cString Allocated string. + * @param length Length of allocated string. + * @param noAlloc Must be true. + */ + SimpleString(char *cString, const size_t length, bool noAlloc = false); +public: + /** + * @brief Construct a new Simple String object. + * + * @param cString Char array to create string from. + */ + SimpleString(const char *cString); + + /** + * @brief Get the c string object + * + * @return const char* Char array (C like string). + */ + const char *get_c_string() const; + + /** + * @brief Concatenate cString to this string. + * + * @param cString String to concatenate. + */ + void concat(const char *cString); + + /** + * @brief Get length of this string. + * + * @return size_t Length of string. + */ + size_t length() const; + + /** + * @brief Get index of first match. + * + * @param c Char to find. + * @param fromIndex Index from which search will begin. + * @return int Index of first match or -1 if not found. + */ + int index_of(const char &c, const size_t fromIndex = 0) const; + + /** + * @brief Get index of first matched character in string. + * + * @param string String to find. + * @param fromIndex Index from which search will begin. + * @return int Index of first matched character or -1 if not found. + */ + int index_of(const char *string, const size_t fromIndex = 0) const; + + /** + * @brief Get index of last match. + * + * @param c Char to find. + * @param fromIndex Index from which search will begin. + * @return int Index of last match or -1 if not found. + */ + int last_index_of(const char &c, const size_t fromIndex = 0) const; + + /** + * @brief Get index of last match. + * + * @param c Character to find. + * @param fromIndex Index from which search will begin. + * @param toIndex Index to which search will continue. + * @return int Index of last match or -1 if not found. + */ + int last_index_of(const char &c, const size_t fromIndex, const size_t toIndex) const; + + /** + * @brief Get index of last match. + * + * @param string String to find. + * @param fromIndex Index from which search will begin. + * @return int Index of last match or -1 if not found. + */ + int last_index_of(const char *string, const size_t fromIndex = 0) const; + + /** + * @brief Check if given character is in this string. + * + * @param c Character to find. + * @return true If char was found in this string. + * @return false If char wasn't found in this string. + */ + bool contains(const char &c) const; + + /** + * @brief Check if given string is in this string. + * + * @param string String to find. + * @return true If string was found in this string. + * @return false If string wasn't found in this string. + */ + bool contains(const char *string) const; + + /** + * @brief Get number of times character is contained in this string. + * + * @param c Char to find. + * @return size_t Number of occurencies. + */ + size_t count(const char &c) const; + + /** + * @brief Get number of times string is contained in this string. + * + * @param string String to find. + * @return size_t Number of occurencies. + */ + size_t count(const char *string) const; + + /** + * @brief Check if string starts with character. + * + * @param c Character to check. + * @return true String starts with required character. + * @return false String doesn't start with required character. + */ + bool starts_with(const char &c) const; + + /** + * @brief Check if string starts with string. + * + * @param c String to check. + * @return true String starts with required string. + * @return false String doesn't start with required string. + */ + bool starts_with(const char *string) const; + + /** + * @brief Check if string ends with character. + * + * @param c Character to check. + * @return true String ends with required character. + * @return false String doesn't end with required character. + */ + bool ends_with(const char &c) const; + + /** + * @brief Check if string ends with string. + * + * @param c String to check. + * @return true String ends with required string. + * @return false String doesn't end with required string. + */ + bool ends_with(const char *string) const; + + /** + * @brief Check if this string is equal to the another one. + * + * @param string String to check. + * @return true Strings are equal. + * @return false Strings aren't equal. + */ + bool equals(const SimpleString &string) const; + + /** + * @brief Check if this string is equal to the another one. + * + * @param string String to check. + * @return true Strings are equal. + * @return false Strings aren't equal. + */ + bool equals(const char *string) const; + + /** + * @brief Transform characters to upper-case. + */ + void to_upper(); + + /** + * @brief Transform characters to lower-case. + */ + void to_lower(); + + /** + * @brief Replace all old characters with new characters. + * + * @param oldChar Charater to replace. + * @param newChar Replacement charater. + */ + void replace(const char &oldChar, const char &newChar); + + /** + * @brief Replace all old substrings with new strings. + * + * @param oldChar Substring to replace. + * @param newChar Replacement string. + */ + void replace(const char *oldString, const char *newString); + + /** + * @brief Remove all occurrencies of character. + * + * @param c Character to remove. + */ + void remove(const char &c); + + /** + * @brief Remove all occurrencies of substring. + * + * @param c Substring to remove. + */ + void remove(const char *oldString); + + /** + * @brief Create substring from given index to end of the string. + * + * @param fromIndex Index from which to create substring. + * @return SimpleString Substring from given index. + */ + SimpleString substring(const size_t fromIndex) const; + + /** + * @brief Create substring from given index with length. + * + * @param fromIndex Index from which to create substring + * @param length Length of substring. + * @return SimpleString Substring from given index, with length. + */ + SimpleString substring(const size_t fromIndex, const size_t length) const; + + /** + * @brief Split string by separator to multiple strings. + * + * @param separator Separator. + * @return std::vector<SimpleString> Vector of strings. + */ + std::vector<SimpleString> split(const char &separator) const; + + /** + * @brief Conversion to c string, char array. + * + * @return const char* C like string + */ + operator const char*() const; + + /** + * @brief Character indexing. + * + * @param index Index of character in string. + * @return char& Reference to character. + */ + char &operator[](const int &index); + + void operator=(const char *cString); + bool operator==(const char *cString) const; + bool operator==(const SimpleString &string) const; + void operator+=(const char *cString); + SimpleString operator+(const char *cString) const; + + /** + * @brief Create string by replicating. + * + * @param cString String to replicate. + * @param replicationCount Number of replications. + * @return SimpleString Replicated string. + */ + static SimpleString replicate(const char* cString, const int replicationCount); +}; +} // namespace azgra \ No newline at end of file diff --git a/czi/source_code/azgra_lib/src/azgra_string.cpp b/czi/source_code/azgra_lib/src/azgra_string.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b07e37f21cef48dfd78500225a00af113be38e6d --- /dev/null +++ b/czi/source_code/azgra_lib/src/azgra_string.cpp @@ -0,0 +1,496 @@ +#include "azgra_string.h" + +namespace azgra +{ +//TODO: Add asserts. + +char *SimpleString::alloc_string(const size_t &length) +{ + char *memory = static_cast<char *>(::operator new(sizeof(char) * length)); + return memory; +} + +char *SimpleString::realloc_string(const size_t &length, const char* oldString, const size_t oldLen) +{ + char *memory = alloc_string(length); + for (size_t i = 0; i < oldLen; i++) + memory[i] = oldString[i]; + return memory; +} + +void SimpleString::free_string(char *memory) +{ + if (memory != nullptr) + { + ::operator delete(memory); + memory = nullptr; + } +} + +size_t SimpleString::c_string_length(const char *cString) +{ + size_t len = 0; + int i = 0; + + for (i = 0; cString[i] != 0; i++) + len++; + + return len; +} + +void SimpleString::internal_initalize(const char *string) +{ + size_t inputStringLen = c_string_length(string); + _length = inputStringLen; + + _string = alloc_string(_length); + + for (size_t i = 0; i < inputStringLen; i++) + _string[i] = string[i]; +} + +SimpleString::SimpleString(char *cString, const size_t length, bool noAlloc) +{ + assert(noAlloc); + _string = cString; + _length = length; +} + +SimpleString::operator const char *() const +{ + return _string; +} + +char &SimpleString::operator[](const int &index) +{ + return _string[index]; +} + +void SimpleString::operator=(const char *cString) +{ + free_string(_string); + internal_initalize(cString); +} + +void SimpleString::operator+=(const char *cString) +{ + concat(cString); +} + +SimpleString SimpleString::operator+(const char *cString) const +{ + SimpleString result(_string); + result.concat(cString); + return result; +} + +bool SimpleString::operator==(const char *cString) const +{ + return equals(cString); +} +bool SimpleString::operator==(const SimpleString &string) const +{ + return equals(string); +} + +SimpleString::SimpleString(const char *cString) +{ + internal_initalize(cString); +} + +void SimpleString::internal_concat(const char *string, const size_t length) +{ + size_t newLength = _length + length; + char *newString = realloc_string(newLength, _string, _length); + + free_string(_string); + + _string = newString; + + for (size_t i = _length; i < newLength; i++) + _string[i] = string[i - _length]; + + _length = newLength; +} + +void SimpleString::concat(const char *cString) +{ + size_t cStringLen = c_string_length(cString); + internal_concat(cString, cStringLen); +} + +const char *SimpleString::get_c_string() const +{ + return _string; +} + +size_t SimpleString::length() const +{ + return _length; +} + +int SimpleString::index_of(const char &c, const size_t fromIndex) const +{ + for (size_t i = fromIndex; i < _length; i++) + { + if (_string[i] == c) + { + return i; + } + } + return -1; +} + +int SimpleString::index_of(const char *string, const size_t fromIndex) const +{ + size_t matchLen = c_string_length(string); + if (matchLen > _length) + { + return -1; + } + + size_t searchFrom = fromIndex; + int indexOfFirstChar = index_of(string[0], searchFrom); + bool found = false; + + while (indexOfFirstChar != -1) + { + if (indexOfFirstChar + (matchLen - 1) > _length) + return -1; + + found = true; + for (size_t matchIndex = 1; matchIndex < matchLen; matchIndex++) + { + if (_string[indexOfFirstChar + matchIndex] != string[matchIndex]) + { + found = false; + break; + } + } + + if (found) + return indexOfFirstChar; + else + { + searchFrom = indexOfFirstChar + 1; + indexOfFirstChar = index_of(string[0], searchFrom); + } + } + + return -1; +} + +int SimpleString::last_index_of(const char &c, const size_t fromIndex) const +{ + return last_index_of(c, fromIndex, _length - 1); +} + +int SimpleString::last_index_of(const char &c, const size_t fromIndex, const size_t toIndex) const +{ + for (int i = (int)toIndex; i >= (int)fromIndex; i--) + { + if (_string[i] == c) + { + return i; + } + } + return -1; +} + +int SimpleString::last_index_of(const char *string, const size_t fromIndex) const +{ + size_t matchLen = c_string_length(string); + if (matchLen > _length) + { + return -1; + } + + size_t searchUpperBound = _length - 1; + int indexOfLastChar = last_index_of(string[matchLen - 1], 0, searchUpperBound); + bool found = false; + + while (indexOfLastChar != -1) + { + if (indexOfLastChar - (matchLen - 1) < fromIndex) + return -1; + + found = true; + for (size_t matchIndex = 1; matchIndex < matchLen; matchIndex++) + { + if (_string[indexOfLastChar - matchIndex] != string[matchLen - matchIndex - 1]) + { + found = false; + break; + } + } + + if (found) + return indexOfLastChar - (matchLen - 1); + else + { + searchUpperBound = indexOfLastChar - 1; + indexOfLastChar = last_index_of(string[matchLen - 1], 0, searchUpperBound); + } + } + + return -1; +} + +bool SimpleString::contains(const char &c) const +{ + return (index_of(c) != -1); +} + +bool SimpleString::contains(const char *string) const +{ + return (index_of(string) != -1); +} + +size_t SimpleString::count(const char &c) const +{ + size_t result = 0; + size_t fromIndex = 0; + + int matchIndex = index_of(c, fromIndex); + + while (matchIndex != -1) + { + ++result; + fromIndex = matchIndex + 1; + matchIndex = index_of(c, fromIndex); + } + return result; +} + +size_t SimpleString::count(const char *string) const +{ + size_t result = 0; + size_t fromIndex = 0; + size_t matchLen = c_string_length(string); + + int matchIndex = index_of(string, fromIndex); + while (matchIndex != -1) + { + ++result; + fromIndex = matchIndex + matchLen; + matchIndex = index_of(string, fromIndex); + } + return result; +} + +bool SimpleString::starts_with(const char &c) const +{ + return (index_of(c) == 0); +} + +bool SimpleString::starts_with(const char *string) const +{ + return (index_of(string) == 0); +} + +bool SimpleString::ends_with(const char &c) const +{ + return (last_index_of(c) == (long)(_length - 1)); +} + +bool SimpleString::ends_with(const char *string) const +{ + return (last_index_of(string) == (long)(_length - c_string_length(string))); +} + +bool SimpleString::equals(const SimpleString &string) const +{ + return equals(string._string); +} + +bool SimpleString::equals(const char *string) const +{ + if (_length != c_string_length(string)) + return false; + + for (size_t i = 0; i < _length; i++) + { + if (_string[i] != string[i]) + return false; + } + return true; +} + +void SimpleString::to_upper() +{ + for (size_t i = 0; i < _length; i++) + { + char c = _string[i]; + if (c >= 'a' && c <= 'z') + _string[i] -= AsciiCaseOffset; + } +} + +void SimpleString::to_lower() +{ + for (size_t i = 0; i < _length; i++) + { + char c = _string[i]; + if (c >= 'A' && c <= 'Z') + _string[i] += AsciiCaseOffset; + } +} + +void SimpleString::replace(const char &oldChar, const char &newChar) +{ + for (size_t i = 0; i < _length; i++) + { + if (_string[i] == oldChar) + _string[i] = newChar; + } +} + +// void SimpleString::replace(const SimpleString &oldString, const SimpleString &newString) +// { +// replace(oldString._string, newString._string); +// } + +void SimpleString::replace(const char *oldString, const char *newString) +{ + size_t matchLen = c_string_length(oldString); + size_t matchCount = count(oldString); + if (matchCount == 0 || matchLen == 0) + return; + + size_t replaceStringLen = c_string_length(newString); + size_t newLength = _length - (matchCount * matchLen) + (matchCount * replaceStringLen); + char *newStringMemory = alloc_string(newLength); + + size_t searchFrom = 0; + size_t newStringIndex = 0; + int index = index_of(oldString, searchFrom); + + while (index != -1) + { + // Copy all in front of match. + for (int i = searchFrom; i < index; i++) + newStringMemory[newStringIndex++] = _string[i]; + + // Copy replace string into new string. + for (size_t i = 0; i < replaceStringLen; i++) + { + newStringMemory[newStringIndex++] = newString[i]; + } + + searchFrom = index + matchLen; + index = index_of(oldString, searchFrom); + } + + // Copy remaining old content. + for (size_t i = searchFrom; i < _length; i++) + newStringMemory[newStringIndex++] = _string[i]; + + free_string(_string); + _string = newStringMemory; + _length = newLength; +} + +void SimpleString::remove(const char &c) +{ + size_t removeCount = count(c); + if (removeCount == 0) + return; + + size_t newLength = _length - removeCount; + char *newString = alloc_string(newLength); + size_t index = 0; + for (size_t i = 0; i < _length; i++) + { + if (_string[i] != c) + { + newString[index++] = _string[i]; + } + } + + free_string(_string); + _length = newLength; + _string = newString; +} + +void SimpleString::remove(const char *string) +{ + size_t matchLen = c_string_length(string); + if (matchLen == 0) + return; + + size_t matchCount = count(string); + size_t newLen = _length - (matchCount * matchLen); + + char *newString = alloc_string(newLen); + + size_t searchFrom = 0; + size_t newStringIndex = 0; + int index = index_of(string, searchFrom); + + while (index != -1) + { + // Copy all in front of match. + for (int i = searchFrom; i < index; i++) + newString[newStringIndex++] = _string[i]; + + searchFrom = index + matchLen; + index = index_of(string, searchFrom); + } + + // Copy remaining old content. + for (size_t i = searchFrom; i < _length; i++) + newString[newStringIndex++] = _string[i]; + + free_string(_string); + _string = newString; + _length = newLen; +} +SimpleString SimpleString::substring(const size_t fromIndex) const +{ + size_t len = _length - fromIndex; + + char *subsMemory = alloc_string(len); + SimpleString result(subsMemory); + for (size_t i = fromIndex; i < _length; i++) + { + result[i - fromIndex] = _string[i]; + } + return result; +} + +SimpleString SimpleString::substring(const size_t fromIndex, const size_t length) const +{ + char *subsMemory = alloc_string(length); + SimpleString result(subsMemory); + + for (size_t i = fromIndex; i < fromIndex + length; i++) + { + result[i - fromIndex] = _string[i]; + } + + return result; +} + +SimpleString SimpleString::replicate(const char* cString, const int replicationCount) +{ + size_t replLen = c_string_length(cString); + size_t resultLen = replLen * replicationCount; + char* resultMemory = alloc_string(resultLen); + + SimpleString result(resultMemory, resultLen, true); + + for(int repl = 0; repl < replicationCount; repl++) + { + for(size_t charIndex = 0; charIndex < replLen; charIndex++) + { + result[(repl*replLen) + charIndex] = cString[charIndex]; + } + } + return result; +} + +/* +std::vector<SimpleString> SimpleString::split(const char &separator) const; +static SimpleString SimpleString::empty(); +*/ +} // namespace azgra