diff --git a/Jupiter/Jupiter.vcxproj b/Jupiter/Jupiter.vcxproj index adacc60..b81cc9d 100644 --- a/Jupiter/Jupiter.vcxproj +++ b/Jupiter/Jupiter.vcxproj @@ -132,6 +132,8 @@ + + diff --git a/Jupiter/Jupiter.vcxproj.filters b/Jupiter/Jupiter.vcxproj.filters index 2ca4bfb..fe61b68 100644 --- a/Jupiter/Jupiter.vcxproj.filters +++ b/Jupiter/Jupiter.vcxproj.filters @@ -203,6 +203,12 @@ Header Files\Strings + + Header Files\Strings + + + Header Files\Strings + diff --git a/Jupiter/Readable_String.h b/Jupiter/Readable_String.h new file mode 100644 index 0000000..83c7485 --- /dev/null +++ b/Jupiter/Readable_String.h @@ -0,0 +1,181 @@ +/** + * Copyright (C) 2014 Justin James. + * + * This license must be preserved. + * Any applications, libraries, or code which make any use of any + * component of this program must not be commercial, unless explicit + * permission is granted from the original author. The use of this + * program for non-profit purposes is permitted. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In the event that this license restricts you from making desired use of this program, contact the original author. + * Written by Justin James + */ + +#if !defined _READABLE_STRING_H_HEADER +#define _READABLE_STRING_H_HEADER + +/** + * @file Readable_String.h + * @brief Defines several basic accessive and comparative virtual functions for strings. + */ + +#include // wchar_t +#include // FILE +#include // std::basic_string type + +namespace Jupiter +{ + + /** + * @brief Provides the basis for String classes by providing implementations for operators, comparative operations, and defining abstract functions. + * Note: This is an abstract type. + * + * @param T Element type which the String will store. Defaults to char. + */ + template class Readable_String + { + public: + + /** + * @brief Fetches an element from the string. + * + * @param index Index of the element to return. + * @return The element located at the specified index. + */ + virtual T &get(size_t index) const = 0; + + /** + * @brief Returns the number of elements in the String. + * + * @return Number of elements in the string. + */ + virtual size_t size() const = 0; + + /** + * @brief Returns a pointer to the underlying string of elements. + * + * @return Pointer to the underlying string of elements. + */ + virtual const T *ptr() const = 0; + + /** + * @brief Checks if the string contains an element with the specified value. + * + * @param value Value of the element to search for. + * @return True if a match is found, false otherwise. + */ + bool contains(const T &value) const; + + /** + * @brief Compares another string against the String. + * + * @param in String to compare against. + * @return 0 if the strings are equal, negative if the first mismatched character is greater in the String, or positive if it's less. + */ + int compare(const Readable_String &in) const; + int compare(const std::basic_string &in) const; + int compare(const T *in) const; + int compare(const T &in) const; + int compare(const std::nullptr_t) const; + + /** + * @brief Checks if the strings are equal. + * Note: Case sensitive. + * + * @param in String to compare against. + * @return True if the contents of the strings are equal, false otherwise. + */ + bool equals(const Readable_String &in) const; + bool equals(const std::basic_string &in) const; + bool equals(const T *in) const; + bool equals(const T &in) const; + bool equals(const std::nullptr_t) const; + + /** + * @brief Checks if the strings are equal. + * Note: Case insensitive. Returns false for any type other than char and wchar_t. + * + * @param in String to compare against. + * @return True if the contents of the strings are equal, false otherwise. + */ + bool equalsi(const Readable_String &in) const; + bool equalsi(const std::basic_string &in) const; + bool equalsi(const T *in) const; + bool equalsi(const T &in) const; + bool equalsi(const std::nullptr_t) const; + + /** + * @brief Checks if the String matches a wildcard format. + * Note: Case sensitive. + * + * @param format Format that the string is compared against. + * @return True if the String matches the wildcard format, false otherwise. + */ + bool match(const Readable_String &format) const; + bool match(const std::basic_string &format) const; + bool match(const T *format) const; + + /** + * @brief Checks if the CString matches a wildcard format. + * Note: Case insensitive. Returns false for any type other than char and wchar_t. + * + * @param format Format that the string is compared against. + * @return True if the CString matches the wildcard format, false otherwise. + */ + bool matchi(const Readable_String &format) const; + bool matchi(const std::basic_string &format) const; + bool matchi(const T *format) const; + + /** + * @brief Counts the number of token deliminated words. + * + * @param whitespace A string of tokens used to deliminate words. + * @return Number of words found. + */ + unsigned int wordCount(const T *whitespace) const; + + /** + * @brief Interprets the string as an integer. + * Note: This returns 0 on any value string type other than char. + * + * @param base Base of the string representation. + * @return Integer representation of the string. + */ + int asInt(int base = 0) const; + + /** + * @brief Interprets the string as an integer. + * Note: This returns 0 on any value string type other than char. + * + * @param base Base of the string representation. + * @return Integer representation of the string. + */ + unsigned int asUnsignedInt(int base = 0) const; + + /** + * @brief Outputs the string to a FILE stream. + * + * @param out Stream to output to. + * @return Number of elements written successfully. + */ + size_t print(FILE *out) const; + size_t print(std::basic_ostream &out) const; + + /** + * @brief Outputs the string and a newline to a FILE stream + * + * @param out Stream to output to. + * @param Number of elements written successfully. + */ + size_t println(FILE *out) const; + size_t println(std::basic_ostream &out) const; + }; +} + +#include "Readable_String_Imp.h" + +#endif // _READABLE_STRING_H_HEADER \ No newline at end of file diff --git a/Jupiter/Readable_String_Imp.h b/Jupiter/Readable_String_Imp.h new file mode 100644 index 0000000..e624e1a --- /dev/null +++ b/Jupiter/Readable_String_Imp.h @@ -0,0 +1,746 @@ +/** + * Copyright (C) 2014 Justin James. + * + * This license must be preserved. + * Any applications, libraries, or code which make any use of any + * component of this program must not be commercial, unless explicit + * permission is granted from the original author. The use of this + * program for non-profit purposes is permitted. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * In the event that this license restricts you from making desired use of this program, contact the original author. + * Written by Justin James + */ + +#if !defined _READABLE_STRING_IMP_H_HEADER +#define _READABLE_STRING_IMP_H_HEADER + +/** + * @file Readable_String_Imp.h + * @brief Provides the implementations for Readable_String functions. + * Note: Modification of this file is not supported in any way. + */ + +#include "Readable_String.h" +#include "Functions.h" + +/** +* IMPLEMENTATION: +* Readable_String +*/ + +// contains + +template bool Jupiter::Readable_String::contains(const T &value) const +{ + for (size_t i = 0; i != this->size(); i++) if (this->get(i) == value) return true; + return false; +} + +// compare() + +template int Jupiter::Readable_String::compare(const Jupiter::Readable_String &in) const +{ + // rewrite to compare multiple bytes at a time. + size_t index = 0; + while (this->get(index) == in.get(index)) + { + index++; + if (index == in.size()) + { + if (index == this->size()) return 0; + return 1; + } + if (index == this->size()) return 0 - in.get(index); + } + return this->get(index) - in.get(index); +} + +template int Jupiter::Readable_String::compare(const std::basic_string &in) const +{ + // rewrite to compare multiple bytes at a time. + size_t index = 0; + while (this->get(index) == in.at(index)) + { + index++; + if (index == in.size()) + { + if (index == this->size()) return 0; + return 1; + } + if (index == this->size()) return 0 - in.at(index); + } + return this->get(index) - in.at(index); +} + +template int Jupiter::Readable_String::compare(const T *s2) const +{ + if (this->size() == 0) return 0 - *s2; + size_t index = 0; + while (this->get(index) == *s2) + { + index++; + if (*s2 == 0) + { + if (index == this->size()) return 0; + return 1; + } + s2++; + if (index == this->size()) return 0 - *s2; + } + return this->get(index) - *s2; +} + +template int Jupiter::Readable_String::compare(const T &in) const +{ + if (this->size() == 0) return 0 - in; + return this->get(0) - in; +} + +template int Jupiter::Readable_String::compare(const std::nullptr_t) const +{ + if (this->size() == 0) return true; + return this->get(0); +} + +// equals() + +template bool Jupiter::Readable_String::equals(const Jupiter::Readable_String &in) const +{ + if (this->size() != in.size()) return false; + + // rewrite to compare multiple bytes at a time. + size_t index = 0; + while (index != this->size()) + { + if (this->get(index) != in.get(index)) return false; + index++; + } + return true; +} + +template bool Jupiter::Readable_String::equals(const std::basic_string &in) const +{ + if (this->size() != in.size()) return false; + // rewrite to compare multiple bytes at a time. + size_t index = 0; + while (index != this->size()) + { + if (this->get(index) != in.at(index)) return false; + index++; + } + return true; +} + +template bool Jupiter::Readable_String::equals(const T *in) const +{ + if (in == nullptr) return this->size() == 0; + for (size_t index = 0; index != this->size(); index++) + { + if (*in == 0 || this->get(index) != *in) return false; + in++; + } + return *in == 0; +} + +template bool Jupiter::Readable_String::equals(const T &in) const +{ + return this->size() == 1 && this->get(0) == in; +} + +template bool Jupiter::Readable_String::equals(std::nullptr_t) const +{ + return this->size() == 0; +} + +// equalsi() + +template<> bool inline Jupiter::Readable_String::equalsi(const Jupiter::Readable_String &in) const +{ + if (this->size() != in.size()) return false; + for (size_t index = 0; index != this->size(); index++) + { + if (toupper(this->get(index)) != toupper(in.get(index))) return false; + } + return true; +} + +template<> bool inline Jupiter::Readable_String::equalsi(const Jupiter::Readable_String &in) const +{ + if (this->size() != in.size()) return false; + for (size_t index = 0; index != this->size(); index++) + { + if (towupper(this->get(index)) != towupper(in.get(index))) return false; + } + return true; +} + +template bool Jupiter::Readable_String::equalsi(const Jupiter::Readable_String &in) const +{ + return this->equals(in); // Concept of "case" not supported for type. +} + +template<> bool inline Jupiter::Readable_String::equalsi(const std::basic_string &in) const +{ + if (this->size() != in.size()) return false; + for (size_t index = 0; index != this->size(); index++) + { + if (toupper(this->get(index)) != toupper(in.at(index))) return false; + } + return true; +} + +template<> bool inline Jupiter::Readable_String::equalsi(const std::basic_string &in) const +{ + if (this->size() != in.size()) return false; + for (size_t index = 0; index != this->size(); index++) + { + if (towupper(this->get(index)) != towupper(in.at(index))) return false; + } + return true; +} + +template bool Jupiter::Readable_String::equalsi(const std::basic_string &in) const +{ + return this->equals(in); // Concept of "case" not supported for type. +} + +template<> bool inline Jupiter::Readable_String::equalsi(const char *in) const +{ + if (in == nullptr) return this->size() == 0; + for (size_t index = 0; index != this->size(); index++) + { + if (*in == 0 || toupper(this->get(index)) != toupper(*in)) return false; + in++; + } + return *in == 0; +} + +template<> bool inline Jupiter::Readable_String::equalsi(const wchar_t *in) const +{ + if (in == nullptr) return this->size() == 0; + for (size_t index = 0; index != this->size(); index++) + { + if (*in == 0 || towupper(this->get(index)) != towupper(*in)) return false; + in++; + } + return *in == 0; +} + +template bool Jupiter::Readable_String::equalsi(const T *in) const +{ + return this->equals(in); // Concept of "case" not supported for type. +} + +template<> bool inline Jupiter::Readable_String::equalsi(const char &in) const +{ + return this->size() == 1 && toupper(this->get(0)) == toupper(in); +} + +template<> bool inline Jupiter::Readable_String::equalsi(const wchar_t &in) const +{ + return this->size() == 1 && towupper(this->get(0)) == towupper(in); +} + +template bool Jupiter::Readable_String::equalsi(const T &in) const +{ + return this->equals(in); // Concept of "case" not supported for type. +} + +template bool Jupiter::Readable_String::equalsi(const std::nullptr_t) const +{ + return this->size() == 0; +} + +// match() + +template<> bool inline Jupiter::Readable_String::match(const Jupiter::Readable_String &format) const +{ + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.get(formatIndex) == '*') + { + formatIndex++; + while (format.get(formatIndex) == '?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.get(formatIndex) == 0) return true; + if (format.get(formatIndex) == '*') continue; + while (format.get(formatIndex) != this->get(index)) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.get(formatIndex) != '?' && format.get(formatIndex) != this->get(index)) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template<> bool inline Jupiter::Readable_String::match(const Jupiter::Readable_String &format) const +{ + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.get(formatIndex) == '*') + { + formatIndex++; + while (format.get(formatIndex) == '?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.get(formatIndex) == 0) return true; + if (format.get(formatIndex) == '*') continue; + while (format.get(formatIndex) != this->get(index)) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.get(formatIndex) != '?' && format.get(formatIndex) != this->get(index)) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template bool Jupiter::Readable_String::match(const Jupiter::Readable_String &format) const +{ + return false; // Wildcard matching not supported for type. +} + +template<> bool inline Jupiter::Readable_String::match(const std::basic_string &format) const +{ + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.at(formatIndex) == '*') + { + formatIndex++; + while (format.at(formatIndex) == '?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.at(formatIndex) == 0) return true; + if (format.at(formatIndex) == '*') continue; + while (format.at(formatIndex) != this->get(index)) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.at(formatIndex) != '?' && format.at(formatIndex) != this->get(index)) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template<> bool inline Jupiter::Readable_String::match(const std::basic_string &format) const +{ + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.at(formatIndex) == '*') + { + formatIndex++; + while (format.at(formatIndex) == '?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.at(formatIndex) == 0) return true; + if (format.at(formatIndex) == '*') continue; + while (format.at(formatIndex) != this->get(index)) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.at(formatIndex) != '?' && format.at(formatIndex) != this->get(index)) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template bool Jupiter::Readable_String::match(const std::basic_string &format) const +{ + return false; // Wildcard matching not supported for type. +} + +template<> inline bool Jupiter::Readable_String::match(const char *format) const +{ + size_t index = 0; + while (*format != 0) + { + if (*format == '*') + { + format++; + while (*format == '?') + { + if (this->get(index) == 0) return false; + format++; + index++; + } + if (*format == 0) return true; + if (*format == '*') continue; + while (*format != this->get(index)) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (*format != '?' && *format != this->get(index)) return false; + format++; + index++; + } + return index == this->size(); +} + +template<> inline bool Jupiter::Readable_String::match(const wchar_t *format) const +{ + size_t index = 0; + while (*format != 0) + { + if (*format == L'*') + { + format++; + while (*format == L'?') + { + if (this->get(index) == 0) return false; + format++; + index++; + } + if (*format == 0) return true; + if (*format == L'*') continue; + while (*format != this->get(index)) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (*format != L'?' && *format != this->get(index)) return false; + format++; + index++; + } + return index == this->size(); +} + +template bool Jupiter::Readable_String::match(const T *format) const +{ + return false; // Wildcard matching not supported for type. +} + +// matchi() + +template<> bool inline Jupiter::Readable_String::matchi(const Jupiter::Readable_String &format) const +{ + int fUpper; + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.get(formatIndex) == L'*') + { + formatIndex++; + while (format.get(formatIndex) == L'?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.get(formatIndex) == 0) return true; + if (format.get(formatIndex) == '*') continue; + fUpper = toupper(format.get(formatIndex)); + while (fUpper != toupper(this->get(index))) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.get(formatIndex) != L'?' && toupper(format.get(formatIndex)) != toupper(this->get(index))) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template<> bool inline Jupiter::Readable_String::matchi(const Jupiter::Readable_String &format) const +{ + wint_t fUpper; + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.get(formatIndex) == L'*') + { + formatIndex++; + while (format.get(formatIndex) == L'?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.get(formatIndex) == 0) return true; + if (format.get(formatIndex) == '*') continue; + fUpper = towupper(format.get(formatIndex)); + while (fUpper != towupper(this->get(index))) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.get(formatIndex) != L'?' && towupper(format.get(formatIndex)) != towupper(this->get(index))) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template bool Jupiter::Readable_String::matchi(const Jupiter::Readable_String &format) const +{ + return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. +} + +template<> bool inline Jupiter::Readable_String::matchi(const std::basic_string &format) const +{ + int fUpper; + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.at(formatIndex) == L'*') + { + formatIndex++; + while (format.at(formatIndex) == L'?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.at(formatIndex) == 0) return true; + if (format.at(formatIndex) == '*') continue; + fUpper = toupper(format.at(formatIndex)); + while (fUpper != toupper(this->get(index))) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.at(formatIndex) != L'?' && toupper(format.at(formatIndex)) != toupper(this->get(index))) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template<> bool inline Jupiter::Readable_String::matchi(const std::basic_string &format) const +{ + wint_t fUpper; + size_t index = 0; + size_t formatIndex = 0; + while (formatIndex != format.size()) + { + if (format.at(formatIndex) == L'*') + { + formatIndex++; + while (format.at(formatIndex) == L'?') + { + if (this->get(index) == 0) return false; + formatIndex++; + index++; + } + if (format.at(formatIndex) == 0) return true; + if (format.at(formatIndex) == '*') continue; + fUpper = towupper(format.at(formatIndex)); + while (fUpper != towupper(this->get(index))) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (format.at(formatIndex) != L'?' && towupper(format.at(formatIndex)) != towupper(this->get(index))) return false; + formatIndex++; + index++; + } + return index == this->size(); +} + +template bool Jupiter::Readable_String::matchi(const std::basic_string &format) const +{ + return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. +} + +template<> bool inline Jupiter::Readable_String::matchi(const char *format) const +{ + int fUpper; + size_t index = 0; + while (*format != 0) + { + if (*format == '*') + { + format++; + while (*format == '?') + { + if (this->get(index) == 0) return false; + format++; + index++; + } + if (*format == 0) return true; + if (*format == '*') continue; + fUpper = toupper(*format); + while (fUpper != toupper(this->get(index))) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (*format != '?' && toupper(*format) != toupper(this->get(index))) return false; + format++; + index++; + } + return index == this->size(); +} + +template<> bool inline Jupiter::Readable_String::matchi(const wchar_t *format) const +{ + wint_t fUpper; + size_t index = 0; + while (*format != 0) + { + if (*format == L'*') + { + format++; + while (*format == L'?') + { + if (this->get(index) == 0) return false; + format++; + index++; + } + if (*format == 0) return true; + if (*format == '*') continue; + fUpper = towupper(*format); + while (fUpper != towupper(this->get(index))) + { + if (this->get(index) == 0) return false; + index++; + } + } + else if (*format != L'?' && towupper(*format) != towupper(this->get(index))) return false; + format++; + index++; + } + return index == this->size(); +} + +template bool Jupiter::Readable_String::matchi(const T *format) const +{ + return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. +} + +// wordCount() + +template unsigned int Jupiter::Readable_String::wordCount(const T *whitespace) const +{ + unsigned int result = 0; + const T *p = this->ptr(); + bool prev = true; + while (*p != 0) + { + if (Jupiter::strpbrk(whitespace, *p) == nullptr) // This isn't whitespace! + { + if (prev == true) // We just left whitespace! + { + prev = false; + result++; + } + } + else prev = true; // This is whitespace! + p++; + } + return result; +} + +// as + +template<> unsigned int inline Jupiter::Readable_String::asUnsignedInt(int base) const +{ + return strtoui_s(this->ptr(), this->size(), base); +} + +template unsigned int Jupiter::Readable_String::asUnsignedInt(int base) const +{ + return 0; +} + +template<> int inline Jupiter::Readable_String::asInt(int base) const +{ + return strtoi_s(this->ptr(), this->size(), base); +} + +template int Jupiter::Readable_String::asInt(int base) const +{ + return 0; +} + +// Stream output + +template size_t Jupiter::Readable_String::print(FILE *out) const +{ + return fwrite(this->ptr(), sizeof(T), this->size(), out); +} + +template<> size_t inline Jupiter::Readable_String::print(FILE *out) const +{ + size_t index = 0; + while (index != this->size() && fputwc(this->get(index), out) != WEOF) index++; + return index; +} + +template size_t Jupiter::Readable_String::print(std::basic_ostream &out) const +{ + size_t index = 0; + while (index != this->size()) + { + out << this->get(index); + index++; + } + return index; +} + +template size_t Jupiter::Readable_String::println(FILE *out) const +{ + size_t r = this->print(out); + if (r != this->size()) return r; + if (fputs("\r\n", out) != EOF) r += 2; + return r; +} + +template size_t Jupiter::Readable_String::println(std::basic_ostream &out) const +{ + size_t r = this->print(out); + if (r != this->size()) return r; + out << std::endl; + return r; +} + +#endif // _READABLE_STRING_IMP_H_HEADER \ No newline at end of file diff --git a/Jupiter/String_Type.h b/Jupiter/String_Type.h index 358ee13..7e6e84e 100644 --- a/Jupiter/String_Type.h +++ b/Jupiter/String_Type.h @@ -24,11 +24,8 @@ * Note: Some methods are commented out. This means that they should be implemented, but could not be put declared in this template (return of abstract type). */ -#include "Jupiter.h" -#include // std::basic_string type #include // va_list -#include -#include +#include "Readable_String.h" namespace Jupiter { @@ -39,7 +36,7 @@ namespace Jupiter * * @param T Element type which the String will store. Defaults to char. */ - template class String_Type + template class String_Type : public Jupiter::Readable_String { public: @@ -65,100 +62,6 @@ namespace Jupiter */ const T *ptr() const; - /** - * @brief Checks if the string contains an element with the specified value. - * - * @param value Value of the element to search for. - * @return True if a match is found, false otherwise. - */ - bool contains(const T &value) const; - - /** - * @brief Compares another string against the String. - * - * @param in String to compare against. - * @return 0 if the strings are equal, negative if the first mismatched character is greater in the String, or positive if it's less. - */ - int compare(const String_Type &in) const; - int compare(const std::basic_string &in) const; - int compare(const T *in) const; - int compare(const T &in) const; - int compare(const std::nullptr_t) const; - - /** - * @brief Checks if the strings are equal. - * Note: Case sensitive. - * - * @param in String to compare against. - * @return True if the contents of the strings are equal, false otherwise. - */ - bool equals(const String_Type &in) const; - bool equals(const std::basic_string &in) const; - bool equals(const T *in) const; - bool equals(const T &in) const; - bool equals(const std::nullptr_t) const; - - /** - * @brief Checks if the strings are equal. - * Note: Case insensitive. Returns false for any type other than char and wchar_t. - * - * @param in String to compare against. - * @return True if the contents of the strings are equal, false otherwise. - */ - bool equalsi(const String_Type &in) const; - bool equalsi(const std::basic_string &in) const; - bool equalsi(const T *in) const; - bool equalsi(const T &in) const; - bool equalsi(const std::nullptr_t) const; - - /** - * @brief Checks if the String matches a wildcard format. - * Note: Case sensitive. - * - * @param format Format that the string is compared against. - * @return True if the String matches the wildcard format, false otherwise. - */ - bool match(const String_Type &format) const; - bool match(const std::basic_string &format) const; - bool match(const T *format) const; - - /** - * @brief Checks if the CString matches a wildcard format. - * Note: Case insensitive. Returns false for any type other than char and wchar_t. - * - * @param format Format that the string is compared against. - * @return True if the CString matches the wildcard format, false otherwise. - */ - bool matchi(const String_Type &format) const; - bool matchi(const std::basic_string &format) const; - bool matchi(const T *format) const; - - /** - * @brief Counts the number of token deliminated words. - * - * @param whitespace A string of tokens used to deliminate words. - * @return Number of words found. - */ - unsigned int wordCount(const T *whitespace) const; - - /** - * @brief Interprets the string as an integer. - * Note: This returns 0 on any value string type other than char. - * - * @param base Base of the string representation. - * @return Integer representation of the string. - */ - int asInt(int base = 0) const; - - /** - * @brief Interprets the string as an integer. - * Note: This returns 0 on any value string type other than char. - * - * @param base Base of the string representation. - * @return Integer representation of the string. - */ - unsigned int asUnsignedInt(int base = 0) const; - /** * @brief Returns a C-Style string version of the String. * @@ -166,24 +69,6 @@ namespace Jupiter */ virtual const T *c_str() const = 0; - /** - * @brief Outputs the string to a FILE stream. - * - * @param out Stream to output to. - * @return Number of elements written successfully. - */ - size_t print(FILE *out) const; - size_t print(std::basic_ostream &out) const; - - /** - * @brief Outputs the string and a newline to a FILE stream - * - * @param out Stream to output to. - * @param Number of elements written successfully. - */ - size_t println(FILE *out) const; - size_t println(std::basic_ostream &out) const; - /** * @brief Sets the CString's contents based on the format string and input variables. * Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t. diff --git a/Jupiter/String_Type_Imp.h b/Jupiter/String_Type_Imp.h index e1d91f5..439ebd1 100644 --- a/Jupiter/String_Type_Imp.h +++ b/Jupiter/String_Type_Imp.h @@ -55,715 +55,6 @@ template const T *Jupiter::String_Type::ptr() const return Jupiter::String_Type::str; } -template bool Jupiter::String_Type::contains(const T &value) const -{ - for (unsigned int i = 0; i < Jupiter::String_Type::length; i++) if (Jupiter::String_Type::str[i] == value) return true; - return false; -} - -// compare() - -template int Jupiter::String_Type::compare(const Jupiter::String_Type &in) const -{ - // rewrite to compare multiple bytes at a time. - size_t index = 0; - while (Jupiter::String_Type::str[index] == in.get(index)) - { - index++; - if (index == in.size()) - { - if (index == Jupiter::String_Type::length) return 0; - return 1; - } - if (index == Jupiter::String_Type::length) return 0 - in.get(index); - } - return Jupiter::String_Type::str[index] - in.get(index); -} - -template int Jupiter::String_Type::compare(const std::basic_string &in) const -{ - // rewrite to compare multiple bytes at a time. - size_t index = 0; - while (Jupiter::String_Type::str[index] == in.at(index)) - { - index++; - if (index == in.size()) - { - if (index == Jupiter::String_Type::length) return 0; - return 1; - } - if (index == Jupiter::String_Type::length) return 0 - in.at(index); - } - return Jupiter::String_Type::str[index] - in.at(index); -} - -template int Jupiter::String_Type::compare(const T *s2) const -{ - if (Jupiter::String_Type::length == 0) return 0 - *s2; - size_t index = 0; - while (Jupiter::String_Type::str[index] == *s2) - { - index++; - if (*s2 == 0) - { - if (index == Jupiter::String_Type::length) return 0; - return 1; - } - s2++; - if (index == Jupiter::String_Type::length) return 0 - *s2; - } - return Jupiter::String_Type::str[index] - *s2; -} - -template int Jupiter::String_Type::compare(const T &in) const -{ - if (Jupiter::String_Type::length == 0) return 0 - in; - return *Jupiter::String_Type::str - in; -} - -template int Jupiter::String_Type::compare(const std::nullptr_t) const -{ - if (Jupiter::String_Type::length == 0) return true; - return *Jupiter::String_Type::str; -} - -// equals() - -template bool Jupiter::String_Type::equals(const Jupiter::String_Type &in) const -{ - if (Jupiter::String_Type::length != in.size()) return false; - - // rewrite to compare multiple bytes at a time. - size_t index = 0; - while (index != Jupiter::String_Type::length) - { - if (Jupiter::String_Type::str[index] != in.str[index]) return false; - index++; - } - return true; -} - -template bool Jupiter::String_Type::equals(const std::basic_string &in) const -{ - if (Jupiter::String_Type::length != in.size()) return false; - // rewrite to compare multiple bytes at a time. - size_t index = 0; - while (index != Jupiter::String_Type::length) - { - if (Jupiter::String_Type::str[index] != in.at(index)) return false; - index++; - } - return true; -} - -template bool Jupiter::String_Type::equals(const T *in) const -{ - if (in == nullptr) return Jupiter::String_Type::length == 0; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (*in == 0 || Jupiter::String_Type::str[index] != *in) return false; - in++; - } - return *in == 0; -} - -template bool Jupiter::String_Type::equals(const T &in) const -{ - return Jupiter::String_Type::length == 1 && *Jupiter::String_Type::str == in; -} - -template bool Jupiter::String_Type::equals(std::nullptr_t) const -{ - return Jupiter::String_Type::length == 0; -} - -// equalsi() - -template<> bool inline Jupiter::String_Type::equalsi(const Jupiter::String_Type &in) const -{ - if (Jupiter::String_Type::length != in.size()) return false; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (toupper(Jupiter::String_Type::str[index]) != toupper(in.str[index])) return false; - } - return true; -} - -template<> bool inline Jupiter::String_Type::equalsi(const Jupiter::String_Type &in) const -{ - if (Jupiter::String_Type::length != in.size()) return false; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (towupper(Jupiter::String_Type::str[index]) != towupper(in.str[index])) return false; - } - return true; -} - -template bool Jupiter::String_Type::equalsi(const Jupiter::String_Type &in) const -{ - return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::String_Type::equalsi(const std::basic_string &in) const -{ - if (Jupiter::String_Type::length != in.size()) return false; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (toupper(Jupiter::String_Type::str[index]) != toupper(in.at(index))) return false; - } - return true; -} - -template<> bool inline Jupiter::String_Type::equalsi(const std::basic_string &in) const -{ - if (Jupiter::String_Type::length != in.size()) return false; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (towupper(Jupiter::String_Type::str[index]) != towupper(in.at(index))) return false; - } - return true; -} - -template bool Jupiter::String_Type::equalsi(const std::basic_string &in) const -{ - return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::String_Type::equalsi(const char *in) const -{ - if (in == nullptr) return Jupiter::String_Type::length == 0; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (*in == 0 || toupper(Jupiter::String_Type::str[index]) != toupper(*in)) return false; - in++; - } - return *in == 0; -} - -template<> bool inline Jupiter::String_Type::equalsi(const wchar_t *in) const -{ - if (in == nullptr) return Jupiter::String_Type::length == 0; - for (size_t index = 0; index != Jupiter::String_Type::length; index++) - { - if (*in == 0 || towupper(Jupiter::String_Type::str[index]) != towupper(*in)) return false; - in++; - } - return *in == 0; -} - -template bool Jupiter::String_Type::equalsi(const T *in) const -{ - return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::String_Type::equalsi(const char &in) const -{ - return Jupiter::String_Type::length == 1 && toupper(*Jupiter::String_Type::str) == toupper(in); -} - -template<> bool inline Jupiter::String_Type::equalsi(const wchar_t &in) const -{ - return Jupiter::String_Type::length == 1 && towupper(*Jupiter::String_Type::str) == towupper(in); -} - -template bool Jupiter::String_Type::equalsi(const T &in) const -{ - return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. -} - -template bool Jupiter::String_Type::equalsi(const std::nullptr_t) const -{ - return Jupiter::String_Type::length == 0; -} - -// match() - -template<> bool inline Jupiter::String_Type::match(const Jupiter::String_Type &format) const -{ - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.str[formatIndex] == '*') - { - formatIndex++; - while (format.str[formatIndex] == '?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.str[formatIndex] == 0) return true; - if (format.str[formatIndex] == '*') continue; - while (format.str[formatIndex] != Jupiter::String_Type::str[index]) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.str[formatIndex] != '?' && format.str[formatIndex] != Jupiter::String_Type::str[index]) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template<> bool inline Jupiter::String_Type::match(const Jupiter::String_Type &format) const -{ - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.str[formatIndex] == '*') - { - formatIndex++; - while (format.str[formatIndex] == '?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.str[formatIndex] == 0) return true; - if (format.str[formatIndex] == '*') continue; - while (format.str[formatIndex] != Jupiter::String_Type::str[index]) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.str[formatIndex] != '?' && format.str[formatIndex] != Jupiter::String_Type::str[index]) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template bool Jupiter::String_Type::match(const Jupiter::String_Type &format) const -{ - return false; // Wildcard matching not supported for type. -} - -template<> bool inline Jupiter::String_Type::match(const std::basic_string &format) const -{ - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.at(formatIndex) == '*') - { - formatIndex++; - while (format.at(formatIndex) == '?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.at(formatIndex) == 0) return true; - if (format.at(formatIndex) == '*') continue; - while (format.at(formatIndex) != Jupiter::String_Type::str[index]) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.at(formatIndex) != '?' && format.at(formatIndex) != Jupiter::String_Type::str[index]) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template<> bool inline Jupiter::String_Type::match(const std::basic_string &format) const -{ - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.at(formatIndex) == '*') - { - formatIndex++; - while (format.at(formatIndex) == '?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.at(formatIndex) == 0) return true; - if (format.at(formatIndex) == '*') continue; - while (format.at(formatIndex) != Jupiter::String_Type::str[index]) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.at(formatIndex) != '?' && format.at(formatIndex) != Jupiter::String_Type::str[index]) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template bool Jupiter::String_Type::match(const std::basic_string &format) const -{ - return false; // Wildcard matching not supported for type. -} - -template<> inline bool Jupiter::String_Type::match(const char *format) const -{ - size_t index = 0; - while (*format != 0) - { - if (*format == '*') - { - format++; - while (*format == '?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - format++; - index++; - } - if (*format == 0) return true; - if (*format == '*') continue; - while (*format != Jupiter::String_Type::str[index]) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (*format != '?' && *format != Jupiter::String_Type::str[index]) return false; - format++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template<> inline bool Jupiter::String_Type::match(const wchar_t *format) const -{ - size_t index = 0; - while (*format != 0) - { - if (*format == L'*') - { - format++; - while (*format == L'?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - format++; - index++; - } - if (*format == 0) return true; - if (*format == L'*') continue; - while (*format != Jupiter::String_Type::str[index]) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (*format != L'?' && *format != Jupiter::String_Type::str[index]) return false; - format++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template bool Jupiter::String_Type::match(const T *format) const -{ - return false; // Wildcard matching not supported for type. -} - -// matchi() - -template<> bool inline Jupiter::String_Type::matchi(const Jupiter::String_Type &format) const -{ - int fUpper; - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.get(formatIndex) == L'*') - { - formatIndex++; - while (format.get(formatIndex) == L'?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.get(formatIndex) == 0) return true; - if (format.get(formatIndex) == '*') continue; - fUpper = toupper(format.get(formatIndex)); - while (fUpper != toupper(Jupiter::String_Type::str[index])) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.get(formatIndex) != L'?' && toupper(format.get(formatIndex)) != toupper(Jupiter::String_Type::str[index])) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template<> bool inline Jupiter::String_Type::matchi(const Jupiter::String_Type &format) const -{ - wint_t fUpper; - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.get(formatIndex) == L'*') - { - formatIndex++; - while (format.get(formatIndex) == L'?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.get(formatIndex) == 0) return true; - if (format.get(formatIndex) == '*') continue; - fUpper = towupper(format.get(formatIndex)); - while (fUpper != towupper(Jupiter::String_Type::str[index])) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.get(formatIndex) != L'?' && towupper(format.get(formatIndex)) != towupper(Jupiter::String_Type::str[index])) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template bool Jupiter::String_Type::matchi(const Jupiter::String_Type &format) const -{ - return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::String_Type::matchi(const std::basic_string &format) const -{ - int fUpper; - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.at(formatIndex) == L'*') - { - formatIndex++; - while (format.at(formatIndex) == L'?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.at(formatIndex) == 0) return true; - if (format.at(formatIndex) == '*') continue; - fUpper = toupper(format.at(formatIndex)); - while (fUpper != toupper(Jupiter::String_Type::str[index])) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.at(formatIndex) != L'?' && toupper(format.at(formatIndex)) != toupper(Jupiter::String_Type::str[index])) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template<> bool inline Jupiter::String_Type::matchi(const std::basic_string &format) const -{ - wint_t fUpper; - size_t index = 0; - size_t formatIndex = 0; - while (formatIndex != format.size()) - { - if (format.at(formatIndex) == L'*') - { - formatIndex++; - while (format.at(formatIndex) == L'?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - formatIndex++; - index++; - } - if (format.at(formatIndex) == 0) return true; - if (format.at(formatIndex) == '*') continue; - fUpper = towupper(format.at(formatIndex)); - while (fUpper != towupper(Jupiter::String_Type::str[index])) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (format.at(formatIndex) != L'?' && towupper(format.at(formatIndex)) != towupper(Jupiter::String_Type::str[index])) return false; - formatIndex++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template bool Jupiter::String_Type::matchi(const std::basic_string &format) const -{ - return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::String_Type::matchi(const char *format) const -{ - int fUpper; - size_t index = 0; - while (*format != 0) - { - if (*format == '*') - { - format++; - while (*format == '?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - format++; - index++; - } - if (*format == 0) return true; - if (*format == '*') continue; - fUpper = toupper(*format); - while (fUpper != toupper(Jupiter::String_Type::str[index])) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (*format != '?' && toupper(*format) != toupper(Jupiter::String_Type::str[index])) return false; - format++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template<> bool inline Jupiter::String_Type::matchi(const wchar_t *format) const -{ - wint_t fUpper; - size_t index = 0; - while (*format != 0) - { - if (*format == L'*') - { - format++; - while (*format == L'?') - { - if (Jupiter::String_Type::str[index] == 0) return false; - format++; - index++; - } - if (*format == 0) return true; - if (*format == '*') continue; - fUpper = towupper(*format); - while (fUpper != towupper(Jupiter::String_Type::str[index])) - { - if (Jupiter::String_Type::str[index] == 0) return false; - index++; - } - } - else if (*format != L'?' && towupper(*format) != towupper(Jupiter::String_Type::str[index])) return false; - format++; - index++; - } - return index == Jupiter::String_Type::length; -} - -template bool Jupiter::String_Type::matchi(const T *format) const -{ - return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. -} - -// wordCount() - -template unsigned int Jupiter::String_Type::wordCount(const T *whitespace) const -{ - unsigned int result = 0; - T *p = Jupiter::String_Type::str; - bool prev = true; - while (*p != 0) - { - if (Jupiter::strpbrk(whitespace, *p) == nullptr) // This isn't whitespace! - { - if (prev == true) // We just left whitespace! - { - prev = false; - result++; - } - } - else prev = true; // This is whitespace! - p++; - } - return result; -} - -// as - -template<> unsigned int inline Jupiter::String_Type::asUnsignedInt(int base) const -{ - return strtoui_s(Jupiter::String_Type::str, Jupiter::String_Type::length, base); -} - -template unsigned int Jupiter::String_Type::asUnsignedInt(int base) const -{ - return 0; -} - -template<> int inline Jupiter::String_Type::asInt(int base) const -{ - return strtoi_s(Jupiter::String_Type::str, Jupiter::String_Type::length, base); -} - -template int Jupiter::String_Type::asInt(int base) const -{ - return 0; -} - -// Stream output - -template size_t Jupiter::String_Type::print(FILE *out) const -{ - return fwrite(Jupiter::String_Type::str, sizeof(T), Jupiter::String_Type::length, out); -} - -template<> size_t inline Jupiter::String_Type::print(FILE *out) const -{ - size_t index = 0; - while (index != Jupiter::String_Type::length && fputwc(Jupiter::String_Type::str[index], out) != WEOF) index++; - return index; -} - -template size_t Jupiter::String_Type::print(std::basic_ostream &out) const -{ - size_t index = 0; - while (index != Jupiter::String_Type::length) - { - out << Jupiter::String_Type::str[index]; - index++; - } - return index; -} - -template size_t Jupiter::String_Type::println(FILE *out) const -{ - size_t r = Jupiter::String_Type::print(out); - if (r != Jupiter::String_Type::length) return r; - if (fputs("\r\n", out) != EOF) r += 2; - return r; -} - -template size_t Jupiter::String_Type::println(std::basic_ostream &out) const -{ - size_t r = Jupiter::String_Type::print(out); - if (r != Jupiter::String_Type::length) return r; - out << std::endl; - return r; -} - // format forwards template size_t Jupiter::String_Type::format(const String_Type &format, ...) diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index f92f4c1..086217a 100644 Binary files a/Release/Jupiter.lib and b/Release/Jupiter.lib differ