VirtualBox

Ignore:
Timestamp:
Nov 26, 2017 4:22:58 AM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
119264
Message:

iprt/string.h: Adding %Rhcb + %Rhci for human readable size formatting (first is using binary prefix, latter is SI units), and adding %Rhub + %RThui for human readable non-size formatting.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/string/strformatrt.cpp

    r69111 r69833  
    817817
    818818            /*
    819              * hex dumping and COM/XPCOM.
     819             * hex dumping, COM/XPCOM, human readable sizes.
    820820             */
    821821            case 'h':
    822822            {
    823                 switch (*(*ppszFormat)++)
     823                ch = *(*ppszFormat)++;
     824                switch (ch)
    824825                {
    825826                    /*
     
    983984                    }
    984985#endif /* IN_RING3 */
     986
     987                    case 'c':
     988                    case 'u':
     989                    {
     990                        unsigned    i;
     991                        ssize_t     cchBuf;
     992                        uint64_t    uValue;
     993                        uint64_t    uFraction = 0;
     994                        const char *pszPrefix = NULL;
     995                        unsigned    cchFixedPart;
     996                        char        ch2 = *(*ppszFormat)++;
     997                        AssertMsgReturn(ch2 == 'b' || ch2 == 'i', ("invalid type '%.10s'!\n", pszFormatOrg), 0);
     998                        uValue = va_arg(*pArgs, uint64_t);
     999
     1000                        if (!(fFlags & RTSTR_F_PRECISION))
     1001                            cchPrecision = 1;
     1002                        else if (cchPrecision > 3)
     1003                            cchPrecision = 3;
     1004                        else if (cchPrecision < 0)
     1005                            cchPrecision = 0;
     1006
     1007                        cchFixedPart = cchPrecision + (cchPrecision != 0) + (ch == 'c');
     1008
     1009                        if (ch2 == 'b')
     1010                        {
     1011                            static const struct
     1012                            {
     1013                                const char *pszPrefix;
     1014                                uint8_t     cShift;
     1015                                uint64_t    cbMin;
     1016                                uint64_t    cbMinZeroPrecision;
     1017                            } s_aUnits[] =
     1018                            {
     1019                                {  "Ei", 60, _1E,  _1E*2 },
     1020                                {  "Pi", 50, _1P,  _1P*2 },
     1021                                {  "Ti", 40, _1T,  _1T*2 },
     1022                                {  "Gi", 30, _1G,  _1G64*2 },
     1023                                {  "Mi", 20, _1M,  _1M*2 },
     1024                                {  "ki", 10, _1K,  _1K*2 },
     1025                            };
     1026                            for (i = 0; i < RT_ELEMENTS(s_aUnits); i++)
     1027                                if (   uValue >= s_aUnits[i].cbMin
     1028                                    && (cchPrecision > 0 || uValue >= s_aUnits[i].cbMinZeroPrecision))
     1029                                {
     1030                                    if (cchPrecision != 0)
     1031                                    {
     1032                                        uFraction   = uValue & (RT_BIT_64(s_aUnits[i].cShift) - 1);
     1033                                        uFraction  *= cchPrecision == 1 ? 10 : cchPrecision == 2 ? 100 : 1000;
     1034                                        uFraction >>= s_aUnits[i].cShift;
     1035                                    }
     1036                                    uValue  >>= s_aUnits[i].cShift;
     1037                                    pszPrefix = s_aUnits[i].pszPrefix;
     1038                                    cchFixedPart += 2;
     1039                                    break;
     1040                                }
     1041                        }
     1042                        else
     1043                        {
     1044                            static const struct
     1045                            {
     1046                                const char *pszPrefix;
     1047                                uint64_t    cbFactor;
     1048                                uint64_t    cbMinZeroPrecision;
     1049                            } s_aUnits[] =
     1050                            {
     1051                                {  "E", UINT64_C(1000000000000000000), UINT64_C(1010000000000000000),  },
     1052                                {  "P", UINT64_C(1000000000000000),    UINT64_C(1010000000000000),     },
     1053                                {  "T", UINT64_C(1000000000000),       UINT64_C(1010000000000),        },
     1054                                {  "G", UINT64_C(1000000000),          UINT64_C(1010000000),           },
     1055                                {  "M", UINT64_C(1000000),             UINT64_C(1010000),              },
     1056                                {  "K", UINT64_C(1000),                UINT64_C(1010),                 },
     1057                            };
     1058                            for (i = 0; i < RT_ELEMENTS(s_aUnits); i++)
     1059                                if (   uValue >= s_aUnits[i].cbFactor
     1060                                    && (cchPrecision > 0 || uValue >= s_aUnits[i].cbMinZeroPrecision))
     1061                                {
     1062                                    if (cchPrecision == 0)
     1063                                        uValue /= s_aUnits[i].cbFactor;
     1064                                    else
     1065                                    {
     1066                                        uFraction   = uValue % s_aUnits[i].cbFactor;
     1067                                        uValue      = uValue / s_aUnits[i].cbFactor;
     1068                                        uFraction  *= cchPrecision == 1 ? 10 : cchPrecision == 2 ? 100 : 1000;
     1069                                        uFraction  += s_aUnits[i].cbFactor >> 1;
     1070                                        uFraction  /= s_aUnits[i].cbFactor;
     1071                                    }
     1072                                    pszPrefix = s_aUnits[i].pszPrefix;
     1073                                    cchFixedPart += 1;
     1074                                    break;
     1075                                }
     1076                        }
     1077
     1078                        cchBuf = RTStrFormatU64(szBuf, sizeof(szBuf), uValue, 10, 0, 0, 0);
     1079                        if (pszPrefix)
     1080                        {
     1081                            if (cchPrecision)
     1082                            {
     1083                                szBuf[cchBuf++] = '.';
     1084                                cchBuf += RTStrFormatU64(&szBuf[cchBuf], sizeof(szBuf) - cchBuf, uFraction, 10, cchPrecision, 0,
     1085                                                         RTSTR_F_ZEROPAD | RTSTR_F_WIDTH);
     1086                            }
     1087                            szBuf[cchBuf++] = *pszPrefix++;
     1088                            if (*pszPrefix)
     1089                                szBuf[cchBuf++] = *pszPrefix;
     1090                        }
     1091                        if (ch == 'c')
     1092                            szBuf[cchBuf++] = 'B';
     1093                        szBuf[cchBuf] = '\0';
     1094
     1095                        cch = 0;
     1096                        if ((fFlags & RTSTR_F_WIDTH) && !(fFlags & RTSTR_F_LEFT))
     1097                            while (cchBuf < cchWidth)
     1098                            {
     1099                                cch += pfnOutput(pvArgOutput, fFlags & RTSTR_F_ZEROPAD ? "0" : " ", 1);
     1100                                cchWidth--;
     1101                            }
     1102                        cch += pfnOutput(pvArgOutput, szBuf, cchBuf);
     1103                        return cch;
     1104                    }
    9851105
    9861106                    default:
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette