sources/mystring.h

Sat, 23 Jul 2016 12:35:43 +0300

author
Teemu Piippo <teemu@compsta2.com>
date
Sat, 23 Jul 2016 12:35:43 +0300
branch
protocol5
changeset 170
40d8d7231a36
parent 159
970d58a01e8b
child 195
be953e1621d9
permissions
-rw-r--r--

Reduce delta between branches

/*
	Copyright 2014 - 2016 Teemu Piippo
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions
	are met:

	1. Redistributions of source code must retain the above copyright
	   notice, this list of conditions and the following disclaimer.
	2. Redistributions in binary form must reproduce the above copyright
	   notice, this list of conditions and the following disclaimer in the
	   documentation and/or other materials provided with the distribution.
	3. Neither the name of the copyright holder nor the names of its
	   contributors may be used to endorse or promote products derived from
	   this software without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
	PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
	OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once
#include <deque>
#include <string>
#include <stdarg.h>
#include "basics.h"
#include "list.h"

BEGIN_ZFC_NAMESPACE


class String
{
public:
	typedef std::string::iterator Iterator;
	typedef std::string::const_iterator ConstIterator;

	String();
	String(char a);
	String(const char* data);
	String(const std::string& data);
	String(const Vector<char>& data);

	void                        append(const char* text);
	void                        append(char character);
	void                        append(const String& text);
	ConstIterator               begin() const;
	Iterator                    begin();
	int                         compare(const String &other) const;
	int                         count(char character) const;
	const char*                 chars() const;
	void                        clear();
	ConstIterator               end() const;
	Iterator                    end();
	bool                        endsWith(const String &other) const;
	int                         find(const char* subString, int startingPosition = 0) const;
	int                         find(char character, int startingPosition = 0) const;
	int                         indexDifference(int a, int b);
	void                        insert(int position, char character);
	void                        insert(int position, const char* string);
	bool                        isEmpty() const;
	bool                        isNumeric() const;
	void                        modifyIndex(int &a) const;
	int                         findLast(const char* subString, int startingPosition = -1) const;
	int                         length() const;
	bool                        maskAgainst(const String &pattern) const;
	String                      md5() const;
	String                      mid(int rangeBegin, int rangeEnd) const;
	void                        normalize(int(*filter)(int) = &isspace);
	String                      normalized(int(*filter)(int) = &isspace) const;
	void                        prepend(String text);
	void                        remove(int position, int length);
	void                        removeAt(int position);
	void                        removeFromEnd(int length);
	void                        removeFromStart(int length);
	void                        replace(const char* text, const char* replacement);
	void                        replace(int position, int amount, const String &text);
	String                      right(int length) const;
	void                        shrinkToFit();
	class StringList            split(const String &delimeter) const;
	class StringList            split(char delimeter) const;
	void __cdecl                sprintf(const char* fmtstr, ...);
	bool                        startsWith(const String &other) const;
	const std::string&          stdString() const;
	void                        strip(char unwanted);
	void                        strip(const List<char> &unwanted);
	const unsigned char*        toBytes() const;
	double                      toDouble(bool* ok = nullptr) const;
	float                       toFloat(bool* ok = nullptr) const;
	long                        toInt(bool* ok = nullptr, int base = 10) const;
	String                      toLowerCase() const;
	String                      toUpperCase() const;
	void                        vsprintf(const char* fmtstr, va_list args);

	static String               fromNumber(short int a);
	static String               fromNumber(int a);
	static String               fromNumber(long int a);
	static String               fromNumber(unsigned short int a);
	static String               fromNumber(unsigned int a);
	static String               fromNumber(unsigned long int a);
	static String               fromNumber(double a);
	static String               fromBytes(const ByteArray& bytes);

	String                      operator+(const String& data) const;
	String                      operator+(const char* data) const;
	String                      operator+(int num) const;
	String&                     operator+=(const String& data);
	String&                     operator+=(const char* data);
	String&                     operator+=(int num);
	String&                     operator+=(char data);
	char&                       operator[](int i);
	char                        operator[](int i) const;
	bool                        operator==(const String& other) const;
	bool                        operator==(const char* other) const;
	bool                        operator!=(const String& other) const;
	bool                        operator!=(const char* other) const;
	bool                        operator>(const String& other) const;
	bool                        operator<(const String& other) const;
	bool                        operator>=(const String& other) const;
	bool                        operator<=(const String& other) const;
	                            operator const char*() const;
	                            operator const std::string&() const;

private:
	std::string m_string;
};


class StringList : public List<String>
{
public:
	StringList();
	StringList(int numvalues);
	StringList(const List<String>& other);
	String join(const String& delim);
};


inline bool operator==(const char* a, const String& b);
inline String operator+(const char* a, const String& b);

// --------------------------------------------------------------------------------------------------------------------

/*!
 * \brief Constructs an empty string.
 */
