Modified the visitor implementation a bit. The Visit() with the BPartition* argument now also gets the level of the partition in the hierarchy.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3900 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2003-07-08 18:26:15 +00:00
parent c54d68a84e
commit 671a745561
10 changed files with 134 additions and 90 deletions

View File

@ -25,8 +25,6 @@ public:
virtual status_t GetPath(BPath *path) const;
virtual BPartition *VisitEachDescendent(BDiskDeviceVisitor *visitor);
bool IsModified() const;
status_t PrepareModifications();
status_t CommitModifications(bool synchronously = true,
@ -38,8 +36,10 @@ private:
friend class BDiskDeviceList;
friend class BDiskDeviceRoster;
status_t SetTo(partition_id id, size_t neededSize = 0);
status_t SetTo(user_disk_device_data *data);
status_t _SetTo(partition_id id, size_t neededSize = 0);
status_t _SetTo(user_disk_device_data *data);
virtual bool _AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level);
user_disk_device_data *fDeviceData;
};

View File

@ -16,7 +16,7 @@ namespace BPrivate {
// PartitionFilter
class PartitionFilter {
public:
virtual bool Filter(BPartition *partition) = 0;
virtual bool Filter(BPartition *partition, int32 level) = 0;
};
// PartitionFilterVisitor
@ -26,7 +26,7 @@ public:
PartitionFilter *filter);
virtual bool Visit(BDiskDevice *device);
virtual bool Visit(BPartition *partition);
virtual bool Visit(BPartition *partition, int32 level);
private:
BDiskDeviceVisitor *fVisitor;
@ -39,7 +39,7 @@ public:
IDFinderVisitor(partition_id id);
virtual bool Visit(BDiskDevice *device);
virtual bool Visit(BPartition *partition);
virtual bool Visit(BPartition *partition, int32 level);
private:
partition_id fID;

View File

@ -6,6 +6,8 @@
#ifndef _DISK_DEVICE_VISITOR_H
#define _DISK_DEVICE_VISITOR_H
#include <SupportDefs.h>
class BDiskDevice;
class BPartition;
@ -17,7 +19,7 @@ public:
// return true to abort iteration
virtual bool Visit(BDiskDevice *device);
virtual bool Visit(BPartition *partition);
virtual bool Visit(BPartition *partition, int32 level);
};
#endif _DISK_DEVICE_VISITOR_H

View File

@ -64,7 +64,7 @@ public:
status_t GetPartitioningInfo(BPartitioningInfo *info) const;
BPartition *VisitEachChild(BDiskDeviceVisitor *visitor);
virtual BPartition *VisitEachDescendent(BDiskDeviceVisitor *visitor);
virtual BPartition *VisitEachDescendant(BDiskDeviceVisitor *visitor);
// Self Modification
@ -113,9 +113,14 @@ private:
BPartition(const Partition &);
virtual ~BPartition();
status_t SetTo(BDiskDevice *device, BPartition *parent,
user_partition_data *data);
void Unset();
status_t _SetTo(BDiskDevice *device, BPartition *parent,
user_partition_data *data);
void _Unset();
int32 _Level() const;
virtual bool _AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level);
BPartition *_VisitEachDescendant(BDiskDeviceVisitor *visitor,
int32 level = -1);
friend class BDiskDevice;

View File

