Changeset 74157 in vbox for trunk/src/VBox/Runtime/common/string
- Timestamp:
- Sep 9, 2018 1:17:21 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/string/strformat.cpp
r69111 r74157 27 27 28 28 /********************************************************************************************************************************* 29 * Defined Constants *30 *********************************************************************************************************************************/31 #define ISDIGIT(c) ((c) >= '0' && (c) <= '9')32 /*#define MAX(a, b) ((a) >= (b) ? (a) : (b))33 #define MIN(a, b) ((a) < (b) ? (a) : (b)) */34 35 36 /*********************************************************************************************************************************37 29 * Header Files * 38 30 *********************************************************************************************************************************/ … … 47 39 # include <iprt/uni.h> 48 40 #endif 41 #include <iprt/ctype.h> 49 42 #include <iprt/string.h> 50 43 #include <iprt/stdarg.h> 51 44 #include "internal/string.h" 52 45 53 /* Wrappers for converting to iprt facilities. */54 #define SSToDS(ptr) ptr55 #define kASSERT Assert56 #define KENDIAN_LITTLE 157 #define KENDIAN KENDIAN_LITTLE58 #define KSIZE size_t59 typedef struct60 {61 uint32_t ulLo;62 uint32_t ulHi;63 } KSIZE64;64 65 66 /*********************************************************************************************************************************67 * Internal Functions *68 *********************************************************************************************************************************/69 static unsigned _strnlen(const char *psz, unsigned cchMax);70 static unsigned _strnlenUtf16(PCRTUTF16 pwsz, unsigned cchMax);71 static int rtStrFormatNumber(char *psz, KSIZE64 ullValue, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags);72 46 73 47 … … 140 114 * Formats an integer number according to the parameters. 141 115 * 142 * @returns Length of the formattednumber.143 * @param psz Pointer to output string buffer of sufficient size.144 * @param u64Value Value to format.116 * @returns Length of the number. 117 * @param psz Pointer to output string. 118 * @param u64Value Value. 145 119 * @param uiBase Number representation base. 146 * @param cchWidth Width .120 * @param cchWidth Width 147 121 * @param cchPrecision Precision. 148 122 * @param fFlags Flags (NTFS_*). … … 151 125 unsigned int fFlags) 152 126 { 153 return rtStrFormatNumber(psz, *(KSIZE64 *)(void *)&u64Value, uiBase, cchWidth, cchPrecision, fFlags);154 }155 RT_EXPORT_SYMBOL(RTStrFormatNumber);156 157 158 159 /**160 * Formats an integer number according to the parameters.161 *162 * @returns Length of the number.163 * @param psz Pointer to output string.164 * @param ullValue Value. Using the high part is optional.165 * @param uiBase Number representation base.166 * @param cchWidth Width167 * @param cchPrecision Precision.168 * @param fFlags Flags (NTFS_*).169 */170 static int rtStrFormatNumber(char *psz, KSIZE64 ullValue, unsigned int uiBase, signed int cchWidth, signed int cchPrecision,171 unsigned int fFlags)172 {173 127 const char *pachDigits = "0123456789abcdef"; 174 128 char *pszStart = psz; 175 129 int cchMax; 176 130 int cchValue; 177 unsigned long ul;178 131 int i; 179 132 int j; 133 char chSign; 180 134 181 135 /* … … 193 147 194 148 /* 195 * Determine value length 149 * Determine value length and sign. Converts the u64Value to unsigned. 196 150 */ 197 151 cchValue = 0; 198 if (ullValue.ulHi || (fFlags & RTSTR_F_64BIT)) 199 { 200 uint64_t u64 = *(uint64_t *)(void *)&ullValue; 201 if ((fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulHi & 0x80000000)) 202 u64 = -(int64_t)u64; 152 chSign = '\0'; 153 if ((fFlags & RTSTR_F_64BIT) || (u64Value & UINT64_C(0xffffffff00000000))) 154 { 155 uint64_t u64; 156 if (!(fFlags & RTSTR_F_VALSIGNED) || !(u64Value & RT_BIT_64(63))) 157 u64 = u64Value; 158 else if (u64Value != RT_BIT_64(63)) 159 { 160 chSign = '-'; 161 u64 = u64Value = -(int64_t)u64Value; 162 } 163 else 164 { 165 chSign = '-'; 166 u64 = u64Value = RT_BIT_64(63); 167 } 203 168 do 204 169 { … … 209 174 else 210 175 { 211 ul = (fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulLo & 0x80000000) ? -(int32_t)ullValue.ulLo : ullValue.ulLo; 176 uint32_t u32 = (uint32_t)u64Value; 177 if (!(fFlags & RTSTR_F_VALSIGNED) || !(u32 & UINT32_C(0x80000000))) 178 { /* likley */ } 179 else if (u32 != UINT32_C(0x80000000)) 180 { 181 chSign = '-'; 182 u64Value = u32 = -(int32_t)u32; 183 } 184 else 185 { 186 chSign = '-'; 187 u64Value = u32 = UINT32_C(0x80000000); 188 } 212 189 do 213 190 { 214 191 cchValue++; 215 u l/= uiBase;216 } while (u l);192 u32 /= uiBase; 193 } while (u32); 217 194 } 218 195 if (fFlags & RTSTR_F_THOUSAND_SEP) … … 230 207 if (fFlags & RTSTR_F_VALSIGNED) 231 208 { 232 if ((ullValue.ulHi || (fFlags & RTSTR_F_64BIT) ? ullValue.ulHi : ullValue.ulLo) & 0x80000000) 233 { 234 ullValue.ulLo = -(int32_t)ullValue.ulLo; 235 if (ullValue.ulHi) 236 ullValue.ulHi = ~ullValue.ulHi; 237 psz[i++] = '-'; 238 } 209 if (chSign != '\0') 210 psz[i++] = chSign; 239 211 else if (fFlags & (RTSTR_F_PLUS | RTSTR_F_BLANK)) 240 212 psz[i++] = (char)(fFlags & RTSTR_F_PLUS ? '+' : ' '); … … 289 261 psz += cchValue; 290 262 i = -1; 291 if ( ullValue.ulHi || (fFlags & RTSTR_F_64BIT))292 { 293 uint64_t u64 = *(uint64_t *)(void *)&ullValue;263 if ((fFlags & RTSTR_F_64BIT) || (u64Value & UINT64_C(0xffffffff00000000))) 264 { 265 uint64_t u64 = u64Value; 294 266 if (fFlags & RTSTR_F_THOUSAND_SEP) 295 267 { … … 313 285 else 314 286 { 315 u l = (fFlags & RTSTR_F_VALSIGNED) && (ullValue.ulLo & 0x80000000) ? -(int32_t)ullValue.ulLo : ullValue.ulLo;287 uint32_t u32 = (uint32_t)u64Value; 316 288 if (fFlags & RTSTR_F_THOUSAND_SEP) 317 289 { … … 320 292 if ((-i - 1) % 4 == 3) 321 293 psz[i--] = ' '; 322 psz[i--] = pachDigits[u l% uiBase];323 u l/= uiBase;324 } while (u l);294 psz[i--] = pachDigits[u32 % uiBase]; 295 u32 /= uiBase; 296 } while (u32); 325 297 } 326 298 else … … 328 300 do 329 301 { 330 psz[i--] = pachDigits[u l% uiBase];331 u l/= uiBase;332 } while (u l);302 psz[i--] = pachDigits[u32 % uiBase]; 303 u32 /= uiBase; 304 } while (u32); 333 305 } 334 306 } … … 344 316 return (unsigned)(psz - pszStart); 345 317 } 318 RT_EXPORT_SYMBOL(RTStrFormatNumber); 346 319 347 320 … … 366 339 char szTmp[64]; /* Worker functions assumes 64 byte buffer! Ugly but faster. */ 367 340 va_list args; 368 KSIZEcch = 0;341 size_t cch = 0; 369 342 const char *pszStartOutput = pszFormat; 370 343 … … 408 381 409 382 /* width */ 410 if ( ISDIGIT(*pszFormat))383 if (RT_C_IS_DIGIT(*pszFormat)) 411 384 { 412 for (cchWidth = 0; ISDIGIT(*pszFormat); pszFormat++)385 for (cchWidth = 0; RT_C_IS_DIGIT(*pszFormat); pszFormat++) 413 386 { 414 387 cchWidth *= 10; … … 433 406 { 434 407 pszFormat++; 435 if ( ISDIGIT(*pszFormat))436 { 437 for (cchPrecision = 0; ISDIGIT(*pszFormat); pszFormat++)408 if (RT_C_IS_DIGIT(*pszFormat)) 409 { 410 for (cchPrecision = 0; RT_C_IS_DIGIT(*pszFormat); pszFormat++) 438 411 { 439 412 cchPrecision *= 10; … … 527 500 szTmp[0] = (char)va_arg(args, int); 528 501 szTmp[1] = '\0'; /* Some output functions wants terminated strings. */ 529 cch += pfnOutput(pvArgOutput, SSToDS(&szTmp[0]), 1);502 cch += pfnOutput(pvArgOutput, &szTmp[0], 1); 530 503 531 504 while (--cchWidth > 0) … … 753 726 } 754 727 } 755 cchNum = RTStrFormatNumber((char *) SSToDS(&szTmp), u64Value, uBase, cchWidth, cchPrecision, fFlags);756 cch += pfnOutput(pvArgOutput, (char *) SSToDS(&szTmp), cchNum);728 cchNum = RTStrFormatNumber((char *)&szTmp, u64Value, uBase, cchWidth, cchPrecision, fFlags); 729 cch += pfnOutput(pvArgOutput, (char *)&szTmp, cchNum); 757 730 break; 758 731 }
Note:
See TracChangeset
for help on using the changeset viewer.