diff --git a/ChangeLog b/ChangeLog index 3172fb40..2521e9d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2020-05-24 Markus Gans + * New class FStringStream implements input and output operations + on FString based streams + 2020-05-21 Markus Gans * Fixed the event queue in FApplication diff --git a/examples/rotozoomer.cpp b/examples/rotozoomer.cpp index e3aa100f..adfa2fd4 100644 --- a/examples/rotozoomer.cpp +++ b/examples/rotozoomer.cpp @@ -183,7 +183,7 @@ void RotoZoomer::generateReport() finalcut::FString dimension_str{}; finalcut::FString time_str{}; finalcut::FString fps_str{}; - std::wostringstream rep; + finalcut::FStringStream rep; dimension_str << getDesktopWidth() << "x" << getDesktopHeight(); int elapsed_ms = int(duration_cast(end - start).count()); diff --git a/src/Makefile.am b/src/Makefile.am index 80c74b67..dadf1af8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,6 +10,7 @@ lib_LTLIBRARIES = libfinal.la libfinal_la_SOURCES = \ fstring.cpp \ + fstringstream.cpp \ fpoint.cpp \ fsize.cpp \ frect.cpp \ @@ -130,6 +131,7 @@ finalcutinclude_HEADERS = \ include/final/fstartoptions.h \ include/final/fstatusbar.h \ include/final/fstring.h \ + include/final/fstringstream.h \ include/final/fsystem.h \ include/final/fsystemimpl.h \ include/final/ftermcap.h \ diff --git a/src/Makefile.clang b/src/Makefile.clang index 55691c9c..80e85541 100644 --- a/src/Makefile.clang +++ b/src/Makefile.clang @@ -51,6 +51,7 @@ INCLUDE_HEADERS = \ fcombobox.h \ fstatusbar.h \ fstring.h \ + fstringstream.h \ fmouse.h \ fkeyboard.h \ fstartoptions.h \ @@ -85,6 +86,7 @@ RM = rm -f LIB = libfinal.so OBJS = \ fstring.o \ + fstringstream.o \ fpoint.o \ fsize.o \ frect.o \ diff --git a/src/Makefile.gcc b/src/Makefile.gcc index d1d2f3a2..7998d9c6 100644 --- a/src/Makefile.gcc +++ b/src/Makefile.gcc @@ -51,6 +51,7 @@ INCLUDE_HEADERS = \ fcombobox.h \ fstatusbar.h \ fstring.h \ + fstringstream.h \ fmouse.h \ fkeyboard.h \ fstartoptions.h \ @@ -85,6 +86,7 @@ RM = rm -f LIB = libfinal.so OBJS = \ fstring.o \ + fstringstream.o \ fpoint.o \ fsize.o \ frect.o \ diff --git a/src/fdialog.cpp b/src/fdialog.cpp index 6311f85d..64b40d70 100644 --- a/src/fdialog.cpp +++ b/src/fdialog.cpp @@ -50,7 +50,7 @@ FDialog::FDialog (FWidget* parent) //---------------------------------------------------------------------- FDialog::FDialog (const FString& txt, FWidget* parent) : FWindow(parent) - , tb_text(txt) + , tb_text{txt} { init(); } diff --git a/src/flogger.cpp b/src/flogger.cpp index b23bdc99..68720d68 100644 --- a/src/flogger.cpp +++ b/src/flogger.cpp @@ -61,7 +61,6 @@ const std::string FLogger::getTimeString() char str[100]; const auto& now = std::chrono::system_clock::now(); const auto& t = std::chrono::system_clock::to_time_t(now); - std::stringstream str_stream; // Print RFC 2822 date struct tm time{}; localtime_r (&t, &time); diff --git a/src/fstring.cpp b/src/fstring.cpp index f10e8623..d23ca52e 100644 --- a/src/fstring.cpp +++ b/src/fstring.cpp @@ -77,14 +77,15 @@ FString::FString (const FString& s) // copy constructor //---------------------------------------------------------------------- FString::FString (FString&& s) noexcept // move constructor { - if ( ! s.isNull() ) - _assign (std::move(s.string)); - else - s.string = nullptr; + string = std::move(s.string); + c_string = std::move(c_string); + length = s.length; + bufsize = s.bufsize; + s.string = nullptr; + s.c_string = nullptr; s.length = 0; s.bufsize = 0; - s.c_string = nullptr; } //---------------------------------------------------------------------- @@ -181,7 +182,15 @@ FString& FString::operator = (const FString& s) //---------------------------------------------------------------------- FString& FString::operator = (FString&& s) noexcept { - _assign (std::move(s.string)); + string = std::move(s.string); + c_string = std::move(c_string); + length = s.length; + bufsize = s.bufsize; + + s.string = nullptr; + s.c_string = nullptr; + s.length = 0; + s.bufsize = 0; return *this; } diff --git a/src/fstringstream.cpp b/src/fstringstream.cpp new file mode 100644 index 00000000..3aa6b3fd --- /dev/null +++ b/src/fstringstream.cpp @@ -0,0 +1,75 @@ +/*********************************************************************** +* fstringstream.cpp - I/O operations on FString based streams * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2020 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +#include "final/fstring.h" +#include "final/fstringstream.h" + +namespace finalcut +{ + +//---------------------------------------------------------------------- +// class FStringStream +//---------------------------------------------------------------------- + +// constructors and destructor +//---------------------------------------------------------------------- +FStringStream::FStringStream (openmode mode) + : std::wiostream{&buffer} + , buffer{mode} +{ } + +//---------------------------------------------------------------------- +FStringStream::FStringStream (const FString& str, openmode mode) + : std::wiostream{&buffer} + , buffer{str.wc_str(), mode} +{ } + +//---------------------------------------------------------------------- +FStringStream::FStringStream (FStringStream&& sstream) + : std::wiostream{std::move(sstream)} + , buffer{std::move(sstream.buffer)} +{ + std::wiostream::set_rdbuf(&buffer); +} + +//---------------------------------------------------------------------- +FStringStream::~FStringStream() // destructor +{ } + +// public methods of FStringStream +//---------------------------------------------------------------------- +FStringStream& FStringStream::operator = (FStringStream&& sstream) +{ + std::wiostream::operator = (std::move(sstream)); + buffer = std::move(sstream.buffer); + return *this; +} + +//---------------------------------------------------------------------- +void FStringStream::swap (FStringStream& sstream) +{ + std::wiostream::swap(sstream); + buffer.swap(sstream.buffer); +} + +} // namespace finalcut + diff --git a/src/ftooltip.cpp b/src/ftooltip.cpp index 31cfbf13..cb4086a8 100644 --- a/src/ftooltip.cpp +++ b/src/ftooltip.cpp @@ -42,7 +42,7 @@ FToolTip::FToolTip (FWidget* parent) //---------------------------------------------------------------------- FToolTip::FToolTip (const FString& txt, FWidget* parent) : FWindow(parent) - , text(txt) + , text{txt} { init(); } diff --git a/src/fvterm.cpp b/src/fvterm.cpp index 4d5bac52..b5ea316e 100644 --- a/src/fvterm.cpp +++ b/src/fvterm.cpp @@ -1895,7 +1895,7 @@ const FChar FVTerm::getOverlappedCharacter (const FPoint& pos, FVTerm* obj) // Gets the overlapped character for a given position return getCharacter (overlapped_character, pos, obj); } -#include + //---------------------------------------------------------------------- void FVTerm::init (bool disable_alt_screen) { diff --git a/src/include/final/emptyfstring.h b/src/include/final/emptyfstring.h index 2c3f9e6a..46174f1f 100644 --- a/src/include/final/emptyfstring.h +++ b/src/include/final/emptyfstring.h @@ -20,6 +20,14 @@ * . * ***********************************************************************/ +/* Standalone class + * ════════════════ + * + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ emptyFString ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + */ + #ifndef EMPTYFSTRING_H #define EMPTYFSTRING_H diff --git a/src/include/final/flog.h b/src/include/final/flog.h index 9b1616dd..ef5d372c 100644 --- a/src/include/final/flog.h +++ b/src/include/final/flog.h @@ -20,12 +20,17 @@ * . * ***********************************************************************/ -/* Standalone class - * ════════════════ +/* Inheritance diagram + * ═══════════════════ * - * ▕▔▔▔▔▔▔▏ - * ▕ FLog ▏ - * ▕▁▁▁▁▁▁▏ + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ std::stringbuf ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▏ + * ▕ FLog ▏ + * ▕▁▁▁▁▁▁▏ */ #ifndef FLOG_H @@ -68,7 +73,6 @@ class FLog : public std::stringbuf LF, CR, CRLF }; - // Constructor FLog(); diff --git a/src/include/final/flogger.h b/src/include/final/flogger.h index a1eda13d..cdba1192 100644 --- a/src/include/final/flogger.h +++ b/src/include/final/flogger.h @@ -20,12 +20,22 @@ * . * ***********************************************************************/ -/* Standalone class - * ════════════════ +/* Inheritance diagram + * ═══════════════════ * - * ▕▔▔▔▔▔▔▔▔▔▏ - * ▕ FLogger ▏ - * ▕▁▁▁▁▁▁▁▁▁▏ + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ std::stringbuf ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▏ + * ▕ FLog ▏ + * ▕▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▔▔▔▏ + * ▕ FLogger ▏ + * ▕▁▁▁▁▁▁▁▁▁▏ */ #ifndef FLOGGER_H diff --git a/src/include/final/fpoint.h b/src/include/final/fpoint.h index 20cb59fd..a3ae4b22 100644 --- a/src/include/final/fpoint.h +++ b/src/include/final/fpoint.h @@ -103,20 +103,20 @@ class FPoint // FPoint inline functions //---------------------------------------------------------------------- inline FPoint::FPoint (const FPoint& p) // copy constructor - : xpos(p.xpos) - , ypos(p.ypos) + : xpos{p.xpos} + , ypos{p.ypos} { } //---------------------------------------------------------------------- inline FPoint::FPoint (FPoint&& p) noexcept // move constructor - : xpos(std::move(p.xpos)) - , ypos(std::move(p.ypos)) + : xpos{std::move(p.xpos)} + , ypos{std::move(p.ypos)} { } //---------------------------------------------------------------------- inline FPoint::FPoint (int x, int y) - : xpos(x) - , ypos(y) + : xpos{x} + , ypos{y} { } //---------------------------------------------------------------------- diff --git a/src/include/final/frect.h b/src/include/final/frect.h index b874a58e..1e538437 100644 --- a/src/include/final/frect.h +++ b/src/include/final/frect.h @@ -148,26 +148,26 @@ class FRect // FRect inline functions //---------------------------------------------------------------------- inline FRect::FRect (const FRect& r) // copy constructor - : X1(r.X1) - , Y1(r.Y1) - , X2(r.X2) - , Y2(r.Y2) + : X1{r.X1} + , Y1{r.Y1} + , X2{r.X2} + , Y2{r.Y2} { } //---------------------------------------------------------------------- inline FRect::FRect (FRect&& r) noexcept // move constructor - : X1(std::move(r.X1)) - , Y1(std::move(r.Y1)) - , X2(std::move(r.X2)) - , Y2(std::move(r.Y2)) + : X1{std::move(r.X1)} + , Y1{std::move(r.Y1)} + , X2{std::move(r.X2)} + , Y2{std::move(r.Y2)} { } //---------------------------------------------------------------------- inline FRect::FRect (int x, int y, std::size_t width, std::size_t height) - : X1(x) - , Y1(y) - , X2(x + int(width) - 1) - , Y2(y + int(height) - 1) + : X1{x} + , Y1{y} + , X2{x + int(width) - 1} + , Y2{y + int(height) - 1} { } //---------------------------------------------------------------------- diff --git a/src/include/final/fsize.h b/src/include/final/fsize.h index 596435e1..fe6373b7 100644 --- a/src/include/final/fsize.h +++ b/src/include/final/fsize.h @@ -112,20 +112,20 @@ class FSize // FSize inline functions //---------------------------------------------------------------------- inline FSize::FSize (const FSize& s) // copy constructor - : width(s.width) - , height(s.height) + : width{s.width} + , height{s.height} { } //---------------------------------------------------------------------- inline FSize::FSize (FSize&& s) noexcept // move constructor - : width(std::move(s.width)) - , height(std::move(s.height)) + : width{std::move(s.width)} + , height{std::move(s.height)} { } //---------------------------------------------------------------------- inline FSize::FSize (std::size_t w, std::size_t h) - : width(w) - , height(h) + : width{w} + , height{h} { } //---------------------------------------------------------------------- diff --git a/src/include/final/fstring.h b/src/include/final/fstring.h index e7984ba4..f1d2f43b 100644 --- a/src/include/final/fstring.h +++ b/src/include/final/fstring.h @@ -87,8 +87,8 @@ class FString explicit FString (int); explicit FString (std::size_t); FString (std::size_t, wchar_t); - FString (const FString&); // implicit conversion copy constructor - FString (FString&&) noexcept; // implicit conversion move constructor + FString (const FString&); // copy constructor + FString (FString&&) noexcept; // move constructor FString (const std::wstring&); // implicit conversion constructor FString (const wchar_t[]); // implicit conversion constructor FString (const std::string&); // implicit conversion constructor @@ -375,11 +375,11 @@ inline const FString FString::getClassName() const //---------------------------------------------------------------------- inline bool FString::isNull() const -{ return ! string; } +{ return ( bufsize == 0 || (bufsize > 0 && ! string) ); } //---------------------------------------------------------------------- inline bool FString::isEmpty() const -{ return ( ! string ) || ( ! *string ); } +{ return ( length == 0 || (length > 0 && string[0] == L'\0') ); } //---------------------------------------------------------------------- inline std::size_t FString::getLength() const diff --git a/src/include/final/fstringstream.h b/src/include/final/fstringstream.h new file mode 100644 index 00000000..f6b2458e --- /dev/null +++ b/src/include/final/fstringstream.h @@ -0,0 +1,120 @@ +/*********************************************************************** +* fstringstream.h - I/O operations on FString based streams * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2020 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +/* Inheritance diagram + * ═══════════════════ + * + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ std::wiostream ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ FStringStream ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + */ + +#ifndef FSTRINGSTREAM_H +#define FSTRINGSTREAM_H + +#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT) + #error "Only can be included directly." +#endif + +#include +#include +#include + +namespace finalcut +{ + +// class forward declaration +class FString; + +//---------------------------------------------------------------------- +// class FStringStream +//---------------------------------------------------------------------- + +class FStringStream : public std::wiostream +{ + public: + using std::ios_base::openmode; + static constexpr openmode in_out = std::ios_base::out + | std::ios_base::in; + + // Constructors + explicit FStringStream (openmode = in_out); + explicit FStringStream (const FString&, openmode = in_out); + + // Disable copy constructor + FStringStream (const FStringStream&) = delete; + + // Move constructor + FStringStream (FStringStream&&); + + // Destructor + ~FStringStream(); + + // Disable copy assignment operator (=) + FStringStream& operator = (const FStringStream&) = delete; + + // Move assignment operator (=) + FStringStream& operator = (FStringStream&& sstream); + + virtual const FString getClassName() const; + void swap (FStringStream&); + void clear(); + std::wstringbuf* rdbuf() const; + FString str() const; + + private: + std::wstringbuf buffer{in_out}; +}; + + +// FStringStream inline functions +//---------------------------------------------------------------------- +inline const FString FStringStream::getClassName() const +{ return "FStringStream"; } + +//---------------------------------------------------------------------- +inline void FStringStream::clear() +{ buffer.str(L""); } + +//---------------------------------------------------------------------- +inline std::wstringbuf* FStringStream::rdbuf() const +{ return const_cast(&buffer); } + +//---------------------------------------------------------------------- +inline FString FStringStream::str() const +{ return buffer.str(); } + + +// FStringStream non-member function +//---------------------------------------------------------------------- +inline void swap (FStringStream& a, FStringStream& b) +{ a.swap(b); } + + +} // namespace finalcut + +#endif // FSTRINGSTREAM_H diff --git a/src/include/final/fsystemimpl.h b/src/include/final/fsystemimpl.h index 4fda025a..44d8c687 100644 --- a/src/include/final/fsystemimpl.h +++ b/src/include/final/fsystemimpl.h @@ -20,12 +20,17 @@ * . * ***********************************************************************/ -/* Standalone class - * ════════════════ +/* Inheritance diagram + * ═══════════════════ * - * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏ - * ▕ FSystemImpl ▏ - * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏ + * ▕▔▔▔▔▔▔▔▔▔▏ + * ▕ FSystem ▏ + * ▕▁▁▁▁▁▁▁▁▁▏ + * ▲ + * │ + * ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏ + * ▕ FSystemImpl ▏ + * ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏ */ #ifndef FSYSTEMIMPL_H diff --git a/src/include/final/ftermbuffer.h b/src/include/final/ftermbuffer.h index 6f55a5d2..84fa4a0e 100644 --- a/src/include/final/ftermbuffer.h +++ b/src/include/final/ftermbuffer.h @@ -35,11 +35,12 @@ #error "Only can be included directly." #endif -#include // std::stringstream #include #include #include +#include "final/fstringstream.h" + namespace finalcut { @@ -122,10 +123,10 @@ inline FTermBuffer::FTermBuffer(Iterator first, Iterator last) template inline FTermBuffer& FTermBuffer::operator << (const typeT& s) { - std::wostringstream outstream; + FStringStream outstream{std::ios_base::out}; outstream << s; - if ( ! outstream.str().empty() ) + if ( ! outstream.str().isEmpty() ) write (outstream.str()); return *this; diff --git a/src/include/final/ftextview.h b/src/include/final/ftextview.h index 859c108c..54606d4f 100644 --- a/src/include/final/ftextview.h +++ b/src/include/final/ftextview.h @@ -51,6 +51,7 @@ #include #include +#include "final/fstringstream.h" #include "final/fwidget.h" namespace finalcut @@ -186,10 +187,10 @@ inline FTextView& FTextView::operator = (const FString& s) template inline FTextView& FTextView::operator << (const typeT& s) { - std::wostringstream outstream; + FStringStream outstream{std::ios_base::out}; outstream << s; - if ( ! outstream.str().empty() ) + if ( ! outstream.str().isEmpty() ) append (outstream.str()); return *this; diff --git a/src/include/final/fvterm.h b/src/include/final/fvterm.h index dfa89328..497d3d11 100644 --- a/src/include/final/fvterm.h +++ b/src/include/final/fvterm.h @@ -49,12 +49,12 @@ #endif #include -#include // std::stringstream #include #include #include #include "final/fc.h" +#include "final/fstringstream.h" #include "final/fterm.h" #define F_PREPROC_HANDLER(i,h) \ @@ -546,10 +546,10 @@ struct FVTerm::FVTermPreprocessing template inline FVTerm& FVTerm::operator << (const typeT& s) { - std::wostringstream outstream; + FStringStream outstream{std::ios_base::out}; outstream << s; - if ( ! outstream.str().empty() ) + if ( ! outstream.str().isEmpty() ) print (outstream.str()); return *this; diff --git a/test/Makefile.am b/test/Makefile.am index b482d451..6c0f8bfa 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -21,6 +21,7 @@ noinst_PROGRAMS = \ fcolorpair_test \ fstyle_test \ fstring_test \ + fstringstream_test \ flogger_test \ fsize_test \ fpoint_test \ @@ -40,6 +41,7 @@ foptiattr_test_SOURCES = foptiattr-test.cpp fcolorpair_test_SOURCES = fcolorpair-test.cpp fstyle_test_SOURCES = fstyle-test.cpp fstring_test_SOURCES = fstring-test.cpp +fstringstream_test_SOURCES = fstringstream-test.cpp flogger_test_SOURCES = flogger-test.cpp fsize_test_SOURCES = fsize-test.cpp fpoint_test_SOURCES = fpoint-test.cpp @@ -59,6 +61,7 @@ TESTS = fobject_test \ fcolorpair_test \ fstyle_test \ fstring_test \ + fstringstream_test \ flogger_test \ fsize_test \ fpoint_test \ diff --git a/test/flogger-test.cpp b/test/flogger-test.cpp index eea57d37..0056d43a 100644 --- a/test/flogger-test.cpp +++ b/test/flogger-test.cpp @@ -35,6 +35,7 @@ //---------------------------------------------------------------------- // class FLoggerTest //---------------------------------------------------------------------- + class myLogger : public finalcut::FLog { public: @@ -288,7 +289,7 @@ void FLoggerTest::fileTest() if ( file_stream.is_open() ) file_stream.close(); - int ret = remove("test.log"); // Delete file + int ret = remove(filename.c_str()); // Delete file if ( ret == -1 ) { diff --git a/test/fstring-test.cpp b/test/fstring-test.cpp index 74cf4647..5e468441 100644 --- a/test/fstring-test.cpp +++ b/test/fstring-test.cpp @@ -58,6 +58,7 @@ class FStringTest : public CPPUNIT_NS::TestFixture void noArgumentTest(); void initLengthTest(); void copyConstructorTest(); + void moveConstructorTest(); void assignmentTest(); void additionAssignmentTest(); void additionTest(); @@ -97,6 +98,7 @@ class FStringTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST (noArgumentTest); CPPUNIT_TEST (initLengthTest); CPPUNIT_TEST (copyConstructorTest); + CPPUNIT_TEST (moveConstructorTest); CPPUNIT_TEST (assignmentTest); CPPUNIT_TEST (additionAssignmentTest); CPPUNIT_TEST (additionTest); @@ -291,6 +293,20 @@ void FStringTest::copyConstructorTest() CPPUNIT_ASSERT ( s2.capacity() == 18 ); } +//---------------------------------------------------------------------- +void FStringTest::moveConstructorTest() +{ + finalcut::FString s1("abc"); + 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 ( s1.isEmpty() ); + CPPUNIT_ASSERT ( s1.getLength() == 0 ); + CPPUNIT_ASSERT ( s1.capacity() == 0 ); +} + //---------------------------------------------------------------------- void FStringTest::assignmentTest() { @@ -370,14 +386,14 @@ void FStringTest::assignmentTest() CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"#" ); CPPUNIT_ASSERT ( s1.getLength() == 1 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() == 16 ); constexpr char s8 = '%'; s1 = s8; CPPUNIT_ASSERT ( s1 ); CPPUNIT_ASSERT ( s1 == L"%" ); CPPUNIT_ASSERT ( s1.getLength() == 1 ); - CPPUNIT_ASSERT ( s1.capacity() == 18 ); + CPPUNIT_ASSERT ( s1.capacity() == 16 ); s1.setString("A character string"); CPPUNIT_ASSERT ( s1 ); @@ -425,6 +441,22 @@ void FStringTest::assignmentTest() CPPUNIT_ASSERT ( s1.isEmpty() ); CPPUNIT_ASSERT ( s1.isNull() ); CPPUNIT_ASSERT ( ! s1 ); + + // Move assignment operator + const finalcut::FString s9 = std::move(finalcut::FString(0)); + CPPUNIT_ASSERT ( ! s9 ); + CPPUNIT_ASSERT ( s9.isNull() ); + CPPUNIT_ASSERT ( s9.isEmpty() ); + finalcut::FString s10("abc"); + const finalcut::FString s11 = std::move(s10); + CPPUNIT_ASSERT ( s11 ); + CPPUNIT_ASSERT ( s11 == L"abc" ); + CPPUNIT_ASSERT ( s11.getLength() == 3 ); + CPPUNIT_ASSERT ( s11.capacity() == 18 ); + CPPUNIT_ASSERT ( s10.isNull() ); + CPPUNIT_ASSERT ( s10.isEmpty() ); + CPPUNIT_ASSERT ( s10.getLength() == 0 ); + CPPUNIT_ASSERT ( s10.capacity() == 0 ); } //---------------------------------------------------------------------- diff --git a/test/fstringstream-test.cpp b/test/fstringstream-test.cpp new file mode 100644 index 00000000..4b12156e --- /dev/null +++ b/test/fstringstream-test.cpp @@ -0,0 +1,235 @@ +/*********************************************************************** +* fstringstream-test.cpp - FStringStream unit tests * +* * +* This file is part of the Final Cut widget toolkit * +* * +* Copyright 2020 Markus Gans * +* * +* The Final Cut is free software; you can redistribute it and/or * +* modify it under the terms of the GNU Lesser General Public License * +* as published by the Free Software Foundation; either version 3 of * +* the License, or (at your option) any later version. * +* * +* The Final Cut is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with this program. If not, see * +* . * +***********************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +//---------------------------------------------------------------------- +// class FStringStreamTest +//---------------------------------------------------------------------- + +class FStringStreamTest : public CPPUNIT_NS::TestFixture +{ + public: + FStringStreamTest() + { } + + protected: + void classNameTest(); + void defaultObjectTest(); + void moveConstructorTest(); + void assignmentTest(); + void swapTest(); + void rdbufTest(); + void fileTest(); + + + private: + // Adds code needed to register the test suite + CPPUNIT_TEST_SUITE (FStringStreamTest); + + // Add a methods to the test suite + CPPUNIT_TEST (classNameTest); + CPPUNIT_TEST (defaultObjectTest); + CPPUNIT_TEST (moveConstructorTest); + CPPUNIT_TEST (assignmentTest); + CPPUNIT_TEST (swapTest); + CPPUNIT_TEST (rdbufTest); + CPPUNIT_TEST (fileTest); + + // End of test suite definition + CPPUNIT_TEST_SUITE_END(); +}; + +//---------------------------------------------------------------------- +void FStringStreamTest::classNameTest() +{ + finalcut::FStringStream string_stream; + const finalcut::FString& classname = string_stream.getClassName(); + CPPUNIT_ASSERT ( classname == "FStringStream" ); +} + +//---------------------------------------------------------------------- +void FStringStreamTest::defaultObjectTest() +{ + finalcut::FStringStream ss{std::ios_base::out}; + CPPUNIT_ASSERT ( ss.str().isNull() ); + CPPUNIT_ASSERT ( ss.str().isEmpty() ); + CPPUNIT_ASSERT ( ss.str() != "" ); + + ss << "Hello"; + CPPUNIT_ASSERT ( ! ss.str().isNull() ); + CPPUNIT_ASSERT ( ! ss.str().isEmpty() ); + CPPUNIT_ASSERT ( ss.str() = "Hello" ); + + ss << ", World!"; + CPPUNIT_ASSERT ( ss.str() == "Hello, World!" ); + CPPUNIT_ASSERT ( ss.str() == L"Hello, World!" ); + + ss.clear(); + CPPUNIT_ASSERT ( ss.str().isNull() ); + CPPUNIT_ASSERT ( ss.str().isEmpty() ); + CPPUNIT_ASSERT ( ss.str() != "" ); + ss.clear(); + + ss << "Three" << " " << "parts"; + CPPUNIT_ASSERT ( ss.str() == L"Three parts" ); + ss.clear(); + + finalcut::FStringStream in{"21 45 45", std::ios_base::in}; + int n1{0}; + int n2{0}; + int n3{0}; + in >> std::hex >> n1 >> n2 + >> std::oct >> n3; + CPPUNIT_ASSERT ( n1 == 33 ); + CPPUNIT_ASSERT ( n2 == 69 ); + CPPUNIT_ASSERT ( n3 == 37 ); + + ss << "Line break at the end" << std::endl; + CPPUNIT_ASSERT ( ss.str() == "Line break at the end\n" ); + ss.clear(); + + ss << std::resetiosflags(std::ios_base::basefield) + << 20 << " " << std::showbase << std::hex + << 20 << " " << std::noshowbase << std::oct + << 20 << " " << std::boolalpha + << bool(20) << " " << std::dec + << 20; + CPPUNIT_ASSERT ( ss.str() == "20 0x14 24 true 20" ); + ss.clear(); + + ss << "|" << std::setfill(L'-') << std::setw(6) << "|"; + CPPUNIT_ASSERT ( ss.str() == "|-----|" ); +} + +//---------------------------------------------------------------------- +void FStringStreamTest::moveConstructorTest() +{ + finalcut::FStringStream ss1{"abc"}; + 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 ); +} + +//---------------------------------------------------------------------- +void FStringStreamTest::assignmentTest() +{ + finalcut::FStringStream ss1{"xyz"}; + finalcut::FStringStream ss2{}; + 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 ); +} + +//---------------------------------------------------------------------- +void FStringStreamTest::swapTest() +{ + finalcut::FStringStream ss1{"FStringStream"}; + finalcut::FStringStream ss2{"FINAL CUT"}; + CPPUNIT_ASSERT ( ss1.str() == "FStringStream" ); + CPPUNIT_ASSERT ( ss2.str() == "FINAL CUT" ); + ss1.swap(ss2); + CPPUNIT_ASSERT ( ss1.str() == "FINAL CUT" ); + CPPUNIT_ASSERT ( ss2.str() == "FStringStream" ); + + finalcut::FStringStream ss3{"dog"}; + finalcut::FStringStream ss4{"cat"}; + CPPUNIT_ASSERT ( ss3.str() == "dog" ); + CPPUNIT_ASSERT ( ss4.str() == "cat" ); + finalcut::swap (ss3, ss4); + CPPUNIT_ASSERT ( ss3.str() == "cat" ); + CPPUNIT_ASSERT ( ss4.str() == "dog" ); +} + +//---------------------------------------------------------------------- +void FStringStreamTest::rdbufTest() +{ + finalcut::FStringStream ss{}; + std::wostream os (ss.rdbuf()); // Associate stream buffer to stream + ss.rdbuf()->sputn (L"0x", 2); + os << std::hex << 255; + CPPUNIT_ASSERT ( ss.str() == "0xff" ); + 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 ); +} + +//---------------------------------------------------------------------- +void FStringStreamTest::fileTest() +{ + std::string filename = "test.log"; + finalcut::FStringStream ss{}; + + { + std::ofstream file_stream(filename, std::ofstream::out); + ss << "FStringStream file test\n"; + file_stream << ss.str(); + + if ( file_stream.is_open() ) + file_stream.close(); + } + + std::string line{}; + std::ifstream file_stream{filename}; + + if ( ! file_stream.eof() && file_stream.good() ) + { + getline(file_stream, line); + CPPUNIT_ASSERT ( line == "FStringStream file test" ); + } + + if ( file_stream.is_open() ) + file_stream.close(); + + int ret = remove(filename.c_str()); // Delete file + + if ( ret == -1 ) + { + std::cerr << "Cannot delete the " << filename << " file"; + } +} + +// Put the test suite in the registry +CPPUNIT_TEST_SUITE_REGISTRATION (FStringStreamTest); + +// The general unit test main part +#include +