From 9cfe6629eafb1ca06da9aa0bdacc8258b3b0ed00 Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Tue, 27 May 2014 15:19:31 -0400 Subject: [PATCH] Added String_Type implementation --- Jupiter/String_Type_Imp.h | 662 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 662 insertions(+) create mode 100644 Jupiter/String_Type_Imp.h diff --git a/Jupiter/String_Type_Imp.h b/Jupiter/String_Type_Imp.h new file mode 100644 index 0000000..8fc7e61 --- /dev/null +++ b/Jupiter/String_Type_Imp.h @@ -0,0 +1,662 @@ +/** + * 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 _STRING_TYPE_IMP_H_HEADER +#define _STRING_TYPE_IMP_H_HEADER + +/** + * @file String_Type_Imp.h + * @brief Provides the implementations for String_Type functions. + * Note: Modification of this file is not supported in any way. + */ + +#include "String_Type.h" +#include "Functions.h" + +/** +* IMPLEMENTATION: +* String_Type +*/ + +template T &Jupiter::String_Type::get(size_t index) const +{ + return Jupiter::String_Type::str[index]; +} + +template size_t Jupiter::String_Type::size() const +{ + return Jupiter::String_Type::length; +} + +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 +{ + return Jupiter::String_Type::compare(in.c_str()); +} + +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; + return Jupiter::String_Type::equals(in.c_str()); +} + +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 Jupiter::String_Type::equalsi(const Jupiter::String_Type &in) const +{ + return false; // Concept of "case" not supported for type. +} + +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 (toupper(Jupiter::String_Type::str[index]) != toupper(in.str[index])) return false; + } + return true; +} + +template bool Jupiter::String_Type::equalsi(const std::basic_string &in) const +{ + if (Jupiter::String_Type::length != in.size()) return false; + return Jupiter::String_Type::equalsi(in.c_str()); +} + +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 false; // 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 false; // 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 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 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 std::basic_string &format) const +{ + return Jupiter::String_Type::match(format.c_str()); +} + +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; // Type is not comparable to wildcards. +} + +// 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; +} + +template bool Jupiter::String_Type::matchi(const std::basic_string &format) const +{ + return Jupiter::String_Type::matchi(format.c_str()); +} + +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; // Type is not comparable to wildcards. 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; + // This may change to simply '\n' at a later date. + 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, ...) +{ + size_t r; + va_list args; + va_start(args, format); + r = this->vformat(format.c_str(), args); + va_end(args); + return r; +} + +template size_t Jupiter::String_Type::format(const std::basic_string &format, ...) +{ + size_t r; + va_list args; + va_start(args, format); + r = this->vformat(format.c_str(), args); + va_end(args); + return r; +} + +template size_t Jupiter::String_Type::format(const T *format, ...) +{ + size_t r; + va_list args; + va_start(args, format); + r = this->vformat(format, args); + va_end(args); + return r; +} + +// aformat forwards + +template size_t Jupiter::String_Type::aformat(const String_Type &format, ...) +{ + size_t r; + va_list args; + va_start(args, format); + r = this->avformat(format.c_str(), args); + va_end(args); + return r; +} + +template size_t Jupiter::String_Type::aformat(const std::basic_string &format, ...) +{ + size_t r; + va_list args; + va_start(args, format); + r = this->avformat(format.c_str(), args); + va_end(args); + return r; +} + +template size_t Jupiter::String_Type::aformat(const T *format, ...) +{ + size_t r; + va_list args; + va_start(args, format); + r = this->avformat(format, args); + va_end(args); + return r; +} + +#endif // _STRING_TYPE_IMP_H_HEADER \ No newline at end of file