summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArnaud Ferraris <arnaud.ferraris@collabora.com>2019-05-08 19:23:07 +0200
committerArnaud Ferraris <arnaud.ferraris@collabora.com>2019-05-08 19:30:33 +0200
commit4937668b5b33dbf686da4b629d776acec8028b25 (patch)
treea5aa5d2afe6fe76e24dbe0661b04be1aaee8a99f /src
parent36bc0e6308e080564d9188d350cace291433f479 (diff)
[libcalamares] Add generic PartitionSize class
Using PartUtils::PartSize as reference, this commit creates a new PartitionSize class in libcalamares, which will then be used in every module needing such a class. Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
Diffstat (limited to 'src')
-rw-r--r--src/libcalamares/CMakeLists.txt5
-rw-r--r--src/libcalamares/partition/PartitionSize.cpp238
-rw-r--r--src/libcalamares/partition/PartitionSize.h103
3 files changed, 345 insertions, 1 deletions
diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt
index c4b9fa40c..bc3ce0511 100644
--- a/src/libcalamares/CMakeLists.txt
+++ b/src/libcalamares/CMakeLists.txt
@@ -22,6 +22,9 @@ set( libSources
ProcessJob.cpp
Settings.cpp
)
+set( partSources
+ partition/PartitionSize.cpp
+)
set( utilsSources
utils/CalamaresUtilsSystem.cpp
utils/CommandList.cpp
@@ -72,7 +75,7 @@ if( WITH_PYTHON )
)
endif()
-add_library( calamares SHARED ${libSources} ${kdsagSources} ${utilsSources} )
+add_library( calamares SHARED ${libSources} ${kdsagSources} ${partSources} ${utilsSources} )
set_target_properties( calamares
PROPERTIES
VERSION ${CALAMARES_VERSION_SHORT}
diff --git a/src/libcalamares/partition/PartitionSize.cpp b/src/libcalamares/partition/PartitionSize.cpp
new file mode 100644
index 000000000..edff0fe1e
--- /dev/null
+++ b/src/libcalamares/partition/PartitionSize.cpp
@@ -0,0 +1,238 @@
+/* === This file is part of Calamares - <https://github.com/calamares> ===
+ *
+ * Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "partition/PartitionSize.h"
+#include "utils/Logger.h"
+#include "utils/Units.h"
+
+namespace Calamares
+{
+
+static const NamedEnumTable<SizeUnit>&
+unitSuffixes()
+{
+ static const NamedEnumTable<SizeUnit> 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() == unit_t::Percent ) && ( value() > 100 || value() < 0 ) )
+ {
+ cDebug() << "Percent value" << value() << "is not valid.";
+ m_value = 0;
+ }
+
+ if ( m_unit == unit_t::None )
+ {
+ m_value = s.toInt();
+ if ( m_value > 0 )
+ m_unit = unit_t::Byte;
+ }
+
+ if ( m_value <= 0 )
+ {
+ m_value = 0;
+ m_unit = unit_t::None;
+ }
+}
+
+qint64
+PartitionSize::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 CalamaresUtils::bytesToSectors ( toBytes(), sectorSize );
+ }
+
+ return -1;
+}
+
+qint64
+PartitionSize::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
+PartitionSize::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
+PartitionSize::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
+PartitionSize::operator< ( const PartitionSize& other ) const
+{
+ if ( ( m_unit == unit_t::None || other.m_unit == unit_t::None ) ||
+ ( m_unit == unit_t::Percent && other.m_unit != unit_t::Percent ) ||
+ ( m_unit != unit_t::Percent && other.m_unit == unit_t::Percent ) )
+ return false;
+
+ switch ( m_unit )
+ {
+ case unit_t::Percent:
+ return ( m_value < other.m_value );
+ case unit_t::Byte:
+ case unit_t::KiB:
+ case unit_t::MiB:
+ case unit_t::GiB:
+ return ( toBytes() < other.toBytes () );
+ }
+
+ return false;
+}
+
+bool
+PartitionSize::operator> ( const PartitionSize& other ) const
+{
+ if ( ( m_unit == unit_t::None || other.m_unit == unit_t::None ) ||
+ ( m_unit == unit_t::Percent && other.m_unit != unit_t::Percent ) ||
+ ( m_unit != unit_t::Percent && other.m_unit == unit_t::Percent ) )
+ return false;
+
+ switch ( m_unit )
+ {
+ case unit_t::Percent:
+ return ( m_value > other.m_value );
+ case unit_t::Byte:
+ case unit_t::KiB:
+ case unit_t::MiB:
+ case unit_t::GiB:
+ return ( toBytes() > other.toBytes () );
+ }
+
+ return false;
+}
+
+bool
+PartitionSize::operator== ( const PartitionSize& other ) const
+{
+ if ( ( m_unit == unit_t::None || other.m_unit == unit_t::None ) ||
+ ( m_unit == unit_t::Percent && other.m_unit != unit_t::Percent ) ||
+ ( m_unit != unit_t::Percent && other.m_unit == unit_t::Percent ) )
+ return false;
+
+ switch ( m_unit )
+ {
+ case unit_t::Percent:
+ return ( m_value == other.m_value );
+ case unit_t::Byte:
+ case unit_t::KiB:
+ case unit_t::MiB:
+ case unit_t::GiB:
+ return ( toBytes() == other.toBytes () );
+ }
+
+ return false;
+}
+
+} // namespace Calamares
diff --git a/src/libcalamares/partition/PartitionSize.h b/src/libcalamares/partition/PartitionSize.h
new file mode 100644
index 000000000..13ffa5c70
--- /dev/null
+++ b/src/libcalamares/partition/PartitionSize.h
@@ -0,0 +1,103 @@
+/* === This file is part of Calamares - <https://github.com/calamares> ===
+ *
+ * Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef PARTITION_PARTITIONSIZE_H
+#define PARTITION_PARTITIONSIZE_H
+
+#include "utils/Units.h"
+#include "utils/NamedSuffix.h"
+
+// Qt
+#include <QString>
+
+namespace Calamares
+{
+
+enum class SizeUnit
+{
+ 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 PartitionSize : public NamedSuffix<SizeUnit, SizeUnit::None>
+{
+public:
+ PartitionSize() : NamedSuffix() { }
+ PartitionSize( int v, unit_t u ) : NamedSuffix( v, u ) { }
+ PartitionSize( const QString& );
+
+ bool isValid() const
+ {
+ return ( unit() != SizeUnit::None ) && ( value() > 0 );
+ }
+
+ bool operator< ( const PartitionSize& other ) const;
+ bool operator> ( const PartitionSize& other ) const;
+ bool operator== ( const PartitionSize& 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;
+};
+
+} // namespace Calamares
+
+#endif // PARTITION_PARTITIONSIZE_H