208 lines
6.3 KiB
C++
208 lines
6.3 KiB
C++
/*************************************************************************
|
|
* Copyright (C) 2008 by Volker Lanz <vl@fidra.de> *
|
|
* Copyright (C) 2016 by Andrius Štikonas <andrius@stikonas.eu> *
|
|
* *
|
|
* This program 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. *
|
|
* *
|
|
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.*
|
|
*************************************************************************/
|
|
|
|
#include "core/partitionnode.h"
|
|
|
|
#include "core/partition.h"
|
|
#include "core/partitionrole.h"
|
|
|
|
#include "fs/filesystem.h"
|
|
|
|
/** Tries to find the predecessor for a Partition.
|
|
@param p the Partition to find a predecessor for
|
|
@return pointer to the predecessor or nullptr if none was found
|
|
*/
|
|
Partition* PartitionNode::predecessor(Partition& p)
|
|
{
|
|
Q_ASSERT(p.parent());
|
|
|
|
Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children();
|
|
|
|
for (int idx = 1; idx < plist.size(); idx++)
|
|
if (plist[idx] == &p)
|
|
return plist[idx - 1];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
@overload
|
|
*/
|
|
const Partition* PartitionNode::predecessor(const Partition& p) const
|
|
{
|
|
Q_ASSERT(p.parent());
|
|
|
|
const Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children();
|
|
|
|
for (int idx = 1; idx < plist.size(); idx++)
|
|
if (plist[idx] == &p)
|
|
return plist[idx - 1];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/** Tries to find the successor for a Partition.
|
|
@param p the Partition to find a successor for
|
|
@return pointer to the successor or nullptr if none was found
|
|
*/
|
|
Partition* PartitionNode::successor(Partition& p)
|
|
{
|
|
Q_ASSERT(p.parent());
|
|
|
|
Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children();
|
|
|
|
for (int idx = plist.size() - 2; idx >= 0; idx--)
|
|
if (plist[idx] == &p)
|
|
return plist[idx + 1];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
@overload
|
|
*/
|
|
const Partition* PartitionNode::successor(const Partition& p) const
|
|
{
|
|
Q_ASSERT(p.parent());
|
|
|
|
const Partitions& plist = p.parent()->isRoot() == false ? p.parent()->children() : children();
|
|
|
|
for (int idx = plist.size() - 2; idx >= 0; idx--)
|
|
if (plist[idx] == &p)
|
|
return plist[idx + 1];
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/** Inserts a Partition into a PartitionNode's children
|
|
@param p pointer to the Partition to insert. May be nullptr.
|
|
@return true on success
|
|
*/
|
|
bool PartitionNode::insert(Partition* p)
|
|
{
|
|
if (p == nullptr)
|
|
return false;
|
|
|
|
for (int idx = 0; idx < children().size(); idx++) {
|
|
if (children()[idx]->firstSector() > p->firstSector()) {
|
|
children().insert(idx, p);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
children().insert(children().size(), p);
|
|
|
|
return true;
|
|
}
|
|
|
|
/** Removes a Partition from the PartitionNode's children.
|
|
@param p pointer to the Partition to remove. May be nullptr.
|
|
@return true on success.
|
|
*/
|
|
bool PartitionNode::remove(Partition* p)
|
|
{
|
|
if (p == nullptr)
|
|
return false;
|
|
|
|
return children().removeOne(p);
|
|
}
|
|
|
|
/** Deletes all children */
|
|
void PartitionNode::clearChildren()
|
|
{
|
|
qDeleteAll(children());
|
|
children().clear();
|
|
}
|
|
|
|
/** Finds a Partition by sector.
|
|
@param s the sector the Partition is at
|
|
@param role the PartitionRole the Partition is supposed to have
|
|
@return pointer to the Partition found or nullptr if none was found
|
|
*/
|
|
Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& role)
|
|
{
|
|
const auto partitions = children();
|
|
for (auto &p : partitions) {
|
|
// (women and) children first. ;-)
|
|
const auto pChildren = p->children();
|
|
for (auto &child : pChildren)
|
|
if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector())
|
|
return child;
|
|
|
|
if ((p->roles().roles() & role.roles()) && s >= p->firstSector() && s <= p->lastSector())
|
|
return p;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
@overload
|
|
*/
|
|
const Partition* PartitionNode::findPartitionBySector(qint64 s, const PartitionRole& role) const
|
|
{
|
|
for (const auto *p : children()) {
|
|
for (const auto &child : p->children())
|
|
if ((child->roles().roles() & role.roles()) && s >= child->firstSector() && s <= child->lastSector())
|
|
return child;
|
|
|
|
if ((p->roles().roles() & role.roles()) && s >= p->firstSector() && s <= p->lastSector())
|
|
return p;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/** Reparents a Partition to this PartitionNode
|
|
@param p the Partition to reparent
|
|
*/
|
|
void PartitionNode::reparent(Partition& p)
|
|
{
|
|
p.setParent(this);
|
|
|
|
if (!isRoot())
|
|
p.setRoles(PartitionRole(PartitionRole::Logical));
|
|
else if (!p.roles().has(PartitionRole::Extended))
|
|
p.setRoles(PartitionRole(PartitionRole::Primary));
|
|
else
|
|
p.setRoles(PartitionRole(PartitionRole::Extended));
|
|
}
|
|
|
|
/** @return the number of the highest mounted child, e.g. 7 if /dev/sdd7 is a child of this PartitionNode and mounted and /dev/sdd8 and /dev/sdd9 and so on aren't
|
|
*/
|
|
qint32 PartitionNode::highestMountedChild() const
|
|
{
|
|
qint32 result = -1;
|
|
|
|
for (const auto * p : children())
|
|
if (p->number() > result && p->isMounted())
|
|
result = p->number();
|
|
|
|
return result;
|
|
}
|
|
|
|
/** @return true if any of the partition's children are mounted */
|
|
bool PartitionNode::isChildMounted() const
|
|
{
|
|
for (const auto * child : children())
|
|
if (child->isMounted() || (child->hasChildren() && child->isChildMounted()))
|
|
return true;
|
|
|
|
return false;
|
|
}
|