/* === This file is part of Calamares - === * * Copyright 2019, Collabora Ltd * Copyright 2019, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Calamares is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Calamares. If not, see . */ #include "partition/PartitionSize.h" #include "utils/Logger.h" #include "utils/Units.h" namespace CalamaresUtils { namespace Partition { static const NamedEnumTable& unitSuffixes() { static const NamedEnumTable names{ { QStringLiteral( "%" ), SizeUnit::Percent }, { QStringLiteral( "K" ), SizeUnit::KiB }, { QStringLiteral( "KiB" ), SizeUnit::KiB }, { QStringLiteral( "M" ), SizeUnit::MiB }, { QStringLiteral( "MiB" ), SizeUnit::MiB }, { QStringLiteral( "G" ), SizeUnit::GiB }, { QStringLiteral( "GiB" ), SizeUnit::GiB } }; return names; } PartitionSize::PartitionSize( 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 PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const { if ( !isValid() ) return -1; if ( totalSectors < 1 || sectorSize < 1 ) return -1; switch ( m_unit ) { case SizeUnit::None: return -1; case SizeUnit::Percent: if ( value() == 100 ) return totalSectors; // Common-case, avoid futzing around else return totalSectors * value() / 100; case SizeUnit::Byte: case SizeUnit::KiB: case SizeUnit::MiB: case SizeUnit::GiB: return CalamaresUtils::bytesToSectors ( toBytes(), sectorSize ); } return -1; } qint64 PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const { if ( !isValid() ) return -1; switch ( m_unit ) { case SizeUnit::None: return -1; case SizeUnit::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 SizeUnit::Byte: case SizeUnit::KiB: case SizeUnit::MiB: case SizeUnit::GiB: return toBytes(); } // notreached return -1; } qint64 PartitionSize::toBytes( qint64 totalBytes ) const { if ( !isValid() ) return -1; switch ( m_unit ) { case SizeUnit::None: return -1; case SizeUnit::Percent: if ( totalBytes < 1 ) return -1; if ( value() == 100 ) return totalBytes; // Common-case, avoid futzing around else return totalBytes * value() / 100; case SizeUnit::Byte: case SizeUnit::KiB: case SizeUnit::MiB: case SizeUnit::GiB: return toBytes(); } // notreached return -1; } qint64 PartitionSize::toBytes() const { if ( !isValid() ) return -1; switch ( m_unit ) { case SizeUnit::None: case SizeUnit::Percent: return -1; case SizeUnit::Byte: return value(); case SizeUnit::KiB: return CalamaresUtils::KiBtoBytes( static_cast( value() ) ); case SizeUnit::MiB: return CalamaresUtils::MiBtoBytes( static_cast( value() ) ); case SizeUnit::GiB: return CalamaresUtils::GiBtoBytes( static_cast( value() ) ); } NOTREACHED return -1; } bool PartitionSize::operator< ( const PartitionSize& other ) const { if ( !unitsComparable( m_unit, other.m_unit ) ) return false; switch ( m_unit ) { case SizeUnit::None: return false; 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 () ); } NOTREACHED return false; } bool PartitionSize::operator> ( const PartitionSize& other ) const { if ( !unitsComparable( m_unit, other.m_unit ) ) return false; switch ( m_unit ) { case SizeUnit::None: return false; 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 () ); } NOTREACHED return false; } bool PartitionSize::operator== ( const PartitionSize& other ) const { if ( !unitsComparable( m_unit, other.m_unit ) ) return false; switch ( m_unit ) { case SizeUnit::None: return false; 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 () ); } NOTREACHED return false; } } } // namespace