string & FileSizeToStr(string &strDestStr, unsigned __int64 Size, int Width, unsigned __int64 ViewFlags) { FormatString strStr; unsigned __int64 Divider; size_t IndexDiv, IndexB; // подготовительные мероприятия if (!UnitStr[0][0][0]) { PrepareUnitStr(); } bool Commas=(ViewFlags & COLUMN_COMMAS)!=0; bool FloatSize=(ViewFlags & COLUMN_FLOATSIZE)!=0; bool Economic=(ViewFlags & COLUMN_ECONOMIC)!=0; bool UseMinSizeIndex=(ViewFlags & COLUMN_MINSIZEINDEX)!=0; size_t MinSizeIndex=(ViewFlags & COLUMN_MINSIZEINDEX_MASK)+1; bool ShowBytesIndex=(ViewFlags & COLUMN_SHOWBYTESINDEX)!=0; if (ViewFlags & COLUMN_THOUSAND) { Divider=1000; IndexDiv=0; } else { Divider=1024; IndexDiv=1; } unsigned __int64 Sz = Size, Divider2 = Divider/2, Divider64 = Divider, OldSize; if (FloatSize) { unsigned __int64 Divider64F = 1, Divider64F_mul = 1000, Divider64F2 = 1, Divider64F2_mul = Divider; //выравнивание идёт по 1000 но само деление происходит на Divider //например 999 bytes покажутся как 999 а вот 1000 bytes уже покажутся как 0.97 K for (IndexB=0; IndexB<UNIT_COUNT-1; IndexB++) { if (Sz < Divider64F*Divider64F_mul) break; Divider64F = Divider64F*Divider64F_mul; Divider64F2 = Divider64F2*Divider64F2_mul; } if (!IndexB) { strStr << Sz; } else { Sz = (OldSize=Sz) / Divider64F2; OldSize = (OldSize % Divider64F2) / (Divider64F2 / Divider64F2_mul); DWORD Decimal = (DWORD)(0.5+(double)(DWORD)OldSize/(double)Divider*100.0); if (Decimal >= 100) { Decimal -= 100; Sz++; } strStr << Sz << L"." << fmt::MinWidth(2) << fmt::FillChar(L'0') << Decimal; FormatNumber(strStr,strStr,2); } if (IndexB>0 || ShowBytesIndex) { Width-=(Economic?1:2); if (Width<0) Width=0; if (Economic) strDestStr.Format(L"%*.*s%1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); else strDestStr.Format(L"%*.*s %1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); } else strDestStr.Format(L"%*.*s",Width,Width,strStr.CPtr()); return strDestStr; } if (Commas) InsertCommas(Sz,strStr); else strStr << Sz; if ((!UseMinSizeIndex && strStr.GetLength()<=static_cast<size_t>(Width)) || Width<5) { if (ShowBytesIndex) { Width-=(Economic?1:2); if (Width<0) Width=0; if (Economic) strDestStr.Format(L"%*.*s%1.1s",Width,Width,strStr.CPtr(),UnitStr[0][IndexDiv]); else strDestStr.Format(L"%*.*s %1.1s",Width,Width,strStr.CPtr(),UnitStr[0][IndexDiv]); } else strDestStr.Format(L"%*.*s",Width,Width,strStr.CPtr()); } else { Width-=(Economic?1:2); IndexB=0; do { //Sz=(Sz+Divider2)/Divider64; Sz = (OldSize=Sz) / Divider64; if ((OldSize % Divider64) > Divider2) ++Sz; IndexB++; if (Commas) { InsertCommas(Sz,strStr); } else { strStr.Clear(); strStr << Sz; } } while ((UseMinSizeIndex && IndexB<MinSizeIndex) || strStr.GetLength() > static_cast<size_t>(Width)); if (Economic) strDestStr.Format(L"%*.*s%1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); else strDestStr.Format(L"%*.*s %1.1s",Width,Width,strStr.CPtr(),UnitStr[IndexB][IndexDiv]); } return strDestStr; }