# HG changeset patch # User Teemu Piippo # Date 1469026600 -10800 # Node ID 37db42ad451ab154ee07353507adb33572283840 # Parent d9073c13dc98d1d91a5576452042a7c4eb1e3751# Parent 7643c21d546b8a729344d62fee36a79c9077a012 Merged with default diff -r d9073c13dc98 -r 37db42ad451a sources/coloredline.cpp --- a/sources/coloredline.cpp Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/coloredline.cpp Wed Jul 20 17:56:40 2016 +0300 @@ -39,18 +39,18 @@ }; ColoredLine::ColoredLine() : - m_length (0), - m_final (false), - m_activeColor (DEFAULT), - m_boldActive (false), - m_colorCodeStage (0) {} + m_length(0), + m_final(false), + m_activeColor(DEFAULT), + m_boldActive(false), + m_colorCodeStage(0) {} // ------------------------------------------------------------------------------------------------- // void ColoredLine::finalize() { if (m_activeColor != DEFAULT) - set_color (m_activeColor, false); + setColor(m_activeColor, false); if (m_boldActive) m_data << RLINE_OFF_BOLD; @@ -60,7 +60,7 @@ // ------------------------------------------------------------------------------------------------- // -void ColoredLine::add_char (char ch) +void ColoredLine::addChar(char ch) { static const ColorCodeInfo colorCodes[] = { @@ -100,7 +100,7 @@ if (m_colorCodeStage == 1) { if (m_activeColor != DEFAULT) - set_color (m_activeColor, false); + setColor(m_activeColor, false); if (m_boldActive) m_data << RLINE_OFF_BOLD; @@ -114,7 +114,7 @@ if (ch >= 'a' and ch <= 'v' and ch != 'l') { const ColorCodeInfo& colorInfo = colorCodes[ch - 'a']; - activate_color(colorInfo.color, colorInfo.bold); + activateColor(colorInfo.color, colorInfo.bold); } if (ch == '[') @@ -127,13 +127,13 @@ { if (ch == ']') { - String color = m_incomingColorName.to_lowercase(); + String color = m_incomingColorName.toLowerCase(); for (const ColorCodeInfo &colorInfo : colorCodes) { - if (String(colorInfo.name).to_lowercase() == color) + if (String(colorInfo.name).toLowerCase() == color) { - activate_color(colorInfo.color, colorInfo.bold); + activateColor(colorInfo.color, colorInfo.bold); m_colorCodeStage = 0; break; } @@ -148,25 +148,25 @@ return; } - if (isprint (ch)) + if (isprint(ch)) { m_string += ch; - m_data << int (ch); + m_data << int(ch); ++m_length; } } // ------------------------------------------------------------------------------------------------- // -void ColoredLine::activate_color (Color color, bool bold) +void ColoredLine::activateColor(Color color, bool bold) { if (m_boldActive) m_data << RLINE_OFF_BOLD; m_activeColor = color; m_boldActive = bold; - assert (m_activeColor < 8); - set_color (m_activeColor, true); + assert(m_activeColor < 8); + setColor(m_activeColor, true); if (m_boldActive) m_data << RLINE_ON_BOLD; @@ -174,31 +174,31 @@ // ------------------------------------------------------------------------------------------------- // -void ColoredLine::add_string (const String& text) +void ColoredLine::addString(const String& text) { for (char a : text) - add_char (a); + addChar(a); } // ------------------------------------------------------------------------------------------------- // -void ColoredLine::set_color (Color a, bool on) +void ColoredLine::setColor(Color a, bool on) { - assert (a < 8); - m_data << (a + (on ? RLINE_ON_COLOR : RLINE_OFF_COLOR)); + assert(a < 8); + m_data << (a +(on ? RLINE_ON_COLOR : RLINE_OFF_COLOR)); } // ------------------------------------------------------------------------------------------------- // How many rows does this line take up? // -int ColoredLine::rows (int cols) const +int ColoredLine::rows(int cols) const { int rows = length() / cols; if (length() % cols != 0) rows++; - return max (rows, 1); + return max(rows, 1); } END_ZFC_NAMESPACE diff -r d9073c13dc98 -r 37db42ad451a sources/coloredline.h --- a/sources/coloredline.h Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/coloredline.h Wed Jul 20 17:56:40 2016 +0300 @@ -20,10 +20,10 @@ 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, + 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 + 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. */ @@ -32,7 +32,7 @@ #include "main.h" BEGIN_ZFC_NAMESPACE -// The order of these colors appears to differ between curses distributions (PDCurses and its +// The order of these colors appears to differ between curses distributions(PDCurses and its // win32a for instance have blue and red swapped). So we need to explicitly define the values // of the enumerators based on their curses values. enum Color @@ -68,14 +68,14 @@ const Vector& data() const { return m_data; } int length() const { return m_length; } - void add_char (char ch); - void add_string (const String& msg); + void addChar(char ch); + void addString(const String& msg); void finalize(); - int rows (int cols) const; + int rows(int cols) const; private: - void activate_color (Color color, bool bold); - void set_color (Color a, bool on); + void activateColor(Color color, bool bold); + void setColor(Color a, bool on); Vector m_data; int m_length; diff -r d9073c13dc98 -r 37db42ad451a sources/geometry.h --- a/sources/geometry.h Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/geometry.h Wed Jul 20 17:56:40 2016 +0300 @@ -30,90 +30,91 @@ #pragma once #include "basics.h" + BEGIN_ZFC_NAMESPACE + struct Position { int x; int y; - Position (int x, int y) : - x (x), - y (y) {} + Position(int x, int y) : + x(x), + y(y) {} Position() : - x (0), - y (0) {} + x(0), + y(0) {} - bool operator< (const Position& other) const + bool operator<(const Position& other) const { if (y != other.y) return y < other.y; - - return x < other.x; + else + return x < other.x; } - bool operator> (const Position& other) const + bool operator>(const Position& other) const { if (y != other.y) return y > other.y; - - return x > other.x; + else + return x > other.x; } - bool operator== (const Position& other) const + bool operator==(const Position& other) const { return y == other.y and x == other.x; } - bool operator!= (const Position& other) const + bool operator!=(const Position& other) const { - return not operator== (other); + return not operator==(other); } - bool operator<= (const Position& other) const + bool operator<=(const Position& other) const { - return not operator> (other); + return not operator>(other); } - bool operator>= (const Position& other) const + bool operator>=(const Position& other) const { - return not operator< (other); + return not operator<(other); } }; -// ------------------------------------------------------------------------------------------------- struct Size { int width; int height; - Size (int width, int height) : - width (width), - height (height) {} + Size(int width, int height) : + width(width), + height(height) {} Size() : - width (0), - height (0) {} + width(0), + height(0) {} - auto area() const -> int + int area() const { return width * height; } }; -// ------------------------------------------------------------------------------------------------- struct Rectangle : Position, Size { - Rectangle (int x, int y, int width, int height) : - Position (x, y), - Size (width, height) {} + Rectangle(int x, int y, int width, int height) : + Position(x, y), + Size(width, height) {} Rectangle() : Position(), Size() {} }; + END_ZFC_NAMESPACE diff -r d9073c13dc98 -r 37db42ad451a sources/interface.cpp --- a/sources/interface.cpp Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/interface.cpp Wed Jul 20 17:56:40 2016 +0300 @@ -513,7 +513,7 @@ break; } - if (not text.is_empty()) + if (not text.isEmpty()) text += " | "; text += "Ctrl+N to connect, Ctrl+Q to "; @@ -717,7 +717,7 @@ case '\b': if (m_cursorPosition > 0) { - getEditableInput().remove_at(--m_cursorPosition); + getEditableInput().removeAt(--m_cursorPosition); m_needInputRender = true; } break; @@ -726,7 +726,7 @@ case 'D' - 'A' + 1: // readline ^D if (m_cursorPosition < getCurrentInput().length()) { - getEditableInput().remove_at(m_cursorPosition); + getEditableInput().removeAt(m_cursorPosition); m_needInputRender = true; } break; @@ -758,7 +758,7 @@ break; case 'Y' - 'A' + 1: // readline ^Y - paste previously deleted text - if (not m_pasteBuffer.is_empty()) + if (not m_pasteBuffer.isEmpty()) { getEditableInput().insert(m_cursorPosition, m_pasteBuffer); m_cursorPosition += m_pasteBuffer.length(); @@ -806,7 +806,7 @@ break; case INPUTSTATE_PASSWORD: - if (m_inputState == INPUTSTATE_PASSWORD and not getCurrentInput().is_empty()) + if (m_inputState == INPUTSTATE_PASSWORD and not getCurrentInput().isEmpty()) { m_session.disconnect(); m_session.set_password(getCurrentInput()); @@ -976,14 +976,14 @@ strftime(timestamp, sizeof timestamp, "[%H:%M:%S] ", localtime(&now)); for (char ch : String(timestamp)) - m_outputLines.last().add_char(ch); + m_outputLines.last().addChar(ch); } // Remove some lines if there's too many of them. 20,000 should be enough, I hope. while (m_outputLines.size() > 20000) m_outputLines.remove_at(0); - m_outputLines.last().add_char(ch); + m_outputLines.last().addChar(ch); } m_needOutputRender = true; @@ -1020,7 +1020,7 @@ for (const String& name : names) { ColoredLine coloredname; - coloredname.add_string(name); + coloredname.addString(name); coloredname.finalize(); m_playerNames.append(coloredname); } @@ -1034,7 +1034,7 @@ { String& input = getEditableInput(); - if (input.starts_with(part)) + if (input.startsWith(part)) { if (input[part.length()] != ' ') complete += ' '; @@ -1053,7 +1053,7 @@ return; StringList args = input.right(input.length() - 1).split(" "); - String command = args[0].to_lowercase(); + String command = args[0].toLowerCase(); args.remove_at(0); if (command == "connect") diff -r d9073c13dc98 -r 37db42ad451a sources/list.h --- a/sources/list.h Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/list.h Wed Jul 20 17:56:40 2016 +0300 @@ -352,6 +352,9 @@ Vector(){} + Vector(int numvalues) : + Super(numvalues){} + Vector (T* data, size_t length) : Super (std::vector (data, data + length)) {} diff -r d9073c13dc98 -r 37db42ad451a sources/mystring.cpp --- a/sources/mystring.cpp Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/mystring.cpp Wed Jul 20 17:56:40 2016 +0300 @@ -35,51 +35,42 @@ BEGIN_ZFC_NAMESPACE -// ------------------------------------------------------------------------------------------------- -// +/*! + * \brief Compares this string with another. + * \param other The string to compare with. + * \returns -1 if this string is lexicographically less than \c other, + * 0 if they are equal, or + * 1 if this string is lexicographically greater than \c other. + */ int String::compare (const String& other) const { - return m_string.compare (other.std_string()); -} - -// ------------------------------------------------------------------------------------------------- -// -void String::trim (int n) -{ - if (n > 0) - m_string = mid (0, length() - n).std_string(); - else - m_string = mid (n, -1).std_string(); + return m_string.compare (other.stdString()); } -// ------------------------------------------------------------------------------------------------- -// -String String::strip (char unwanted) const +/*! + * \brief Removes all instances of an unwanted character from this string. + * \param unwanted Character to remove. + */ +void String::strip (char unwanted) { - String result (m_string); - - for (int pos = 0; (pos = result.find (unwanted)) != -1;) - result.remove_at (pos--); - - return result; + for (int pos = 0; (pos = find (unwanted)) != -1;) + removeAt (pos--); } -// ------------------------------------------------------------------------------------------------- -// -String String::strip (const List& unwanted) const +/*! + * \brief Removes all instances of multiple characters from this string. + * \param unwanted Characters to remove. + */ +void String::strip (const List& unwanted) { - String result (m_string); - - for (String c : unwanted) - for (int pos = 0; (pos = result.find (c)) != -1;) - result.remove_at (pos--); - - return result; + for (char character : unwanted) + strip(character); } -// ------------------------------------------------------------------------------------------------- -// -String String::to_uppercase() const +/*! + * \returns an upper-case version of this string. + */ +String String::toUpperCase() const { String result (m_string); @@ -92,9 +83,10 @@ return result; } -// ------------------------------------------------------------------------------------------------- -// -String String::to_lowercase() const +/*! + * \returns a lower-case version of this string. + */ +String String::toLowerCase() const { String result (m_string); @@ -107,86 +99,99 @@ return result; } -// ------------------------------------------------------------------------------------------------- -// -StringList String::split (char del) const +/*! + * \brief Splits this string using the provided delimeter. + * \param delimeter Delimeter to use for splitting. + * \returns a string list containing the split strings. + */ +StringList String::split (char delimeter) const { - String delimstr; - delimstr += del; - return split (delimstr); + String delimeterString; + delimeterString += delimeter; + return split (delimeterString); } -// ------------------------------------------------------------------------------------------------- -// -StringList String::split (const String& del) const +/*! + * \brief Splits this string using the provided delimeter. + * \param delimeter Delimeter to use for splitting. + * \returns a string list containing the split strings. + */ +StringList String::split (const String& delimeter) const { - StringList res; + StringList result; int a = 0; int b; // Find all separators and store the text left to them. - while ((b = find (del, a)) != -1) + while ((b = find (delimeter, a)) != -1) { String sub = mid (a, b); if (sub.length() > 0) - res << sub; + result << sub; - a = b + del.length(); + a = b + delimeter.length(); } // Add the string at the right of the last separator if (a < (int) length()) - res.append (mid (a, length())); + result.append (mid (a, length())); - return res; + return result; } -// ------------------------------------------------------------------------------------------------- -// -void String::replace (const char* a, const char* b) +/*! + * \brief Replaces all instances of \c text with \c replacement. + * \param text Text to replace away. + * \param replacement Text to replace \c text with. + */ +void String::replace (const char* text, const char* replacement) { - long pos; + int position; - while ((pos = find (a)) != -1) - m_string = m_string.replace (pos, strlen (a), b); + while ((position = find (text)) != -1) + m_string = m_string.replace (position, strlen (text), replacement); } -// ------------------------------------------------------------------------------------------------- -// -int String::count (char needle) const +/*! + * \param character Character to count. + * \returns the amount of \c character found in the string. + */ +int String::count (char character) const { int result = 0; for (char ch : *this) { - if (ch == needle) + if (ch == character) result++; } return result; } -// ------------------------------------------------------------------------------------------------- -// -// Returns a substring from [a, b) -// -String String::mid (int a, int b) const +/*! + * \param a Starting index of the range. + * \param b Ending index of the range. + * \returns a sub-string containing all characters from \c a to \c b, not including the character at \c b. + */ +String String::mid (int rangeBegin, int rangeEnd) const { - a = max(a, 0); - b = min(b, length()); + modifyIndex(rangeBegin); + modifyIndex(rangeEnd); + rangeBegin = max(rangeBegin, 0); + rangeEnd = min(rangeEnd, length()); - if (b == -1) - b = length(); - - if (b <= a) + if (rangeEnd <= rangeBegin) return ""; else - return m_string.substr(a, b - a); + return m_string.substr(rangeBegin, rangeEnd - rangeBegin); } -// ------------------------------------------------------------------------------------------------- -// +/*! + * \param length Amount of characters to return. + * \returns the \c length right-most characters of the string. + */ String String::right(int length) const { if (length >= this->length()) @@ -195,90 +200,94 @@ return String(chars() + this->length() - length); } -// ------------------------------------------------------------------------------------------------- -// -int String::word_position (int n) const +/*! + * \brief Finds the first instance of a sub-string. + * \param subString Sub-string to search within this string. + * \param startingPosition Position to start looking for the sub-string from. + * \returns the position the first instance of sub-string found, or -1 if not found. + */ +int String::find (const char* subString, int startingPosition) const { - int count = 0; + int position = m_string.find (subString, startingPosition); + + if (position == int (std::string::npos)) + return -1; + else + return position; +} + +/*! + * \brief Finds the first instance of a character. + * \param character Character to search within this string. + * \param startingPosition Position to start looking for the character from. + * \returns the position of the first instance of the provided character found, or -1 if not found. + */ +int String::find (char character, int startingPosition) const +{ + int position = m_string.find (character, startingPosition); - for (char ch : *this) + if (position == int (std::string::npos)) + return -1; + else + return position; +} + +/*! + * \brief Finds the last instance of a sub-string. + * \param subString Sub-string to search within this string. + * \param startingPosition Position to start looking for the sub-string from. + * \returns the position the last instance of sub-string found, or -1 if not found. + */ +int String::findLast (const char* subString, int startingPosition) const +{ + modifyIndex(startingPosition); + + for (; startingPosition > 0; startingPosition--) { - if (not isspace(ch) or ++count < n) - continue; + if (strncmp (chars() + startingPosition, subString, strlen (subString)) == 0) + return startingPosition; } return -1; } -// ------------------------------------------------------------------------------------------------- -// -int String::find (const char* c, int a) const +/*! + * \brief Converts this string to an integer. + * \param ok An pointer to a boolean to store whether or not the conversion was successful. + * If \c ok is \c NULL, the success state is not stored. + * \param base The base to interpret this string with. + * \returns the resulting integer. + */ +long String::toInt (bool* ok, int base) const { - int pos = m_string.find (c, a); - - if (pos == int (std::string::npos)) - return -1; + errno = 0; + char* endPointer; + long result = strtol (chars(), &endPointer, base); - return pos; -} + if (ok != nullptr) + *ok = (errno == 0 and *endPointer == '\0'); -// ------------------------------------------------------------------------------------------------- -// -int String::find (char ch, int a) const -{ - int pos = m_string.find (ch, a); - - if (pos == int (std::string::npos)) - return -1; - - return pos; + return result; } -// ------------------------------------------------------------------------------------------------- -// -int String::find_last (const char* c, int a) const +/*! + * \brief Converts this string to a floating-point number. + * \param ok An pointer to a boolean to store whether or not the conversion was successful. + * If \c ok is \c NULL, the success state is not stored. + * \returns the resulting floating-point number. + */ +float String::toFloat (bool* ok) const { - if (a == -1 or a >= length()) - a = length() - 1; - - for (; a > 0; a--) - if (m_string[a] == c[0] and strncmp (chars() + a, c, strlen (c)) == 0) - return a; - - return -1; + return static_cast(toDouble(ok)); } -// ------------------------------------------------------------------------------------------------- -// -long String::to_int (bool* ok, int base) const -{ - errno = 0; - char* endptr; - long i = strtol (chars(), &endptr, base); - - if (ok) - *ok = (errno == 0 and *endptr == '\0'); - - return i; -} - -// ------------------------------------------------------------------------------------------------- -// -float String::to_float (bool* ok) const -{ - errno = 0; - char* endptr; - float i = (float) strtod (chars(), &endptr); - - if (ok != nullptr) - *ok = (errno == 0 and *endptr == '\0'); - - return i; -} - -// ------------------------------------------------------------------------------------------------- -// -double String::to_double (bool* ok) const +/*! + * \brief Converts this string to a double-precision floating-point number. + * \param ok An pointer to a boolean to store whether or not the conversion was successful. + * If \c ok is \c NULL, the success state is not stored. + * \returns the resulting floating-point number. + */ +double String::toDouble (bool* ok) const { errno = 0; char* endptr; @@ -290,93 +299,124 @@ return i; } -// ------------------------------------------------------------------------------------------------- -// -String String::operator+ (const String& data) const +/*! + * \brief Catenates this string with another string. + * \param text String to catenate to the end of this string. + * \returns the resulting string. + */ +String String::operator+ (const String& text) const { String newString = *this; - newString.append (data); + newString.append (text); + return newString; +} + +/*! + * \brief Catenates this string with another string. + * \param text String to catenate to the end of this string. + * \returns the resulting string. + */ +String String::operator+ (const char* text) const +{ + String newString = *this; + newString.append (text); return newString; } -// ------------------------------------------------------------------------------------------------- -// -String String::operator+ (const char* data) const +/*! + * \returns whether or not this string represents a number. + */ +bool String::isNumeric() const { - String newstr = *this; - newstr.append (data); - return newstr; + char* endPointer; + strtol (chars(), &endPointer, 10); + return (endPointer != nullptr) and (*endPointer != '\0'); } -// ------------------------------------------------------------------------------------------------- -// -bool String::is_numeric() const +/*! + * \param other Sub-string to find from the end of this string. + * \return whether or not this string ends with the provided sub-string. + */ +bool String::endsWith (const String& other) const { - char* endptr; - strtol (chars(), &endptr, 10); - return not (endptr && *endptr); + if (length() < other.length()) + { + return false; + } + else + { + const int offset = length() - other.length(); + return strncmp (chars() + offset, other.chars(), other.length()) == 0; + } } -// ------------------------------------------------------------------------------------------------- -// -bool String::ends_with (const String& other) +/*! + * \param other Sub-string to find from the beginning of this string. + * \returns whether or not this string begins with the provided sub-string. + */ +bool String::startsWith (const String& other) const { if (length() < other.length()) return false; - - const int ofs = length() - other.length(); - return strncmp (chars() + ofs, other.chars(), other.length()) == 0; + else + return strncmp (chars(), other.chars(), other.length()) == 0; } -// ------------------------------------------------------------------------------------------------- -// -bool String::starts_with (const String& other) const -{ - if (length() < other.length()) - return false; - - return strncmp (chars(), other.chars(), other.length()) == 0; -} - -// ------------------------------------------------------------------------------------------------- -// -void __cdecl String::sprintf (const char* fmtstr, ...) +/*! + * \brief Formats this string using \c printf -like syntax. + * \param formatString Template string to use with formatting. + * \param ... Variadic arguments to use with formatting. + */ +void __cdecl String::sprintf (const char* formatString, ...) { va_list args; - va_start (args, fmtstr); - this->vsprintf (fmtstr, args); + va_start (args, formatString); + this->vsprintf (formatString, args); va_end (args); } -// ------------------------------------------------------------------------------------------------- -// -void String::vsprintf (const char* fmtstr, va_list args) +/*! + * \brief Formats this string using \c vsnprintf, using the provided arguments. + * \param formatString Template string to use with formatting. + * \param args Variadic arguments to use with formatting. + */ +void String::vsprintf (const char* formatString, va_list args) { - char* buf = nullptr; - int bufsize = 256; + // Copy the argument list so that we have something to provide to vsnprintf in case we have to call it again. + va_list argsCopy; + va_copy(argsCopy, args); - do + // First, attempt to format using a fixed-size buffer. + static char buffer[1024]; + size_t length = vsnprintf(buffer, sizeof buffer, formatString, args); + + if (length < sizeof buffer) { - bufsize *= 2; - delete[] buf; - buf = new char[bufsize]; + // vsnprintf succeeded in fitting the formatted string into the buffer, so we're done. + m_string = buffer; } - while (vsnprintf (buf, bufsize, fmtstr, args) >= bufsize); - - m_string = buf; - delete[] buf; + else + { + // vsnprintf needs more space, so we have to allocate a new buffer and try again. + Vector newBuffer(length + 1); + vsnprintf(newBuffer.data(), length + 1, formatString, argsCopy); + m_string = newBuffer; + } } -// ------------------------------------------------------------------------------------------------- -// -String StringList::join (const String& delim) +/*! + * \brief Joins the elements of this string list into one longer string. + * \param delimeter The delimeter to place between the element strings. + * \returns the catenated string. + */ +String StringList::join (const String& delimeter) { String result; for (const String &item : container()) { - if (result.is_empty() == false) - result += delim; + if (result.isEmpty() == false) + result += delimeter; result += item; } @@ -384,13 +424,17 @@ return result; } -// ------------------------------------------------------------------------------------------------- -// -bool String::mask_against (const String& pattern) const +/*! + * \brief Tries to match this string against a mask pattern. In the pattern, '?' refers to one character, and '*' to + * any number of characters. + * \param pattern The masking pattern to use for matching. + * \returns whether or not this string matches the provided pattern. + */ +bool String::maskAgainst (const String& pattern) const { // Elevate to uppercase for case-insensitive matching - String pattern_upper = pattern.to_uppercase(); - String this_upper = to_uppercase(); + String pattern_upper = pattern.toUpperCase(); + String this_upper = toUpperCase(); const char* maskstring = pattern_upper.chars(); const char* mptr = &maskstring[0]; @@ -432,71 +476,93 @@ return true; } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (short int a) +/*! + * \brief Converts a short integer into a string. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (short int value) { - char buf[32]; - ::sprintf (buf, "%d", a); - return String (buf); + char buffer[32]; + ::sprintf (buffer, "%d", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (int a) +/*! + * \brief Converts an integer into a string. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (int value) { - char buf[32]; - ::sprintf (buf, "%d", a); - return String (buf); + char buffer[32]; + ::sprintf (buffer, "%d", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (long int a) +/*! + * \brief Converts a long integer into a string. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (long int value) { - char buf[32]; - ::sprintf (buf, "%ld", a); - return String (buf); + char buffer[32]; + ::sprintf (buffer, "%ld", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (unsigned short int a) +/*! + * \brief Converts an unsigned short integer into a string. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (unsigned short int value) { - char buf[32]; - ::sprintf (buf, "%u", a); - return String (buf); + char buffer[32]; + ::sprintf (buffer, "%u", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (unsigned int a) +/*! + * \brief Converts an unsigned integer into a string. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (unsigned int value) { - char buf[32]; - ::sprintf (buf, "%u", a); - return String (buf); + char buffer[32]; + ::sprintf (buffer, "%u", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (unsigned long int a) +/*! + * \brief Converts an unsigned long integer into a string. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (unsigned long int value) { - char buf[32]; - ::sprintf (buf, "%lu", a); - return String (buf); + char buffer[32]; + ::sprintf (buffer, "%lu", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// -String String::from_number (double a) +/*! + * \brief Converts a double-precision floating point number into a string, using the "%f" format specifier. + * \param value The value to convert. + * \returns the resulting string. + */ +String String::fromNumber (double value) { - char buf[64]; - ::sprintf (buf, "%f", a); - return String (buf); + char buffer[64]; + ::sprintf (buffer, "%f", value); + return String (buffer); } -// ------------------------------------------------------------------------------------------------- -// +/*! + * \returns the MD5-checksum of this string. + */ String String::md5() const { char checksum[33]; @@ -505,8 +571,11 @@ return String (checksum); } -// ------------------------------------------------------------------------------------------------- -// +/*! + * \brief Removes leading and trailing whitespace from this string. Alternatively a custom filter can be used to strip + * something else than whitespace. + * \param filter The filtering function to use. + */ void String::normalize (int (*filter)(int)) { int a = 0; @@ -524,8 +593,10 @@ m_string = m_string.substr (a, b - a + 1); } -// ------------------------------------------------------------------------------------------------- -// +/*! + * \returns a version of this string without leading or trailing whitespace. Alternatively a custom filter can be used + * to strip something else than whitespace. + */ String String::normalized (int (*filter)(int)) const { String result = *this; diff -r d9073c13dc98 -r 37db42ad451a sources/mystring.h --- a/sources/mystring.h Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/mystring.h Wed Jul 20 17:56:40 2016 +0300 @@ -34,151 +34,566 @@ #include #include "basics.h" #include "list.h" + BEGIN_ZFC_NAMESPACE -class String; -class StringList; -// ------------------------------------------------------------------------------------------------- -// class String { public: - String() {} - - String (char a) - { - char buffer[2] = { a, '0' }; - m_string = buffer; - } - - String (const char* data) : - m_string (data) {} - - String (const std::string& data) : - m_string (data) {} - - String (const Vector& data) : - m_string (data.data(), data.size()) {} - typedef std::string::iterator Iterator; typedef std::string::const_iterator ConstIterator; - ConstIterator begin() const { return m_string.cbegin(); } - int compare (const String &other) const; - int count (char needle) const; - const char* chars() const { return m_string.c_str(); } - ConstIterator end() const { return m_string.end(); } - int find (const char* c, int a = 0) const; - int find (char ch, int a = 0) const; - bool is_empty() const { return m_string[0] == '\0'; } - bool is_numeric() const; - int find_last (const char*c, int a) const; - int length() const { return m_string.length(); } - bool mask_against (const String &pattern) const; - String md5() const; - String mid (int a, int b) const; - String right (int length) const; - StringList split (const String &del) const; - StringList split (char del) const; - const std::string& std_string() const { return m_string; } - String strip (char unwanted) const; - String strip (const List &unwanted) const; - double to_double (bool* ok = nullptr) const; - float to_float (bool* ok = nullptr) const; - long to_int (bool* ok = nullptr, int base = 10) const; - String to_lowercase() const; - String to_uppercase() const; - int word_position (int n) const; + String(); + String(char a); + String(const char* data); + String(const std::string& data); + String(const Vector& data); - void append (const char* data) { m_string.append (data); } - void append (char data) { m_string.push_back (data); } - void append (const String& data) { m_string.append (data.chars()); } - Iterator begin() { return m_string.begin(); } - void clear() { m_string.clear(); } - Iterator end() { return m_string.end(); } - bool ends_with (const String &other); - int index_difference (int a, int b) { modify_index (a); modify_index (b); return b - a; } - void insert (int pos, char c) { m_string.insert (m_string.begin() + pos, c); } - void insert (int pos, const char*c) { m_string.insert (pos, c); } - void modify_index (int &a) { if (a < 0) { a = length() - a; } } - void normalize (int (*filter)(int) = &isspace); - String normalized (int (*filter)(int) = &isspace) const; - void prepend (String a) { m_string = (a + m_string).std_string(); } - void remove (int pos, int len) { m_string.replace (pos, len, ""); } - void remove_at (int pos) { m_string.erase (m_string.begin() + pos); } - void remove_from_end (int len) { remove (length() - len, len); } - void remove_from_start (int len) { remove (0, len); } - void replace (const char* a, const char* b); - void replace (int pos, int n, const String &a) { m_string.replace (pos, n, a.chars()); } - void shrink_to_fit() { m_string.shrink_to_fit(); } - void __cdecl sprintf (const char* fmtstr, ...); - void vsprintf (const char* fmtstr, va_list args); - bool starts_with (const String &other) const; - void trim (int n); + 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 &unwanted); + 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 from_number (short int a); - static String from_number (int a); - static String from_number (long int a); - static String from_number (unsigned short int a); - static String from_number (unsigned int a); - static String from_number (unsigned long int a); - static String from_number (double a); + 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); - String operator+ (const String& data) const; - String operator+ (const char* data) const; - String operator+ (int num) const { return *this + String::from_number (num); } - String& operator+= (const String& data) { append (data); return *this; } - String& operator+= (const char* data) { append (data); return *this; } - String& operator+= (int num) { return operator+= (String::from_number (num)); } - String& operator+= (char data) { append (data); return *this; } - char& operator[] (int i) { return m_string[i]; } - char operator[] (int i) const { return m_string[i]; } - bool operator== (const String& other) const { return std_string() == other.std_string(); } - bool operator== (const char* other) const { return m_string == other; } - bool operator!= (const String& other) const { return std_string() != other.std_string(); } - bool operator!= (const char* other) const { return m_string != other; } - bool operator> (const String& other) const { return std_string() > other.std_string(); } - bool operator< (const String& other) const { return std_string() < other.std_string(); } - bool operator>= (const String& other) const { return std_string() >= other.std_string(); } - bool operator<= (const String& other) const { return std_string() <= other.std_string(); } - operator const char*() const { return chars(); } - operator const std::string&() const { return std_string(); } + 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 { public: - typedef List Super; - - StringList() {} - - StringList (int numvalues) : - Super (numvalues) {} - - StringList (const Super& other) : - Super (other) {} - - String join (const String& delim); + StringList(); + StringList(int numvalues); + StringList(const List& other); + String join(const String& delim); }; -// ------------------------------------------------------------------------------------------------- -// -inline bool operator== (const char* a, const String& b) + +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& 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) { - return b == a; + 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); } -// ------------------------------------------------------------------------------------------------- -// -inline String operator+ (const char* a, const String& b) +/*! + * \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) { - return String (a) + b; + 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(); +} + +/*! + * \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(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& other) : + List(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 diff -r d9073c13dc98 -r 37db42ad451a sources/network/ipaddress.cpp --- a/sources/network/ipaddress.cpp Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/network/ipaddress.cpp Wed Jul 20 17:56:40 2016 +0300 @@ -161,7 +161,7 @@ } if (colonpos != -1) - value.port = (unsigned short) input.mid (colonpos + 1, -1).to_int(); + value.port = (unsigned short) input.mid (colonpos + 1, -1).toInt(); return value; } diff -r d9073c13dc98 -r 37db42ad451a sources/network/rconsession.cpp --- a/sources/network/rconsession.cpp Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/network/rconsession.cpp Wed Jul 20 17:56:40 2016 +0300 @@ -367,7 +367,7 @@ // bool RCONSession::send_command (const String& message) { - if (m_state != RCON_CONNECTED or message.is_empty()) + if (m_state != RCON_CONNECTED or message.isEmpty()) return false; Bytestream packet; diff -r d9073c13dc98 -r 37db42ad451a sources/network/udpsocket.cpp --- a/sources/network/udpsocket.cpp Wed Jul 20 15:03:37 2016 +0300 +++ b/sources/network/udpsocket.cpp Wed Jul 20 17:56:40 2016 +0300 @@ -105,7 +105,7 @@ if (::bind (m_socket, reinterpret_cast (&svaddr), sizeof svaddr) == -1) { - m_error = String ("Couldn't bind to port ") + String::from_number (port); + m_error = String ("Couldn't bind to port ") + String::fromNumber (port); return false; }