Changeset 168 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Jan 18, 2007 6:53:45 PM (18 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/include/VBoxGlobal.h
r1 r168 324 324 bool aCanResize = true); 325 325 326 static unsigned long long parseSize (QString); 327 static QString formatSize (unsigned long long); 326 static QChar decimalSep(); 327 static QString sizeRegexp(); 328 329 static Q_UINT64 parseSize (const QString &); 330 static QString formatSize (Q_UINT64, int aMode = 0); 328 331 329 332 signals: -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
r132 r168 1357 1357 } 1358 1358 1359 /** 1360 * Returns the decimal separator for the current locale. 1361 */ 1359 1362 /* static */ 1360 unsigned long long VBoxGlobal::parseSize (QString aText) 1361 { 1362 QRegExp regexp ("^(\\d+([^\\s^\\d^B^K^M^G^T^P]\\d{1,2})?)\\s?(B|KB|MB|GB|TB|PB)?$"); 1363 QChar VBoxGlobal::decimalSep() 1364 { 1365 QString n = QLocale::system().toString (0.0, 'f', 1).stripWhiteSpace(); 1366 return n [1]; 1367 } 1368 1369 /** 1370 * Returns the regexp string that defines the format of the human-readable 1371 * size representation, <tt>####[.##] B|KB|MB|GB|TB|PB</tt>. 1372 * 1373 * This regexp will capture 5 groups of text: 1374 * - cap(1): integer number in case when no decimal point is present 1375 * (if empty, it means that decimal point is present) 1376 * - cap(2): size suffix in case when no decimal point is present (may be empty) 1377 * - cap(3): integer number in case when decimal point is present (may be empty) 1378 * - cap(4): fraction number (hundredth) in case when decimal point is present 1379 * - cap(5): size suffix in case when decimal point is present (note that 1380 * B cannot appear there) 1381 */ 1382 /* static */ 1383 QString VBoxGlobal::sizeRegexp() 1384 { 1385 QString regexp = 1386 QString ("^(?:(?:(\\d+)(?:\\s?([KMGTP]?B))?)|(?:(\\d*)%1(\\d{1,2})(?:\\s?([KMGTP]B))))$") 1387 .arg (decimalSep()); 1388 return regexp; 1389 } 1390 1391 /** 1392 * Parses the given size string that should be in form of 1393 * <tt>####[.##] B|KB|MB|GB|TB|PB</tt> and returns the size value 1394 * in bytes. Zero is returned on error. 1395 */ 1396 /* static */ 1397 Q_UINT64 VBoxGlobal::parseSize (const QString &aText) 1398 { 1399 QRegExp regexp (sizeRegexp()); 1363 1400 int pos = regexp.search (aText); 1364 1401 if (pos != -1) 1365 1402 { 1366 QString size = regexp.cap (1); 1367 QString suffix = regexp.cap (3); 1368 double result = QLocale::system().toDouble(size); 1369 if (suffix.isEmpty() || suffix == "B") 1370 return (unsigned long long)result; 1371 else if (suffix == "KB") 1372 return (unsigned long long)(result * _1K); 1373 else if (suffix == "MB") 1374 return (unsigned long long)(result * _1M); 1375 else if (suffix == "GB") 1376 return (unsigned long long)(result * _1G); 1377 else if (suffix == "TB") 1378 return (unsigned long long)(result * _1T); 1379 else if (suffix == "PB") 1380 return (unsigned long long)(result * _1P); 1381 else 1382 return 0; 1403 QString intgS = regexp.cap (1); 1404 QString hundS; 1405 QString suff = regexp.cap (2); 1406 if (intgS.isEmpty()) 1407 { 1408 intgS = regexp.cap (3); 1409 hundS = regexp.cap (4); 1410 suff = regexp.cap (5); 1411 } 1412 1413 Q_UINT64 denom = 0; 1414 if (suff.isEmpty() || suff == "B") 1415 denom = 1; 1416 else if (suff == "KB") 1417 denom = _1K; 1418 else if (suff == "MB") 1419 denom = _1M; 1420 else if (suff == "GB") 1421 denom = _1G; 1422 else if (suff == "TB") 1423 denom = _1T; 1424 else if (suff == "PB") 1425 denom = _1P; 1426 1427 Q_UINT64 intg = intgS.toULongLong(); 1428 if (denom == 1) 1429 return intg; 1430 1431 Q_UINT64 hund = hundS.rightJustify (2, '0').toULongLong(); 1432 hund = hund * denom / 100; 1433 intg = intg * denom + hund; 1434 return intg; 1383 1435 } 1384 1436 else … … 1386 1438 } 1387 1439 1440 /** 1441 * Formats the given \a size value in bytes to a human readable string 1442 * in form of <tt>####[.##] B|KB|MB|GB|TB|PB</tt>. 1443 * 1444 * The \a mode parameter is used for resulting numbers that get a fractional 1445 * part after converting the \a size to KB, MB etc: 1446 * <ul> 1447 * <li>When \a mode is 0, the result is rounded to the closest number 1448 * containing two decimal digits. 1449 * </li> 1450 * <li>When \a mode is -1, the result is rounded to the largest two decimal 1451 * digit number that is not greater than the result. This guarantees that 1452 * converting the resulting string back to the integer value in bytes 1453 * will not produce a value greater that the initial \a size parameter. 1454 * </li> 1455 * <li>When \a mode is 1, the result is rounded to the smallest two decimal 1456 * digit number that is not less than the result. This guarantees that 1457 * converting the resulting string back to the integer value in bytes 1458 * will not produce a value less that the initial \a size parameter. 1459 * </li> 1460 * </ul> 1461 * 1462 * @param aSize size value in bytes 1463 * @param aMode convertion mode (-1, 0 or 1) 1464 * @return human-readable size string 1465 */ 1388 1466 /* static */ 1389 QString VBoxGlobal::formatSize (unsigned long long aSize) 1390 { 1391 double size; 1392 QString suffix; 1467 QString VBoxGlobal::formatSize (Q_UINT64 aSize, int aMode /* = 0 */) 1468 { 1469 static const char *Suffixes [] = { "B", "KB", "MB", "GB", "TB", "PB", NULL }; 1470 1471 Q_UINT64 denom = 0; 1472 int suffix = 0; 1473 1393 1474 if (aSize < _1K) 1394 1475 { 1395 size = aSize;1396 suffix = "B";1476 denom = 1; 1477 suffix = 0; 1397 1478 } 1398 1479 else if (aSize < _1M) 1399 1480 { 1400 size = (double)aSize /_1K;1401 suffix = "KB";1481 denom = _1K; 1482 suffix = 1; 1402 1483 } 1403 1484 else if (aSize < _1G) 1404 1485 { 1405 size = (double)aSize /_1M;1406 suffix = "MB";1486 denom = _1M; 1487 suffix = 2; 1407 1488 } 1408 1489 else if (aSize < _1T) 1409 1490 { 1410 size = (double)aSize /_1G;1411 suffix = "GB";1491 denom = _1G; 1492 suffix = 3; 1412 1493 } 1413 1494 else if (aSize < _1P) 1414 1495 { 1415 size = (double)aSize /_1T;1416 suffix = "TB";1496 denom = _1T; 1497 suffix = 4; 1417 1498 } 1418 1499 else 1419 1500 { 1420 size = (double)aSize / _1P; 1421 suffix = "PB"; 1422 } 1423 QString number = QLocale::system().toString(size, 'f', 2); 1424 number.remove (QRegExp ("\\s+")); 1425 return QString ("%1 %2").arg (number).arg (suffix); 1501 denom = _1P; 1502 suffix = 5; 1503 } 1504 1505 Q_UINT64 intg = aSize / denom; 1506 Q_UINT64 hund = aSize % denom; 1507 1508 QString number; 1509 if (denom > 1) 1510 { 1511 if (hund) 1512 { 1513 hund *= 100; 1514 /* not greater */ 1515 if (aMode < 0) hund = hund / denom; 1516 /* not less */ 1517 else if (aMode > 0) hund = (hund + denom - 1) / denom; 1518 /* nearest */ 1519 else hund = (hund + denom / 2) / denom; 1520 } 1521 /* check for the fractional part overflow due to rounding */ 1522 if (hund == 100) 1523 { 1524 hund = 0; 1525 ++ intg; 1526 /* check if we've got 1024 XB after rounding and scale down if so */ 1527 if (intg == 1024 && Suffixes [suffix + 1] != NULL) 1528 { 1529 intg /= 1024; 1530 ++ suffix; 1531 } 1532 } 1533 number = QString ("%1%2%3").arg (intg).arg (decimalSep()) 1534 .arg (QString::number (hund).leftJustify (2, '0')); 1535 } 1536 else 1537 { 1538 number = QString::number (intg); 1539 } 1540 1541 return QString ("%1 %2").arg (number).arg (Suffixes [suffix]); 1426 1542 } 1427 1543
Note:
See TracChangeset
for help on using the changeset viewer.