From 7f9ba7464b3844697bdd557f36f1750ed37d1140 Mon Sep 17 00:00:00 2001 From: Markus Gans Date: Sun, 30 May 2021 23:52:03 +0200 Subject: [PATCH] FString internally changed from wchar_t* to std::wstring --- ChangeLog | 3 + examples/calculator.cpp | 3 +- examples/ui.cpp | 2 +- src/fbutton.cpp | 8 +- src/fbuttongroup.cpp | 2 +- src/ffiledialog.cpp | 10 +- src/fkeyboard.cpp | 2 +- src/flistbox.cpp | 4 +- src/fmessagebox.cpp | 2 +- src/foptimove.cpp | 20 +- src/fstring.cpp | 667 ++++++++-------------------------- src/fterm_functions.cpp | 4 +- src/ftermbuffer.cpp | 1 - src/ftermxterminal.cpp | 4 - src/ftextview.cpp | 4 +- src/ftogglebutton.cpp | 4 +- src/fvterm.cpp | 6 +- src/include/final/foptimove.h | 2 +- src/include/final/fstring.h | 66 ++-- src/include/final/fterm.h | 2 +- test/fstring-test.cpp | 157 +++----- test/fstringstream-test.cpp | 12 +- 22 files changed, 274 insertions(+), 711 deletions(-) diff --git a/ChangeLog b/ChangeLog index 22014ac6..80bc366b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +2021-05-30 Markus Gans + * FString internally changed from wchar_t* to std::wstring + 2021-05-24 Markus Gans * Using std::string for the attribute buffer diff --git a/examples/calculator.cpp b/examples/calculator.cpp index d03a6a1a..77ab1b75 100644 --- a/examples/calculator.cpp +++ b/examples/calculator.cpp @@ -385,7 +385,7 @@ void Calc::drawDispay() { finalcut::FString display{input}; - if ( display.isNull() || display.isEmpty() ) + if ( display.isEmpty() ) display = L'0'; if ( display.right(3) == L"-0." ) @@ -651,7 +651,6 @@ void Calc::radix_point (const lDouble&) return; if ( isDataEntryKey(last_key) - && ! input.isNull() && ! input.isEmpty() && ! input.includes('.') ) input += '.'; diff --git a/examples/ui.cpp b/examples/ui.cpp index 898b2e65..316d6101 100644 --- a/examples/ui.cpp +++ b/examples/ui.cpp @@ -1013,7 +1013,7 @@ void MyDialog::cb_view (const finalcut::FMenuItem* item) else file = finalcut::FFileDialog::fileOpenChooser (this); - if ( file.isNull() ) + if ( file.isEmpty() ) return; const auto& view = new TextWindow(this); diff --git a/src/fbutton.cpp b/src/fbutton.cpp index 442baadb..40c310bb 100644 --- a/src/fbutton.cpp +++ b/src/fbutton.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2012-2020 Markus Gans * +* Copyright 2012-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -209,11 +209,7 @@ bool FButton::setDown (bool enable) //---------------------------------------------------------------------- void FButton::setText (const FString& txt) { - if ( txt.isNull() ) - text.setString(""); - else - text.setString(txt); - + text.setString(txt); detectHotkey(); } diff --git a/src/fbuttongroup.cpp b/src/fbuttongroup.cpp index 2404bbe8..fd7a35af 100644 --- a/src/fbuttongroup.cpp +++ b/src/fbuttongroup.cpp @@ -361,7 +361,7 @@ void FButtonGroup::draw() //---------------------------------------------------------------------- void FButtonGroup::drawLabel() { - if ( text.isNull() || text.isEmpty() ) + if ( text.isEmpty() ) return; FString label_text{}; diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index 902fc494..d2dce52b 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -65,15 +65,15 @@ FString fileChooser ( FWidget* parent FString path{dirname}; FString file_filter{filter}; - if ( path.isNull() || path.isEmpty() ) + if ( path.isEmpty() ) { path.setString(FFileDialog::getHomeDir()); - if ( path.isNull() || path.isEmpty() ) + if ( path.isEmpty() ) path.setString("/"); } - if ( file_filter.isNull() || file_filter.isEmpty() ) + if ( file_filter.isEmpty() ) file_filter.setString("*"); FFileDialog fileopen ( path @@ -111,7 +111,7 @@ FFileDialog::FFileDialog ( const FString& dirname , filter_pattern{filter} , dlg_type{type} { - if ( ! dirname.isNull() ) + if ( ! dirname.isEmpty() ) setPath(dirname); init(); @@ -728,7 +728,7 @@ void FFileDialog::cb_processActivate() { return ! entry.name.empty() && input - && ! input.isNull() + && ! input.isEmpty() && std::strcmp(entry.name.c_str(), input.c_str()) == 0 && entry.directory; } diff --git a/src/fkeyboard.cpp b/src/fkeyboard.cpp index 30c8f6ae..bb469bf5 100644 --- a/src/fkeyboard.cpp +++ b/src/fkeyboard.cpp @@ -398,7 +398,7 @@ inline bool FKeyboard::isKeypressTimeout() //---------------------------------------------------------------------- FKey FKeyboard::UTF8decode (const std::string& utf8) const { - using distance_type = std::iterator_traits::difference_type; + using distance_type = std::string::difference_type; FKey ucs{FKey::None}; // Universal coded character constexpr std::size_t max = 4; const auto len = utf8.length(); diff --git a/src/flistbox.cpp b/src/flistbox.cpp index 5ca7472d..91884f25 100644 --- a/src/flistbox.cpp +++ b/src/flistbox.cpp @@ -749,7 +749,7 @@ void FListBox::drawScrollbars() const //---------------------------------------------------------------------- void FListBox::drawHeadline() { - if ( text.isNull() || text.isEmpty() ) + if ( text.isEmpty() ) return; const FString txt{" " + text + " "}; @@ -1678,7 +1678,7 @@ void FListBox::changeOnResize() const //---------------------------------------------------------------------- void FListBox::lazyConvert(FListBoxItems::iterator iter, std::size_t y) { - if ( conv_type != ConvertType::Lazy || ! iter->getText().isNull() ) + if ( conv_type != ConvertType::Lazy || ! iter->getText().isEmpty() ) return; lazy_inserter (*iter, source_container, y + std::size_t(yoffset)); diff --git a/src/fmessagebox.cpp b/src/fmessagebox.cpp index e7f7e172..fcb71b3c 100644 --- a/src/fmessagebox.cpp +++ b/src/fmessagebox.cpp @@ -281,7 +281,7 @@ void FMessageBox::calculateDimensions() if ( text_num_lines == 0 ) return; - if ( ! headline_text.isNull() ) + if ( ! headline_text.isEmpty() ) headline_height = 2; for (auto&& line : text_components) diff --git a/src/foptimove.cpp b/src/foptimove.cpp index 7d109098..8aa1930a 100644 --- a/src/foptimove.cpp +++ b/src/foptimove.cpp @@ -604,9 +604,9 @@ int FOptiMove::capDurationToLength (int duration) const } //---------------------------------------------------------------------- -int FOptiMove::repeatedAppend ( const Capability& o - , int count - , std::string& dst ) const +int FOptiMove::repeatedAppend ( std::string& dst + , const Capability& o + , int count ) const { const std::size_t src_len = std::strlen(o.cap); const std::size_t dst_len = dst.length(); @@ -702,7 +702,7 @@ inline void FOptiMove::downMove ( std::string& move, int& vtime if ( ! move.empty() ) move.clear(); - vtime = repeatedAppend (F_cursor_down, num, move); + vtime = repeatedAppend (move, F_cursor_down, num); } } @@ -723,7 +723,7 @@ inline void FOptiMove::upMove ( std::string& move, int& vtime if ( ! move.empty() ) move.clear(); - vtime = repeatedAppend (F_cursor_up, num, move); + vtime = repeatedAppend (move, F_cursor_up, num); } } @@ -737,7 +737,6 @@ inline int FOptiMove::horizontalMove (std::string& hmove, int from_x, int to_x) // Move to fixed column position hmove = FTermcap::encodeParameter(F_column_address.cap, to_x); htime = F_column_address.duration; - } if ( to_x > from_x ) @@ -777,7 +776,7 @@ inline void FOptiMove::rightMove ( std::string& hmove, int& htime if ( tab_pos > to_x ) break; - htime_r += repeatedAppend (F_tab, 1, str); + htime_r += repeatedAppend (str, F_tab, 1); if ( htime_r >= LONG_DURATION ) break; @@ -788,7 +787,7 @@ inline void FOptiMove::rightMove ( std::string& hmove, int& htime num = to_x - pos; } - htime_r += repeatedAppend (F_cursor_right, num, str); + htime_r += repeatedAppend (str, F_cursor_right, num); if ( htime_r < htime ) { @@ -827,7 +826,7 @@ inline void FOptiMove::leftMove ( std::string& hmove, int& htime if ( tab_pos < to_x ) break; - htime_l += repeatedAppend (F_back_tab, 1, str); + htime_l += repeatedAppend (str, F_back_tab, 1); if ( htime_l >= LONG_DURATION ) break; @@ -838,11 +837,10 @@ inline void FOptiMove::leftMove ( std::string& hmove, int& htime num = pos - to_x; } - htime_l += repeatedAppend (F_cursor_left, num, str); + htime_l += repeatedAppend (str, F_cursor_left, num); if ( htime_l < htime ) { - hmove = str; htime = htime_l; } diff --git a/src/fstring.cpp b/src/fstring.cpp index 7179865e..8bdd09a6 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -45,26 +45,19 @@ const wchar_t FString::const_null_char{L'\0'}; FString::FString (int len) { if ( len > 0 ) - _initLength(std::size_t(len)); - else - _initLength(0); + string = std::wstring(std::size_t(len), L'\0'); } //---------------------------------------------------------------------- FString::FString (std::size_t len) { - _initLength(len); + string = std::wstring(len, L'\0'); } //---------------------------------------------------------------------- FString::FString (std::size_t len, wchar_t c) { - _initLength(len); - const wchar_t* ps = string; - wchar_t* pe = string + len; - - while ( pe != ps ) - *--pe = c; + string = std::wstring(len, c); } //---------------------------------------------------------------------- @@ -75,28 +68,22 @@ FString::FString (std::size_t len, const UniChar& c) //---------------------------------------------------------------------- FString::FString (const FString& s) // copy constructor { - if ( ! s.isNull() ) + if ( ! s.isEmpty() ) _assign (s.string); } //---------------------------------------------------------------------- FString::FString (FString&& s) noexcept // move constructor : string{s.string} - , length{s.length} - , bufsize{s.bufsize} - , c_string{s.c_string} { - s.string = nullptr; - s.length = 0; - s.bufsize = 0; - s.c_string = nullptr; + s.string.clear(); } //---------------------------------------------------------------------- FString::FString (const std::wstring& s) { if ( ! s.empty() ) - _assign (s.c_str()); + _assign (s); } //---------------------------------------------------------------------- @@ -111,9 +98,8 @@ FString::FString (const std::string& s) { if ( ! s.empty() ) { - const wchar_t* wc_string = _to_wcstring(s.c_str()); - _assign(wc_string); - delete[] wc_string; + const auto wide_string = _toWideString(s.c_str()); + _assign(wide_string); } } @@ -122,9 +108,8 @@ FString::FString (const char s[]) { if ( s ) { - const wchar_t* wc_string = _to_wcstring(s); - _assign( wc_string ); - delete[] wc_string; + const auto wide_string = _toWideString(s); + _assign(wide_string); } } @@ -157,13 +142,7 @@ FString::FString (const char c) //---------------------------------------------------------------------- FString::~FString() // destructor -{ - if ( string ) - delete[] string; - - if ( c_string ) - delete[] c_string; -} +{ } // FString operators @@ -181,21 +160,8 @@ FString& FString::operator = (FString&& s) noexcept { if ( &s != this ) { - if ( string ) - delete[] string; - - if ( c_string ) - delete[] c_string; - string = s.string; - length = s.length; - bufsize = s.bufsize; - c_string = s.c_string; - - s.string = nullptr; - s.length = 0; - s.bufsize = 0; - s.c_string = nullptr; + s.string.clear(); } return *this; @@ -204,14 +170,14 @@ FString& FString::operator = (FString&& s) noexcept //---------------------------------------------------------------------- const FString& FString::operator += (const FString& s) { - _insert (length, s.length, s.string); + string.append(s.string); return *this; } //---------------------------------------------------------------------- FString& FString::operator << (const FString& s) { - _insert (length, s.length, s.string); + string.append(s.string); return *this; } @@ -219,7 +185,7 @@ FString& FString::operator << (const FString& s) FString& FString::operator << (const UniChar& c) { FString s{static_cast(c)}; - _insert (length, s.length, s.string); + string.append(s.string); return *this; } @@ -227,7 +193,7 @@ FString& FString::operator << (const UniChar& c) FString& FString::operator << (const wchar_t c) { FString s{c}; - _insert (length, s.length, s.string); + string.append(s.string); return *this; } @@ -235,42 +201,42 @@ FString& FString::operator << (const wchar_t c) FString& FString::operator << (const char c) { FString s{c}; - _insert (length, s.length, s.string); + string.append(s.string); return *this; } //---------------------------------------------------------------------- const FString& FString::operator >> (FString& s) const { - s._insert (s.length, length, string); + s.string.append(string); return *this; } //---------------------------------------------------------------------- const FString& FString::operator >> (std::wstring& s) const { - s += std::wstring(string); + s += string; return *this; } //---------------------------------------------------------------------- const FString& FString::operator >> (std::string& s) const { - s += toString(); + s.append(toString()); return *this; } //---------------------------------------------------------------------- const FString& FString::operator >> (wchar_t& c) const { - c = ( length > 0 ) ? string[0] : L'\0'; + c = ( ! isEmpty() ) ? string[0] : L'\0'; return *this; } //---------------------------------------------------------------------- const FString& FString::operator >> (char& c) const { - c = ( length > 0 ) ? char(string[0] & 0xff) : '\0'; + c = ( ! isEmpty() ) ? char(string[0] & 0xff) : '\0'; return *this; } @@ -333,7 +299,7 @@ const FString& FString::operator >> (float& num) const //---------------------------------------------------------------------- FString::operator bool () const { - return string; + return ! isEmpty(); } //---------------------------------------------------------------------- @@ -347,12 +313,7 @@ const FString& FString::operator () () const //---------------------------------------------------------------------- FString FString::clear() { - if ( string ) - delete[] string; - - length = 0; - bufsize = 0; - string = nullptr; + string.clear(); return *this; } @@ -361,7 +322,7 @@ const wchar_t* FString::wc_str() const { // Returns a constant wide character string - return string; + return string.c_str(); } //---------------------------------------------------------------------- @@ -369,7 +330,7 @@ wchar_t* FString::wc_str() { // Returns a wide character string - return string; + return const_cast(string.c_str()); } //---------------------------------------------------------------------- @@ -377,12 +338,13 @@ const char* FString::c_str() const { // Returns a constant c-string - if ( length > 0 ) - return _to_cstring(string); - else if ( string ) - return ""; + if ( ! isEmpty() ) + { + char_string = _toCharString(string); + return char_string.c_str(); + } else - return nullptr; + return ""; } //---------------------------------------------------------------------- @@ -390,21 +352,19 @@ char* FString::c_str() { // Returns a c-string - if ( length > 0 ) - return const_cast(_to_cstring(string)); - else if ( string ) + if ( ! isEmpty() ) { - static char empty_string{'\0'}; - return &empty_string; + char_string = _toCharString(string); + return const_cast(char_string.c_str()); } else - return nullptr; + return const_cast(""); } //---------------------------------------------------------------------- std::string FString::toString() const { - return {c_str(), length}; + return c_str(); } //---------------------------------------------------------------------- @@ -489,7 +449,7 @@ long FString::toLong() const long tenth_limit{LONG_MAX / 10}; long tenth_limit_digit{LONG_MAX % 10}; const FString s{trim()}; - const wchar_t* p = s.string; + const wchar_t* p = s.string.c_str(); if ( ! p ) throw std::invalid_argument ("null value"); @@ -542,7 +502,7 @@ uLong FString::toULong() const const uLong tenth_limit{ULONG_MAX / 10}; const uLong tenth_limit_digit{ULONG_MAX % 10}; const FString s{trim()}; - const wchar_t* p = s.string; + const wchar_t* p = s.string.c_str(); if ( ! p ) throw std::invalid_argument ("null value"); @@ -596,14 +556,11 @@ float FString::toFloat() const //---------------------------------------------------------------------- double FString::toDouble() const { - if ( ! string ) + if ( isEmpty() ) throw std::invalid_argument ("null value"); - if ( ! *string ) - throw std::invalid_argument ("empty value"); - wchar_t* p{}; - const double ret = std::wcstod(string, &p); + const double ret = std::wcstod(string.c_str(), &p); if ( p != nullptr && *p != L'\0' ) throw std::invalid_argument ("no valid floating point value"); @@ -623,48 +580,46 @@ double FString::toDouble() const //---------------------------------------------------------------------- FString FString::ltrim() const { - const FString s{*this}; + // Handle empty string + if ( isEmpty() ) + return *this; - // handle NULL and empty string - if ( ! (string && *string) ) - return s; + auto iter = string.begin(); + const auto last = string.end(); - const wchar_t* p = s.string; + while ( iter != last && std::iswspace(std::wint_t(*iter)) ) + ++iter; - while ( std::iswspace(std::wint_t(*p)) ) - p++; - - return p; + if ( iter != last ) + return std::wstring(iter, last); + else + return {}; } //---------------------------------------------------------------------- FString FString::rtrim() const { - FString s{*this}; + // Handle empty string + if ( isEmpty() ) + return *this; - // handle NULL and empty string - if ( ! (string && *string) ) - return s; + const auto first = string.begin(); + auto iter = string.end() - 1; - wchar_t* p = s.string; - wchar_t* last = p + length; + while ( iter != first && std::iswspace(std::wint_t(*iter)) ) + --iter; - while ( std::iswspace(std::wint_t(*--last)) && last > p ) - s.length--; - - if ( last == p && std::iswspace(std::wint_t(*last)) ) - s = L""; + if ( first != iter ) + return std::wstring(first, iter + 1); else - *(last + 1) = '\0'; - - return s; + return {}; } //---------------------------------------------------------------------- FString FString::trim() const { - // handle NULL and empty string - if ( ! (string && *string) ) + // Handle NULL and empty string + if ( isEmpty() ) return *this; const FString s{ltrim()}; @@ -674,60 +629,44 @@ FString FString::trim() const //---------------------------------------------------------------------- FString FString::left (std::size_t len) const { - FString s{*this}; + // Handle empty and too long strings + if ( isEmpty() || len > getLength() ) + return *this; - // handle NULL and empty string - if ( ! (string && *string) ) - return s; - - if ( len > length ) - return s; - - wchar_t* p = s.string; - s.length = len; - *(p + len) = '\0'; - return s; + return string.substr(0, len); } //---------------------------------------------------------------------- FString FString::right (std::size_t len) const { - const FString s{*this}; + // Handle empty and too long strings + if ( isEmpty() || len > getLength() ) + return *this; - // handle NULL and empty string - if ( ! (string && *string) ) - return s; - - if ( len > length ) - return s; - - const wchar_t* p = s.string; - p += (length - len); - return p; + return string.substr(string.size() - len, len); } //---------------------------------------------------------------------- FString FString::mid (std::size_t pos, std::size_t len) const { - const FString s{*this}; - - // handle NULL and empty string - if ( ! (string && *string) ) - return s; + // Handle empty string + if ( isEmpty() ) + return *this; if ( pos == 0 ) pos = 1; + auto length = string.length(); + if ( pos <= length && pos + len > length ) len = length - pos + 1; if ( pos > length || pos + len - 1 > length || len == 0 ) - return {L""}; + return {}; - wchar_t* p = s.string; - wchar_t* first = p + pos - 1; - *(first + len) = '\0'; - return first; + auto first = string.begin() + static_cast(pos) - 1; + auto last = first + static_cast(len); + return std::wstring(first, last); } //---------------------------------------------------------------------- @@ -736,12 +675,12 @@ FStringList FString::split (const FString& delimiter) const const FString s{*this}; FStringList string_list{}; - // handle NULL and empty string - if ( ! (string && *string) ) + // Handle empty string + if ( isEmpty() ) return string_list; wchar_t* rest{nullptr}; - const wchar_t* token = _extractToken(&rest, s.string, delimiter.wc_str()); + const wchar_t* token = _extractToken(&rest, s.string.c_str(), delimiter.wc_str()); while ( token ) { @@ -898,43 +837,19 @@ FString& FString::setFormatedNumber (uInt64 num, char separator) //---------------------------------------------------------------------- bool FString::operator < (const FString& s) const { - if ( string && ! s.string ) - return false; - - if ( ! string && s.string ) - return true; - - if ( ! (string || s.string) ) - return false; - - return std::wcscmp(string, s.string) < 0; + return string < s.string; } //---------------------------------------------------------------------- bool FString::operator <= (const FString& s) const { - if ( ! (string || s.string) ) - return true; - - if ( string && ! s.string ) - return false; - - if ( ! string && s.string ) - return true; - - return std::wcscmp(string, s.string) <= 0; + return string <= s.string; } //---------------------------------------------------------------------- bool FString::operator == (const FString& s) const { - if ( ! (string || s.string) ) - return true; - - if ( bool(string) != bool(s.string) || length != s.length ) - return false; - - return std::wcscmp(string, s.string) == 0; + return string == s.string; } //---------------------------------------------------------------------- @@ -946,87 +861,49 @@ bool FString::operator != (const FString& s) const //---------------------------------------------------------------------- bool FString::operator >= (const FString& s) const { - if ( string && ! s.string ) - return true; - - if ( ! string && s.string ) - return false; - - if ( ! (string || s.string) ) - return true; - - return std::wcscmp(string, s.string) >= 0; + return string >= s.string; } //---------------------------------------------------------------------- bool FString::operator > (const FString& s) const { - if ( ! (string || s.string) ) - return false; - - if ( string && ! s.string ) - return true; - - if ( ! string && s.string ) - return false; - - return std::wcscmp(string, s.string) > 0; + return string > s.string; } //---------------------------------------------------------------------- const FString& FString::insert (const FString& s, int pos) { - if ( isNegative(pos) || uInt(pos) > length ) + if ( isNegative(pos) || uInt(pos) > string.length() ) throw std::out_of_range(""); - _insert (uInt(pos), s.length, s.string); + string.insert(uInt(pos), s.string, 0 , s.getLength()); return *this; } //---------------------------------------------------------------------- const FString& FString::insert (const FString& s, std::size_t pos) { - if ( pos > length ) + if ( pos > string.length() ) throw std::out_of_range(""); - _insert (pos, s.length, s.string); + string.insert(uInt(pos), s.string, 0 , s.getLength()); return *this; } //---------------------------------------------------------------------- FString FString::replace (const FString& from, const FString& to) const { + // Handle empty strings + if ( isEmpty() || from.isEmpty() ) + return *this; + FString s{*this}; + std::wstring::size_type pos{}; - // handle NULL and empty string - if ( ! (string && *string) ) - return s; - - if ( from.isNull() || to.isNull() ) - return s; - - if ( from.isEmpty() ) - return s; - - const wchar_t* p = s.string; - const std::size_t from_length = from.getLength(); - const std::size_t to_length = to.getLength(); - std::size_t pos{0}; - - while ( *p ) + while ( (pos = s.string.find(from.string, pos)) != std::wstring::npos ) { - if ( std::wcsncmp(p, from.string, from_length) == 0 ) - { - s._remove(pos, from_length); - s._insert(pos, to_length, to.string); - pos += to_length; - p = s.string + pos; - } - else - { - pos++; - p++; - } + s.string.replace (pos, from.getLength(), to.string); + pos += to.getLength(); } return s; @@ -1061,7 +938,7 @@ FString FString::replaceControlCodes() const //---------------------------------------------------------------------- FString FString::expandTabs (int tabstop) const { - FString instr{string}; + FString instr{*this}; FString outstr{}; if ( tabstop <= 0 ) @@ -1108,8 +985,7 @@ FString FString::removeDel() const } } - s.string[i] = L'\0'; - s.length = i; + s.string.erase(i); return s; } @@ -1133,8 +1009,7 @@ FString FString::removeBackspaces() const } } - s.string[i] = L'\0'; - s.length = i; + s.string.erase(i); return s; } @@ -1150,352 +1025,104 @@ const FString& FString::overwrite (const FString& s, int pos) //---------------------------------------------------------------------- const FString& FString::overwrite (const FString& s, std::size_t pos) { - if ( pos > length ) - pos = length; - - if ( length >= (pos + s.length) ) - { - std::wcsncpy (string + pos, s.string, s.length); - } - else - { - std::wcsncpy (string + pos, s.string, length - pos); - _insert (length, pos + s.length - length, s.string + length - pos); - } + if ( pos > string.length() ) + pos = string.length(); + string.replace(pos, s.getLength(), s.string); return *this; } //---------------------------------------------------------------------- const FString& FString::remove (std::size_t pos, std::size_t len) { + auto length = string.length(); + if ( pos > length ) return *this; if ( pos + len > length ) len = length - pos; - _remove (pos, len); - + string.erase (pos, len); return *this; } //---------------------------------------------------------------------- bool FString::includes (const FString& s) const { - if ( ! s ) + if ( s.isEmpty() ) return false; - if ( ! (string && s.string) ) - return false; - - return std::wcsstr(string, s.string) != nullptr; + return string.find(s.string) != std::wstring::npos; } // private methods of FString //---------------------------------------------------------------------- -inline void FString::_initLength (std::size_t len) +void FString::_assign (const std::wstring& s) { - if ( len == 0 ) + if ( string == s ) return; - length = len; - bufsize = FWDBUFFER + len + 1; - - try - { - string = new wchar_t[bufsize]; - std::wmemset (string, L'\0', bufsize); - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[bufsize]"); - } + string = s; } //---------------------------------------------------------------------- -void FString::_assign (const wchar_t s[]) +inline std::string FString::_toCharString (const std::wstring& s) const { - if ( ! s ) - { - clear(); - return; - } + if ( s.empty() ) + return {}; - if ( string && std::wcscmp(string, s) == 0 ) - return; // string == s - - std::size_t new_length{std::wcslen(s)}; - - if ( ! string || new_length > capacity() ) - { - if ( string ) - delete[] string; - - bufsize = FWDBUFFER + new_length + 1; - - try - { - string = new wchar_t[bufsize]; - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[bufsize]"); - return; - } - } - - std::wcsncpy (string, s, bufsize); - length = new_length; - string[capacity()] = L'\0'; -} - -//---------------------------------------------------------------------- -void FString::_insert (std::size_t len, const wchar_t s[]) -{ - if ( len == 0 ) // String s is a null or a empty string - return; - - if ( string ) - delete[] string; - - length = len; - bufsize = FWDBUFFER + length + 1; - - try - { - string = new wchar_t[bufsize]; - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[bufsize]"); - return; - } - - std::wcsncpy (string, s, bufsize); - string[capacity()] = L'\0'; -} - -//---------------------------------------------------------------------- -void FString::_insert ( std::size_t pos - , std::size_t len - , const wchar_t s[] ) -{ - if ( len == 0 ) // String s is a null or a empty string - return; - - if ( ! string ) // string is null - { - _insert (len, s); - } - else - { - std::size_t x{}; - - if ( length + len <= capacity() ) - { - // output string <= bufsize - for (x = length; x + 1 > pos; x--) // shifting right side + '\0' - string[x + len] = string[x]; - - for (x = 0; x < len; x++) // insert string - string[x + pos] = s[x]; - - length += len; - } - else - { - // output string > bufsize - bufsize = FWDBUFFER + length + len + 1; - wchar_t* sptr{}; - - try - { - sptr = new wchar_t[bufsize]; // generate new string - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[bufsize]"); - return; - } - - std::size_t y{0}; - - for (x = 0; x < pos; x++) // left side - sptr[y++] = string[x]; - - for (x = 0 ; x < len; x++) // insert string - sptr[y++] = s[x]; - - for (x = pos; x < length + 1; x++) // right side + '\0' - sptr[y++] = string[x]; - - length += len; - delete[] string; // delete old string - string = sptr; - } - } -} - -//---------------------------------------------------------------------- -void FString::_remove (std::size_t pos, std::size_t len) -{ - if ( capacity() - length + len <= FWDBUFFER ) - { - // shifting left side to pos - for (std::size_t i = pos; i + len < length + 1; i++) - string[i] = string[i + len]; - - length -= len; - } - else - { - bufsize = length + 1 - len + FWDBUFFER; - wchar_t* sptr{}; - - try - { - sptr = new wchar_t[bufsize]; // generate new string - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[bufsize]"); - return; - } - - std::size_t x{}; - std::size_t y{}; - - for (x = 0; x < pos; x++) // left side - sptr[y++] = string[x]; - - for (x = pos + len; x < length + 1; x++) // right side + '\0' - sptr[y++] = string[x]; - - delete[] string; // delete old string - string = sptr; - length -= len; - } -} - -//---------------------------------------------------------------------- -inline const char* FString::_to_cstring (const wchar_t s[]) const -{ - if ( ! s ) // handle NULL string - return nullptr; - - if ( ! *s ) // handle empty string - { - try - { - // Generate a empty string ("") - c_string = new char[1](); - } - catch (const std::bad_alloc&) - { - badAllocOutput ("char[1]"); - return nullptr; - } - - return c_string; - } - - if ( c_string ) - delete[] c_string; - - const wchar_t* src = s; + const wchar_t* src = s.c_str(); auto state = std::mbstate_t(); auto size = std::wcsrtombs(nullptr, &src, 0, &state) + 1; - try - { - c_string = new char[size]; + std::vector dest(size); - // pre-initialiaze the whole string with '\0' - std::memset (c_string, '\0', size); - } - catch (const std::bad_alloc&) - { - badAllocOutput ("char[size]"); - return nullptr; - } - - const auto mblength = std::wcsrtombs (c_string, &src, size, &state); + const auto mblength = std::wcsrtombs (dest.data(), &src, size, &state); if ( mblength == static_cast(-1) && errno != EILSEQ ) { - delete[] c_string; - c_string = nullptr; - return ""; + return {}; } - return c_string; + return dest.data(); } //---------------------------------------------------------------------- -inline const wchar_t* FString::_to_wcstring (const char s[]) const +inline std::wstring FString::_toWideString (const std::string& s) const { - if ( ! s ) // handle NULL string - return nullptr; + if ( s.empty() ) + return {}; - if ( ! *s ) // handle empty string - { - try - { - // Generate a empty wide string (L"") - return new wchar_t[1](); - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[1]"); - return nullptr; - } - } - - const char* src = s; - wchar_t* dest{}; + const char* src = s.c_str(); auto state = std::mbstate_t(); auto size = std::mbsrtowcs(nullptr, &src, 0, &state) + 1; if ( size == 0 ) // ...malformed UTF-8 string - return nullptr; + return {}; - try - { - dest = new wchar_t[size]; - // pre-initialiaze the whole string with '\0' - std::wmemset (dest, L'\0', size); - } - catch (const std::bad_alloc&) - { - badAllocOutput ("wchar_t[size]"); - return nullptr; - } + std::vector dest(size); - const auto wclength = std::mbsrtowcs (dest, &src, size, &state); + const auto wide_length = std::mbsrtowcs (dest.data(), &src, size, &state); - if ( wclength == static_cast(-1) ) + if ( wide_length == static_cast(-1) ) { - if ( src != s ) - return dest; + if ( src != s.c_str() ) + return dest.data(); else { - delete[] dest; - return nullptr; + return {}; } } - if ( wclength == size ) + if ( wide_length == size ) dest[size - 1] = '\0'; - if ( wclength ) - return dest; + if ( wide_length != 0 ) + return dest.data(); else - { - delete[] dest; - return nullptr; - } + return {}; } //---------------------------------------------------------------------- @@ -1525,8 +1152,7 @@ inline const wchar_t* FString::_extractToken ( wchar_t* rest[] //---------------------------------------------------------------------- FString operator + (const FString& s1, const FString& s2) { - FString tmp{s1}; - tmp._insert (tmp.length, s2.length, s2.wc_str()); + auto tmp = s1.string + s2.string; return tmp; } @@ -1535,14 +1161,14 @@ std::ostream& operator << (std::ostream& outstr, const FString& s) { const auto width = std::size_t(outstr.width()); - if ( s.length > 0 ) + if ( s.string.length() > 0 ) { - outstr << s._to_cstring(s.string); + outstr << s._toCharString(s.string).c_str(); } else if ( width > 0 ) { const FString fill_str{width, wchar_t(outstr.fill())}; - outstr << s._to_cstring(fill_str.string); + outstr << s._toCharString(fill_str.string).c_str(); } return outstr; @@ -1553,12 +1179,11 @@ std::istream& operator >> (std::istream& instr, FString& s) { std::array buf{}; instr.getline (buf.data(), FString::INPBUFFER); - const wchar_t* wc_str = s._to_wcstring(buf.data()); + const auto wide_string = s._toWideString(buf.data()); - if ( wc_str ) + if ( ! wide_string.empty() ) { - s._assign (wc_str); - delete[] wc_str; + s._assign (wide_string); } return instr; @@ -1569,7 +1194,7 @@ std::wostream& operator << (std::wostream& outstr, const FString& s) { const auto width = std::size_t(outstr.width()); - if ( s.length > 0 ) + if ( s.string.length() > 0 ) { outstr << s.string; } diff --git a/src/fterm_functions.cpp b/src/fterm_functions.cpp index 8ad22ec3..fa5056eb 100644 --- a/src/fterm_functions.cpp +++ b/src/fterm_functions.cpp @@ -199,9 +199,9 @@ constexpr std::array reverse_newfont_list = // FTerm non-member functions //---------------------------------------------------------------------- -uInt env2uint (const char* env) +uInt env2uint (const std::string& env) { - const FString str{getenv(env)}; + const FString str{getenv(env.data())}; if ( str.isEmpty() ) return 0; diff --git a/src/ftermbuffer.cpp b/src/ftermbuffer.cpp index dab1f39f..008e096a 100644 --- a/src/ftermbuffer.cpp +++ b/src/ftermbuffer.cpp @@ -66,7 +66,6 @@ FString FTermBuffer::toString() const //---------------------------------------------------------------------- int FTermBuffer::write (const FString& string) { - assert ( ! string.isNull() ); data.reserve(data.size() + string.getLength()); const auto last = string.end(); auto begin = string.begin(); diff --git a/src/ftermxterminal.cpp b/src/ftermxterminal.cpp index 1e15cbfe..741f074e 100644 --- a/src/ftermxterminal.cpp +++ b/src/ftermxterminal.cpp @@ -345,10 +345,6 @@ void FTermXTerminal::setXTermTitle() || FTermcap::osc_support ) { oscPrefix(); - - if ( xterm_title.isNull() ) - xterm_title = ""; - FTerm::putstringf (OSC "0;%s" BEL, xterm_title.c_str()); oscPostfix(); std::fflush(stdout); diff --git a/src/ftextview.cpp b/src/ftextview.cpp index 87651bcd..c26fe81a 100644 --- a/src/ftextview.cpp +++ b/src/ftextview.cpp @@ -280,9 +280,7 @@ void FTextView::replaceRange (const FString& str, int from, int to) auto iter = data.begin(); data.erase (iter + from, iter + to + 1); - - if ( ! str.isNull() ) - insert(str, from); + insert(str, from); } //---------------------------------------------------------------------- diff --git a/src/ftogglebutton.cpp b/src/ftogglebutton.cpp index a69633e8..212e24a8 100644 --- a/src/ftogglebutton.cpp +++ b/src/ftogglebutton.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2014-2020 Markus Gans * +* Copyright 2014-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -383,7 +383,7 @@ void FToggleButton::draw() //---------------------------------------------------------------------- void FToggleButton::drawLabel() { - if ( text.isNull() || text.isEmpty() ) + if ( text.isEmpty() ) return; const FString txt(text); diff --git a/src/fvterm.cpp b/src/fvterm.cpp index a7f9de00..d378663d 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -342,8 +342,8 @@ void FVTerm::delPreprocessingHandler (const FVTerm* instance) //---------------------------------------------------------------------- int FVTerm::print (const FString& string) { - if ( string.isNull() ) - return -1; + if ( string.isEmpty() ) + return 0; FTermBuffer term_buffer{}; term_buffer.write(string); @@ -353,7 +353,7 @@ int FVTerm::print (const FString& string) //---------------------------------------------------------------------- int FVTerm::print (FTermArea* area, const FString& string) { - if ( ! area || string.isNull() ) + if ( ! area || string.isEmpty() ) return -1; FTermBuffer term_buffer{}; diff --git a/src/include/final/foptimove.h b/src/include/final/foptimove.h index f677fb89..f9da1170 100644 --- a/src/include/final/foptimove.h +++ b/src/include/final/foptimove.h @@ -167,7 +167,7 @@ class FOptiMove final void calculateCharDuration(); int capDuration (const char[], int) const; int capDurationToLength (int) const; - int repeatedAppend (const Capability&, int, std::string&) const; + int repeatedAppend (std::string&, const Capability&, int) const; int relativeMove (std::string&, int, int, int, int) const; int verticalMove (std::string&, int, int) const; void downMove (std::string&, int&, int, int) const; diff --git a/src/include/final/fstring.h b/src/include/final/fstring.h index 5eb64645..110972c4 100644 --- a/src/include/final/fstring.h +++ b/src/include/final/fstring.h @@ -80,10 +80,11 @@ class FString { public: // Using-declarations - using iterator = wchar_t*; - using const_iterator = const wchar_t*; - using reference = wchar_t&; - using const_reference = const wchar_t&; + using iterator = std::wstring::iterator; + using const_iterator = std::wstring::const_iterator; + using reference = std::wstring::reference; + using const_reference = std::wstring::const_reference; + using difference_type = std::wstring::difference_type; // Constructors FString () = default; @@ -167,7 +168,7 @@ class FString virtual FString getClassName() const; // inquiries - bool isNull() const noexcept; + bool isNull() const noexcept; // deprecated bool isEmpty() const noexcept; // Methods @@ -245,24 +246,17 @@ class FString private: // Constants - static constexpr uInt FWDBUFFER = 15; static constexpr uInt INPBUFFER = 200; // Methods - void _initLength (std::size_t); - void _assign (const wchar_t[]); - void _insert (std::size_t, const wchar_t[]); - void _insert (std::size_t, std::size_t, const wchar_t[]); - void _remove (std::size_t, std::size_t); - const char* _to_cstring (const wchar_t[]) const; - const wchar_t* _to_wcstring (const char[]) const; - const wchar_t* _extractToken (wchar_t*[], const wchar_t[], const wchar_t[]) const; + void _assign (const std::wstring&); + std::string _toCharString (const std::wstring&) const; + std::wstring _toWideString (const std::string&) const; + const wchar_t* _extractToken (wchar_t*[], const wchar_t[], const wchar_t[]) const; // Data members - wchar_t* string{nullptr}; - std::size_t length{0}; - std::size_t bufsize{0}; - mutable char* c_string{nullptr}; + std::wstring string{}; + mutable std::string char_string{}; static wchar_t null_char; static const wchar_t const_null_char; @@ -288,7 +282,7 @@ template inline FString::reference FString::operator [] (const IndexT pos) { - if ( isNegative(pos) || pos > IndexT(length) ) + if ( isNegative(pos) || pos > IndexT(string.length()) ) throw std::out_of_range(""); // Invalid index position - if ( std::size_t(pos) == length ) + if ( std::size_t(pos) == string.length() ) return null_char; return string[std::size_t(pos)]; @@ -309,10 +303,10 @@ inline FString::reference FString::operator [] (const IndexT pos) template inline FString::const_reference FString::operator [] (const IndexT pos) const { - if ( isNegative(pos) || pos > IndexT(length) ) + if ( isNegative(pos) || pos > IndexT(string.length()) ) throw std::out_of_range(""); // Invalid index position - if ( std::size_t(pos) == length ) + if ( std::size_t(pos) == string.length() ) return const_null_char; return string[std::size_t(pos)]; @@ -371,63 +365,63 @@ inline FString FString::getClassName() const { return "FString"; } //---------------------------------------------------------------------- -inline bool FString::isNull() const noexcept -{ return ( bufsize == 0 || (bufsize > 0 && ! string) ); } +inline bool FString::isNull() const noexcept // deprecated +{ return false; } //---------------------------------------------------------------------- inline bool FString::isEmpty() const noexcept -{ return ( length == 0 || (length > 0 && string[0] == L'\0') ); } +{ return string.empty(); } //---------------------------------------------------------------------- inline std::size_t FString::getLength() const noexcept -{ return length; } +{ return string.length(); } //---------------------------------------------------------------------- inline std::size_t FString::capacity() const noexcept -{ return ( length > 0 ) ? bufsize - 1 : 0; } +{ return string.capacity(); } //---------------------------------------------------------------------- inline FString::iterator FString::begin() noexcept -{ return string; } +{ return string.begin(); } //---------------------------------------------------------------------- inline FString::iterator FString::end() noexcept -{ return string + length; } +{ return string.end(); } //---------------------------------------------------------------------- inline FString::const_iterator FString::begin() const noexcept -{ return string; } +{ return string.cbegin(); } //---------------------------------------------------------------------- inline FString::const_iterator FString::end() const noexcept -{ return string + length; } +{ return string.cend(); } //---------------------------------------------------------------------- inline FString::reference FString::front() { assert ( ! isEmpty() ); - return (*this)[0]; + return string.front(); } //---------------------------------------------------------------------- inline FString::reference FString::back() { assert( ! isEmpty() ); - return (*this)[length - 1]; + return string.back(); } //---------------------------------------------------------------------- inline FString::const_reference FString::front() const { assert ( ! isEmpty() ); - return (*this)[0]; + return string.front(); } //---------------------------------------------------------------------- inline FString::const_reference FString::back() const { assert( ! isEmpty() ); - return (*this)[length - 1]; + return string.back(); } //---------------------------------------------------------------------- diff --git a/src/include/final/fterm.h b/src/include/final/fterm.h index 7fcb8ac8..6661bc24 100644 --- a/src/include/final/fterm.h +++ b/src/include/final/fterm.h @@ -367,7 +367,7 @@ class FTerm final // non-member function forward declarations // implemented in fterm_functions.cpp //---------------------------------------------------------------------- -uInt env2uint (const char*); +uInt env2uint (const std::string&); bool isReverseNewFontchar (wchar_t); bool hasFullWidthSupports(); wchar_t cp437_to_unicode (uChar); diff --git a/test/fstring-test.cpp b/test/fstring-test.cpp index 2b1e9488..4bf2bafc 100644 --- a/test/fstring-test.cpp +++ b/test/fstring-test.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2018-2020 Markus Gans * +* Copyright 2018-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -158,12 +158,11 @@ void FStringTest::classNameTest() void FStringTest::noArgumentTest() { finalcut::FString empty; - CPPUNIT_ASSERT ( empty.isNull() ); CPPUNIT_ASSERT ( empty.isEmpty() ); CPPUNIT_ASSERT ( empty.getLength() == 0 ); - CPPUNIT_ASSERT ( empty.capacity() == 0 ); - CPPUNIT_ASSERT ( empty.wc_str() == nullptr ); - CPPUNIT_ASSERT ( empty.c_str() == nullptr ); + CPPUNIT_ASSERT ( empty.capacity() < std::wstring().max_size() ); + CPPUNIT_ASSERT ( empty.wc_str()[0] == L'\0' ); + CPPUNIT_ASSERT ( empty.c_str()[0] == '\0' ); CPPUNIT_ASSERT_EQUAL ( empty.toString(), std::string() ); CPPUNIT_ASSERT ( strlen(finalcut::FString(99).c_str()) == 0 ); CPPUNIT_ASSERT ( wcslen(finalcut::FString(99).wc_str()) == 0 ); @@ -171,17 +170,16 @@ void FStringTest::noArgumentTest() CPPUNIT_ASSERT ( wcslen(finalcut::FString("").wc_str()) == 0 ); char* cstr = empty.c_str(); - CPPUNIT_ASSERT ( cstr == nullptr ); + CPPUNIT_ASSERT ( cstr[0] == '\0' ); wchar_t* wcstr = empty.wc_str(); - CPPUNIT_ASSERT ( wcstr == nullptr ); + CPPUNIT_ASSERT ( wcstr[0] == L'\0' ); std::string str = empty.toString(); CPPUNIT_ASSERT ( str.length() == 0 ); CPPUNIT_ASSERT ( str.size() == 0 ); CPPUNIT_ASSERT ( str.empty() ); const finalcut::FString fstr = str; - CPPUNIT_ASSERT ( fstr.isNull() ); CPPUNIT_ASSERT ( fstr.isEmpty() ); - CPPUNIT_ASSERT ( fstr.capacity() == 0 ); + CPPUNIT_ASSERT ( fstr.capacity() < std::wstring().max_size() ); cstr = 0; CPPUNIT_ASSERT ( empty == cstr ); @@ -209,7 +207,7 @@ void FStringTest::noArgumentTest() CPPUNIT_ASSERT_EQUAL ( empty, finalcut::FString(L"123") ); empty.clear(); - CPPUNIT_ASSERT ( empty.isNull() ); + CPPUNIT_ASSERT ( empty.isEmpty() ); } //---------------------------------------------------------------------- @@ -217,70 +215,60 @@ void FStringTest::initLengthTest() { const finalcut::FString s1(0); CPPUNIT_ASSERT ( s1.getLength() == 0 ); - CPPUNIT_ASSERT ( s1.capacity() == 0 ); - CPPUNIT_ASSERT ( s1.isNull() ); + CPPUNIT_ASSERT ( s1.capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( s1.isEmpty() ); constexpr int x1 = 10; constexpr std::size_t x2 = 10; const finalcut::FString s2(x1); CPPUNIT_ASSERT ( s2.getLength() == 10 ); - CPPUNIT_ASSERT ( s2.capacity() == 25 ); - CPPUNIT_ASSERT ( ! s2.isNull() ); - CPPUNIT_ASSERT ( s2.isEmpty() ); + CPPUNIT_ASSERT ( s2.capacity() >= 10 ); + CPPUNIT_ASSERT ( ! s2.isEmpty() ); const finalcut::FString s3(x2); CPPUNIT_ASSERT ( s3.getLength() == 10 ); - CPPUNIT_ASSERT ( s3.capacity() == 25 ); - CPPUNIT_ASSERT ( ! s3.isNull() ); - CPPUNIT_ASSERT ( s3.isEmpty() ); + CPPUNIT_ASSERT ( s3.capacity() >= 10 ); + CPPUNIT_ASSERT ( ! s3.isEmpty() ); const finalcut::FString s4(0, L'-'); CPPUNIT_ASSERT ( s4.getLength() == 0 ); - CPPUNIT_ASSERT ( s4.capacity() == 0 ); - CPPUNIT_ASSERT ( s4.isNull() ); + CPPUNIT_ASSERT ( s4.capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( s4.isEmpty() ); const finalcut::FString s5(0, '-'); CPPUNIT_ASSERT ( s5.getLength() == 0 ); - CPPUNIT_ASSERT ( s5.capacity() == 0 ); - CPPUNIT_ASSERT ( s5.isNull() ); + CPPUNIT_ASSERT ( s5.capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( s5.isEmpty() ); const finalcut::FString s6(0, char(0)); CPPUNIT_ASSERT ( s6.getLength() == 0 ); - CPPUNIT_ASSERT ( s6.capacity() == 0 ); - CPPUNIT_ASSERT ( s6.isNull() ); + CPPUNIT_ASSERT ( s6.capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( s6.isEmpty() ); const finalcut::FString s7(x1, '-'); CPPUNIT_ASSERT ( s7.getLength() == 10 ); - CPPUNIT_ASSERT ( ! s7.isNull() ); + CPPUNIT_ASSERT ( s7.capacity() >= 10 ); CPPUNIT_ASSERT ( ! s7.isEmpty() ); const finalcut::FString s8(x2, '-'); CPPUNIT_ASSERT ( s8.getLength() == 10 ); - CPPUNIT_ASSERT ( s8.capacity() == 25 ); - CPPUNIT_ASSERT ( ! s8.isNull() ); + CPPUNIT_ASSERT ( s8.capacity() >= 10 ); CPPUNIT_ASSERT ( ! s8.isEmpty() ); const finalcut::FString s9(x1, L'-'); CPPUNIT_ASSERT ( s9.getLength() == 10 ); - CPPUNIT_ASSERT ( s9.capacity() == 25 ); - CPPUNIT_ASSERT ( ! s9.isNull() ); + CPPUNIT_ASSERT ( s9.capacity() >= 10 ); CPPUNIT_ASSERT ( ! s9.isEmpty() ); const finalcut::FString s10(x2, L'-'); CPPUNIT_ASSERT ( s10.getLength() == 10 ); - CPPUNIT_ASSERT ( s10.capacity() == 25 ); - CPPUNIT_ASSERT ( ! s10.isNull() ); + CPPUNIT_ASSERT ( s10.capacity() >= 10 ); CPPUNIT_ASSERT ( ! s10.isEmpty() ); const finalcut::FString s11(x2, wchar_t(0)); CPPUNIT_ASSERT ( s11.getLength() == 10 ); - CPPUNIT_ASSERT ( s11.capacity() == 25 ); - CPPUNIT_ASSERT ( ! s11.isNull() ); - CPPUNIT_ASSERT ( s11.isEmpty() ); + CPPUNIT_ASSERT ( s11.capacity() >= 10 ); + CPPUNIT_ASSERT ( ! s11.isEmpty() ); } //---------------------------------------------------------------------- @@ -290,7 +278,7 @@ void FStringTest::copyConstructorTest() const finalcut::FString s2(s1); CPPUNIT_ASSERT ( s2 == L"abc" ); CPPUNIT_ASSERT ( s2.getLength() == 3 ); - CPPUNIT_ASSERT ( s2.capacity() == 18 ); + CPPUNIT_ASSERT ( s2.capacity() >= 3 ); } //---------------------------------------------------------------------- @@ -300,11 +288,10 @@ void FStringTest::moveConstructorTest() const finalcut::FString s2{std::move(s1)}; CPPUNIT_ASSERT ( s2 == L"abc" ); CPPUNIT_ASSERT ( s2.getLength() == 3 ); - CPPUNIT_ASSERT ( s2.capacity() == 18 ); - CPPUNIT_ASSERT ( s1.isNull() ); + CPPUNIT_ASSERT ( s2.capacity() >= 3 ); CPPUNIT_ASSERT ( s1.isEmpty() ); CPPUNIT_ASSERT ( s1.getLength() == 0 ); - CPPUNIT_ASSERT ( s1.capacity() == 0 ); + CPPUNIT_ASSERT ( s1.capacity() < std::wstring().max_size() ); } //---------------------------------------------------------------------- @@ -313,37 +300,30 @@ void FStringTest::assignmentTest() finalcut::FString s1; s1 = static_cast(0); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 = std::wstring(); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 = std::string(); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 = static_cast(0); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 = static_cast(0); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 = wchar_t(0); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 = char(0); CPPUNIT_ASSERT ( ! s1 ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); const finalcut::FString s2("abc"); @@ -351,49 +331,49 @@ void FStringTest::assignmentTest() CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"abc" ); CPPUNIT_ASSERT ( s1.getLength() == 3 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() >= 3 ); const std::wstring s3(L"def"); s1 = s3; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"def" ); CPPUNIT_ASSERT ( s1.getLength() == 3 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() >= 3 ); const std::string s4("ghi"); s1 = s4; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"ghi" ); CPPUNIT_ASSERT ( s1.getLength() == 3 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() >= 3 ); constexpr wchar_t s5[] = L"abc"; s1 = s5; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"abc" ); CPPUNIT_ASSERT ( s1.getLength() == 3 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() >= 3 ); constexpr char s6[] = "def"; s1 = s6; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"def" ); CPPUNIT_ASSERT ( s1.getLength() == 3 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() >= 3 ); constexpr wchar_t s7 = L'#'; s1 = s7; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"#" ); CPPUNIT_ASSERT ( s1.getLength() == 1 ); - CPPUNIT_ASSERT ( s1.capacity() == 16 ); + CPPUNIT_ASSERT ( s1.capacity() >= 1 ); constexpr char s8 = '%'; s1 = s8; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"%" ); CPPUNIT_ASSERT ( s1.getLength() == 1 ); - CPPUNIT_ASSERT ( s1.capacity() == 16 ); + CPPUNIT_ASSERT ( s1.capacity() >= 1 ); s1.setString("A character string"); CPPUNIT_ASSERT ( s1 ); @@ -407,10 +387,10 @@ void FStringTest::assignmentTest() CPPUNIT_ASSERT ( s1 == L"A wide character string" ); s1.setString(""); - CPPUNIT_ASSERT ( s1 ); + CPPUNIT_ASSERT ( ! s1 ); s1.setString(L""); - CPPUNIT_ASSERT ( s1 ); + CPPUNIT_ASSERT ( ! s1 ); s1.setString(""); CPPUNIT_ASSERT ( s1 == "" ); @@ -425,28 +405,25 @@ void FStringTest::assignmentTest() CPPUNIT_ASSERT ( s1.isEmpty() ); s1.setString(""); - CPPUNIT_ASSERT ( ! s1.isNull() ); + CPPUNIT_ASSERT ( s1.isEmpty() ); s1.setString(L""); - CPPUNIT_ASSERT ( ! s1.isNull() ); + CPPUNIT_ASSERT ( s1.isEmpty() ); constexpr wchar_t* wc = 0; s1.setString(wc); CPPUNIT_ASSERT ( s1.isEmpty() ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( ! s1 ); constexpr char* c = 0; s1.setString(c); CPPUNIT_ASSERT ( s1.isEmpty() ); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( ! s1 ); // Move assignment operator auto empty = finalcut::FString(0); const finalcut::FString s9 = std::move(empty); CPPUNIT_ASSERT ( ! s9 ); - CPPUNIT_ASSERT ( s9.isNull() ); CPPUNIT_ASSERT ( s9.isEmpty() ); finalcut::FString s10("abc"); @@ -454,11 +431,10 @@ void FStringTest::assignmentTest() CPPUNIT_ASSERT ( s11 ); CPPUNIT_ASSERT ( s11 == L"abc" ); CPPUNIT_ASSERT ( s11.getLength() == 3 ); - CPPUNIT_ASSERT ( s11.capacity() == 18 ); - CPPUNIT_ASSERT ( s10.isNull() ); + CPPUNIT_ASSERT ( s11.capacity() >= 3 ); CPPUNIT_ASSERT ( s10.isEmpty() ); CPPUNIT_ASSERT ( s10.getLength() == 0 ); - CPPUNIT_ASSERT ( s10.capacity() == 0 ); + CPPUNIT_ASSERT ( s10.capacity() < std::wstring().max_size() ); } //---------------------------------------------------------------------- @@ -475,7 +451,6 @@ void FStringTest::additionAssignmentTest() CPPUNIT_ASSERT ( s1 == L"abcdef" ); s1.clear(); - CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( s1.isEmpty() ); s1 += std::wstring(L"abc"); CPPUNIT_ASSERT ( s1 == L"abc" ); @@ -545,8 +520,8 @@ void FStringTest::additionTest() // Empty const finalcut::FString + ... const finalcut::FString s3; CPPUNIT_ASSERT ( s3.getLength() == 0 ); - CPPUNIT_ASSERT ( s3.c_str() == nullptr ); - CPPUNIT_ASSERT ( s3.wc_str() == nullptr ); + CPPUNIT_ASSERT ( s3.c_str()[0] == '\0' ); + CPPUNIT_ASSERT ( s3.wc_str()[0] == L'\0' ); CPPUNIT_ASSERT ( s3 + finalcut::FString("def") == L"def" ); CPPUNIT_ASSERT ( s3 + std::wstring(L"def") == L"def" ); CPPUNIT_ASSERT ( s3 + const_cast(L"def") == L"def" ); @@ -558,8 +533,8 @@ void FStringTest::additionTest() // Empty finalcut::FString + ... finalcut::FString s4; CPPUNIT_ASSERT ( s4.getLength() == 0 ); - CPPUNIT_ASSERT ( s4.c_str() == nullptr ); - CPPUNIT_ASSERT ( s4.wc_str() == nullptr ); + CPPUNIT_ASSERT ( s4.c_str()[0] == '\0' ); + CPPUNIT_ASSERT ( s4.wc_str()[0] == L'\0' ); CPPUNIT_ASSERT ( s4 + finalcut::FString("def") == L"def" ); CPPUNIT_ASSERT ( s4 + std::wstring(L"def") == L"def" ); CPPUNIT_ASSERT ( s4 + const_cast(L"def") == L"def" ); @@ -642,7 +617,7 @@ void FStringTest::equalTest() CPPUNIT_ASSERT ( one_char == ch ); CPPUNIT_ASSERT ( ch == one_char.c_str()[0] ); CPPUNIT_ASSERT ( one_char.getLength() == 1 ); - CPPUNIT_ASSERT ( one_char.capacity() == 16 ); + CPPUNIT_ASSERT ( one_char.capacity() >= 1 ); constexpr wchar_t wch = L'a'; CPPUNIT_ASSERT ( one_char == wch ); @@ -656,7 +631,7 @@ void FStringTest::equalTest() constexpr char cstr[] = "abc"; CPPUNIT_ASSERT ( str == cstr ); CPPUNIT_ASSERT ( str.getLength() == 3 ); - CPPUNIT_ASSERT ( str.capacity() == 18 ); + CPPUNIT_ASSERT ( str.capacity() >= 3 ); CPPUNIT_ASSERT ( strncmp(cstr, str.c_str(), 3) == 0 ); constexpr wchar_t wcstr[] = L"abc"; @@ -677,7 +652,7 @@ void FStringTest::equalTest() CPPUNIT_ASSERT ( s->c_str()[0] == 'c'); CPPUNIT_ASSERT ( s->getLength() == 1 ); - CPPUNIT_ASSERT ( s->capacity() == 16 ); + CPPUNIT_ASSERT ( s->capacity() >= 1 ); } //---------------------------------------------------------------------- @@ -688,7 +663,7 @@ void FStringTest::notEqualTest() CPPUNIT_ASSERT ( one_char != ch ); CPPUNIT_ASSERT ( ch != one_char.c_str()[0] ); CPPUNIT_ASSERT ( one_char.getLength() == 1 ); - CPPUNIT_ASSERT ( one_char.capacity() == 16 ); + CPPUNIT_ASSERT ( one_char.capacity() >= 1 ); constexpr wchar_t wch = L'_'; CPPUNIT_ASSERT ( one_char != wch ); @@ -704,8 +679,8 @@ void FStringTest::notEqualTest() CPPUNIT_ASSERT ( strlen(s1.c_str()) == 3 ); CPPUNIT_ASSERT ( s2.getLength() == 3 ); CPPUNIT_ASSERT ( strlen(s2.c_str()) == 6 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); - CPPUNIT_ASSERT ( s2.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() >= 3 ); + CPPUNIT_ASSERT ( s2.capacity() >= 3 ); CPPUNIT_ASSERT ( strncmp(cstr, s1.c_str(), 3) != 0 ); constexpr wchar_t wcstr[] = L"abc"; @@ -1196,15 +1171,15 @@ void FStringTest::formatTest() const finalcut::FString null_fstring{}; str2.sprintf (null_fstring, 0); - CPPUNIT_ASSERT ( str2.isNull() ); + CPPUNIT_ASSERT ( str2.isEmpty() ); constexpr wchar_t* null_wstring = 0; str2.sprintf (null_wstring, 0); - CPPUNIT_ASSERT ( str2.isNull() ); + CPPUNIT_ASSERT ( str2.isEmpty() ); constexpr char* null_string = 0; str2.sprintf (null_string, 0); - CPPUNIT_ASSERT ( str2.isNull() ); + CPPUNIT_ASSERT ( str2.isEmpty() ); std::setlocale (LC_NUMERIC, "C"); finalcut::FString fnum1, fnum2; @@ -1483,31 +1458,27 @@ void FStringTest::trimTest() const finalcut::FString& trim_str2 = L"\n \n\n"; CPPUNIT_ASSERT ( trim_str2.rtrim().isEmpty() ); - CPPUNIT_ASSERT ( ! trim_str2.rtrim().isNull() ); CPPUNIT_ASSERT ( trim_str2.rtrim().getLength() == 0 ); - CPPUNIT_ASSERT ( trim_str2.rtrim().capacity() == 0 ); + CPPUNIT_ASSERT ( trim_str2.rtrim().capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( *(trim_str2.rtrim().c_str() + trim_str2.rtrim().getLength()) == '\0' ); CPPUNIT_ASSERT ( *(trim_str2.rtrim().wc_str() + trim_str2.rtrim().getLength()) == L'\0' ); CPPUNIT_ASSERT ( trim_str2.ltrim().isEmpty() ); - CPPUNIT_ASSERT ( ! trim_str2.ltrim().isNull() ); CPPUNIT_ASSERT ( trim_str2.ltrim().getLength() == 0 ); - CPPUNIT_ASSERT ( trim_str2.ltrim().capacity() == 0 ); + CPPUNIT_ASSERT ( trim_str2.ltrim().capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( *(trim_str2.ltrim().c_str() + trim_str2.ltrim().getLength()) == '\0' ); CPPUNIT_ASSERT ( *(trim_str2.ltrim().wc_str() + trim_str2.ltrim().getLength()) == L'\0' ); const finalcut::FString trim_str3{}; CPPUNIT_ASSERT ( trim_str3.ltrim().isEmpty() ); - CPPUNIT_ASSERT ( trim_str3.ltrim().isNull() ); CPPUNIT_ASSERT ( trim_str3.ltrim().getLength() == 0 ); - CPPUNIT_ASSERT ( trim_str3.ltrim().capacity() == 0 ); + CPPUNIT_ASSERT ( trim_str3.ltrim().capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( trim_str3.rtrim().isEmpty() ); CPPUNIT_ASSERT ( trim_str3.rtrim().isEmpty() ); CPPUNIT_ASSERT ( trim_str3.rtrim().getLength() == 0 ); - CPPUNIT_ASSERT ( trim_str3.rtrim().capacity() == 0 ); + CPPUNIT_ASSERT ( trim_str3.rtrim().capacity() < std::wstring().max_size() ); CPPUNIT_ASSERT ( trim_str3.trim().isEmpty() ); - CPPUNIT_ASSERT ( trim_str3.trim().isNull() ); CPPUNIT_ASSERT ( trim_str3.trim().getLength() == 0 ); - CPPUNIT_ASSERT ( trim_str3.trim().capacity() == 0 ); + CPPUNIT_ASSERT ( trim_str3.trim().capacity() < std::wstring().max_size() ); } //---------------------------------------------------------------------- @@ -1527,9 +1498,7 @@ void FStringTest::subStringTest() CPPUNIT_ASSERT ( str1.left(-5).getLength() == 39 ); CPPUNIT_ASSERT ( str1.left(0) == L"" ); CPPUNIT_ASSERT ( str1.left(0).isEmpty() ); - CPPUNIT_ASSERT ( ! str1.left(0).isNull() ); - CPPUNIT_ASSERT ( finalcut::FString().left(5).isNull() ); - CPPUNIT_ASSERT ( ! finalcut::FString("").left(5).isNull() ); + CPPUNIT_ASSERT ( finalcut::FString().left(5).isEmpty() ); CPPUNIT_ASSERT ( finalcut::FString("").left(5).isEmpty() ); CPPUNIT_ASSERT ( finalcut::FString("").left(5).getLength() == 0 ); @@ -1546,9 +1515,7 @@ void FStringTest::subStringTest() CPPUNIT_ASSERT ( str1.right(-5).getLength() == 39 ); CPPUNIT_ASSERT ( str1.right(0) == L"" ); CPPUNIT_ASSERT ( str1.right(0).isEmpty() ); - CPPUNIT_ASSERT ( ! str1.right(0).isNull() ); - CPPUNIT_ASSERT ( finalcut::FString().right(5).isNull() ); - CPPUNIT_ASSERT ( ! finalcut::FString("").right(5).isNull() ); + CPPUNIT_ASSERT ( finalcut::FString().right(5).isEmpty() ); CPPUNIT_ASSERT ( finalcut::FString("").right(5).isEmpty() ); CPPUNIT_ASSERT ( finalcut::FString("").right(5).getLength() == 0 ); @@ -1567,9 +1534,7 @@ void FStringTest::subStringTest() CPPUNIT_ASSERT ( str1.mid(0, 0) == L"" ); CPPUNIT_ASSERT ( str1.mid(0, 5) == L"Look " ); CPPUNIT_ASSERT ( str1.mid(0, 0).isEmpty() ); - CPPUNIT_ASSERT ( ! str1.mid(0, 0).isNull() ); - CPPUNIT_ASSERT ( finalcut::FString().mid(5, 0).isNull() ); - CPPUNIT_ASSERT ( ! finalcut::FString("").mid(5, 0).isNull() ); + CPPUNIT_ASSERT ( finalcut::FString().mid(5, 0).isEmpty() ); CPPUNIT_ASSERT ( finalcut::FString("").mid(5, 0).isEmpty() ); CPPUNIT_ASSERT ( str1.mid(5, 0).getLength() == 0 ); @@ -1935,14 +1900,10 @@ void FStringTest::replaceTest() CPPUNIT_ASSERT ( s1.replace(from6, empty) == "ABC" ); s1.clear(); - CPPUNIT_ASSERT ( s1.replace(from1, to1).isNull() ); CPPUNIT_ASSERT ( s1.replace(from1, to1).isEmpty() ); - CPPUNIT_ASSERT ( s1.replace(from6, to1).isNull() ); CPPUNIT_ASSERT ( s1.replace(from6, to1).isEmpty() ); - CPPUNIT_ASSERT ( s1.replace(from5, to5).isNull() ); CPPUNIT_ASSERT ( s1.replace(from5, to5).isEmpty() ); - CPPUNIT_ASSERT ( s1.replace(from7, to7).isNull() ); CPPUNIT_ASSERT ( s1.replace(from7, to7).isEmpty() ); } diff --git a/test/fstringstream-test.cpp b/test/fstringstream-test.cpp index 36642e53..d26e439f 100644 --- a/test/fstringstream-test.cpp +++ b/test/fstringstream-test.cpp @@ -3,7 +3,7 @@ * * * This file is part of the FINAL CUT widget toolkit * * * -* Copyright 2020 Markus Gans * +* Copyright 2020-2021 Markus Gans * * * * FINAL CUT is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -83,12 +83,10 @@ void FStringStreamTest::classNameTest() void FStringStreamTest::defaultObjectTest() { finalcut::FStringStream ss{std::ios_base::out}; - CPPUNIT_ASSERT ( ss.str().isNull() ); CPPUNIT_ASSERT ( ss.str().isEmpty() ); - CPPUNIT_ASSERT ( ss.str() != "" ); + CPPUNIT_ASSERT ( ss.str() == "" ); ss << "Hello"; - CPPUNIT_ASSERT ( ! ss.str().isNull() ); CPPUNIT_ASSERT ( ! ss.str().isEmpty() ); CPPUNIT_ASSERT ( ss.str() = "Hello" ); @@ -97,9 +95,8 @@ void FStringStreamTest::defaultObjectTest() CPPUNIT_ASSERT ( ss.str() == L"Hello, World!" ); ss.clear(); - CPPUNIT_ASSERT ( ss.str().isNull() ); CPPUNIT_ASSERT ( ss.str().isEmpty() ); - CPPUNIT_ASSERT ( ss.str() != "" ); + CPPUNIT_ASSERT ( ss.str() == "" ); ss.clear(); ss << "Three" << " " << "parts"; @@ -140,7 +137,6 @@ void FStringStreamTest::moveConstructorTest() const finalcut::FStringStream ss2{std::move(ss1)}; CPPUNIT_ASSERT ( ss2.str() == L"abc" ); CPPUNIT_ASSERT ( ss2.str().getLength() == 3 ); - CPPUNIT_ASSERT ( ss1.str().isNull() ); CPPUNIT_ASSERT ( ss1.str().isEmpty() ); CPPUNIT_ASSERT ( ss1.str().getLength() == 0 ); } @@ -153,7 +149,6 @@ void FStringStreamTest::assignmentTest() ss2 = std::move(ss1); CPPUNIT_ASSERT ( ss2.str() == L"xyz" ); CPPUNIT_ASSERT ( ss2.str().getLength() == 3 ); - CPPUNIT_ASSERT ( ss1.str().isNull() ); CPPUNIT_ASSERT ( ss1.str().isEmpty() ); CPPUNIT_ASSERT ( ss1.str().getLength() == 0 ); } @@ -189,7 +184,6 @@ void FStringStreamTest::rdbufTest() CPPUNIT_ASSERT ( ss.str().getLength() == 4 ); ss.rdbuf()->str(L""); - CPPUNIT_ASSERT ( ss.str().isNull() ); CPPUNIT_ASSERT ( ss.str().isEmpty() ); CPPUNIT_ASSERT ( ss.str().getLength() == 0 ); }