diff --git a/Jupiter/CString.h b/Jupiter/CString.h index 149e6b9..fe224e1 100644 --- a/Jupiter/CString.h +++ b/Jupiter/CString.h @@ -30,8 +30,7 @@ namespace Jupiter { /** - * @brief Provides the basis for CString classes by providing the implementations for many abstract methods in String_Type. - * Note: This is an abstract type. + * @brief Provides the basis for CString classes by providing a minimalist implementation (i.e: no extra variables). * * @param T Element type which the CString will store. Defaults to char. */ @@ -62,24 +61,6 @@ namespace Jupiter */ bool remove(const T &value); - /** 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; }; - }; - - /** - * @brief Provides a "strict" CString implementation that's more optimized for minimal memory usage. - * Note: This recreates the underlying C-style string with every concatenation. - * - * @param T Element type which the CString will store. Defaults to char. - */ - template class CString_Strict : public CString_Type - { - public: - /** * @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. @@ -108,7 +89,7 @@ namespace Jupiter * @param ... Inputs to match the format specifiers. * @return String containing the new format. */ - static CString_Strict Format(const T *format, ...); + static CString_Type Format(const T *format, ...); /** * @brief Creates a partial copy of the string. @@ -116,7 +97,7 @@ namespace Jupiter * @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; + CString_Type substring(size_t pos) const; /** * @brief Creates a partial copy of the string. @@ -125,7 +106,7 @@ namespace Jupiter * @param length Number of characters to copy. * @return String containing a partial copy of the original string. */ - CString_Strict substring(size_t pos, size_t length) const; + CString_Type substring(size_t pos, size_t length) const; /** * @brief Creates a partial copy of the string. @@ -134,7 +115,8 @@ namespace Jupiter * @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); + static CString_Type substring(const Jupiter::String_Type &in, size_t pos); + static CString_Type substring(const T *in, size_t pos); /** * @brief Creates a partial copy of the string. @@ -144,7 +126,8 @@ namespace Jupiter * @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); + static CString_Type substring(const Jupiter::String_Type &in, size_t pos, size_t length); + static CString_Type substring(const T *in, size_t pos, size_t length); /** * @brief Creates a partial copy of the string, based on a set of tokens. @@ -153,7 +136,7 @@ namespace Jupiter * @param whitespace A string of tokens used to deliminate words. * @return String containing a partial copy of the original string. */ - CString_Strict getWord(size_t pos, const T *whitespace) const; + CString_Type getWord(size_t pos, const T *whitespace) const; /** * @brief Creates a partial copy of an input string, based on a set of tokens. @@ -163,7 +146,7 @@ namespace Jupiter * @param whitespace A string of tokens used to deliminate words. * @return String containing a partial copy of the original string. */ - static CString_Strict getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); + static CString_Type getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); /** * @brief Creates a partial copy of an input string, based on a set of tokens. @@ -173,7 +156,7 @@ namespace Jupiter * @param whitespace A string of tokens used to deliminate words. * @return String containing a partial copy of the original string. */ - static CString_Strict getWord(const T *in, size_t pos, const T *whitespace); + static CString_Type getWord(const T *in, size_t pos, const T *whitespace); /** * @brief Creates a partial copy of the string, based on a set of tokens. @@ -182,7 +165,7 @@ namespace Jupiter * @param whitespace A string of tokens used to deliminate words. * @return String containing a partial copy of the original string. */ - CString_Strict gotoWord(size_t pos, const T *whitespace) const; + CString_Type gotoWord(size_t pos, const T *whitespace) const; /** * @brief Creates a partial copy of the string, based on a set of tokens. @@ -192,7 +175,7 @@ namespace Jupiter * @param whitespace A string of tokens used to deliminate words. * @return String containing a partial copy of the original string. */ - static CString_Strict gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); + static CString_Type gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); /** * @brief Copies the data from the input string to the CString. @@ -205,26 +188,6 @@ namespace Jupiter size_t set(const T *in); size_t set(const T in); - /** - * @brief Sets the string buffer. - * Note: This class will free the buffer for you when it's done. - * - * @param in New buffer to be used. - * @return The length of the string. - */ - size_t setString(T *in); - - /** - * @brief Sets the string buffer. - * Note: This class will free the buffer for you when it's done. DO NOT DELETE THE INPUT BUFFER. - * Note: This method is unique to the CString_Strict template class, and does not appear in CString_Loose. - * - * @param in New buffer to be used. - * @param size At least the number of characters in the buffer, not including the null-terminator. - * @return The length of the string. - */ - size_t setString(T *in, size_t size); - /** * @brief Copies the data from the input string and concatenates it to the end of CString. * @@ -236,26 +199,58 @@ namespace Jupiter size_t concat(const T *in); size_t concat(const T in); + /** 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; }; + + static const Jupiter::CString_Type empty; /** Empty instantation of CString_Type */ + /** Default Constructor */ - CString_Strict(); + CString_Type(); + + /** + * @brief Size hint constructor. + * Note: For the CString_Type base class, this is only truly useful internally. + * + * @param size Minimum number of elements the string must be able to hold. + */ + CString_Type(size_t size); + + /** Move Constructor */ + CString_Type(CString_Type &&source); /** Copy Constructors */ - CString_Strict(const String_Type &in); - CString_Strict(const std::basic_string &in); - CString_Strict(const T *in); - CString_Strict(size_t size); + CString_Type(const String_Type &in); + CString_Type(const std::basic_string &in); + CString_Type(const T *in); - /** Destructor */ - virtual ~CString_Strict(); + protected: - /** Assignment Operators */ - inline CString_Strict &operator=(const CString_Strict &right) { this->set(right); return *this; }; - inline CString_Strict &operator=(const CString_Type &right) { this->set(right); return *this; }; - inline CString_Strict &operator=(const String_Type &right) { this->set(right); return *this; }; - inline CString_Strict &operator=(const std::basic_string &right) { this->set(right); return *this; }; - inline CString_Strict &operator=(const T *right) { this->set(right); return *this; }; - inline CString_Strict &operator=(const T right) { this->set(right); return *this; }; + /** + * @brief Sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSize(size_t len); + + /** + * @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSizeNoCopy(size_t len); + + /** Dummy constructor to prevent string initialization */ + CString_Type(Jupiter::String_Constructor_Base &) {}; }; + template using CString_Strict = CString_Type; /** * @brief Provides a "loose" CString implementation that's more optimized for repeated concatenations. @@ -267,26 +262,6 @@ namespace Jupiter { public: - /** - * @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. - * @return Number of characters written. - */ - size_t vformat(const T *format, va_list args); - - /** - * @brief Appends to a 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. - * @return Number of characters written. - */ - size_t avformat(const T *format, va_list args); - /** * @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. @@ -322,6 +297,7 @@ namespace Jupiter * @return String containing a partial copy of the original string. */ static CString_Loose substring(const Jupiter::String_Type &in, size_t pos); + static CString_Loose substring(const T *in, size_t pos); /** * @brief Creates a partial copy of the string. @@ -332,6 +308,7 @@ namespace Jupiter * @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); + static CString_Loose substring(const T *in, size_t pos, size_t length); /** * @brief Creates a partial copy of the string, based on a set of tokens. @@ -383,48 +360,26 @@ namespace Jupiter */ static CString_Loose gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); - /** - * @brief Copies the data from the input string to the CString. - * - * @param in String containing the data to be copied. - * @return New size of the CString. - */ - size_t set(const CString_Loose &in); - size_t set(const String_Type &in); - size_t set(const std::basic_string &in); - size_t set(const T *in); - size_t set(const T in); - - /** - * @brief Copies the data from the input string and concatenats it to the end of CString. - * - * @param in String containing the data to be concatenated. - * @return New size of the CString. - */ - size_t concat(const String_Type &in); - size_t concat(const std::basic_string &in); - size_t concat(const T *in); - size_t concat(const T in); - /** Default constructor */ CString_Loose(); /** * @brief Size hint constructor. * - * @param size Minimum size of new string's buffer. + * @param size Minimum number of elements the string must be able to hold. */ CString_Loose(size_t size); + /** Move Constructor */ + CString_Loose(CString_Loose &&source); + /** 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); - - /** Destructor */ - virtual ~CString_Loose(); + static const Jupiter::CString_Loose empty; /** Empty instantation of CString_Loose */ static const size_t start_size = 8; /** Starting size for loose CStrings. */ /** Assignment Operators */ @@ -436,6 +391,28 @@ namespace Jupiter inline CString_Loose &operator=(const T right) { this->set(right); return *this; }; protected: + + /** + * @brief Sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSize(size_t len); + + /** + * @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSizeNoCopy(size_t len); + + /** Dummy constructor to prevent string initialization */ + CString_Loose(Jupiter::String_Constructor_Base &) {}; + size_t strSize; /** Size of underlying C-string buffer */ }; @@ -445,12 +422,6 @@ namespace Jupiter /** Definition of a Loose Wide CString */ typedef CString_Loose WCStringL; - /** Definition of a Strict CString. */ - typedef CString_Strict CStringS; - - /** Definition of a Strict Wide CString */ - typedef CString_Strict WCStringS; - /** Definition of a CString. */ typedef CStringL CString; @@ -463,14 +434,20 @@ namespace Jupiter /** Generic Wide CString Type */ typedef CString_Type WCStringType; + /** Definition of a Strict CString. */ + typedef CStringType CStringS; + + /** Definition of a Strict Wide CString */ + typedef WCStringType WCStringS; + /** Empty String constants */ - static const Jupiter::CStringS emptyCStringS; - static const Jupiter::CStringL emptyCStringL; + static const Jupiter::CStringS &emptyCStringS = Jupiter::CStringS::empty; + static const Jupiter::CStringL &emptyCStringL = Jupiter::CStringL::empty; static const Jupiter::CStringType &emptyCString = emptyCStringS; static const Jupiter::StringType &emptyString = emptyCString; } -/** Implementation for CString_Type, CString_Strict, and CString_Loose. Very scary. */ +/** Implementation for CString_Type and CString_Loose. Very scary. */ #include "CString_Imp.h" #endif // _CSTRING_H_HEADER \ No newline at end of file diff --git a/Jupiter/CString_Imp.h b/Jupiter/CString_Imp.h index bd9d83e..c588e94 100644 --- a/Jupiter/CString_Imp.h +++ b/Jupiter/CString_Imp.h @@ -43,65 +43,43 @@ * CString_Type */ -template const T *Jupiter::CString_Type::c_str() const -{ - return Jupiter::String_Type::str; -} - -template size_t Jupiter::CString_Type::truncate(size_t n) -{ - Jupiter::String_Type::str[Jupiter::String_Type::truncate(n)] = 0; - return Jupiter::String_Type::length; -} - -template bool Jupiter::CString_Type::remove(const T &value) -{ - if (Jupiter::Shift_String_Type::remove(value)) - { - Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; - return true; - } - return false; -} - -/** -* IMPLEMENTATION: -* CString_Strict -*/ - -template Jupiter::CString_Strict::CString_Strict() : Jupiter::CString_Strict::CString_Strict(size_t(0)) +template Jupiter::CString_Type::CString_Type() : Jupiter::CString_Type::CString_Type(size_t(0)) { } -template Jupiter::CString_Strict::CString_Strict(size_t size) +template Jupiter::CString_Type::CString_Type(size_t len) { - // We need a size variable to actually make any real use of this. - Jupiter::Shift_String_Type::base = new T[size+1]; + Jupiter::Shift_String_Type::base = new T[len + 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) +template Jupiter::CString_Type::CString_Type(Jupiter::CString_Type &&source) : Jupiter::Shift_String_Type(std::move(source)) { - 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; +} + +template Jupiter::CString_Type::CString_Type(const Jupiter::String_Type &in) : Jupiter::CString_Type::CString_Type(in.size()) +{ + while (Jupiter::String_Type::length < in.size() && in.get(Jupiter::String_Type::length) != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.get(Jupiter::String_Type::length); + Jupiter::String_Type::length++; + } Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; } -template Jupiter::CString_Strict::CString_Strict(const std::basic_string &in) +template Jupiter::CString_Type::CString_Type(const std::basic_string &in) : Jupiter::CString_Type::CString_Type(in.size()) { - 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()); + while (Jupiter::String_Type::length < in.size() && in.at(Jupiter::String_Type::length) != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.at(Jupiter::String_Type::length); + Jupiter::String_Type::length++; + } + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; } -template Jupiter::CString_Strict::CString_Strict(const T *in) +template Jupiter::CString_Type::CString_Type(const T *in) { if (in == nullptr) { @@ -119,14 +97,47 @@ template Jupiter::CString_Strict::CString_Strict(const T *in) } } -template Jupiter::CString_Strict::~CString_Strict() +template bool Jupiter::CString_Type::setBufferSize(size_t len) { - delete[] Jupiter::Shift_String_Type::base; + if (Jupiter::Shift_String_Type::setBufferSize(len + 1)) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return true; + } + return false; +} + +template bool Jupiter::CString_Type::setBufferSizeNoCopy(size_t len) +{ + bool r = Jupiter::Shift_String_Type::setBufferSizeNoCopy(len + 1); + *Jupiter::String_Type::str = 0; + return r; +} + +template const T *Jupiter::CString_Type::c_str() const +{ + return Jupiter::String_Type::str; +} + +template size_t Jupiter::CString_Type::truncate(size_t n) +{ + Jupiter::String_Type::str[Jupiter::String_Type::truncate(n)] = 0; + return Jupiter::String_Type::length; +} + +template bool Jupiter::CString_Type::remove(const T &value) +{ + if (Jupiter::Shift_String_Type::remove(value)) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return true; + } + return false; } // vformat() -template<> size_t inline Jupiter::CString_Strict::vformat(const char *format, va_list args) +template<> size_t inline Jupiter::CString_Type::vformat(const char *format, va_list args) { int minLen; va_list sargs; @@ -134,19 +145,14 @@ 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::String_Type::length) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = new char[minLen + 1]; - } - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + this->setBufferSizeNoCopy(minLen); 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) +template<> size_t inline Jupiter::CString_Type::vformat(const wchar_t *format, va_list args) { int minLen; va_list sargs; @@ -154,26 +160,21 @@ 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::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; + this->setBufferSizeNoCopy(minLen); 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) +template size_t Jupiter::CString_Type::vformat(const T *format, va_list args) { return 0; } // avformat() -template<> size_t inline Jupiter::CString_Strict::avformat(const char *format, va_list args) +template<> size_t inline Jupiter::CString_Type::avformat(const char *format, va_list args) { int minLen; va_list sargs; @@ -181,12 +182,7 @@ template<> size_t inline Jupiter::CString_Strict::avformat(const char *for minLen = vsnprintf(nullptr, 0, format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - - char *t = new char[minLen + Jupiter::String_Type::length + 1]; - Jupiter::strcpy(t, Jupiter::String_Type::str); - delete[] Jupiter::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = t; - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + this->setBufferSize(Jupiter::String_Type::length + minLen); minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen, format, args); if (minLen <= 0) return 0; @@ -195,7 +191,7 @@ template<> size_t inline Jupiter::CString_Strict::avformat(const char *for return minLen; } -template<> size_t inline Jupiter::CString_Strict::avformat(const wchar_t *format, va_list args) +template<> size_t inline Jupiter::CString_Type::avformat(const wchar_t *format, va_list args) { int minLen; va_list sargs; @@ -203,12 +199,7 @@ template<> size_t inline Jupiter::CString_Strict::avformat(const wchar_ minLen = vswprintf(nullptr, 0, format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. - - 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; + this->setBufferSize(minLen + Jupiter::String_Type::length); minLen = vswprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen, format, args); if (minLen <= 0) return 0; @@ -217,14 +208,14 @@ template<> size_t inline Jupiter::CString_Strict::avformat(const wchar_ return minLen; } -template size_t Jupiter::CString_Strict::avformat(const T *format, va_list args) +template size_t Jupiter::CString_Type::avformat(const T *format, va_list args) { return 0; } -template Jupiter::CString_Strict Jupiter::CString_Strict::Format(const T *format, ...) +template Jupiter::CString_Type Jupiter::CString_Type::Format(const T *format, ...) { - CString_Strict r; + CString_Type r; va_list args; va_start(args, format); r.vformat(format, args); @@ -232,182 +223,96 @@ template Jupiter::CString_Strict Jupiter::CString_Strict::Form return r; } -template Jupiter::CString_Strict Jupiter::CString_Strict::substring(size_t pos) const +template Jupiter::CString_Type Jupiter::CString_Type::substring(size_t pos) const { - return Jupiter::CString_Strict::substring(*this, pos, Jupiter::String_Type::length - pos); + return Jupiter::CString_Type::substring(*this, pos); } -template Jupiter::CString_Strict Jupiter::CString_Strict::substring(size_t pos, size_t len) const +template Jupiter::CString_Type Jupiter::CString_Type::substring(size_t pos, size_t len) const { - return Jupiter::CString_Strict::substring(*this, pos, len); + return Jupiter::CString_Type::substring(*this, pos, len); } -template Jupiter::CString_Strict Jupiter::CString_Strict::substring(const Jupiter::String_Type &in, size_t pos) +template Jupiter::CString_Type Jupiter::CString_Type::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; + if (pos >= in.size()) return Jupiter::CString_Type(); + Jupiter::CString_Type r = Jupiter::CString_Type(in.size() - pos); + for (r.length = 0; pos + r.length != in.size() && in.get(pos + r.length) != 0; r.length++) r.str[r.length] = in.get(pos + r.length); + r.str[r.length] = 0; return r; } -template Jupiter::CString_Strict Jupiter::CString_Strict::substring(const Jupiter::String_Type &in, size_t pos, size_t len) +template Jupiter::CString_Type Jupiter::CString_Type::substring(const T *in, size_t pos) { - if (pos > in.size()) return Jupiter::CString_Strict(); - if (len > in.size() - pos) len = in.size() - pos; - Jupiter::CString_Strict r = Jupiter::CString_Strict(len); - size_t index; - for (index = 0; index != len && in.get(index + pos) != 0; index++) r.str[index] = in.get(index + pos); - r.str[index] = 0; - r.length = index; + Jupiter::CString_Type r = Jupiter::String_Type::substring(in, pos); + r.str[r.length] = 0; return r; } -template Jupiter::CString_Strict Jupiter::CString_Strict::getWord(size_t pos, const T *whitespace) const +template Jupiter::CString_Type Jupiter::CString_Type::substring(const Jupiter::String_Type &in, size_t pos, size_t len) { - return Jupiter::CString_Strict::getWord(*this, pos, whitespace); + if (pos + len >= in.size()) return Jupiter::CString_Type::substring(in, pos); + Jupiter::CString_Type r = Jupiter::CString_Type(len); + for (r.length = 0; r.length != len && in.get(pos + r.length) != 0; r.length++) r.str[r.length] = in.get(pos + r.length); + r.str[r.length] = 0; + return r; } -template Jupiter::CString_Strict Jupiter::CString_Strict::getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) +template Jupiter::CString_Type Jupiter::CString_Type::substring(const T *in, size_t pos, size_t len) { - 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); + Jupiter::CString_Type r = Jupiter::String_Type::substring(in, pos, len); + r.str[r.length] = 0; + return r; } -template Jupiter::CString_Strict Jupiter::CString_Strict::getWord(const T *in, size_t pos, const T *whitespace) +template Jupiter::CString_Type Jupiter::CString_Type::getWord(size_t pos, const T *whitespace) const { - Jupiter::CString_Strict r; - unsigned int x = 0; - unsigned int y = 1; - unsigned int i; - for (i = 0; i < pos || y == 1; x++) - { - if (in[x] == 0) return r; - if (Jupiter::strpbrk(whitespace, in[x]) != nullptr) - { - if (y != 1) - { - y = 1; - i++; - } - } - else - { - if (i >= pos) break; - y = 0; - } - } + return Jupiter::CString_Type::getWord(*this, pos, whitespace); +} - for (y = x; Jupiter::strpbrk(whitespace, in[y]) == nullptr && in[y] != 0; y++); - r.length = y - x; - delete[] r.base; - 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.length] = 0; - return r; +template Jupiter::CString_Type Jupiter::CString_Type::getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) +{ + return Jupiter::String_Type::getWord(in, pos, whitespace); } -template Jupiter::CString_Strict Jupiter::CString_Strict::gotoWord(size_t pos, const T *whitespace) const +template Jupiter::CString_Type Jupiter::CString_Type::getWord(const T *in, size_t pos, const T *whitespace) { - return Jupiter::CString_Strict::gotoWord(*this, pos, whitespace); + return Jupiter::String_Type::getWord(in, pos, whitespace); } -template Jupiter::CString_Strict Jupiter::CString_Strict::gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) +template Jupiter::CString_Type Jupiter::CString_Type::gotoWord(size_t pos, const T *whitespace) const { - unsigned int x = 0; - bool y = true; - for (unsigned int i = 0; i < pos || y == true; x++) - { - if (in.get(x) == 0) return Jupiter::CString_Strict(); - if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) - { - if (y != 1) - { - y = true; - i++; - } - } - else - { - if (i >= pos) break; - y = false; - } - } - return Jupiter::CString_Strict::substring(in, x); + return Jupiter::CString_Type::gotoWord(*this, pos, whitespace); } -template size_t Jupiter::CString_Strict::set(const String_Type &in) +template Jupiter::CString_Type Jupiter::CString_Type::gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) { - size_t sSize = in.size(); - if (Jupiter::String_Type::length < sSize) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = new T[sSize + 1]; - } - 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::gotoWord(in, pos, whitespace); +} + +template size_t Jupiter::CString_Type::set(const String_Type &in) +{ + this->setBufferSizeNoCopy(in.size()); + for (Jupiter::String_Type::length = 0; Jupiter::String_Type::length < in.size() && in.get(Jupiter::String_Type::length) != 0; Jupiter::String_Type::length++) + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.get(Jupiter::String_Type::length); return Jupiter::String_Type::length; } -template size_t Jupiter::CString_Strict::set(const std::basic_string &in) +template size_t Jupiter::CString_Type::set(const std::basic_string &in) { - size_t sSize = in.size(); - if (Jupiter::String_Type::length < sSize) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = new T[sSize + 1]; - } - 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; + this->setBufferSizeNoCopy(in.size()); + for (Jupiter::String_Type::length = 0; Jupiter::String_Type::length < in.size() && in.at(Jupiter::String_Type::length) != 0; Jupiter::String_Type::length++) + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.at(Jupiter::String_Type::length); + return Jupiter::String_Type::length; } -template size_t Jupiter::CString_Strict::set(const T *in) +template size_t Jupiter::CString_Type::set(const T *in) { - size_t sSize = Jupiter::strlen(in); - if (Jupiter::String_Type::length < sSize) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = new T[sSize + 1]; - } - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; - Jupiter::String_Type::length = sSize; - Jupiter::strcpy(Jupiter::String_Type::str, in); - return sSize; + Jupiter::String_Type::str[Jupiter::String_Type::set(in)] = 0; + return Jupiter::String_Type::length; } -template size_t Jupiter::CString_Strict::set(const T in) +template size_t Jupiter::CString_Type::set(const T in) { if (in == 0) { @@ -415,85 +320,60 @@ template size_t Jupiter::CString_Strict::set(const T in) *Jupiter::String_Type::str = 0; return Jupiter::String_Type::length = 0; } - if (Jupiter::String_Type::length < 1) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = new T[2]; - } - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + this->setBufferSizeNoCopy(1); *Jupiter::String_Type::str = in; Jupiter::String_Type::str[1] = 0; return Jupiter::String_Type::length = 1; } -template size_t Jupiter::CString_Strict::setString(T *in) -{ - return Jupiter::CString_Strict::setString(in, Jupiter::strlen(in)); -} - -template size_t Jupiter::CString_Strict::setString(T *in, size_t 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) +template size_t Jupiter::CString_Type::concat(const String_Type &in) { size_t nSize = Jupiter::String_Type::length + in.size(); - T *tmp = new T[nSize + 1]; - 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; + const T *inData = in.ptr(); + this->setBufferSize(nSize); + while (Jupiter::String_Type::length != nSize && *inData != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = *inData; + Jupiter::String_Type::length++; + inData++; + } + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; return Jupiter::String_Type::length; } -template size_t Jupiter::CString_Strict::concat(const std::basic_string &in) +template size_t Jupiter::CString_Type::concat(const std::basic_string &in) { 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::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; + const T *inData = in.data(); + this->setBufferSize(nSize); + while (Jupiter::String_Type::length != nSize && *inData != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = *inData; + Jupiter::String_Type::length++; + inData++; + } + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } -template size_t Jupiter::CString_Strict::concat(const T *in) +template size_t Jupiter::CString_Type::concat(const T *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::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; + this->setBufferSize(nSize); + Jupiter::strcpy(Jupiter::String_Type::str + Jupiter::String_Type::length, in); + return Jupiter::String_Type::length = nSize; } -template size_t Jupiter::CString_Strict::concat(const T c) +template size_t Jupiter::CString_Type::concat(const T c) { - 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::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; + this->setBufferSize(Jupiter::String_Type::length + 1); + Jupiter::String_Type::str[Jupiter::String_Type::length] = c; + Jupiter::String_Type::str[++Jupiter::String_Type::length] = 0; + return Jupiter::String_Type::length; } +template const Jupiter::CString_Type Jupiter::CString_Type::empty = Jupiter::CString_Type(); + /** * IMPLEMENTATION: * CString_Loose @@ -503,17 +383,23 @@ template Jupiter::CString_Loose::CString_Loose() : Jupiter::CStri { } -template Jupiter::CString_Loose::CString_Loose(size_t size) +template Jupiter::CString_Loose::CString_Loose(Jupiter::CString_Loose &&source) : Jupiter::CString_Type(std::move(source)) +{ + Jupiter::CString_Loose::strSize = source.strSize; + source.strSize = 0; +} + +template Jupiter::CString_Loose::CString_Loose(size_t len) : Jupiter::CString_Type::CString_Type(Jupiter::stringConstructorBase) { - if (size < Jupiter::CString_Loose::start_size) size = Jupiter::CString_Loose::start_size; - Jupiter::CString_Loose::strSize = size; + if (len < Jupiter::CString_Loose::start_size) Jupiter::CString_Loose::strSize = Jupiter::CString_Loose::start_size; + else Jupiter::CString_Loose::strSize = getPowerTwo32(len + 1); 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::String_Type::length = 0; } -template Jupiter::CString_Loose::CString_Loose(const Jupiter::CString_Loose &in) +template Jupiter::CString_Loose::CString_Loose(const Jupiter::CString_Loose &in) : Jupiter::CString_Type::CString_Type(Jupiter::stringConstructorBase) { Jupiter::CString_Loose::strSize = in.strSize; Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; @@ -522,30 +408,27 @@ template Jupiter::CString_Loose::CString_Loose(const Jupiter::CSt Jupiter::String_Type::length = in.length; } -template Jupiter::CString_Loose::CString_Loose(const Jupiter::String_Type &in) +template Jupiter::CString_Loose::CString_Loose(const Jupiter::String_Type &in) : Jupiter::CString_Loose::CString_Loose(in.size()) { - 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::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; + while (Jupiter::String_Type::length < in.size() && in.get(Jupiter::String_Type::length) != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.get(Jupiter::String_Type::length); + Jupiter::String_Type::length++; + } Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; } -template Jupiter::CString_Loose::CString_Loose(const std::basic_string &in) +template Jupiter::CString_Loose::CString_Loose(const std::basic_string &in) : Jupiter::CString_Loose::CString_Loose(in.size()) { - 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::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()); + while (Jupiter::String_Type::length < in.size() && in.at(Jupiter::String_Type::length) != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.at(Jupiter::String_Type::length); + Jupiter::String_Type::length++; + } + Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; } -template Jupiter::CString_Loose::CString_Loose(const T *in) +template Jupiter::CString_Loose::CString_Loose(const T *in) : Jupiter::CString_Type::CString_Type(Jupiter::stringConstructorBase) { if (in == nullptr) { @@ -566,121 +449,38 @@ template Jupiter::CString_Loose::CString_Loose(const T *in) } } -template Jupiter::CString_Loose::~CString_Loose() -{ - delete[] Jupiter::Shift_String_Type::base; -} - -template<> size_t inline Jupiter::CString_Loose::vformat(const char *format, va_list args) -{ - int minLen; - va_list sargs; - va_copy(sargs, args); - 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. - if ((unsigned)minLen > Jupiter::CString_Loose::strSize) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::CString_Loose::strSize = getPowerTwo32(minLen + 1); - Jupiter::Shift_String_Type::base = new char[Jupiter::CString_Loose::strSize]; - } - 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::String_Type::length] = 0; - return Jupiter::String_Type::length; -} - -template<> size_t inline Jupiter::CString_Loose::vformat(const wchar_t *format, va_list args) -{ - int minLen; - va_list sargs; - va_copy(sargs, args); - 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. - if ((unsigned)minLen > Jupiter::CString_Loose::strSize) - { - delete[] Jupiter::CString_Type::base; - Jupiter::CString_Loose::strSize = getPowerTwo32(minLen + 1); - Jupiter::CString_Type::base = new wchar_t[Jupiter::CString_Loose::strSize]; - } - Jupiter::String_Type::str = Jupiter::CString_Type::base; - Jupiter::String_Type::length = minLen; - vswprintf(Jupiter::String_Type::str, Jupiter::CString_Loose::strSize, format, args); - 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) -{ - return 0; -} - -template<> size_t inline Jupiter::CString_Loose::avformat(const char *format, va_list args) +template bool Jupiter::CString_Loose::setBufferSize(size_t len) { - int minLen; - va_list sargs; - va_copy(sargs, args); - 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::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::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::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) + len = getPowerTwo32(len + 1); + if (len > Jupiter::CString_Loose::strSize) { - Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + T *ptr = new T[len]; + for (unsigned int i = 0; i < Jupiter::String_Type::length; i++) ptr[i] = Jupiter::Shift_String_Type::str[i]; + ptr[Jupiter::String_Type::length] = 0; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = ptr; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + return true; } - 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::String_Type::length += minLen; - Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; - return minLen; + return false; } -template<> size_t inline Jupiter::CString_Loose::avformat(const wchar_t *format, va_list args) +template bool Jupiter::CString_Loose::setBufferSizeNoCopy(size_t len) { - int minLen; - va_list sargs; - va_copy(sargs, args); - 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::String_Type::length; - if ((unsigned)minLen + 1 > Jupiter::CString_Loose::strSize) + len = getPowerTwo32(len + 1); + if (len > Jupiter::CString_Loose::strSize) { - Jupiter::CString_Loose::strSize = getPowerTwo32(minLen + 1); - wchar_t *tmpStr = new wchar_t[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; - } - else if ((unsigned)minLen + 1 + (Jupiter::String_Type::str - Jupiter::CString_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::String_Type::length = 0; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new T[len]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + *Jupiter::String_Type::str = 0; + return true; } - 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::String_Type::length += minLen; - Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; - return minLen; -} - -template size_t Jupiter::CString_Loose::avformat(const T *format, va_list args) -{ - return 0; + Jupiter::String_Type::length = 0; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + *Jupiter::String_Type::str = 0; + return false; } template Jupiter::CString_Loose Jupiter::CString_Loose::Format(const T *format, ...) @@ -708,21 +508,32 @@ template Jupiter::CString_Loose Jupiter::CString_Loose::substr 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); + for (index = pos; 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 T *in, size_t pos) +{ + Jupiter::CString_Loose r = Jupiter::String_Type::substring(in, pos); + r.str[r.length] = 0; + return r; +} + template Jupiter::CString_Loose Jupiter::CString_Loose::substring(const Jupiter::String_Type &in, size_t pos, size_t len) { - if (pos > in.size()) return Jupiter::CString_Loose(); - if (len > in.size() - pos) len = in.size() - pos; + if (pos + len >= in.size()) return Jupiter::CString_Loose::substring(in, pos); Jupiter::CString_Loose r = Jupiter::CString_Loose(len); - size_t index; - for (index = 0; index != len && in.get(index + pos) != 0; index++) r.str[index] = in.get(index + pos); - r.str[index] = 0; - r.length = index; + for (r.length = 0; r.length != len && in.get(r.length + pos) != 0; r.length++) r.str[r.length] = in.get(r.length + pos); + r.str[r.length] = 0; + return r; +} + +template Jupiter::CString_Loose Jupiter::CString_Loose::substring(const T *in, size_t pos, size_t len) +{ + Jupiter::CString_Loose r = Jupiter::String_Type::substring(in, pos, len); + r.str[r.length] = 0; return r; } @@ -733,65 +544,12 @@ 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) { - 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); + return Jupiter::String_Type::getWord(in, pos, whitespace); } template Jupiter::CString_Loose Jupiter::CString_Loose::getWord(const T *in, size_t pos, const T *whitespace) { - Jupiter::CString_Loose r; - unsigned int x = 0; - unsigned int y = 1; - unsigned int i; - for (i = 0; i < pos || y == 1; x++) - { - if (in[x] == 0) return r; - if (Jupiter::strpbrk(whitespace, in[x]) != nullptr) - { - if (y != 1) - { - y = 1; - i++; - } - } - else - { - if (i >= pos) break; - y = 0; - } - } - for (y = x; Jupiter::strpbrk(whitespace, in[y]) == nullptr && in[y] != 0; y++); - r.length = y - x; - r.strSize = getPowerTwo32(r.length + 1); - delete[] r.base; - r.base = new T[r.strSize]; - r.str = r.base; - for (i = 0; x < y; i++) - { - r.str[i] = in[x]; - x++; - } - r.str[i] = 0; - return r; + return Jupiter::String_Type::getWord(in, pos, whitespace); } template Jupiter::CString_Loose Jupiter::CString_Loose::gotoWord(size_t pos, const T *whitespace) const @@ -801,193 +559,9 @@ 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) { - unsigned int x = 0; - bool y = true; - for (unsigned int i = 0; i < pos || y == true; x++) - { - if (in.get(x) == 0) return Jupiter::CString_Loose(); - if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) - { - if (y == false) - { - y = true; - i++; - } - } - else - { - if (i >= pos) break; - y = false; - } - } - return Jupiter::CString_Loose::substring(in, x); -} - -template size_t Jupiter::CString_Loose::set(const CString_Loose &in) -{ - if (Jupiter::CString_Loose::strSize <= in.length) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::CString_Loose::strSize = in.strSize; - Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; - } - 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::String_Type::length; -} - -template size_t Jupiter::CString_Loose::set(const String_Type &in) -{ - size_t sSize = in.size() + 1; - if (Jupiter::CString_Loose::strSize < sSize) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::CString_Loose::strSize = getPowerTwo32(sSize); - Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; - } - 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) -{ - size_t sSize = in.size() + 1; - if (Jupiter::CString_Loose::strSize < sSize) - { - delete[] Jupiter::Shift_String_Type::base; - Jupiter::CString_Loose::strSize = getPowerTwo32(sSize); - Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; - } - 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::String_Type::length; -} - -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::Shift_String_Type::base; - Jupiter::CString_Loose::strSize = getPowerTwo32(sSize); - Jupiter::Shift_String_Type::base = new T[Jupiter::CString_Loose::strSize]; - } - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; - Jupiter::String_Type::length = sSize - 1; - Jupiter::strcpy(Jupiter::String_Type::str, in); - return Jupiter::String_Type::length; -} - -template size_t Jupiter::CString_Loose::set(const T in) -{ - if (in == 0) - { - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; - *Jupiter::String_Type::str = 0; - return Jupiter::String_Type::length = 0; - } - 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; + return Jupiter::String_Type::gotoWord(in, pos, whitespace); } -template size_t Jupiter::CString_Loose::concat(const String_Type &in) -{ - 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::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::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) - { - Jupiter::strcpy(Jupiter::Shift_String_Type::base, Jupiter::String_Type::str); - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; - } - 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::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::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::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) - { - 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::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::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::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::Shift_String_Type::base) > Jupiter::CString_Loose::strSize) - { - 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::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::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::Shift_String_Type::base; - Jupiter::Shift_String_Type::base = tmp; - Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; - } - else if (Jupiter::String_Type::length + 1 + (Jupiter::String_Type::str - Jupiter::Shift_String_Type::base) >= Jupiter::CString_Loose::strSize) - { - 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::String_Type::length] = in; - Jupiter::String_Type::length++; - Jupiter::String_Type::str[Jupiter::String_Type::length] = 0; - return Jupiter::String_Type::length; -} +template const Jupiter::CString_Loose Jupiter::CString_Loose::empty = Jupiter::CString_Loose(); #endif // _CSTRING_IMP_H_HEADER \ No newline at end of file diff --git a/Jupiter/File.cpp b/Jupiter/File.cpp index fdbe8c7..4934b79 100644 --- a/Jupiter/File.cpp +++ b/Jupiter/File.cpp @@ -28,7 +28,7 @@ int64_t getFileSize(const char *file) const size_t defaultBufferSize = 8192; -template class JUPITER_API Jupiter::CString_Strict; +template class JUPITER_API Jupiter::CString_Type; struct JUPITER_API Jupiter::File::Data { diff --git a/Jupiter/IRC_Client.cpp b/Jupiter/IRC_Client.cpp index e234053..78fc326 100644 --- a/Jupiter/IRC_Client.cpp +++ b/Jupiter/IRC_Client.cpp @@ -30,7 +30,7 @@ Jupiter::INIFile _Config; Jupiter::INIFile *Jupiter::IRC::Client::Config = &_Config; -template class JUPITER_API Jupiter::CString_Strict; +template class JUPITER_API Jupiter::CString_Type; template class JUPITER_API Jupiter::ArrayList; template class JUPITER_API Jupiter::ArrayList; diff --git a/Jupiter/Jupiter.vcxproj b/Jupiter/Jupiter.vcxproj index 62616cf..adacc60 100644 --- a/Jupiter/Jupiter.vcxproj +++ b/Jupiter/Jupiter.vcxproj @@ -74,6 +74,8 @@ %(AdditionalIncludeDirectories) Async Speed + 4505 + true Console @@ -133,8 +135,13 @@ + + + + + diff --git a/Jupiter/Jupiter.vcxproj.filters b/Jupiter/Jupiter.vcxproj.filters index 1e27077..2ca4bfb 100644 --- a/Jupiter/Jupiter.vcxproj.filters +++ b/Jupiter/Jupiter.vcxproj.filters @@ -57,9 +57,6 @@ Source Files\IRC - - Source Files\IRC - Source Files\IRC @@ -102,6 +99,9 @@ Source Files + + Source Files\IRC + @@ -188,6 +188,21 @@ Header Files + + Header Files\Strings + + + Header Files\Strings + + + Header Files\Strings + + + Header Files\Strings + + + Header Files\Strings + diff --git a/Jupiter/Shift_String.h b/Jupiter/Shift_String.h index 2314936..c030286 100644 --- a/Jupiter/Shift_String.h +++ b/Jupiter/Shift_String.h @@ -62,7 +62,41 @@ namespace Jupiter */ virtual bool remove(const T &value); + /** + * @brief Default constructor for the Shift_String_Type class. + */ + Shift_String_Type() {} + + /** + * @brief Move constructor for the Shift_String_Type class. + */ + Shift_String_Type(Jupiter::Shift_String_Type &&source); + + /** + * @brief Destructor for the Shift_String_Type class. + */ + virtual ~Shift_String_Type(); + protected: + + /** + * @brief Sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSize(size_t len); + + /** + * @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This still empties the string if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSizeNoCopy(size_t len); + T *base; /** Base pointer for the underlying String's memory allocation */ }; } diff --git a/Jupiter/Shift_String_Imp.h b/Jupiter/Shift_String_Imp.h index e80fda3..d807d5c 100644 --- a/Jupiter/Shift_String_Imp.h +++ b/Jupiter/Shift_String_Imp.h @@ -24,6 +24,17 @@ * Note: Modification of this file is not supported in any way. */ +template Jupiter::Shift_String_Type::Shift_String_Type(Jupiter::Shift_String_Type &&source) : Jupiter::String_Type(std::move(source)) +{ + Jupiter::Shift_String_Type::base = source.base; + source.base = nullptr; +} + +template Jupiter::Shift_String_Type::~Shift_String_Type() +{ + if (Jupiter::Shift_String_Type::base != nullptr) delete[] Jupiter::Shift_String_Type::base; +} + template size_t Jupiter::Shift_String_Type::shiftLeft(size_t len) { size_t offset = Jupiter::String_Type::str - Jupiter::Shift_String_Type::base; @@ -53,4 +64,33 @@ template bool Jupiter::Shift_String_Type::remove(const T &value) return Jupiter::String_Type::remove(value); } +template bool Jupiter::Shift_String_Type::setBufferSize(size_t len) +{ + if (len > Jupiter::String_Type::length) + { + T *ptr = new T[len]; + for (unsigned int i = 0; i < Jupiter::String_Type::length; i++) ptr[i] = Jupiter::String_Type::str[i]; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = ptr; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + return true; + } + return false; +} + +template bool Jupiter::Shift_String_Type::setBufferSizeNoCopy(size_t len) +{ + if (len > Jupiter::String_Type::length) + { + Jupiter::String_Type::length = 0; + delete[] Jupiter::Shift_String_Type::base; + Jupiter::Shift_String_Type::base = new T[len]; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + return true; + } + Jupiter::String_Type::length = 0; + Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; + return false; +} + #endif // _SHIFT_STRING_IMP_H_HEADER \ No newline at end of file diff --git a/Jupiter/String_Type.h b/Jupiter/String_Type.h index a7de4d4..358ee13 100644 --- a/Jupiter/String_Type.h +++ b/Jupiter/String_Type.h @@ -232,10 +232,10 @@ namespace Jupiter * @param in String containing the data to be copied. * @return New size of the String. */ - virtual size_t set(const String_Type &in) = 0; - virtual size_t set(const std::basic_string &in) = 0; - virtual size_t set(const T *in) = 0; - virtual size_t set(const T in) = 0; + virtual size_t set(const String_Type &in); + virtual size_t set(const std::basic_string &in); + virtual size_t set(const T *in); + virtual size_t set(const T in); /** * @brief Copies the data from the input string and concatenates it to the end of String. @@ -243,16 +243,66 @@ namespace Jupiter * @param in String containing the data to be concatenated. * @return New size of the CString. */ - virtual size_t concat(const String_Type &in) = 0; - virtual size_t concat(const std::basic_string &in) = 0; - virtual size_t concat(const T *in) = 0; - virtual size_t concat(const T in) = 0; + virtual size_t concat(const String_Type &in); + virtual size_t concat(const std::basic_string &in); + virtual size_t concat(const T *in); + virtual size_t concat(const T in); + + /** + * @brief Copies a part of an input string and returns it in an output type. + * + * @param R Type to return. Must be a subclass of String_Type. + * + * @param in String to get a partial copy of. + * @param pos Position to start copying from. + * @return Partial copy of the input string. + */ + template class R> static R substring(const Jupiter::String_Type &in, size_t pos); + template class R> static R substring(const T *in, size_t pos); + + /** + * @brief Copies a part of an input string and returns it in an output type. + * + * @param R Type to return. Must be a subclass of String_Type. + * + * @param in String to get a partial copy of. + * @param pos Position to start copying from. + * @param len Number of elements to copy. + * @return Partial copy of the input string. + */ + template class R> static R substring(const Jupiter::String_Type &in, size_t pos, size_t len); + template class R> static R substring(const T *in, size_t pos, size_t len); + + /** + * @brief Copies a "word" from an input string and returns it in an output type. + * + * @param R Type to return. Must be a subclass of String_Type. + * + * @param in String to get a partial copy of. + * @param pos Index of the word to copy. + * @param whitespace String of characters that are to be considered whitespace. + * @return Copy of the word at the specified index on success, an empty string otherwise. + */ + template class R> static R getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); + template class R> static R getWord(const T *in, size_t pos, const T *whitespace); + + /** + * @brief Copies a part of an input string starting at a specified "word" and returns it in an output type. + * + * @param R Type to return. Must be a subclass of String_Type. + * + * @param in String to get a partial copy of. + * @param pos Index of the word to start copying from. + * @param whitespace String of characters that are to be considered whitespace. + * @return Copy of the string starting at the specified word on success, an empty string otherwise. + */ + template class R> static R gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace); + template class R> static R gotoWord(const T *in, size_t pos, const T *whitespace); /** Access operator */ inline T &operator[](size_t index) { return Jupiter::String_Type::get(index); }; - // Mutative operators. - // Note: All extending classes must overload operator= for its own type. + /** Mutative operators */ inline String_Type &operator+=(const String_Type &right) { this->concat(right); return *this; }; inline String_Type &operator+=(const std::basic_string &right) { this->concat(right); return *this; }; inline String_Type &operator+=(const T *right) { this->concat(right); return *this; }; @@ -263,7 +313,7 @@ namespace Jupiter inline String_Type &operator=(const T *right) { this->set(right); return *this; }; inline String_Type &operator=(const T right) { this->set(right); return *this; }; - // Comparative operators. + /** Comparative operators */ inline bool operator==(const String_Type &right)const{ return this->equals(right); } inline bool operator==(const std::basic_string &right)const{ return this->equals(right); } inline bool operator==(const T *right)const{ return this->equals(right); } @@ -289,6 +339,16 @@ namespace Jupiter inline bool operator>=(const T *right)const{ return !operator<(right); } inline bool operator>=(const T right)const{ return !operator<(right); } + /** + * @brief Default constructor for the String_Type class. + */ + String_Type() {} + + /** + * @brief Move constructor for the String_Type class. + */ + String_Type(Jupiter::String_Type &&source); + /** * The following constructors should exist: * A default constructor @@ -299,6 +359,25 @@ namespace Jupiter */ protected: + + /** + * @brief Sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSize(size_t len) = 0; + + /** + * @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements. + * Note: This does nothing if len is less than the string's current length. + * + * @param len Minimum number of elements the string buffer must be able to hold. + * @return True if a new buffer was allocated, false otherwise. + */ + virtual bool setBufferSizeNoCopy(size_t len) = 0; + T *str; /** Pointer for the underlying string of elements */ size_t length; /** Number of representable elements in the string */ }; diff --git a/Jupiter/String_Type_Imp.h b/Jupiter/String_Type_Imp.h index 09abe8d..7bdc687 100644 --- a/Jupiter/String_Type_Imp.h +++ b/Jupiter/String_Type_Imp.h @@ -32,6 +32,12 @@ * String_Type */ +template Jupiter::String_Type::String_Type(Jupiter::String_Type &&source) +{ + Jupiter::String_Type::str = source.str; + source.str = nullptr; +} + template T &Jupiter::String_Type::get(size_t index) const { return Jupiter::String_Type::str[index]; @@ -74,7 +80,19 @@ template int Jupiter::String_Type::compare(const Jupiter::String_ template int Jupiter::String_Type::compare(const std::basic_string &in) const { - return Jupiter::String_Type::compare(in.c_str()); + // 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 @@ -126,7 +144,14 @@ template bool Jupiter::String_Type::equals(const Jupiter::String_ 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()); + // 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 @@ -152,35 +177,54 @@ template bool Jupiter::String_Type::equals(std::nullptr_t) const // 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 false; // Concept of "case" not supported for type. + return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. } -template<> bool inline Jupiter::String_Type::equalsi(const Jupiter::String_Type &in) const +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.str[index])) return false; + if (toupper(Jupiter::String_Type::str[index]) != toupper(in.at(index))) return false; } return true; } -template<> bool inline Jupiter::String_Type::equalsi(const Jupiter::String_Type &in) const +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.str[index])) return false; + 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 { - if (Jupiter::String_Type::length != in.size()) return false; - return Jupiter::String_Type::equalsi(in.c_str()); + return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. } template<> bool inline Jupiter::String_Type::equalsi(const char *in) const @@ -207,7 +251,7 @@ template<> bool inline Jupiter::String_Type::equalsi(const wchar_t *in) template bool Jupiter::String_Type::equalsi(const T *in) const { - return false; // Concept of "case" not supported for type. + return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. } template<> bool inline Jupiter::String_Type::equalsi(const char &in) const @@ -222,7 +266,7 @@ template<> bool inline Jupiter::String_Type::equalsi(const wchar_t &in) template bool Jupiter::String_Type::equalsi(const T &in) const { - return false; // Concept of "case" not supported for type. + return Jupiter::String_Type::equals(in); // Concept of "case" not supported for type. } template bool Jupiter::String_Type::equalsi(const std::nullptr_t) const @@ -232,11 +276,6 @@ template bool Jupiter::String_Type::equalsi(const std::nullptr_t) // 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; @@ -297,9 +336,74 @@ template<> bool inline Jupiter::String_Type::match(const Jupiter::Strin 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 Jupiter::String_Type::match(format.c_str()); + return false; // Wildcard matching not supported for type. } template<> inline bool Jupiter::String_Type::match(const char *format) const @@ -362,7 +466,7 @@ template<> inline bool Jupiter::String_Type::match(const wchar_t *forma template bool Jupiter::String_Type::match(const T *format) const { - return false; // Type is not comparable to wildcards. + return false; // Wildcard matching not supported for type. } // matchi() @@ -433,12 +537,76 @@ template<> bool inline Jupiter::String_Type::matchi(const Jupiter::Stri template bool Jupiter::String_Type::matchi(const Jupiter::String_Type &format) const { - return false; + 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 Jupiter::String_Type::matchi(format.c_str()); + 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 @@ -505,7 +673,7 @@ template<> bool inline Jupiter::String_Type::matchi(const wchar_t *form 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. + return false; // Wildcard matching not supported for type. Concept of "case" not supported for type. } // wordCount() @@ -582,7 +750,6 @@ 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; } @@ -692,4 +859,231 @@ template bool Jupiter::String_Type::remove(const T &value) return false; } +template size_t Jupiter::String_Type::set(const String_Type &in) +{ + this->setBufferSizeNoCopy(in.size()); + for (Jupiter::String_Type::length = 0; Jupiter::String_Type::length < in.size() != 0; Jupiter::String_Type::length++) + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.get(Jupiter::String_Type::length); + return Jupiter::String_Type::length; +} + +template size_t Jupiter::String_Type::set(const std::basic_string &in) +{ + this->setBufferSizeNoCopy(in.size()); + for (Jupiter::String_Type::length = 0; Jupiter::String_Type::length < in.size(); Jupiter::String_Type::length++) + Jupiter::String_Type::str[Jupiter::String_Type::length] = in.at(Jupiter::String_Type::length); + return Jupiter::String_Type::length; +} + +template size_t Jupiter::String_Type::set(const T *in) +{ + size_t nLen = Jupiter::strlen(in); + this->setBufferSizeNoCopy(nLen); + for (Jupiter::String_Type::length = 0; *in != 0; Jupiter::String_Type::length++, in++) Jupiter::String_Type::str[Jupiter::String_Type::length] = *in; + return Jupiter::String_Type::length; +} + +template size_t Jupiter::String_Type::set(const T in) +{ + this->setBufferSizeNoCopy(1); + *Jupiter::String_Type::str = in; + return Jupiter::String_Type::length = 1; +} + +template size_t Jupiter::String_Type::concat(const String_Type &in) +{ + size_t nSize = Jupiter::String_Type::length + in.size(); + const T *inData = in.ptr(); + this->setBufferSize(nSize); + while (Jupiter::String_Type::length != nSize) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = *inData; + Jupiter::String_Type::length++; + inData++; + } + return Jupiter::String_Type::length; +} + +template size_t Jupiter::String_Type::concat(const std::basic_string &in) +{ + size_t nSize = Jupiter::String_Type::length + in.size(); + const T *inData = in.data(); + this->setBufferSize(nSize); + while (Jupiter::String_Type::length != nSize) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = *inData; + Jupiter::String_Type::length++; + inData++; + } + return Jupiter::String_Type::length; +} + +template size_t Jupiter::String_Type::concat(const T *in) +{ + size_t nSize = Jupiter::String_Type::length + Jupiter::strlen(in); + this->setBufferSize(nSize); + while (*in != 0) + { + Jupiter::String_Type::str[Jupiter::String_Type::length] = *in; + Jupiter::String_Type::length++; + in++; + } + return Jupiter::String_Type::length; +} + +template size_t Jupiter::String_Type::concat(const T c) +{ + this->setBufferSize(Jupiter::String_Type::length + 1); + Jupiter::String_Type::str[Jupiter::String_Type::length] = c; + return ++Jupiter::String_Type::length; +} + +/** +* IMPLEMENTATION: +* String helper templates +*/ + +// substring + +template template class R> R Jupiter::String_Type::substring(const Jupiter::String_Type &in, size_t pos) +{ + if (pos >= in.size()) return R(); + R r = R(in.size() - pos); + for (r.length = 0; pos + r.length != in.size(); r.length++) r.str[r.length] = in.get(pos + r.length); + return r; +} + +template template class R> R Jupiter::String_Type::substring(const Jupiter::String_Type &in, size_t pos, size_t len) +{ + if (pos + len >= in.size()) return R::substring(in, pos); + R r = R(len); + for (r.length = 0; r.length != len; r.length++) r.str[r.length] = in.get(pos + r.length); + return r; +} + +template template class R> R Jupiter::String_Type::substring(const T *in, size_t pos) +{ + size_t strLen = Jupiter::strlen(in); + if (pos >= strLen) return R(); + R r = R(strLen - pos); + in += pos; + for (r.length = 0; *in != 0; r.length++, in++) r.str[r.length] = *in; + return r; +} + +template template class R> R Jupiter::String_Type::substring(const T *in, size_t pos, size_t len) +{ + R r = R(len); + in += pos; + for (r.length = 0; r.length != len; r.length++, in++) r.str[r.length] = *in; + return r; +} + +// getWord + +template template class R> R Jupiter::String_Type::getWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) +{ + unsigned int x = 0; + unsigned int y = 1; + for (unsigned int i = 0; i < pos || y == 1; x++) + { + if (x == in.size()) return R(); + if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) + { + if (y != 1) + { + y = 1; + i++; + } + } + else + { + if (i >= pos) break; + y = 0; + } + } + for (y = x; y != in.size() && Jupiter::strpbrk(whitespace, in.get(y)) == nullptr; y++); + return R::substring(in, x, y - x); +} + +template template class R> R Jupiter::String_Type::getWord(const T *in, size_t pos, const T *whitespace) +{ + unsigned int x = 0; + unsigned int y = 1; + for (unsigned int i = 0; i < pos || y == 1; x++) + { + if (in[x] == 0) return R(); + if (Jupiter::strpbrk(whitespace, in[x]) != nullptr) + { + if (y != 1) + { + y = 1; + i++; + } + } + else + { + if (i >= pos) break; + y = 0; + } + } + for (y = x; in[y] != 0 && Jupiter::strpbrk(whitespace, in[y]) == nullptr; y++); + return R::substring(in, x, y - x); +} + +// gotoWord + +template template class R> R Jupiter::String_Type::gotoWord(const Jupiter::String_Type &in, size_t pos, const T *whitespace) +{ + unsigned int x = 0; + bool y = true; + for (unsigned int i = 0; i < pos || y == true; x++) + { + if (x == in.size()) return R(); + if (Jupiter::strpbrk(whitespace, in.get(x)) != nullptr) + { + if (y != true) + { + y = true; + i++; + } + } + else + { + if (i >= pos) break; + y = false; + } + } + return R::substring(in, x); +} + +template template class R> R Jupiter::String_Type::gotoWord(const T *in, size_t pos, const T *whitespace) +{ + unsigned int x = 0; + bool y = true; + for (unsigned int i = 0; i < pos || y == true; x++) + { + if (in[x] == 0) return R(); + if (Jupiter::strpbrk(whitespace, in[x]) != nullptr) + { + if (y != true) + { + y = true; + i++; + } + } + else + { + if (i >= pos) break; + y = false; + } + } + return R::substring(in, x); +} + +namespace Jupiter +{ + static struct String_Constructor_Base {} stringConstructorBase; +} + #endif // _STRING_TYPE_IMP_H_HEADER \ No newline at end of file diff --git a/Release/Jupiter.lib b/Release/Jupiter.lib index a6b98c1..62187fc 100644 Binary files a/Release/Jupiter.lib and b/Release/Jupiter.lib differ diff --git a/Tester/Tester.vcxproj b/Tester/Tester.vcxproj index e055047..b825fc1 100644 --- a/Tester/Tester.vcxproj +++ b/Tester/Tester.vcxproj @@ -73,6 +73,7 @@ true true true + MachineX86