- 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:
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
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
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
*/
static wxString GetHomeDir();
+ //@{
/**
- Returns the size of the file 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).
- */
- wxString GetHumanReadableSize(const wxString& failmsg = "Not available",
- int precision = 1) 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);
+ Returns the representation of the file size in a human-readable form.
+
+ 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,
+ wxSizeConvention conv = wxSIZE_CONV_TRADIONAL) const;
+
+ 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).
/* 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;
+
+ 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 wxString::Format(_("%.*f TB"), precision, bytesize/TERABYTESIZE);
+ return result;
}
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
CPPUNIT_TEST( TestStrip );
CPPUNIT_TEST( TestNormalize );
CPPUNIT_TEST( TestReplace );
+ CPPUNIT_TEST( TestGetHumanReadable );
#ifdef __WINDOWS__
CPPUNIT_TEST( TestShortLongPath );
#endif // __WINDOWS__
void TestStrip();
void TestNormalize();
void TestReplace();
+ void TestGetHumanReadable();
#ifdef __WINDOWS__
void TestShortLongPath();
#endif // __WINDOWS__
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("") );