inline String::String() {}

/*!
 * \brief Constructs a string from a single character.
 * \param character Character to create a string out of.
 */
inline String::String(char character)
{
	char buffer[2] = { character, '\0' };
	m_string = buffer;
}

/*!
 * \brief Constructs a string from a char-array.
 * \param string char-array to convert.
 */
inline String::String(const char* string) :
	m_string(string) {}

/*!
 * \brief Constructs a string out of a \c std::string .
 * \param string \c std::string to base the construction on.
 */
inline String::String(const std::string& string) :
	m_string(string) {}

/*!
 * \brief Constructs a string out of a vector of characters. The vector does not have to be null-terminated.
 * \param charVector Vector of characters to construct the string out of.
 */
inline String::String(const Vector<char>& charVector) :
	m_string(charVector.data(), charVector.size()) {}

/*!
 * \returns a constant iterator to the beginning of the string.
 */
inline String::ConstIterator String::begin() const
{
	return m_string.cbegin();
}

/*!
 * \returns the string's contents as a char-array.
 */
inline const char* String::chars() const
{
	return m_string.c_str();
}

/*!
 * \returns the string's constant end-iterator.
 */
inline String::ConstIterator String::end() const
{
	return m_string.end();
}

/*!
 * \returns whether or not the string is empty.
 */
inline bool String::isEmpty() const
{
	return m_string[0] == '\0';
}

/*!
 * \returns the length of the string.
 */
inline int String::length() const
{
	return m_string.length();
}

/*!
 * \returns the underlying \c std::string .
 */
inline const std::string& String::stdString() const
{
	return m_string;
}

/*!
 * \brief Adds text from a char-array to the end of the string.
 * \param text Text to append.
 */
inline void String::append(const char* text)
{
	m_string.append(text);
}

/*!
 * \brief Adds text to the end of the string.
 * \param text Text to append.
 */
inline void String::append(char character)
{
	m_string.push_back(character);
}

/*!
 * \brief Adds text from another string to the end of this string.
 * \param text Text to append.
 */
inline void String::append(const String& text)
{
	m_string.append(text.chars());
}

/*!
 * \returns a mutable iterator to the beginning of the string.
 */
inline String::Iterator String::begin()
{
	return m_string.begin();
}

/*!
 * \brief Clears the string.
 */
inline void String::clear()
{
	m_string.clear();
}

/*!
 * \returns the string's mutable end-iterator.
 */
inline String::Iterator String::end()
{
	return m_string.end();
}

/*!
 * \brief Compares two string indices, supporting negatives as offsets from the end of string.
 * \param a First index to compare
 * \param b Second index to compare
 * \returns the difference of two indices.
 */
inline int String::indexDifference(int a, int b)
{
	modifyIndex(a);
	modifyIndex(b);
	return b - a;
}

/*!
 * \brief Inserts a character into the string.
 * \param position Position in the string where to insert the character into.
 * \param character Character to insert into the string.
 */
inline void String::insert(int position, char character)
{
	m_string.insert(m_string.begin() + position, character);
}

/*!
 * \brief Inserts a substring into the string.
 * \param position Position in the string where to insert the substring.
 * \param string Substring to insert.
 */
inline void String::insert(int position, const char* string)
{
	m_string.insert(position, string);
}

/*!
 * \brief Modifies the given index so that if it is negative, it is translated into a positive index starting from the
 *        end of the string. For example, an index of -1 will be modified to point to the last character in the string,
 *        -2 to the second last, etc.
 * \param index Index to translate.
 */
inline void String::modifyIndex(int& index) const
{
	if (index < 0)
		index = length() - index;
}

/*!
 * \brief Prepends the given text to the beginning of the string.
 * \param text Text to prepend.
 */
inline void String::prepend(String text)
{
	m_string = (text + m_string).stdString();
}

/*!
 * \brief Removes a range of text from the string.
 * \param position Position where to start removing text.
 * \param length Amount of characters to remove.
 */
inline void String::remove(int position, int length)
{
	m_string.replace(position, length, "");
}

/*!
 * \brief Removes a single character from the string.
 * \param position Position of the character to remove string from.
 */
inline void String::removeAt(int position)
{
	m_string.erase(m_string.begin() + position);
}

/*!
 * \brief Removes a number of characters from the end of the string.
 * \param length Amount of characters to remove.
 */
inline void String::removeFromEnd(int length)
{
	remove(this->length() - length, length);
}

/*!
 * \brief Removes a number of characters from the beginning of the string.
 * \param length Amount of characters to remove.
 */
inline void String::removeFromStart(int length)
{
	remove(0, length);
}

/*!
 * \brief Replaces a range of text in the string with another.
 * \param position Position where to start replacing text.
 * \param amount Amount of characters to replace.
 * \param text Replacement string.
 */