@ -181,17 +181,6 @@ BDiskDevice::GetPath(BPath *path) const
return path->SetTo(fDeviceData->path);
}
// VisitEachDescendent
BPartition *
BDiskDevice::VisitEachDescendent(BDiskDeviceVisitor *visitor)
{
if (!visitor)
return NULL;
if (visitor->Visit(this))
return this;
return BPartition::VisitEachDescendent(visitor);
}
// IsModified
bool
BDiskDevice::IsModified() const
@ -226,9 +215,9 @@ BDiskDevice::CancelModifications()
return B_ERROR;
}
// SetTo
// _SetTo
status_t
BDiskDevice::SetTo(partition_id id, size_t neededSize)
BDiskDevice::_SetTo(partition_id id, size_t neededSize)
{
Unset();
// get the device data
@ -259,25 +248,25 @@ BDiskDevice::SetTo(partition_id id, size_t neededSize)
} while (error == B_BUFFER_OVERFLOW);
// set the data
if (error == B_OK)
error = SetTo((user_disk_device_data*)buffer);
error = _SetTo((user_disk_device_data*)buffer);
// cleanup on error
if (error != B_OK)
free(buffer);
return error;
}
// SetTo
// _SetTo
status_t
BDiskDevice::SetTo(user_disk_device_data *data)
BDiskDevice::_SetTo(user_disk_device_data *data)
{
Unset();
if (!data)
return B_BAD_VALUE;
fDeviceData = data;
status_t error = BPartition::SetTo(this, NULL,
&fDeviceData->device_partition_data);
status_t error = BPartition::_SetTo(this, NULL,
&fDeviceData->device_partition_data);
if (error != B_OK) {
// Don't call Unset() here. If SetTo() fails, the caller retains
// Don't call Unset() here. If _SetTo() fails, the caller retains
// ownership of the supplied data.
// TODO: Maybe introduce a _Unset() to avoid potential future
// problems.
@ -286,6 +275,13 @@ BDiskDevice::SetTo(user_disk_device_data *data)
return error;
}
// _AcceptVisitor
bool
BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
{
return visitor->Visit(this);
}
#if 0

View File

@ -27,10 +27,10 @@ PartitionFilterVisitor::Visit(BDiskDevice *device)
// Visit
bool
PartitionFilterVisitor::Visit(BPartition *partition)
PartitionFilterVisitor::Visit(BPartition *partition, int32 level)
{
if (fFilter->Filter(partition))
return fVisitor->Visit(partition);
if (fFilter->Filter(partition, level))
return fVisitor->Visit(partition, level);
return false;
}
@ -53,7 +53,7 @@ IDFinderVisitor::Visit(BDiskDevice *device)
// Visit
bool
IDFinderVisitor::Visit(BPartition *partition)
IDFinderVisitor::Visit(BPartition *partition, int32 level)
{
return (partition->UniqueID() == fID);
}

View File

@ -82,7 +82,7 @@ BDiskDeviceRoster::GetNextDevice(BDiskDevice *device)
partition_id id = _kern_get_next_disk_device_id(&fCookie, &neededSize);
if (id < 0)
return id;
return device->SetTo(id, neededSize);
return device->_SetTo(id, neededSize);
}
// RewindDevices
@ -214,8 +214,8 @@ BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
BPartition *foundPartition = NULL;
while (!foundPartition && GetNextDevice(useDevice) == B_OK)
foundPartition = useDevice->VisitEachDescendent(visitor);
// TODO: That probably not correct. VisitEachDescendent()
foundPartition = useDevice->VisitEachDescendant(visitor);
// TODO: That probably not correct. VisitEachDescendant()
// should also invoke Visit(BDiskDevice*).
fCookie = oldCookie;
if (!terminatedEarly)
@ -247,7 +247,7 @@ BDiskDeviceRoster::VisitAll(BDiskDeviceVisitor *visitor)
fCookie = 0;
BDiskDevice device;
while (!terminatedEarly && GetNextDevice(&device) == B_OK)
terminatedEarly = device.VisitEachDescendent(visitor);
terminatedEarly = device.VisitEachDescendant(visitor);
fCookie = oldCookie;
}
return terminatedEarly;
@ -279,7 +279,7 @@ BDiskDeviceRoster::VisitEachMountedPartition(BDiskDeviceVisitor *visitor,
bool terminatedEarly = false;
if (visitor) {
struct MountedPartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
virtual bool Filter(BPartition *partition, int32)
{ return partition->IsMounted(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
@ -315,7 +315,7 @@ BDiskDeviceRoster::VisitEachMountablePartition(BDiskDeviceVisitor *visitor,
bool terminatedEarly = false;
if (visitor) {
struct MountablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
virtual bool Filter(BPartition *partition, int32)
{ return partition->ContainsFileSystem(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
@ -351,7 +351,7 @@ BDiskDeviceRoster::VisitEachInitializablePartition(BDiskDeviceVisitor *visitor,
/* bool terminatedEarly = false;
if (visitor) {
struct InitializablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
virtual bool Filter(BPartition *partition, int32)
{ return !partition->CanInitialize(NULL); }
// TODO: ???
} filter;
@ -375,7 +375,7 @@ BDiskDeviceRoster::VisitEachPartitionablePartition(BDiskDeviceVisitor *visitor,
bool terminatedEarly = false;
if (visitor) {
struct PartitionablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
virtual bool Filter(BPartition *partition, int32)
{ return partition->ContainsPartitioningSystem(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);

View File

@ -42,6 +42,7 @@ BDiskDeviceVisitor::~BDiskDeviceVisitor()
Overridden by derived classes.
This class' version does nothing and it returns \c false.
\param device The visited disk device.
\return \c true, if the iteration shall be terminated at this point,
\c false otherwise.
*/
@ -60,11 +61,13 @@ BDiskDeviceVisitor::Visit(BDiskDevice *device)
Overridden by derived classes.
This class' version does nothing and it returns \c false.
\param partition The visited partition.
\param level The level of the partition in the partition tree.
\return \c true, if the iteration shall be terminated at this point,
\c false otherwise.
*/
bool
BDiskDeviceVisitor::Visit(BPartition *partition)
BDiskDeviceVisitor::Visit(BPartition *partition, int32 level)
{
return false;
}

View File

@ -37,7 +37,7 @@ BPartition::BPartition()
*/
BPartition::~BPartition()
{
Unset();
_Unset();
}
// Offset
@ -362,35 +362,30 @@ BPartition *
BPartition::VisitEachChild(BDiskDeviceVisitor *visitor)
{
if (visitor) {
int32 level = _Level();
for (int32 i = 0; BPartition *child = ChildAt(i); i++) {
if (visitor->Visit(child))
if (child->_AcceptVisitor(visitor, level))
return child;
}
}
return NULL;
}
// VisitEachDescendent
// VisitEachDescendant
BPartition *
BPartition::VisitEachDescendent(BDiskDeviceVisitor *visitor)
BPartition::VisitEachDescendant(BDiskDeviceVisitor *visitor)
{
if (visitor) {
if (visitor->Visit(this))
return this;
for (int32 i = 0; BPartition *child = ChildAt(i); i++) {
if (BPartition *result = child->VisitEachDescendent(visitor))
return result;
}
}
if (visitor)
return _VisitEachDescendant(visitor);
return NULL;
}
// SetTo
// _SetTo
status_t
BPartition::SetTo(BDiskDevice *device, BPartition *parent,
user_partition_data *data)
BPartition::_SetTo(BDiskDevice *device, BPartition *parent,
user_partition_data *data)
{
Unset();
_Unset();
if (!device || !data)
return B_BAD_VALUE;
fPartitionData = data;
@ -402,7 +397,7 @@ BPartition::SetTo(BDiskDevice *device, BPartition *parent,
for (int32 i = 0; error == B_OK && i < fPartitionData->child_count; i++) {
BPartition *child = new(nothrow) BPartition;
if (child) {
error = child->SetTo(fDevice, this, fPartitionData->children[i]);
error = child->_SetTo(fDevice, this, fPartitionData->children[i]);
if (error != B_OK)
delete child;
} else
@ -410,13 +405,13 @@ BPartition::SetTo(BDiskDevice *device, BPartition *parent,
}
// cleanup on error
if (error != B_OK)
Unset();
_Unset();
return error;
}
// Unset
// _Unset
void
BPartition::Unset()
BPartition::_Unset()
{
// delete children
if (fPartitionData) {
@ -431,6 +426,41 @@ BPartition::Unset()
fPartitionData = NULL;
}
// _Level
int32
BPartition::_Level() const
{
int32 level = 0;
const BPartition *ancestor = this;
while ((ancestor = ancestor->Parent()))
level++;
return level;
}
// _AcceptVisitor
bool
BPartition::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
{
return visitor->Visit(this, level);
}
// _VisitEachDescendant
BPartition *
BPartition::_VisitEachDescendant(BDiskDeviceVisitor *visitor, int32 level)
{
if (level < 0)
level = _Level();
if (_AcceptVisitor(visitor, level))
return this;
for (int32 i = 0; BPartition *child = ChildAt(i); i++) {
if (BPartition *result = child->_VisitEachDescendant(visitor,
level + 1)) {
return result;
}
}
return NULL;
}
#if 0

View File

@ -32,37 +32,45 @@ public:
else
pathString = strerror(error);
printf("device %ld: `%s'\n", device->UniqueID(), pathString);
printf(" removable: %d\n", device->IsRemovable());
printf(" has media: %d\n", device->HasMedia());
printf(" removable: %d\n", device->IsRemovable());
printf(" has media: %d\n", device->HasMedia());
printf(" ---\n");
Visit(device, 0);
return false;
}
virtual bool Visit(BPartition *partition)
virtual bool Visit(BPartition *partition, int32 level)
{
BPath path;
status_t error = partition->GetPath(&path);
const char *pathString = NULL;
if (error == B_OK)
pathString = path.Path();
else
pathString = strerror(error);
printf(" partition %ld: `%s'\n", partition->UniqueID(), pathString);
printf(" offset: %lld\n", partition->Offset());
printf(" size: %lld\n", partition->Size());
printf(" block size: %lu\n", partition->BlockSize());
printf(" index: %ld\n", partition->Index());
printf(" status: %lu\n", partition->Status());
printf(" file system: %d\n", partition->ContainsFileSystem());
printf(" part. system: %d\n",
char prefix[128];
sprintf(prefix, "%*s", 2 * (int)level, "");
if (level > 0) {
BPath path;
status_t error = partition->GetPath(&path);
const char *pathString = NULL;
if (error == B_OK)
pathString = path.Path();
else
pathString = strerror(error);
printf("%spartition %ld: `%s'\n", prefix, partition->UniqueID(),
pathString);
}
printf("%s offset: %lld\n", prefix, partition->Offset());
printf("%s size: %lld\n", prefix, partition->Size());
printf("%s block size: %lu\n", prefix, partition->BlockSize());
printf("%s index: %ld\n", prefix, partition->Index());
printf("%s status: %lu\n", prefix, partition->Status());
printf("%s file system: %d\n", prefix,
partition->ContainsFileSystem());
printf("%s part. system: %d\n", prefix,
partition->ContainsPartitioningSystem());
printf(" device: %d\n", partition->IsDevice());
printf(" read only: %d\n", partition->IsReadOnly());
printf(" mounted: %d\n", partition->IsMounted());
printf(" flags: %lx\n", partition->Flags());
printf(" name: `%s'\n", partition->Name());
printf(" content name: `%s'\n", partition->ContentName());
printf(" type: `%s'\n", partition->Type());
printf(" content type: `%s'\n", partition->ContentType());
printf("%s device: %d\n", prefix, partition->IsDevice());
printf("%s read only: %d\n", prefix, partition->IsReadOnly());
printf("%s mounted: %d\n", prefix, partition->IsMounted());
printf("%s flags: %lx\n", prefix, partition->Flags());
printf("%s name: `%s'\n", prefix, partition->Name());
printf("%s content name: `%s'\n", prefix, partition->ContentName());
printf("%s type: `%s'\n", prefix, partition->Type());
printf("%s content type: `%s'\n", prefix, partition->ContentType());
// volume, icon,...
return false;
}