std::wstring CSizeFormatBase::Format(COptionsBase* pOptions, int64_t size, bool add_bytes_suffix, CSizeFormatBase::_format format, bool thousands_separator, int num_decimal_places) { assert(format != formats_count); assert(size >= 0); if (size < 0) { size = 0; } if (format == bytes) { std::wstring result = FormatNumber(pOptions, size, &thousands_separator); if (!add_bytes_suffix) { return result; } else { return fz::sprintf(fztranslate("%s byte", "%s bytes", size), result); } } std::wstring places; int divider; if (format == si1000) { divider = 1000; } else { divider = 1024; } // Exponent (2^(10p) or 10^(3p) depending on option int p = 0; int64_t r = size; int remainder = 0; bool clipped = false; while (r > divider && p < 6) { int64_t const rr = r / divider; if (remainder != 0) { clipped = true; } remainder = static_cast<int>(r - rr * divider); r = rr; ++p; } if (!num_decimal_places) { if (remainder != 0 || clipped) { ++r; } } else if (p) { // Don't add decimal places on exact bytes if (format != si1000) { // Binary, need to convert 1024 into range from 1-1000 if (clipped) { ++remainder; clipped = false; } remainder = (int)ceil((double)remainder * 1000 / 1024); } int max; switch (num_decimal_places) { default: num_decimal_places = 1; // Fall-through case 1: max = 9; divider = 100; break; case 2: max = 99; divider = 10; break; case 3: max = 999; break; } if (num_decimal_places != 3) { if (remainder % divider) { clipped = true; } remainder /= divider; } if (clipped) { remainder++; } if (remainder > max) { r++; remainder = 0; } wchar_t fmt[] = L"%00d"; fmt[2] = '0' + num_decimal_places; places = fz::sprintf(fmt, remainder); } std::wstring result = ToString(r, 0, 0); if (!places.empty()) { std::wstring const& sep = GetRadixSeparator(); result += sep; result += places; } result += ' '; static wchar_t byte_unit = 0; if (!byte_unit) { std::wstring t = _("B <Unit symbol for bytes. Only translate first letter>"); // @translator: Only translate first letter. byte_unit = t[0]; } if (!p) { return result + byte_unit; } result += prefix[p]; if (format == iec) { result += 'i'; } result += byte_unit; return result; }
wxString CSizeFormatBase::Format(COptionsBase* pOptions, wxLongLong size, bool add_bytes_suffix, enum CSizeFormatBase::_format format, bool thousands_separator, int num_decimal_places) { wxASSERT(format != formats_count); wxASSERT(size >= 0); if( size < 0 ) { size = 0; } if (format == bytes) { wxString result = FormatNumber(pOptions, size, &thousands_separator); if (!add_bytes_suffix) return result; else { // wxPLURAL has no support for wxLongLong int last; if (size > 1000000000) last = (1000000000 + (size % 1000000000)).GetLo(); else last = size.GetLo(); return wxString::Format(wxPLURAL("%s byte", "%s bytes", last), result); } } wxString places; int divider; if (format == si1000) divider = 1000; else divider = 1024; // Exponent (2^(10p) or 10^(3p) depending on option int p = 0; wxLongLong r = size; int remainder = 0; bool clipped = false; while (r > divider && p < 6) { const wxLongLong rr = r / divider; if (remainder != 0) clipped = true; remainder = (r - rr * divider).GetLo(); r = rr; ++p; } if (!num_decimal_places) { if (remainder != 0 || clipped) ++r; } else if (p) { // Don't add decimal places on exact bytes if (format != si1000) { // Binary, need to convert 1024 into range from 1-1000 if (clipped) { ++remainder; clipped = false; } remainder = (int)ceil((double)remainder * 1000 / 1024); } int max; switch (num_decimal_places) { default: num_decimal_places = 1; // Fall-through case 1: max = 9; divider = 100; break; case 2: max = 99; divider = 10; break; case 3: max = 999; break; } if (num_decimal_places != 3) { if (remainder % divider) clipped = true; remainder /= divider; } if (clipped) remainder++; if (remainder > max) { r++; remainder = 0; } places.Printf(_T("%d"), remainder); const size_t len = places.Len(); for (size_t i = len; i < static_cast<size_t>(num_decimal_places); ++i) places = _T("0") + places; } wxString result = r.ToString(); if (!places.empty()) { const wxString& sep = GetRadixSeparator(); result += sep; result += places; } result += ' '; static wxChar byte_unit = 0; if (!byte_unit) { wxString t = _("B <Unit symbol for bytes. Only translate first letter>"); byte_unit = t[0]; } if (!p) return result + byte_unit; result += prefix[p]; if (format == iec) result += 'i'; result += byte_unit; return result; }