inline void String::replace(int position, int amount, const String& text)
{
	m_string.replace(position, amount, text.chars());
}

/*!
 * \brief Shrinks the string so that it does not allocate more characters than necessary.
 */
inline void String::shrinkToFit()
{
	m_string.shrink_to_fit();
}

/*!
 * \brief Converts a number into a string, and returns a new string with the number appended to the end of the string.
 * \param number Number to convert and append.
 * \returns the resulting string.
 */
inline String String::operator+(int number) const
{
	return *this + String::fromNumber(number);
}

/*!
 * \brief Appends text into the string.
 * \param text Text to append.
 * \returns a reference to this string.
 */
inline String& String::operator+=(const String& text)
{
	append(text);
	return *this;
}

/*!
 * \brief Appends text into the string.
 * \param text Text to append.
 * \returns a reference to this string.
 */
inline String& String::operator+=(const char* text)
{
	append(text);
	return *this;
}

/*!
 * \brief Converts a number into a string, and appends it into this string.
 * \param number The number to append.
 * \returns a refence to this string.
 */
inline String& String::operator+=(int number)
{
	return operator+=(String::fromNumber(number));
}

/*!
 * \brief Appends a character into this string.
 * \param character The character to append.
 * \return a reference to this string.
 */
inline String& String::operator+=(char character)
{
	append(character);
	return *this;
}

/*!
 * \param index Index referring to a character of this string.
 * \returns an editable reference to the character pointed by the given index.
 */
inline char& String::operator[](int index)
{
	return m_string[index];
}

/*!
 * \param index Index referring to a character of this string.
 * \returns an const reference to the character pointed by the given index.
 */
inline char String::operator[](int index) const
{
	return m_string[index];
}

/*!
 * \param other String to compare with.
 * \returns whether or not this string is the same as the other string.
 */
inline bool String::operator==(const String& other) const
{
	return stdString() == other.stdString();
}

/*!
 * \param other String to compare with.
 * \returns whether or not this string is the same as the other string.
 */
inline bool String::operator==(const char* other) const
{
	return m_string == other;
}

/*!
 * \param other String to compare with.
 * \returns whether or not this string is different than the other string.
 */
inline bool String::operator!=(const String& other) const
{
	return stdString() != other.stdString();
}

/*!
 * \param other String to compare with.
 * \returns whether or not this string is different than the other string.
 */
inline bool String::operator!=(const char* other) const
{
	return m_string != other;
}

/*!
 * \param other String to compare with.
 * \return whether or not this string is lexicographically greater than the other string.
 */
inline bool String::operator>(const String& other) const
{
	return stdString() > other.stdString();
}

/*!
 * \param other String to compare with.
 * \return whether or not this string is lexicographically lesser than the other string.
 */
inline bool String::operator<(const String& other) const
{
	return stdString() < other.stdString();
}

/*!
 * \param other String to compare with.
 * \return whether or not this string is lexicographically at least as great as the other string.
 */
inline bool String::operator>=(const String& other) const
{
	return stdString() >= other.stdString();
}

/*!
 * \param other String to compare with.
 * \return whether or not this string is lexicographically at most as great as the other string.
 */
inline bool String::operator<=(const String& other) const
{
	return stdString() <= other.stdString();
}

/*!
 * \returns a char-array representation of this string.
 */
inline String::operator const char*() const
{
	return chars();
}

/*!
 * \returns the underlying \c std::string of this string.
 */
inline String::operator const std::string&() const
{
	return stdString();
}

/*!
 * \returns the underlying char-array representation of this string, casted to unsigned chars.
 */
inline const unsigned char* String::toBytes() const
{
	return reinterpret_cast<const unsigned char*>(chars());
}

/*!
 * \brief Constructs an empty string list.
 */
inline StringList::StringList() {}

/*!
 * \brief Constructs a string list containing \c numvalues empty strings.
 * \param numvalues Amount of empty strings to fill.
 */
inline StringList::StringList(int numvalues) :
	List<String>(numvalues) {}

/*!
 * \brief Constructs a string list from another list of strings.
 * \param other The list of strings to use for construction.
 */
inline StringList::StringList(const List<String>& other) :
	List<String>(other) {}

/*!
 * \brief An \c operator== implementation that allows a char-array to be at the left side of a string comparison
 *        with a \c String.
 * \param one A char-array representation of a string to compare.
 * \param other A string to compare.
 * \returns whether or not the two parameters are equal.
 */
inline bool operator==(const char* one, const String& other)
{
	return other == one;
}

/*!
 * \brief An \c operator+ implementation that allows a char-array to be at the left side of a string catenation
 *        with a \c String.
 * \param one A char-array representation of a string to catenate.
 * \param other A string to catenate.
 * \returns the catenated string.
 */
inline String operator+(const char* one, const String& other)
{
	return String(one) + other;
}


END_ZFC_NAMESPACE

mercurial