Skip to content

Instantly share code, notes, and snippets.

@dranger003
Created October 19, 2015 00:43
Show Gist options
  • Save dranger003/17322a9ad83815390f58 to your computer and use it in GitHub Desktop.
Save dranger003/17322a9ad83815390f58 to your computer and use it in GitHub Desktop.
// FormatBytes.h : includes AtlConvertBytes, AtlFormatBytes
//
// Written by "Daniel Ranger" <[email protected]>
// Copyright (c) 2009 Daniel Ranger
//
// DESCRIPTION
//
// Utility functions to convert a number of bytes into either a specific
// unit or the unit based on the multiple of the base (1000 or 1024).
//
// LICENSE
//
// This is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, at version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef __FORMATBYTES_H__
#define __FORMATBYTES_H__
#pragma once
#ifndef _INC_MATH
#include <math.h>
#endif // _INC_MATH
#ifndef __ATLSTR_H__
#include <atlstr.h>
#endif // __ATLSTR_H__
// Enums
/////////////////////////////////////////////////////////////////////////////
enum PREFIXNORM
{
PN_SI, // Base 10 (i.e. 1000)
PN_IEC, // Base 2 (i.e. 1024)
PN_DECIMAL = PN_SI,
PN_BINARY = PN_IEC
};
enum BINARYPREFIX
{
BP_NONE = -2,
BP_AUTO,
// SI IEC 60027 Exp (b10/b2) Exp (b1000/b1024)
BP_KILO, // KIBI 3 1
BP_MEGA, // MEBI 6 2
BP_GIGA, // GIBI 9 3
BP_TERA, // TEBI 12 4
BP_PETA, // PEBI 15 5
BP_EXA, // EXBI 18 6
BP_ZETTA, // ZEBI 21 7
BP_YOTTA // YOBI 24 8
};
// Typedefs
/////////////////////////////////////////////////////////////////////////////
#ifndef LPDOUBLE
typedef DOUBLE *LPDOUBLE;
#endif // LPDOUBLE
typedef BINARYPREFIX *LPBINARYPREFIX;
// Constants
/////////////////////////////////////////////////////////////////////////////
const INT iPrefixBase[] = { 1000, 1024 };
const LPTSTR pszPrefixes[][8] = {
{ _T("KB"), _T("MB"), _T("GB"), _T("TB"),
_T("PB"), _T("EB"), _T("ZB"), _T("YB") },
{ _T("KiB"), _T("MiB"), _T("GiB"), _T("TiB"),
_T("PiB"), _T("EiB"), _T("ZiB"), _T("YiB") },
};
// AtlConvertBytes
/////////////////////////////////////////////////////////////////////////////
BOOL AtlConvertBytes(
LPDOUBLE pdResult,
LPBINARYPREFIX piBinaryPrefix,
ULONGLONG ullBytes,
BINARYPREFIX iBinaryPrefix = BP_AUTO,
PREFIXNORM iPrefixNorm = PN_DECIMAL)
{
if (!pdResult || !piBinaryPrefix)
return FALSE;
DOUBLE dSize = (DOUBLE)ullBytes;
DOUBLE dBase = (FLOAT)iPrefixBase[iPrefixNorm];
*pdResult = dSize;
*piBinaryPrefix = iBinaryPrefix;
if (iBinaryPrefix == BP_NONE) // No conversion required
return TRUE;
DOUBLE dExponent = 0;
if (iBinaryPrefix == BP_AUTO) // Try to find a suitable prefix
{
if (dSize < dBase)
{
*piBinaryPrefix = BP_NONE;
}
else
{
dExponent = ::floor(::log(dSize) / ::log(dBase));
*piBinaryPrefix = (BINARYPREFIX)((INT)dExponent - 1);
}
}
else // Use provided prefix
{
dExponent = iBinaryPrefix + 1;
}
*pdResult = dSize / ::pow(dBase, dExponent);
return TRUE;
}
// AtlFormatBytes
/////////////////////////////////////////////////////////////////////////////
CString AtlFormatBytes(
LPBINARYPREFIX piBinaryPrefix,
ULONGLONG ullBytes,
BINARYPREFIX iBinaryPrefix = BP_AUTO,
PREFIXNORM iPrefixNorm = PN_SI,
INT iDecimals = 2,
BOOL bFormatPrefix = TRUE)
{
DOUBLE dResult;
BOOL bRes = ::AtlConvertBytes(&dResult, piBinaryPrefix, ullBytes, iBinaryPrefix, iPrefixNorm);
ATLASSERT(bRes);
if (*piBinaryPrefix == BP_NONE || ullBytes < iPrefixBase[iPrefixNorm])
iDecimals = 0;
CString szFormat, szResult;
szFormat.Format(_T("%%.%df"), iDecimals);
if (bFormatPrefix)
{
if (*piBinaryPrefix == BP_NONE)
szFormat.Append(_T(" B"));
else
szFormat.AppendFormat(_T(" %s"), pszPrefixes[iPrefixNorm][*piBinaryPrefix]);
}
szResult.Format(szFormat, dResult);
return szResult;
}
#endif // __FORMATBYTES_H__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment