Introduce new partition size class based on NamedSuffix

In order to maintain consistency, and make use, create a new PartSize
class in the PartUtils namespace, which inherits from NamedSuffix for
easier parsing and handling of size strings.

The switch to using this class instead of the previous functions will be
done in a follow-up commit.

Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
main
Arnaud Ferraris 6 years ago
parent 680b0bc472
commit 3a58ae5e8b

@ -43,6 +43,216 @@
namespace PartUtils
{
static const NamedEnumTable<SizeUnit>&
unitSuffixes()
{
static const NamedEnumTable<SizeUnit> names{
{ QStringLiteral( "%" ), SizeUnit::Percent },
{ QStringLiteral( "B" ), SizeUnit::Byte },
{ QStringLiteral( "K" ), SizeUnit::KiB },
{ QStringLiteral( "M" ), SizeUnit::MiB },
{ QStringLiteral( "G" ), SizeUnit::GiB }
};
return names;
}
PartSize::PartSize( const QString& s )
: NamedSuffix( unitSuffixes(), s )
{
if ( ( unit() == SizeUnit::Percent ) && ( value() > 100 || value() < 0 ) )
{
cDebug() << "Percent value" << value() << "is not valid.";
m_value = 0;
}
if ( m_unit == SizeUnit::None )
{
m_value = s.toInt();
if ( m_value > 0 )
m_unit = SizeUnit::Byte;
}
if ( m_value <= 0 )
{
m_value = 0;
m_unit = SizeUnit::None;
}
}
qint64
PartSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const
{
if ( !isValid() )
return -1;
if ( totalSectors < 1 || sectorSize < 1 )
return -1;
switch ( m_unit )
{
case unit_t::None:
return -1;
case unit_t::Percent:
if ( value() == 100 )
return totalSectors; // Common-case, avoid futzing around
else
return totalSectors * value() / 100;
case unit_t::Byte:
case unit_t::KiB:
case unit_t::MiB:
case unit_t::GiB:
return bytesToSectors ( toBytes(), sectorSize );
}
return -1;
}
qint64
PartSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const
{
if ( !isValid() )
return -1;
switch ( m_unit )
{
case unit_t::None:
return -1;
case unit_t::Percent:
if ( totalSectors < 1 || sectorSize < 1 )
return -1;
if ( value() == 100 )
return totalSectors * sectorSize; // Common-case, avoid futzing around
else
return totalSectors * value() / 100;
case unit_t::Byte:
case unit_t::KiB:
case unit_t::MiB:
case unit_t::GiB:
return toBytes();
}
// notreached
return -1;
}
qint64
PartSize::toBytes( qint64 totalBytes ) const
{
if ( !isValid() )
return -1;
switch ( m_unit )
{
case unit_t::None:
return -1;
case unit_t::Percent:
if ( totalBytes < 1 )
return -1;
if ( value() == 100 )
return totalBytes; // Common-case, avoid futzing around
else
return totalBytes * value() / 100;
case unit_t::Byte:
case unit_t::KiB:
case unit_t::MiB:
case unit_t::GiB:
return toBytes();
}
// notreached
return -1;
}
qint64
PartSize::toBytes() const
{
if ( !isValid() )
return -1;
switch ( m_unit )
{
case unit_t::Byte:
return value();
case unit_t::KiB:
return CalamaresUtils::KiBtoBytes( static_cast<unsigned long long>( value() ) );
case unit_t::MiB:
return CalamaresUtils::MiBtoBytes( static_cast<unsigned long long>( value() ) );
case unit_t::GiB:
return CalamaresUtils::GiBtoBytes( static_cast<unsigned long long>( value() ) );
default:
break;
}
// Reached only when unit is Percent or None
return -1;
}
bool
PartSize::operator< ( const PartSize& other ) const
{
if ( ( m_unit == SizeUnit::None || other.m_unit == SizeUnit::None ) ||
( m_unit == SizeUnit::Percent && other.m_unit != SizeUnit::Percent ) ||
( m_unit != SizeUnit::Percent && other.m_unit == SizeUnit::Percent ) )
return false;
switch ( m_unit )
{
case SizeUnit::Percent:
return ( m_value < other.m_value );
case SizeUnit::Byte:
case SizeUnit::KiB:
case SizeUnit::MiB:
case SizeUnit::GiB:
return ( toBytes() < other.toBytes () );
}
return false;
}
bool
PartSize::operator> ( const PartSize& other ) const
{
if ( ( m_unit == SizeUnit::None || other.m_unit == SizeUnit::None ) ||
( m_unit == SizeUnit::Percent && other.m_unit != SizeUnit::Percent ) ||
( m_unit != SizeUnit::Percent && other.m_unit == SizeUnit::Percent ) )
return false;
switch ( m_unit )
{
case SizeUnit::Percent:
return ( m_value > other.m_value );
case SizeUnit::Byte:
case SizeUnit::KiB:
case SizeUnit::MiB:
case SizeUnit::GiB:
return ( toBytes() > other.toBytes () );
}
return false;
}
bool
PartSize::operator== ( const PartSize& other ) const
{
if ( ( m_unit == SizeUnit::None || other.m_unit == SizeUnit::None ) ||
( m_unit == SizeUnit::Percent && other.m_unit != SizeUnit::Percent ) ||
( m_unit != SizeUnit::Percent && other.m_unit == SizeUnit::Percent ) )
return false;
switch ( m_unit )
{
case SizeUnit::Percent:
return ( m_value == other.m_value );
case SizeUnit::Byte:
case SizeUnit::KiB:
case SizeUnit::MiB:
case SizeUnit::GiB:
return ( toBytes() == other.toBytes () );
}
return false;
}
QString
convenienceName( const Partition* const candidate )
{

@ -23,6 +23,7 @@
#include "OsproberEntry.h"
#include "utils/Units.h"
#include "utils/NamedSuffix.h"
// KPMcore
#include <kpmcore/fs/filesystem.h>
@ -37,15 +38,77 @@ namespace PartUtils
{
using CalamaresUtils::MiBtoBytes;
enum SizeUnit
enum class SizeUnit
{
Percent = 0,
None,
Percent,
Byte,
KiB,
MiB,
GiB
};
/** @brief Partition size expressions
*
* Sizes can be specified in bytes, KiB, MiB, GiB or percent (of
* the available drive space are on). This class handles parsing
* of such strings from the config file.
*/
class PartSize : public NamedSuffix<SizeUnit, SizeUnit::None>
{
public:
PartSize() : NamedSuffix() { };
PartSize( int v, unit_t u ) : NamedSuffix( v, u ) { };
PartSize( const QString& );
bool isValid() const
{
return ( unit() != SizeUnit::None ) && ( value() > 0 );
}
bool operator< ( const PartSize& other ) const;
bool operator> ( const PartSize& other ) const;
bool operator== ( const PartSize& other ) const;
/** @brief Convert the size to the number of sectors @p totalSectors .
*
* Each sector has size @p sectorSize, for converting sizes in Bytes,
* KiB, MiB or GiB to sector counts.
*
* @return the number of sectors needed, or -1 for invalid sizes.
*/
qint64 toSectors( qint64 totalSectors, qint64 sectorSize ) const;
/** @brief Convert the size to bytes.
*
* The device's sectors count @p totalSectors and sector size
* @p sectoreSize are used to calculated the total size, which
* is then used to calculate the size when using Percent.
*
* @return the size in bytes, or -1 for invalid sizes.
*/
qint64 toBytes( qint64 totalSectors, qint64 sectorSize ) const;
/** @brief Convert the size to bytes.
*
* Total size @p totalBytes is needed for sizes in Percent. This
* parameter is unused in any other case.
*
* @return the size in bytes, or -1 for invalid sizes.
*/
qint64 toBytes( qint64 totalBytes ) const;
/** @brief Convert the size to bytes.
*
* This method is only valid for sizes in Bytes, KiB, MiB or GiB.
* It will return -1 in any other case.
*
* @return the size in bytes, or -1 if it cannot be calculated.
*/
qint64 toBytes() const;
};
/**
* @brief Provides a nice human-readable name for @p candidate
*

Loading…
Cancel
Save