Add support for IEC and SI size units to wxFileName::GetHumanReadableSize().
Allow choosing the multiplier to use (1000 or 1024) and the names of the units (SI or IEC). By default, still use traditional convention, i.e. multiplier of 1024 but SI unit names. This will probably need to be changed to use IEC units in the future. Also added unit test for this function. Closes #10673. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63870 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
2028c33ab5
commit
b2edb8f3c5
@ -438,6 +438,7 @@ All:
|
||||
- Correct bugs when using wxTextInputStream with wxConvAuto (Leon Buikstra).
|
||||
- Don't crash when input is empty in wxFileConfig ctor (Lukasz Michalski).
|
||||
- Correct wxSocket::Peek() to not block (Anders Larsen).
|
||||
- Added IEC and SI units support to GetHumanReadableSize() (Julien Weinzorn).
|
||||
|
||||
Unix:
|
||||
|
||||
|
@ -65,6 +65,15 @@ enum wxPathFormat
|
||||
wxPATH_MAX // Not a valid value for specifying path format
|
||||
};
|
||||
|
||||
// different convention that may be used with GetHumanReadableSize()
|
||||
enum wxSizeConvention
|
||||
{
|
||||
wxSIZE_CONV_TRADIONAL, // 1024 bytes = 1 KB
|
||||
wxSIZE_CONV_IEC, // 1024 bytes = 1 KiB
|
||||
wxSIZE_CONV_SI // 1000 bytes = 1 KB
|
||||
};
|
||||
|
||||
|
||||
// the kind of normalization to do with the file name: these values can be
|
||||
// or'd together to perform several operations at once
|
||||
enum wxPathNormalize
|
||||
@ -540,11 +549,15 @@ public:
|
||||
static wxULongLong GetSize(const wxString &file);
|
||||
|
||||
// returns the size in a human readable form
|
||||
wxString GetHumanReadableSize(const wxString &nullsize = wxGetTranslation(wxT("Not available")),
|
||||
int precision = 1) const;
|
||||
static wxString GetHumanReadableSize(const wxULongLong &sz,
|
||||
const wxString &nullsize = wxGetTranslation(wxT("Not available")),
|
||||
int precision = 1);
|
||||
wxString
|
||||
GetHumanReadableSize(const wxString& nullsize = _("Not available"),
|
||||
int precision = 1,
|
||||
wxSizeConvention conv = wxSIZE_CONV_TRADIONAL) const;
|
||||
static wxString
|
||||
GetHumanReadableSize(const wxULongLong& sz,
|
||||
const wxString& nullsize = _("Not available"),
|
||||
int precision = 1,
|
||||
wxSizeConvention conv = wxSIZE_CONV_TRADIONAL);
|
||||
#endif // wxUSE_LONGLONG
|
||||
|
||||
|
||||
|
@ -28,6 +28,25 @@ enum wxPathFormat
|
||||
wxPATH_MAX //!< Not a valid value for specifying path format
|
||||
};
|
||||
|
||||
/**
|
||||
Different conventions for human readable sizes.
|
||||
|
||||
@see wxFileName::GetHumanReadableSize().
|
||||
|
||||
@since 2.9.1
|
||||
*/
|
||||
enum wxSizeConvention
|
||||
{
|
||||
/// 1000 bytes = 1KiB.
|
||||
wxSIZE_CONV_REAL_SI,
|
||||
|
||||
/// 1000 bytes = 1KB.
|
||||
wxSIZE_CONV_TRAD_1000,
|
||||
|
||||
/// 1024 bytes = 1KB.
|
||||
wxSIZE_CONV_TRAD_1024
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
The kind of normalization to do with the file name: these values can be
|
||||
@ -522,30 +541,41 @@ public:
|
||||
*/
|
||||
static wxString GetHomeDir();
|
||||
|
||||
//@{
|
||||
/**
|
||||
Returns the size of the file in a human-readable form.
|
||||
Returns the representation of the file size in a human-readable form.
|
||||
|
||||
If the size could not be retrieved the @c failmsg string
|
||||
is returned. In case of success, the returned string is
|
||||
a floating-point number with @c precision decimal digits
|
||||
followed by the size unit (B, kB, MB, GB, TB: respectively
|
||||
bytes, kilobytes, megabytes, gigabytes, terabytes).
|
||||
In the first version, the size of this file is used. In the second one,
|
||||
the specified size @a bytes is used.
|
||||
|
||||
If the file size could not be retrieved or @a bytes is ::wxInvalidSize
|
||||
or zero, the @c failmsg string is returned.
|
||||
|
||||
Otherwise the returned string is a floating-point number with @c
|
||||
precision decimal digits followed by the abbreviation of the unit used.
|
||||
By default the traditional, although incorrect, convention of using SI
|
||||
units for multiples of 1024 is used, i.e. returned string will use
|
||||
suffixes of B, KB, MB, GB, TB for bytes, kilobytes, megabytes,
|
||||
gigabytes and terabytes respectively. With the IEC convention the names
|
||||
of the units are changed to B, KiB, MiB, GiB and TiB fofr bytes,
|
||||
kibibytes, mebibyes, gibibytes and tebibytes. Finally, with SI
|
||||
convention the same B, KB, MB, GB and TB suffixes are used but in their
|
||||
correct SI meaning, i.e. as multiples of 1000 and not 1024.
|
||||
|
||||
Support for the different size conventions is new in wxWidgets 2.9.1,
|
||||
in previous versions only the traditional convention was implemented.
|
||||
*/
|
||||
wxString GetHumanReadableSize(const wxString& failmsg = "Not available",
|
||||
int precision = 1) const;
|
||||
wxString
|
||||
GetHumanReadableSize(const wxString& failmsg = _("Not available"),
|
||||
int precision = 1,
|
||||
wxSizeConvention conv = wxSIZE_CONV_TRADIONAL) const;
|
||||
|
||||
/**
|
||||
Returns the size of the given number of bytes in a human-readable form.
|
||||
|
||||
If @a bytes is ::wxInvalidSize or zero, then @a nullsize is returned.
|
||||
|
||||
In case of success, the returned string is a floating-point number with
|
||||
@a precision decimal digits followed by the size unit (B, kB, MB, GB,
|
||||
TB: respectively bytes, kilobytes, megabytes, gigabytes, terabytes).
|
||||
*/
|
||||
static wxString GetHumanReadableSize(const wxULongLong& bytes,
|
||||
const wxString& nullsize = "Not available",
|
||||
int precision = 1);
|
||||
static wxString
|
||||
GetHumanReadableSize(const wxULongLong& bytes,
|
||||
const wxString& nullsize = _("Not available"),
|
||||
int precision = 1,
|
||||
wxSizeConvention conv = wxSIZE_CONV_REAL_SI);
|
||||
//@}
|
||||
|
||||
/**
|
||||
Return the long form of the path (returns identity on non-Windows platforms).
|
||||
|
@ -2647,27 +2647,53 @@ wxULongLong wxFileName::GetSize(const wxString &filename)
|
||||
/* static */
|
||||
wxString wxFileName::GetHumanReadableSize(const wxULongLong &bs,
|
||||
const wxString &nullsize,
|
||||
int precision)
|
||||
int precision,
|
||||
wxSizeConvention conv)
|
||||
{
|
||||
static const double KILOBYTESIZE = 1024.0;
|
||||
static const double MEGABYTESIZE = 1024.0*KILOBYTESIZE;
|
||||
static const double GIGABYTESIZE = 1024.0*MEGABYTESIZE;
|
||||
static const double TERABYTESIZE = 1024.0*GIGABYTESIZE;
|
||||
|
||||
if (bs == 0 || bs == wxInvalidSize)
|
||||
// deal with trivial case first
|
||||
if ( bs == 0 || bs == wxInvalidSize )
|
||||
return nullsize;
|
||||
|
||||
double bytesize = bs.ToDouble();
|
||||
if (bytesize < KILOBYTESIZE)
|
||||
return wxString::Format(_("%s B"), bs.ToString().c_str());
|
||||
if (bytesize < MEGABYTESIZE)
|
||||
return wxString::Format(_("%.*f kB"), precision, bytesize/KILOBYTESIZE);
|
||||
if (bytesize < GIGABYTESIZE)
|
||||
return wxString::Format(_("%.*f MB"), precision, bytesize/MEGABYTESIZE);
|
||||
if (bytesize < TERABYTESIZE)
|
||||
return wxString::Format(_("%.*f GB"), precision, bytesize/GIGABYTESIZE);
|
||||
// depending on the convention used the multiplier may be either 1000 or
|
||||
// 1024 and the binary infix may be empty (for "KB") or "i" (for "KiB")
|
||||
double multiplier;
|
||||
wxString biInfix;
|
||||
|
||||
return wxString::Format(_("%.*f TB"), precision, bytesize/TERABYTESIZE);
|
||||
switch ( conv )
|
||||
{
|
||||
case wxSIZE_CONV_IEC:
|
||||
biInfix = "i";
|
||||
// fall through
|
||||
|
||||
case wxSIZE_CONV_TRADIONAL:
|
||||
multiplier = 1024.;
|
||||
break;
|
||||
|
||||
case wxSIZE_CONV_SI:
|
||||
multiplier = 1000;
|
||||
break;
|
||||
}
|
||||
|
||||
const double kiloByteSize = multiplier;
|
||||
const double megaByteSize = multiplier * kiloByteSize;
|
||||
const double gigaByteSize = multiplier * megaByteSize;
|
||||
const double teraByteSize = multiplier * gigaByteSize;
|
||||
|
||||
const double bytesize = bs.ToDouble();
|
||||
|
||||
wxString result;
|
||||
if ( bytesize < kiloByteSize )
|
||||
result.Printf("%s B", bs.ToString());
|
||||
else if ( bytesize < megaByteSize )
|
||||
result.Printf("%.*f K%sB", precision, bytesize/kiloByteSize, biInfix);
|
||||
else if (bytesize < gigaByteSize)
|
||||
result.Printf("%.*f M%sB", precision, bytesize/megaByteSize, biInfix);
|
||||
else if (bytesize < teraByteSize)
|
||||
result.Printf("%.*f G%sB", precision, bytesize/gigaByteSize, biInfix);
|
||||
else
|
||||
result.Printf("%.*f T%sB", precision, bytesize/teraByteSize, biInfix);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
wxULongLong wxFileName::GetSize() const
|
||||
@ -2675,9 +2701,11 @@ wxULongLong wxFileName::GetSize() const
|
||||
return GetSize(GetFullPath());
|
||||
}
|
||||
|
||||
wxString wxFileName::GetHumanReadableSize(const wxString &failmsg, int precision) const
|
||||
wxString wxFileName::GetHumanReadableSize(const wxString& failmsg,
|
||||
int precision,
|
||||
wxSizeConvention conv) const
|
||||
{
|
||||
return GetHumanReadableSize(GetSize(), failmsg, precision);
|
||||
return GetHumanReadableSize(GetSize(), failmsg, precision, conv);
|
||||
}
|
||||
|
||||
#endif // wxUSE_LONGLONG
|
||||
|
@ -125,6 +125,7 @@ private:
|
||||
CPPUNIT_TEST( TestStrip );
|
||||
CPPUNIT_TEST( TestNormalize );
|
||||
CPPUNIT_TEST( TestReplace );
|
||||
CPPUNIT_TEST( TestGetHumanReadable );
|
||||
#ifdef __WINDOWS__
|
||||
CPPUNIT_TEST( TestShortLongPath );
|
||||
#endif // __WINDOWS__
|
||||
@ -139,6 +140,7 @@ private:
|
||||
void TestStrip();
|
||||
void TestNormalize();
|
||||
void TestReplace();
|
||||
void TestGetHumanReadable();
|
||||
#ifdef __WINDOWS__
|
||||
void TestShortLongPath();
|
||||
#endif // __WINDOWS__
|
||||
@ -478,6 +480,39 @@ void FileNameTestCase::TestReplace()
|
||||
fn.GetFullPath(wxPATH_UNIX) );
|
||||
}
|
||||
|
||||
void FileNameTestCase::TestGetHumanReadable()
|
||||
{
|
||||
static const struct TestData
|
||||
{
|
||||
const char *result;
|
||||
wxULongLong size;
|
||||
int prec;
|
||||
wxSizeConvention conv;
|
||||
} testData[] =
|
||||
{
|
||||
{ "NA", 0, 1, wxSIZE_CONV_TRADIONAL },
|
||||
{ "2.0 KB", 2000, 1, wxSIZE_CONV_TRADIONAL },
|
||||
{ "1.953 KiB", 2000, 3, wxSIZE_CONV_IEC },
|
||||
{ "2.000 KB", 2000, 3, wxSIZE_CONV_SI },
|
||||
{ "297 KB", 304351, 0, wxSIZE_CONV_TRADIONAL },
|
||||
{ "304 KB", 304351, 0, wxSIZE_CONV_SI },
|
||||
};
|
||||
|
||||
for ( unsigned n = 0; n < WXSIZEOF(testData); n++ )
|
||||
{
|
||||
const TestData& td = testData[n];
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL
|
||||
(
|
||||
td.result,
|
||||
wxFileName::GetHumanReadableSize(td.size, "NA", td.prec, td.conv)
|
||||
);
|
||||
}
|
||||
|
||||
// also test the default convention value
|
||||
CPPUNIT_ASSERT_EQUAL( "1.4 MB", wxFileName::GetHumanReadableSize(1512993, "") );
|
||||
}
|
||||
|
||||
void FileNameTestCase::TestStrip()
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL( "", wxFileName::StripExtension("") );
|
||||
|
Loading…
Reference in New Issue
Block a user