From 4ab689832e0ee38353ea2ebe1cb0bb91fc494a0b Mon Sep 17 00:00:00 2001 From: JustinAJ Date: Tue, 27 May 2014 15:18:47 -0400 Subject: [PATCH] Moved many comparative functions to String_Type, fixed some bugs, and added more substring methods. Also improved general safety. --- Jupiter/CString.h | 197 ++++----- Jupiter/CString_Imp.h | 914 ++++++++++++++++-------------------------- 2 files changed, 424 insertions(+), 687 deletions(-) diff --git a/Jupiter/CString.h b/Jupiter/CString.h index 2f22194..76a370c 100644 --- a/Jupiter/CString.h +++ b/Jupiter/CString.h @@ -18,9 +18,6 @@ #if !defined _CSTRING_H_HEADER #define _CSTRING_H_HEADER -#include -#include "String_Type.h" - /** * @file CString.h * @brief Defines the base CString_Type, as well as a series of CString types. @@ -28,6 +25,8 @@ * for types char and wchar_t; inputs with other types will simply return false. */ +#include "Shift_String.h" + namespace Jupiter { /** @@ -36,7 +35,7 @@ namespace Jupiter * * @param T Element type which the CString will store. Defaults to char. */ - template class CString_Type : public String_Type + template class CString_Type : public Shift_String_Type { public: @@ -47,81 +46,14 @@ namespace Jupiter */ const T *c_str() const; - /** - * @brief Returns the number of elements in the CString. - * - * @return Number of elements in the string. - */ - size_t size() const; - - /** - * @brief Compares another string against the CString. - * - * @param in String to compare against. - * @return 0 if the strings are equal, negative if the first mismatched character is greater in the CString, 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; - - /** - * @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; - - /** - * @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; - - /** - * @brief Checks if the CString matches a wildcard format. - * Note: Case sensitive. 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 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 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. * * @param format Format that the string is compared against. - * @param ... Inputs to match the format specifiers. + * @param args Variable arguments list to match the format specifiers. * @return Number of characters written. */ - virtual size_t format(const String_Type &format, ...); - virtual size_t format(const std::basic_string &format, ...); - virtual size_t format(const T *format, ...); virtual size_t vformat(const T *format, va_list args) = 0; /** @@ -129,22 +61,11 @@ namespace Jupiter * Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t. * * @param format Format that the string is compared against. - * @param ... Inputs to match the format specifiers. + * @param args Variable arguments list to match the format specifiers. * @return Number of characters written. */ - virtual size_t aformat(const String_Type &format, ...); - virtual size_t aformat(const std::basic_string &format, ...); - virtual size_t aformat(const T *format, ...); virtual size_t avformat(const T *format, va_list args) = 0; - /** - * @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 Truncates the string by a specified number of elements. * @@ -153,30 +74,6 @@ namespace Jupiter */ size_t truncate(size_t n); - /** - * @brief Fetches an element from the string. - * - * @param index Index of the element to return. - * @return The element located at the specified index. - */ - T &get(size_t index) const; - - /** - * @brief Shifts the string pointer to the left. - * - * @param length Number of elements to shift - * @return Number of elements shifted to the left. - */ - size_t shiftLeft(size_t length); - - /** - * @brief Shifts the string pointer to the right. - * - * @param length Number of elements to shift - * @return Number of elements shifted. - */ - size_t shiftRight(size_t length); - /** * @brief Removes the first instance of an element from the string. * @@ -185,27 +82,12 @@ namespace Jupiter */ bool remove(T &value); - /** - * @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); - - /** Access Operator */ - inline T &operator[](size_t pos) { return Jupiter::String_Type::str[pos]; }; - /** Assignment Operators */ inline CString_Type &operator=(const CString_Type &right) { this->set(right); return *this; }; inline CString_Type &operator=(const String_Type &right) { this->set(right); return *this; }; inline CString_Type &operator=(const std::basic_string &right) { this->set(right); return *this; }; inline CString_Type &operator=(const T *right) { this->set(right); return *this; }; inline CString_Type &operator=(const T right) { this->set(right); return *this; }; - - protected: - T *base; /** Base pointer for the underlying C-style string */ - size_t strLen; /** Length of underlying C-style string */ }; /** @@ -248,6 +130,14 @@ namespace Jupiter */ static CString_Strict Format(const T *format, ...); + /** + * @brief Creates a partial copy of the string. + * + * @param pos Position in the string to start copying from. + * @return String containing a partial copy of the original string. + */ + CString_Strict substring(size_t pos) const; + /** * @brief Creates a partial copy of the string. * @@ -257,6 +147,25 @@ namespace Jupiter */ CString_Strict substring(size_t pos, size_t length) const; + /** + * @brief Creates a partial copy of the string. + * + * @param in String to get a partial copy of. + * @param pos Position in the string to start copying from. + * @return String containing a partial copy of the original string. + */ + static CString_Strict substring(const Jupiter::String_Type &in, size_t pos); + + /** + * @brief Creates a partial copy of the string. + * + * @param in String to get a partial copy of. + * @param pos Position in the string to start copying from. + * @param length Number of characters to copy. + * @return String containing a partial copy of the original string. + */ + static CString_Strict substring(const Jupiter::String_Type &in, size_t pos, size_t length); + /** * @brief Creates a partial copy of the string, based on a set of tokens. * @@ -351,11 +260,10 @@ namespace Jupiter CString_Strict(); /** Copy Constructors */ - CString_Strict(const CString_Strict &in); CString_Strict(const String_Type &in); CString_Strict(const std::basic_string &in); CString_Strict(const T *in); - CString_Strict(const T in); + CString_Strict(size_t size); /** Destructor */ virtual ~CString_Strict(); @@ -409,6 +317,14 @@ namespace Jupiter */ static CString_Loose Format(const T *format, ...); + /** + * @brief Creates a partial copy of the string. + * + * @param pos Position in the string to start copying from. + * @return String containing a partial copy of the original string. + */ + CString_Loose substring(size_t pos) const; + /** * @brief Creates a partial copy of the string. * @@ -418,6 +334,25 @@ namespace Jupiter */ CString_Loose substring(size_t pos, size_t length) const; + /** + * @brief Creates a partial copy of the string. + * + * @param in String to get a partial copy of. + * @param pos Position in the string to start copying from. + * @return String containing a partial copy of the original string. + */ + static CString_Loose substring(const Jupiter::String_Type &in, size_t pos); + + /** + * @brief Creates a partial copy of the string. + * + * @param in String to get a partial copy of. + * @param pos Position in the string to start copying from. + * @param length Number of characters to copy. + * @return String containing a partial copy of the original string. + */ + static CString_Loose substring(const Jupiter::String_Type &in, size_t pos, size_t length); + /** * @brief Creates a partial copy of the string, based on a set of tokens. * @@ -494,12 +429,18 @@ namespace Jupiter /** Default constructor */ CString_Loose(); + /** + * @brief Size hint constructor. + * + * @param size Minimum size of new string's buffer. + */ + CString_Loose(size_t size); + /** Copy Constructors */ CString_Loose(const CString_Loose &in); CString_Loose(const String_Type &in); CString_Loose(const std::basic_string &in); CString_Loose(const T *in); - CString_Loose(const T in); /** Destructor */ virtual ~CString_Loose(); @@ -545,8 +486,8 @@ namespace Jupiter /** Empty String constants */ static const Jupiter::CStringS emptyCStringS; static const Jupiter::CStringS emptyCStringL; - static const Jupiter::CStringS &emptyCString = emptyCStringS; - static const Jupiter::CStringS &emptyString = emptyCString; + static const Jupiter::CStringType &emptyCString = emptyCStringS; + static const Jupiter::StringType &emptyString = emptyCString; } /** Implementation for CString_Type, CString_Strict, and CString_Loose. Very scary. */ diff --git a/Jupiter/CString_Imp.h b/Jupiter/CString_Imp.h index 4e3f214..41e03e9 100644 --- a/Jupiter/CString_Imp.h +++ b/Jupiter/CString_Imp.h @@ -18,15 +18,15 @@ #if !defined _CSTRING_IMP_H_HEADER #define _CSTRING_IMP_H_HEADER -#include "Functions.h" -#include "CString.h" - /** * @file CString_Imp.h * @brief Provides the implementations for CString_Type functions, as well as extending classes. * Note: Modification of this file is not supported in any way. */ +#include "Functions.h" +#include "CString.h" + /** * IMPLEMENTATION: * CString_Type @@ -37,295 +37,36 @@ template const T *Jupiter::CString_Type::c_str() const return Jupiter::String_Type::str; } -template size_t Jupiter::CString_Type::size() const -{ - return Jupiter::CString_Type::strLen; -} - -template int Jupiter::CString_Type::compare(const Jupiter::String_Type &in) const -{ - return Jupiter::CString_Type::compare(in.c_str()); -} - -template int Jupiter::CString_Type::compare(const std::basic_string &in) const -{ - return Jupiter::CString_Type::compare(in.c_str()); -} - -template int Jupiter::CString_Type::compare(const T *s2) const -{ - const T *s1 = Jupiter::String_Type::str; - while (*s1 != 0 && *s1 == *s2) - { - s1++; - s2++; - } - return *s1 - *s2; -} - -template int Jupiter::CString_Type::compare(const T s2) const -{ - return *Jupiter::String_Type::str - s2; -} - -template bool Jupiter::CString_Type::equals(const Jupiter::String_Type &in) const -{ - if (Jupiter::CString_Type::strLen != in.size()) return false; - return Jupiter::CString_Type::equals(in.c_str()); -} - -template bool Jupiter::CString_Type::equals(const std::basic_string &in) const -{ - if (Jupiter::CString_Type::strLen != in.size()) return false; - return Jupiter::CString_Type::equals(in.c_str()); -} - -template bool Jupiter::CString_Type::equals(const T *in) const -{ - if (in == nullptr) return Jupiter::CString_Type::strLen == 0; - return Jupiter::streql(Jupiter::String_Type::str, in); -} - -template bool Jupiter::CString_Type::equals(const T in) const -{ - return *Jupiter::String_Type::str == in && ((in == 0) || Jupiter::String_Type::str[1] == 0); -} - -// equalsi() - -template bool Jupiter::CString_Type::equalsi(const Jupiter::String_Type &in) const -{ - if (Jupiter::CString_Type::strLen != in.size()) return false; - return Jupiter::CString_Type::equalsi(in.c_str()); -} - -template bool Jupiter::CString_Type::equalsi(const std::basic_string &in) const -{ - if (Jupiter::CString_Type::strLen != in.size()) return false; - return Jupiter::CString_Type::equalsi(in.c_str()); -} - -template<> bool inline Jupiter::CString_Type::equalsi(const char *in) const -{ - return streqli(Jupiter::String_Type::str, in); -} - -template<> bool inline Jupiter::CString_Type::equalsi(const wchar_t *in) const -{ - return wstreqli(Jupiter::String_Type::str, in); -} - -template bool Jupiter::CString_Type::equalsi(const T *in) const -{ - return false; // Concept of "case" not supported for type. -} - -template<> bool inline Jupiter::CString_Type::equalsi(const char in) const -{ - return toupper(*Jupiter::String_Type::str) == toupper(in) && ((in == 0) || Jupiter::String_Type::str[1] == 0); -} - -template<> bool inline Jupiter::CString_Type::equalsi(const wchar_t in) const -{ - return towupper(*Jupiter::String_Type::str) == towupper(in) && ((in == 0) || Jupiter::String_Type::str[1] == 0); -} - -template bool Jupiter::CString_Type::equalsi(const T in) const -{ - return false; // Concept of "case" not supported for type. -} - -// match() - -template bool Jupiter::CString_Type::match(const Jupiter::String_Type &format) const -{ - return Jupiter::CString_Type::match(format.c_str()); -} - -template bool Jupiter::CString_Type::match(const std::basic_string &format) const -{ - return Jupiter::CString_Type::match(format.c_str()); -} - -template<> inline bool Jupiter::CString_Type::match(const char *format) const -{ - return strmatch(format, Jupiter::String_Type::str); -} - -template<> inline bool Jupiter::CString_Type::match(const wchar_t *format) const -{ - return wstrmatch(format, Jupiter::String_Type::str); -} - -template bool Jupiter::CString_Type::match(const T *format) const -{ - return false; // Type is not comparable to wildcards. -} - -// matchi() - -template bool Jupiter::CString_Type::matchi(const Jupiter::String_Type &format) const -{ - return Jupiter::CString_Type::matchi(format.c_str()); -} - -template bool Jupiter::CString_Type::matchi(const std::basic_string &format) const -{ - return Jupiter::CString_Type::matchi(format.c_str()); -} - -template<> bool inline Jupiter::CString_Type::matchi(const char *format) const -{ - return strmatchi(format, Jupiter::String_Type::str); -} - -template<> bool inline Jupiter::CString_Type::matchi(const wchar_t *format) const -{ - return wstrmatchi(format, Jupiter::String_Type::str); -} - -template bool Jupiter::CString_Type::matchi(const T *format) const -{ - return false; // Type is not comparable to wildcards. Concept of "case" not supported for type. -} - -// format forwards - -template size_t Jupiter::CString_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::CString_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::CString_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::CString_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::CString_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::CString_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; -} - -template unsigned int Jupiter::CString_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; -} - template size_t Jupiter::CString_Type::truncate(size_t n) { - if (n >= Jupiter::CString_Type::strLen) + if (n >= Jupiter::String_Type::length) { - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = 0; - Jupiter::CString_Type::strLen = 0; + Jupiter::String_Type::length = 0; return 0; } - Jupiter::CString_Type::strLen -= n; - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; - return Jupiter::CString_Type::strLen; -} - -template T &Jupiter::CString_Type::get(size_t index) const -{ - return Jupiter::String_Type::str[index]; -} - -template size_t Jupiter::CString_Type::shiftLeft(size_t length) -{ - size_t offset = Jupiter::String_Type::str - Jupiter::CString_Type::base; - if (length > offset) length = offset; - Jupiter::String_Type::str -= length; - Jupiter::CString_Type::strLen += length; - return length; -} - -template size_t Jupiter::CString_Type::shiftRight(size_t length) -{ - if (length > Jupiter::CString_Type::strLen) length = Jupiter::CString_Type::strLen; - Jupiter::String_Type::str += length; - Jupiter::CString_Type::strLen -= length; - return length; + Jupiter::String_Type::length -= n; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template bool Jupiter::CString_Type::remove(T &value) { - for (unsigned int i = 0; i < Jupiter::CString_Type::strLen; i++) + for (unsigned int i = 0; i < Jupiter::String_Type::length; i++) { if (Jupiter::String_Type::str[i] == value) { - if (i == strLen - 1) Jupiter::CString_Type::truncate(1); + if (i == Jupiter::String_Type::length - 1) Jupiter::CString_Type::truncate(1); else if (i == 0) { - if (Jupiter::CString_Type::strLen == 1) Jupiter::CString_Type::truncate(1); + if (Jupiter::String_Type::length == 1) Jupiter::CString_Type::truncate(1); else Jupiter::CString_Type::shiftRight(1); } else { Jupiter::strcpy(Jupiter::String_Type::str + i, Jupiter::String_Type::str + i + 1); - Jupiter::CString_Type::strLen--; + Jupiter::String_Type::length--; } return true; } @@ -333,46 +74,40 @@ template bool Jupiter::CString_Type::remove(T &value) return false; } -template bool Jupiter::CString_Type::contains(const T &value) -{ - for (unsigned int i = 0; i < Jupiter::CString_Type::strLen; i++) if (Jupiter::String_Type::str[i] == value) return true; - return false; -} - /** * IMPLEMENTATION: * CString_Strict */ -template Jupiter::CString_Strict::CString_Strict() +template Jupiter::CString_Strict::CString_Strict() : Jupiter::CString_Strict::CString_Strict(size_t(0)) { - Jupiter::CString_Type::base = new T[1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - *Jupiter::String_Type::str = 0; - Jupiter::CString_Type::strLen = 0; } -template Jupiter::CString_Strict::CString_Strict(const Jupiter::CString_Strict &in) +template Jupiter::CString_Strict::CString_Strict(size_t size) { - Jupiter::CString_Type::strLen = in.strLen; - Jupiter::CString_Type::base = new T[Jupiter::CString_Type::strLen + 1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::strcpy(Jupiter::String_Type::str, in.str); + // We need a size variable to actually make any real use of this. + Jupiter::Shift_String_Type::base = new T[size+1]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + *Jupiter::String_Type::str = 0; + Jupiter::String_Type::length = 0; } template Jupiter::CString_Strict::CString_Strict(const Jupiter::String_Type &in) { - Jupiter::CString_Type::strLen = in.size(); - Jupiter::CString_Type::base = new T[Jupiter::CString_Type::strLen + 1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); + Jupiter::String_Type::length = in.size(); + Jupiter::Shift_String_Type::base = new T[Jupiter::String_Type::length + 1]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + size_t index; + for (index = 0; index < Jupiter::String_Type::length && in.get(index) != 0; index++) Jupiter::String_Type::str[index] = in.get(index); + Jupiter::String_Type::length = index; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; } template Jupiter::CString_Strict::CString_Strict(const std::basic_string &in) { - Jupiter::CString_Type::strLen = in.size(); - Jupiter::CString_Type::base = new T[Jupiter::CString_Type::strLen + 1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::length = in.size(); + Jupiter::Shift_String_Type::base = new T[Jupiter::String_Type::length + 1]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); } @@ -380,42 +115,23 @@ template Jupiter::CString_Strict::CString_Strict(const T *in) { if (in == nullptr) { - Jupiter::CString_Type::strLen = 0; - Jupiter::CString_Type::base = new T[1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::length = 0; + Jupiter::Shift_String_Type::base = new T[1]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = 0; } else { - Jupiter::CString_Type::strLen = Jupiter::strlen(in); - Jupiter::CString_Type::base = new T[Jupiter::CString_Type::strLen + 1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::length = Jupiter::strlen(in); + Jupiter::Shift_String_Type::base = new T[Jupiter::String_Type::length + 1]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::strcpy(Jupiter::String_Type::str, in); } } -template Jupiter::CString_Strict::CString_Strict(const T c) -{ - if (c == 0) - { - Jupiter::CString_Type::strLen = 0; - Jupiter::CString_Type::base = new T[1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - *Jupiter::String_Type::str = 0; - } - else - { - Jupiter::CString_Type::strLen = 1; - Jupiter::CString_Type::base = new T[Jupiter::CString_Type::strLen + 1]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - *Jupiter::String_Type::str = c; - Jupiter::String_Type::str[1] = 0; - } -} - template Jupiter::CString_Strict::~CString_Strict() { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; } // vformat() @@ -428,16 +144,16 @@ template<> size_t inline Jupiter::CString_Strict::vformat(const char *form minLen = vsnprintf(nullptr, 0, format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - if ((unsigned)minLen > Jupiter::CString_Type::strLen) + if ((unsigned)minLen > Jupiter::String_Type::length) { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = new char[minLen + 1]; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new char[minLen + 1]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = minLen; - vsnprintf(Jupiter::String_Type::str, Jupiter::CString_Type::strLen, format, args); - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; - return Jupiter::CString_Type::strLen; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = minLen; + vsnprintf(Jupiter::String_Type::str, Jupiter::String_Type::length, format, args); + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template<> size_t inline Jupiter::CString_Strict::vformat(const wchar_t *format, va_list args) @@ -448,16 +164,16 @@ template<> size_t inline Jupiter::CString_Strict::vformat(const wchar_t minLen = vswprintf(nullptr, 0, format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - if ((unsigned)minLen > Jupiter::CString_Type::strLen) + if ((unsigned)minLen > Jupiter::String_Type::length) { delete[] Jupiter::CString_Type::base; Jupiter::CString_Type::base = new wchar_t[minLen + 1]; } Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = minLen; - vswprintf(Jupiter::String_Type::str, Jupiter::CString_Type::strLen, format, args); - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; - return Jupiter::CString_Type::strLen; + Jupiter::String_Type::length = minLen; + vswprintf(Jupiter::String_Type::str, Jupiter::String_Type::length, format, args); + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Strict::vformat(const T *format, va_list args) @@ -476,16 +192,16 @@ template<> size_t inline Jupiter::CString_Strict::avformat(const char *for va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - char *t = new char[minLen + Jupiter::CString_Type::strLen + 1]; + char *t = new char[minLen + Jupiter::String_Type::length + 1]; Jupiter::strcpy(t, Jupiter::String_Type::str); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = t; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = t; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; - minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, minLen, format, args); + minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen, format, args); if (minLen <= 0) return 0; - Jupiter::CString_Type::strLen += minLen; - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; + Jupiter::String_Type::length += minLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; return minLen; } @@ -498,16 +214,16 @@ template<> size_t inline Jupiter::CString_Strict::avformat(const wchar_ va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - wchar_t *t = new wchar_t[minLen + Jupiter::CString_Type::strLen + 1]; + wchar_t *t = new wchar_t[minLen + Jupiter::String_Type::length + 1]; Jupiter::strcpy(t, Jupiter::String_Type::str); delete[] Jupiter::CString_Type::base; Jupiter::CString_Type::base = t; Jupiter::String_Type::str = Jupiter::CString_Type::base; - minLen = vswprintf(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, minLen, format, args); + minLen = vswprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen, format, args); if (minLen <= 0) return 0; - Jupiter::CString_Type::strLen += minLen; - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; + Jupiter::String_Type::length += minLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; return minLen; } @@ -526,11 +242,36 @@ template Jupiter::CString_Strict Jupiter::CString_Strict::Form return r; } +template Jupiter::CString_Strict Jupiter::CString_Strict::substring(size_t pos) const +{ + return Jupiter::CString_Strict::substring(*this, pos, Jupiter::String_Type::length - pos); +} + template Jupiter::CString_Strict Jupiter::CString_Strict::substring(size_t pos, size_t length) const { - Jupiter::CString_Strict r; - r.setString(new char[length + 1], length); - r.strLen = Jupiter::strlen(Jupiter::strcpy(r.str, Jupiter::String_Type::str + pos, length)); + return Jupiter::CString_Strict::substring(*this, pos, length); +} + +template Jupiter::CString_Strict Jupiter::CString_Strict::substring(const Jupiter::String_Type &in, size_t pos) +{ + if (pos > in.size()) return Jupiter::CString_Strict(); + Jupiter::CString_Strict r = Jupiter::CString_Strict(in.size() - pos); + size_t index; + for (index = pos; index != in.size() && in.get(index) != 0; index++) r.str[index - pos] = in.get(index); + r.str[index - pos] = 0; + r.length = index; + return r; +} + +template Jupiter::CString_Strict Jupiter::CString_Strict::substring(const Jupiter::String_Type &in, size_t pos, size_t length) +{ + if (pos > in.size()) return Jupiter::CString_Strict(); + if (length > in.size() - pos) length = in.size() - pos; + Jupiter::CString_Strict r = Jupiter::CString_Strict(length); + size_t index; + for (index = 0; index != length && in.get(index + pos) != 0; index++) r.str[index] = in.get(index + pos); + r.str[index] = 0; + r.length = index; return r; } @@ -541,7 +282,27 @@ template Jupiter::CString_Strict Jupiter::CString_Strict::getW template Jupiter::CString_Strict Jupiter::CString_Strict::getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) { - return Jupiter::CString_Strict::getWord(in.c_str(), pos, whitespace); + unsigned int x = 0; + unsigned int y = 1; + for (unsigned int i = 0; i < pos || y == 1; x++) + { + if (in.get(x) == 0) return Jupiter::CString_Strict(); + if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) + { + if (y != 1) + { + y = 1; + i++; + } + } + else + { + if (i >= pos) break; + y = 0; + } + } + for (y = x; Jupiter::strpbrk(whitespace, in.get(y)) == nullptr && in.get(y) != 0; y++); + return Jupiter::CString_Strict::substring(in, x, y - x); } template Jupiter::CString_Strict Jupiter::CString_Strict::getWord(const T *in, size_t pos, const T *whitespace) @@ -569,16 +330,16 @@ template Jupiter::CString_Strict Jupiter::CString_Strict::getW } for (y = x; Jupiter::strpbrk(whitespace, in[y]) == nullptr && in[y] != 0; y++); - r.strLen = y - x; + r.length = y - x; delete[] r.base; - r.base = new char[r.strLen + 1]; + r.base = new T[r.length + 1]; r.str = r.base; for (i = 0; x < y; i++) { r.str[i] = in[x]; x++; } - r.str[r.strLen] = 0; + r.str[r.length] = 0; return r; } @@ -589,12 +350,11 @@ template Jupiter::CString_Strict Jupiter::CString_Strict::goto template Jupiter::CString_Strict Jupiter::CString_Strict::gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) { - Jupiter::CString_Strict r; unsigned int x = 0; bool y = true; for (unsigned int i = 0; i < pos || y == true; x++) { - if (in.get(x) == 0) return r; + if (in.get(x) == 0) return Jupiter::CString_Strict(); if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) { if (y != 1) @@ -609,35 +369,36 @@ template Jupiter::CString_Strict Jupiter::CString_Strict::goto y = false; } } - // Remake later to get character-by-character -- c_str not guaranteed to be fast. - r = in.c_str() + x; - return r; + return Jupiter::CString_Strict::substring(in, x); } template size_t Jupiter::CString_Strict::set(const String_Type &in) { size_t sSize = in.size(); - if (Jupiter::CString_Type::strLen < sSize) + if (Jupiter::String_Type::length < sSize) { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = new T[sSize + 1]; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new T[sSize + 1]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = sSize; - Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); - return sSize; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = sSize; + size_t index; + for (index = 0; index < Jupiter::String_Type::length && in.get(index) != 0; index++) Jupiter::String_Type::str[index] = in.get(index); + Jupiter::String_Type::length = index; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Strict::set(const std::basic_string &in) { size_t sSize = in.size(); - if (Jupiter::CString_Type::strLen < sSize) + if (Jupiter::String_Type::length < sSize) { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = new T[sSize + 1]; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new T[sSize + 1]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = sSize; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = sSize; Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); return sSize; } @@ -645,13 +406,13 @@ template size_t Jupiter::CString_Strict::set(const std::basic_str template size_t Jupiter::CString_Strict::set(const T *in) { size_t sSize = Jupiter::strlen(in); - if (Jupiter::CString_Type::strLen < sSize) + if (Jupiter::String_Type::length < sSize) { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = new T[sSize + 1]; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new T[sSize + 1]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = sSize; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = sSize; Jupiter::strcpy(Jupiter::String_Type::str, in); return sSize; } @@ -660,19 +421,19 @@ template size_t Jupiter::CString_Strict::set(const T in) { if (in == 0) { - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = 0; - return Jupiter::CString_Type::strLen = 0; + return Jupiter::String_Type::length = 0; } - if (Jupiter::CString_Type::strLen < 1) + if (Jupiter::String_Type::length < 1) { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = new T[2]; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new T[2]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = in; Jupiter::String_Type::str[1] = 0; - return Jupiter::CString_Type::strLen = 1; + return Jupiter::String_Type::length = 1; } template size_t Jupiter::CString_Strict::setString(T *in) @@ -682,62 +443,64 @@ template size_t Jupiter::CString_Strict::setString(T *in) template size_t Jupiter::CString_Strict::setString(T *in, size_t size) { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = in; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - return Jupiter::CString_Type::strLen = size; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = in; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + return Jupiter::String_Type::length = size; } template size_t Jupiter::CString_Strict::concat(const String_Type &in) { - size_t nSize = Jupiter::CString_Type::strLen + in.size(); + size_t nSize = Jupiter::String_Type::length + in.size(); T *tmp = new T[nSize + 1]; - Jupiter::strcpy(tmp, Jupiter::String_Type::str); - Jupiter::strcpy(tmp + Jupiter::CString_Type::strLen, in.c_str()); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = nSize; - return nSize; + Jupiter::strcpy(tmp, Jupiter::String_Type::str); // str guaranteed to be null-terminated. + size_t index; + for (index = Jupiter::String_Type::length; index < nSize && in.get(index - Jupiter::String_Type::length); index++) Jupiter::String_Type::str[index] = in.get(index - Jupiter::String_Type::length); + Jupiter::String_Type::str[index] = 0; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = index; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Strict::concat(const std::basic_string &in) { - size_t nSize = Jupiter::CString_Type::strLen + in.size(); + size_t nSize = Jupiter::String_Type::length + in.size(); T *tmp = new T[nSize + 1]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); - Jupiter::strcpy(tmp + Jupiter::CString_Type::strLen, in.c_str()); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = nSize; + Jupiter::strcpy(tmp + Jupiter::String_Type::length, in.c_str()); + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = nSize; return nSize; } template size_t Jupiter::CString_Strict::concat(const T *in) { - size_t nSize = Jupiter::CString_Type::strLen + Jupiter::strlen(in); + size_t nSize = Jupiter::String_Type::length + Jupiter::strlen(in); T *tmp = new T[nSize + 1]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); - Jupiter::strcpy(tmp + Jupiter::CString_Type::strLen, in); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = nSize; + Jupiter::strcpy(tmp + Jupiter::String_Type::length, in); + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = nSize; return nSize; } template size_t Jupiter::CString_Strict::concat(const T c) { - size_t nSize = Jupiter::CString_Type::strLen + 1; + size_t nSize = Jupiter::String_Type::length + 1; T *tmp = new T[nSize + 1]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); tmp[nSize - 1] = c; tmp[nSize] = 0; - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = nSize; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = nSize; return nSize; } @@ -746,41 +509,49 @@ template size_t Jupiter::CString_Strict::concat(const T c) * CString_Loose */ -template Jupiter::CString_Loose::CString_Loose() +template Jupiter::CString_Loose::CString_Loose() : Jupiter::CString_Loose::CString_Loose(Jupiter::CString_Loose::start_size) { - Jupiter::CString_Loose::strSize = Jupiter::CString_Loose::start_size; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; +} + +template Jupiter::CString_Loose::CString_Loose(size_t size) +{ + if (size < Jupiter::CString_Loose::start_size) size = Jupiter::CString_Loose::start_size; + Jupiter::CString_Loose::strSize = size; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = 0; - Jupiter::CString_Type::strLen = 0; + Jupiter::String_Type::length = 0; } template Jupiter::CString_Loose::CString_Loose(const Jupiter::CString_Loose &in) { Jupiter::CString_Loose::strSize = in.strSize; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::strcpy(Jupiter::String_Type::str, in.str); - Jupiter::CString_Type::strLen = in.strLen; + Jupiter::String_Type::length = in.length; } template Jupiter::CString_Loose::CString_Loose(const Jupiter::String_Type &in) { - Jupiter::CString_Type::strLen = in.size(); - Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::CString_Type::strLen + 1); + Jupiter::String_Type::length = in.size(); + Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::String_Type::length + 1); if (Jupiter::CString_Loose::strSize < 8) Jupiter::CString_Loose::strSize = 8; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + size_t index; + for (index = 0; index < Jupiter::String_Type::length && in.get(index) != 0; index++) Jupiter::String_Type::str[index] = in.get(index); + Jupiter::String_Type::length = index; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; } template Jupiter::CString_Loose::CString_Loose(const std::basic_string &in) { - Jupiter::CString_Type::strLen = in.size(); - Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::CString_Type::strLen + 1); + Jupiter::String_Type::length = in.size(); + Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::String_Type::length + 1); if (Jupiter::CString_Loose::strSize < 8) Jupiter::CString_Loose::strSize = 8; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); } @@ -789,43 +560,25 @@ template Jupiter::CString_Loose::CString_Loose(const T *in) if (in == nullptr) { Jupiter::CString_Loose::strSize = Jupiter::CString_Loose::start_size; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = 0; - Jupiter::CString_Type::strLen = 0; + Jupiter::String_Type::length = 0; } else { - Jupiter::CString_Type::strLen = Jupiter::strlen(in); - Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::CString_Type::strLen + 1); + Jupiter::String_Type::length = Jupiter::strlen(in); + Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::String_Type::length + 1); if (Jupiter::CString_Loose::strSize < 8) Jupiter::CString_Loose::strSize = 8; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::strcpy(Jupiter::String_Type::str, in); } } -template Jupiter::CString_Loose::CString_Loose(const T in) -{ - Jupiter::CString_Loose::strSize = Jupiter::CString_Loose::start_size; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; - Jupiter::String_Type::str = Jupiter::CString_Type::base; - if (in == 0) - { - Jupiter::CString_Type::strLen = 0; - *Jupiter::String_Type::str = 0; - } - else - { - Jupiter::CString_Type::strLen = 1; - *Jupiter::String_Type::str = in; - Jupiter::String_Type::str[1] = 0; - } -} - template Jupiter::CString_Loose::~CString_Loose() { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; } template<> size_t inline Jupiter::CString_Loose::vformat(const char *format, va_list args) @@ -838,15 +591,15 @@ template<> size_t inline Jupiter::CString_Loose::vformat(const char *forma if (minLen < 0) return 0; // We simply can not work with this. if ((unsigned)minLen > Jupiter::CString_Loose::strSize) { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; Jupiter::CString_Loose::strSize = getPowerTwo32(minLen + 1); - Jupiter::CString_Type::base = new char[Jupiter::CString_Loose::strSize]; + Jupiter::Shift_String_Type::base = new char[Jupiter::CString_Loose::strSize]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = minLen; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = minLen; vsnprintf(Jupiter::String_Type::str, Jupiter::CString_Loose::strSize, format, args); - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; - return Jupiter::CString_Type::strLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template<> size_t inline Jupiter::CString_Loose::vformat(const wchar_t *format, va_list args) @@ -864,10 +617,10 @@ template<> size_t inline Jupiter::CString_Loose::vformat(const wchar_t Jupiter::CString_Type::base = new wchar_t[Jupiter::CString_Loose::strSize]; } Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = minLen; + Jupiter::String_Type::length = minLen; vswprintf(Jupiter::String_Type::str, Jupiter::CString_Loose::strSize, format, args); - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; - return Jupiter::CString_Type::strLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::vformat(const T *format, va_list args) @@ -883,25 +636,25 @@ template<> size_t inline Jupiter::CString_Loose::avformat(const char *form minLen = vsnprintf(nullptr, 0, format, sargs); // Portable as of C++11. va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - minLen += Jupiter::CString_Type::strLen; + minLen += Jupiter::String_Type::length; if ((unsigned)minLen + 1 > Jupiter::CString_Loose::strSize) { Jupiter::CString_Loose::strSize = getPowerTwo32(minLen + 1); char *tmpStr = new char[Jupiter::CString_Loose::strSize]; Jupiter::strcpy(tmpStr, Jupiter::String_Type::str); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmpStr; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmpStr; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - else if ((unsigned)minLen + 1 + (Jupiter::String_Type::str - Jupiter::CString_Type::base) > Jupiter::CString_Loose::strSize) + else if ((unsigned)minLen + 1 + (Jupiter::String_Type::str - Jupiter::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) { - Jupiter::strcpy(Jupiter::CString_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, Jupiter::CString_Loose::strSize - Jupiter::CString_Type::strLen, format, args); + minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, Jupiter::CString_Loose::strSize - Jupiter::String_Type::length, format, args); if (minLen <= 0) return 0; - Jupiter::CString_Type::strLen += minLen; - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; + Jupiter::String_Type::length += minLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; return minLen; } @@ -913,7 +666,7 @@ template<> size_t inline Jupiter::CString_Loose::avformat(const wchar_t minLen = vswprintf(nullptr, 0, format, sargs); // Portable as of C++11. va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - minLen += Jupiter::CString_Type::strLen; + minLen += Jupiter::String_Type::length; if ((unsigned)minLen + 1 > Jupiter::CString_Loose::strSize) { Jupiter::CString_Loose::strSize = getPowerTwo32(minLen + 1); @@ -928,10 +681,10 @@ template<> size_t inline Jupiter::CString_Loose::avformat(const wchar_t Jupiter::strcpy(Jupiter::CString_Type::base, Jupiter::String_Type::str); Jupiter::String_Type::str = Jupiter::CString_Type::base; } - minLen = vswprintf(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, Jupiter::CString_Loose::strSize - Jupiter::CString_Type::strLen, format, args); + minLen = vswprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, Jupiter::CString_Loose::strSize - Jupiter::String_Type::length, format, args); if (minLen <= 0) return 0; - Jupiter::CString_Type::strLen += minLen; - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; + Jupiter::String_Type::length += minLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; return minLen; } @@ -950,15 +703,36 @@ template Jupiter::CString_Loose Jupiter::CString_Loose::Format return r; } +template Jupiter::CString_Loose Jupiter::CString_Loose::substring(size_t pos) const +{ + return Jupiter::CString_Loose::substring(*this, pos, Jupiter::String_Type::length - pos); +} + template Jupiter::CString_Loose Jupiter::CString_Loose::substring(size_t pos, size_t length) const { - Jupiter::CString_Loose r; - r.strSize = getPowerTwo32(length + 1); - delete[] r.base; - r.base = new char[r.strSize]; - r.str = r.base; - r.strLen = length; - Jupiter::strcpy(r.str, Jupiter::String_Type::str + pos, length); + return Jupiter::CString_Loose::substring(*this, pos, length); +} + +template Jupiter::CString_Loose Jupiter::CString_Loose::substring(const Jupiter::String_Type &in, size_t pos) +{ + if (pos > in.size()) return Jupiter::CString_Loose(); + Jupiter::CString_Loose r = Jupiter::CString_Loose(in.size() - pos); + size_t index; + for (index = pos; index != in.size() && in.get(index) != 0; index++) r.str[index - pos] = in.get(index); + r.str[index - pos] = 0; + r.length = index; + return r; +} + +template Jupiter::CString_Loose Jupiter::CString_Loose::substring(const Jupiter::String_Type &in, size_t pos, size_t length) +{ + if (pos > in.size()) return Jupiter::CString_Loose(); + if (length > in.size() - pos) length = in.size() - pos; + Jupiter::CString_Loose r = Jupiter::CString_Loose(length); + size_t index; + for (index = 0; index != length && in.get(index + pos) != 0; index++) r.str[index] = in.get(index + pos); + r.str[index] = 0; + r.length = index; return r; } @@ -969,7 +743,27 @@ template Jupiter::CString_Loose Jupiter::CString_Loose::getWor template Jupiter::CString_Loose Jupiter::CString_Loose::getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) { - return Jupiter::CString_Loose::getWord(in.c_str(), pos, whitespace); + unsigned int x = 0; + unsigned int y = 1; + for (unsigned int i = 0; i < pos || y == 1; x++) + { + if (in.get(x) == 0) return Jupiter::CString_Loose(); + if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) + { + if (y != 1) + { + y = 1; + i++; + } + } + else + { + if (i >= pos) break; + y = 0; + } + } + for (y = x; Jupiter::strpbrk(whitespace, in.get(y)) == nullptr && in.get(y) != 0; y++); + return Jupiter::CString_Loose::substring(in, x, y - x); } template Jupiter::CString_Loose Jupiter::CString_Loose::getWord(const T *in, size_t pos, const T *whitespace) @@ -996,10 +790,10 @@ template Jupiter::CString_Loose Jupiter::CString_Loose::getWor } } for (y = x; Jupiter::strpbrk(whitespace, in[y]) == nullptr && in[y] != 0; y++); - r.strLen = y - x; - r.strSize = getPowerTwo32(r.strLen + 1); + r.length = y - x; + r.strSize = getPowerTwo32(r.length + 1); delete[] r.base; - r.base = new char[r.strSize]; + r.base = new T[r.strSize]; r.str = r.base; for (i = 0; x < y; i++) { @@ -1017,12 +811,11 @@ template Jupiter::CString_Loose Jupiter::CString_Loose::gotoWo template Jupiter::CString_Loose Jupiter::CString_Loose::gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) { - Jupiter::CString_Loose r; unsigned int x = 0; bool y = true; for (unsigned int i = 0; i < pos || y == true; x++) { - if (in.get(x) == 0) return r; + if (in.get(x) == 0) return Jupiter::CString_Loose(); if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) { if (y == false) @@ -1037,23 +830,21 @@ template Jupiter::CString_Loose Jupiter::CString_Loose::gotoWo y = false; } } - // Remake later to get character-by-character -- c_str not guaranteed to be fast. - r = in.c_str() + x; - return r; + return Jupiter::CString_Loose::substring(in, x); } template size_t Jupiter::CString_Loose::set(const CString_Loose &in) { - if (Jupiter::CString_Loose::strSize <= in.strLen) + if (Jupiter::CString_Loose::strSize <= in.length) { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; Jupiter::CString_Loose::strSize = in.strSize; - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = in.strLen; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = in.length; Jupiter::strcpy(Jupiter::String_Type::str, in.str); - return Jupiter::CString_Type::strLen; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::set(const String_Type &in) @@ -1061,14 +852,17 @@ template size_t Jupiter::CString_Loose::set(const String_Type size_t sSize = in.size() + 1; if (Jupiter::CString_Loose::strSize < sSize) { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; Jupiter::CString_Loose::strSize = getPowerTwo32(sSize); - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = sSize - 1; - Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); - return Jupiter::CString_Type::strLen; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = sSize - 1; + size_t index; + for (index = 0; index != Jupiter::String_Type::length && in.get(index) != 0; index++) Jupiter::String_Type::str[index] = in.get(index); + Jupiter::String_Type::length = index; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::set(const std::basic_string &in) @@ -1076,14 +870,14 @@ template size_t Jupiter::CString_Loose::set(const std::basic_stri size_t sSize = in.size() + 1; if (Jupiter::CString_Loose::strSize < sSize) { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; Jupiter::CString_Loose::strSize = getPowerTwo32(sSize); - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = sSize - 1; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = sSize - 1; Jupiter::strcpy(Jupiter::String_Type::str, in.c_str()); - return Jupiter::CString_Type::strLen; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::set(const T *in) @@ -1091,26 +885,26 @@ template size_t Jupiter::CString_Loose::set(const T *in) size_t sSize = Jupiter::strlen(in) + 1; if (Jupiter::CString_Loose::strSize < sSize) { - delete[] Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; Jupiter::CString_Loose::strSize = getPowerTwo32(sSize); - Jupiter::CString_Type::base = new T[Jupiter::CString_Loose::strSize]; + Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::CString_Type::strLen = sSize - 1; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + Jupiter::String_Type::length = sSize - 1; Jupiter::strcpy(Jupiter::String_Type::str, in); - return Jupiter::CString_Type::strLen; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::set(const T in) { if (in == 0) { - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = 0; - return Jupiter::CString_Type::strLen = 0; + return Jupiter::String_Type::length = 0; } - Jupiter::CString_Type::strLen = 1; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::String_Type::length = 1; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; *Jupiter::String_Type::str = in; Jupiter::String_Type::str[1] = 0; return 1; @@ -1118,90 +912,92 @@ template size_t Jupiter::CString_Loose::set(const T in) template size_t Jupiter::CString_Loose::concat(const String_Type &in) { - size_t nLen = Jupiter::CString_Type::strLen + in.size(); + size_t nLen = Jupiter::String_Type::length + in.size(); if (nLen + 1 > Jupiter::CString_Loose::strSize) { Jupiter::CString_Loose::strSize = getPowerTwo32(nLen + 1); T *tmp = new T[Jupiter::CString_Loose::strSize]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - else if (nLen + 1 + (Jupiter::String_Type::str - Jupiter::CString_Type::base) > Jupiter::CString_Loose::strSize) + else if (nLen + 1 + (Jupiter::String_Type::str - Jupiter::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) { - Jupiter::strcpy(Jupiter::CString_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - Jupiter::strcpy(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, in.c_str()); - Jupiter::CString_Type::strLen = nLen; - return Jupiter::CString_Type::strLen; + size_t index; + for (index = Jupiter::String_Type::length; index < nLen && in.get(index - Jupiter::String_Type::length); index++) Jupiter::String_Type::str[index] = in.get(index - Jupiter::String_Type::length); + Jupiter::String_Type::length = index; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::concat(const std::basic_string &in) { - size_t nLen = Jupiter::CString_Type::strLen + in.size(); + size_t nLen = Jupiter::String_Type::length + in.size(); if (nLen + 1 > Jupiter::CString_Loose::strSize) { Jupiter::CString_Loose::strSize = getPowerTwo32(nLen + 1); T *tmp = new T[Jupiter::CString_Loose::strSize]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - else if (nLen + 1 + (Jupiter::String_Type::str - Jupiter::CString_Type::base) > Jupiter::CString_Loose::strSize) + else if (nLen + 1 + (Jupiter::String_Type::str - Jupiter::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) { - Jupiter::strcpy(Jupiter::CString_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - Jupiter::strcpy(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, in.c_str()); - Jupiter::CString_Type::strLen = nLen; - return Jupiter::CString_Type::strLen; + Jupiter::strcpy(Jupiter::String_Type::str + Jupiter::String_Type::length, in.c_str()); + Jupiter::String_Type::length = nLen; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::concat(const T *in) { - size_t nLen = Jupiter::CString_Type::strLen + Jupiter::strlen(in); + size_t nLen = Jupiter::String_Type::length + Jupiter::strlen(in); if (nLen + 1 > Jupiter::CString_Loose::strSize) { Jupiter::CString_Loose::strSize = getPowerTwo32(nLen + 1); T *tmp = new T[Jupiter::CString_Loose::strSize]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - else if (nLen + 1 + (Jupiter::String_Type::str - Jupiter::CString_Type::base) > Jupiter::CString_Loose::strSize) + else if (nLen + 1 + (Jupiter::String_Type::str - Jupiter::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) { - Jupiter::strcpy(Jupiter::CString_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - Jupiter::strcpy(Jupiter::String_Type::str + Jupiter::CString_Type::strLen, in); - Jupiter::CString_Type::strLen = nLen; - return Jupiter::CString_Type::strLen; + Jupiter::strcpy(Jupiter::String_Type::str + Jupiter::String_Type::length, in); + Jupiter::String_Type::length = nLen; + return Jupiter::String_Type::length; } template size_t Jupiter::CString_Loose::concat(const T in) { - if (Jupiter::CString_Type::strLen + 1 == Jupiter::CString_Loose::strSize) + if (Jupiter::String_Type::length + 1 == Jupiter::CString_Loose::strSize) { Jupiter::CString_Loose::strSize = getPowerTwo32(Jupiter::CString_Loose::strSize + 1); T *tmp = new T[Jupiter::CString_Loose::strSize]; Jupiter::strcpy(tmp, Jupiter::String_Type::str); - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::CString_Type::base; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = tmp; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - else if (Jupiter::CString_Type::strLen + 1 + (Jupiter::String_Type::str - Jupiter::CString_Type::base) >= Jupiter::CString_Loose::strSize) + else if (Jupiter::String_Type::length + 1 + (Jupiter::String_Type::str - Jupiter::Shift_String_Type::base) >= Jupiter::CString_Loose::strSize) { - Jupiter::strcpy(Jupiter::CString_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::CString_Type::base; + Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = in; - Jupiter::CString_Type::strLen++; - Jupiter::String_Type::str[Jupiter::CString_Type::strLen] = 0; - return Jupiter::CString_Type::strLen; + Jupiter::String_Type::str[Jupiter::String_Type::length] = in; + Jupiter::String_Type::length++; + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } #endif // _CSTRING_IMP_H_HEADER \ No newline at end of file