From 736fe4477b28852a44535a32b3869af654e99811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 31 Dec 2019 19:05:53 -0300 Subject: [PATCH] Added Time::toString(). Http request demo: improvements in progress report. --HG-- branch : dev --- include/eepp/system/time.hpp | 10 +- src/eepp/system/filesystem.cpp | 14 +-- src/eepp/system/time.cpp | 116 ++++++++++++--------- src/examples/http_request/http_request.cpp | 28 ++++- 4 files changed, 106 insertions(+), 62 deletions(-) diff --git a/include/eepp/system/time.hpp b/include/eepp/system/time.hpp index feded1c23..dc8ee03f5 100644 --- a/include/eepp/system/time.hpp +++ b/include/eepp/system/time.hpp @@ -3,6 +3,7 @@ #define EE_SYSTEMCTIME_HPP #include +#include namespace EE { namespace System { @@ -31,6 +32,9 @@ class EE_API Time Int64 asMicroseconds() const; static const Time Zero; ///< Predefined "zero" time value + + /** Converts the time into a human readable string. */ + std::string toString(); private : friend EE_API Time Seconds(double); @@ -276,13 +280,13 @@ value, times can also be negative. Usage example: @code Time t1 = Seconds(0.1f); -double milli = t1.AsMilliseconds(); // 100 +double milli = t1.asMilliseconds(); // 100 Time t2 = Milliseconds(30); -Int64 micro = t2.AsMicroseconds(); // 30000 +Int64 micro = t2.asMicroseconds(); // 30000 Time t3 = Microseconds(-800000); -double sec = t3.AsSeconds(); // -0.8 +double sec = t3.asSeconds(); // -0.8 @endcode @code diff --git a/src/eepp/system/filesystem.cpp b/src/eepp/system/filesystem.cpp index 5650473b4..9a8bebda7 100644 --- a/src/eepp/system/filesystem.cpp +++ b/src/eepp/system/filesystem.cpp @@ -510,15 +510,15 @@ std::string FileSystem::sizeToString( const Int64& Size ) { } switch (c) { - case 0: size = " bytes"; break; - case 1: size = " KiB"; break; - case 2: size = " MiB"; break; - case 3: size = " GiB"; break; - case 4: size = " TiB"; break; - default: size = " WTF"; + case 0: size = "bytes"; break; + case 1: size = "KiB"; break; + case 2: size = "MiB"; break; + case 3: size = "GiB"; break; + case 4: size = "TiB"; break; + default: size = "WTF"; } - return std::string( String::toStr( mem ) + size ); + return String::format( "%4.2f %s", mem, size.c_str() ); } bool FileSystem::changeWorkingDirectory( const std::string & path ) { diff --git a/src/eepp/system/time.cpp b/src/eepp/system/time.cpp index 838528606..617962b89 100644 --- a/src/eepp/system/time.cpp +++ b/src/eepp/system/time.cpp @@ -1,13 +1,11 @@ +#include #include namespace EE { namespace System { const Time Time::Zero; -Time::Time() : - mMicroseconds(0) -{ -} +Time::Time() : mMicroseconds( 0 ) {} double Time::asSeconds() const { return mMicroseconds / 1000000.0; @@ -21,125 +19,143 @@ Int64 Time::asMicroseconds() const { return mMicroseconds; } -Time::Time(Int64 Microseconds) : - mMicroseconds(Microseconds) -{ +Time::Time( Int64 Microseconds ) : mMicroseconds( Microseconds ) {} + +std::string Time::toString() { + Uint64 totalSeconds = asSeconds(); + + if ( asSeconds() < 1 ) { + return String::format( "%4.2fms", asMilliseconds() ); + } else if ( totalSeconds < 60 ) { + return String::format( "%llus", totalSeconds ); + } + + long minutesLeft = totalSeconds / 60; + long secondsLeft = totalSeconds - minutesLeft * 60; + + if ( minutesLeft < 60 ) { + return String::format( "%02ldm %02lds", minutesLeft, secondsLeft ); + } else { + long hoursLeft = minutesLeft / 60; + minutesLeft = minutesLeft - hoursLeft * 60; + return String::format( "%02ldh %02ldm %02lds", hoursLeft, minutesLeft, secondsLeft ); + } } -Time Seconds(double amount) { - return Time(static_cast(amount * 1000000)); +Time Seconds( double amount ) { + return Time( static_cast( amount * 1000000 ) ); } -Time Milliseconds(double amount) { - return Time(static_cast(amount * 1000)); +Time Milliseconds( double amount ) { + return Time( static_cast( amount * 1000 ) ); } -Time Microseconds(Int64 amount) { - return Time(amount); +Time Microseconds( Int64 amount ) { + return Time( amount ); } -bool operator ==(Time left, Time right) { +bool operator==( Time left, Time right ) { return left.asMicroseconds() == right.asMicroseconds(); } -bool operator !=(Time left, Time right) { +bool operator!=( Time left, Time right ) { return left.asMicroseconds() != right.asMicroseconds(); } -bool operator <(Time left, Time right) { +bool operator<( Time left, Time right ) { return left.asMicroseconds() < right.asMicroseconds(); } -bool operator >(Time left, Time right) { +bool operator>( Time left, Time right ) { return left.asMicroseconds() > right.asMicroseconds(); } -bool operator <=(Time left, Time right) { +bool operator<=( Time left, Time right ) { return left.asMicroseconds() <= right.asMicroseconds(); } -bool operator >=(Time left, Time right) { +bool operator>=( Time left, Time right ) { return left.asMicroseconds() >= right.asMicroseconds(); } -Time operator -(Time right) { - return Microseconds(-right.asMicroseconds()); +Time operator-( Time right ) { + return Microseconds( -right.asMicroseconds() ); } -Time operator +(Time left, Time right) { - return Microseconds(left.asMicroseconds() + right.asMicroseconds()); +Time operator+( Time left, Time right ) { + return Microseconds( left.asMicroseconds() + right.asMicroseconds() ); } -Time& operator +=(Time& left, Time right) { +Time& operator+=( Time& left, Time right ) { return left = left + right; } -Time operator -(Time left, Time right) { - return Microseconds(left.asMicroseconds() - right.asMicroseconds()); +Time operator-( Time left, Time right ) { + return Microseconds( left.asMicroseconds() - right.asMicroseconds() ); } -Time& operator -=(Time& left, Time right) { +Time& operator-=( Time& left, Time right ) { return left = left - right; } -Time operator *(Time left, Time right) { - return Microseconds(left.asMicroseconds() * right.asMicroseconds()); +Time operator*( Time left, Time right ) { + return Microseconds( left.asMicroseconds() * right.asMicroseconds() ); } -Time operator *(Time left, double right) { - return Seconds(left.asSeconds() * right); +Time operator*( Time left, double right ) { + return Seconds( left.asSeconds() * right ); } -Time operator *(double left, Time right) { +Time operator*( double left, Time right ) { return right * left; } -Time operator *(Time left, Int64 right) { - return Microseconds(left.asMicroseconds() * right); +Time operator*( Time left, Int64 right ) { + return Microseconds( left.asMicroseconds() * right ); } -Time operator *(Int64 left, Time right) { +Time operator*( Int64 left, Time right ) { return right * left; } -Time& operator *=(Time& left, Time right) { +Time& operator*=( Time& left, Time right ) { return left = left * right; } -Time& operator *=(Time& left, double right) { +Time& operator*=( Time& left, double right ) { return left = left * right; } -Time& operator *=(Time& left, Int64 right) { +Time& operator*=( Time& left, Int64 right ) { return left = left * right; } -Time operator /(Time left, Time right) { - return Microseconds(left.asMicroseconds() / right.asMicroseconds()); +Time operator/( Time left, Time right ) { + return Microseconds( left.asMicroseconds() / right.asMicroseconds() ); } -Time operator /(Time left, double right) { - return Seconds(left.asSeconds() / right); +Time operator/( Time left, double right ) { + return Seconds( left.asSeconds() / right ); } -Time operator /(Time left, Int64 right) { - return Microseconds(left.asMicroseconds() / right); +Time operator/( Time left, Int64 right ) { + return Microseconds( left.asMicroseconds() / right ); } -Time& operator /=(Time& left, Time right) { +Time& operator/=( Time& left, Time right ) { return left = left / right; } -Time& operator /=(Time& left, Int64 right) { +Time& operator/=( Time& left, Int64 right ) { return left = left / right; } -Time operator %(Time left, Time right) { - return Microseconds(left.asMicroseconds() % right.asMicroseconds()); +Time operator%( Time left, Time right ) { + return Microseconds( left.asMicroseconds() % right.asMicroseconds() ); } -Time& operator %=(Time& left, Time right) { +Time& operator%=( Time& left, Time right ) { return left = left % right; } -}} +}} // namespace EE::System diff --git a/src/examples/http_request/http_request.cpp b/src/examples/http_request/http_request.cpp index ef95f72d8..9234d88f3 100644 --- a/src/examples/http_request/http_request.cpp +++ b/src/examples/http_request/http_request.cpp @@ -129,8 +129,32 @@ EE_MAIN_FUNC int main (int argc, char * argv []) { if ( progress ) { request.setProgressCallback( []( const Http&, const Http::Request&, const Http::Response&, const Http::Request::Status& status, size_t totalBytes, size_t currentBytes ) { if ( status == Http::Request::ContentReceived ) { - std::cout << "\rDownloaded " << FileSystem::sizeToString( currentBytes ).c_str() << " of " << FileSystem::sizeToString( totalBytes ).c_str() << " "; + static Clock elapsed; + static Clock tickElapsed; + if ( tickElapsed.getElapsedTime().asMilliseconds() < 100.f && totalBytes != currentBytes ) + return true; + tickElapsed.restart(); + double progress = currentBytes / static_cast( totalBytes ); + Time eta( elapsed.getElapsedTime() / progress - elapsed.getElapsedTime() ); + int percent = static_cast( eefloor( progress * 100. ) ); + std::string bytesProgress( + String::format( + "%s of %s", FileSystem::sizeToString( currentBytes ).c_str(), + FileSystem::sizeToString( totalBytes ).c_str() ) ); + double downloadSpeed = currentBytes / elapsed.getElapsedTime().asSeconds(); + std::cout << "\rDownloaded " << percent << "% (" << bytesProgress << ")."; + + if ( totalBytes != currentBytes ) { + std::cout << " ETA: " << eta.toString() << "."; + } else { + std::cout << " Downloaded in: " << elapsed.getElapsedTime().toString() << "."; + } + + std::cout << " Download Speed: " << FileSystem::sizeToString( downloadSpeed ) << "/s."; + std::cout << " "; std::cout << std::flush; + if ( totalBytes == currentBytes ) + std::cout << std::endl; } return true; }); @@ -191,7 +215,7 @@ EE_MAIN_FUNC int main (int argc, char * argv []) { if ( !lastPathSegment.empty() ) { // Save with the path end segment name - if ( !FileSystem::fileExists( path + lastPathSegment ) ) { + if ( !FileSystem::fileExists( path + lastPathSegment ) || resume ) { path += lastPathSegment; } else { path += FileSystem::fileGetNumberedFileNameFromPath( path, lastPathSegment );