Changeset 69833 in vbox for trunk/src/VBox/Runtime/common/string
- Timestamp:
- Nov 26, 2017 4:22:58 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 119264
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/strformatrt.cpp
r69111 r69833 817 817 818 818 /* 819 * hex dumping and COM/XPCOM.819 * hex dumping, COM/XPCOM, human readable sizes. 820 820 */ 821 821 case 'h': 822 822 { 823 switch (*(*ppszFormat)++) 823 ch = *(*ppszFormat)++; 824 switch (ch) 824 825 { 825 826 /* … … 983 984 } 984 985 #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 } 985 1105 986 1106 default:
Note:
See TracChangeset
for help on using the changeset viewer.