From 671a745561ca173ffd87a0213672151344d6555c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 8 Jul 2003 18:26:15 +0000 Subject: [PATCH] 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 --- headers/private/storage/DiskDevice.h | 8 +-- headers/private/storage/DiskDevicePrivate.h | 6 +- headers/private/storage/DiskDeviceVisitor.h | 4 +- headers/private/storage/Partition.h | 13 ++-- src/kits/storage/DiskDevice.cpp | 34 ++++----- src/kits/storage/DiskDevicePrivate.cpp | 8 +-- src/kits/storage/DiskDeviceRoster.cpp | 16 ++--- src/kits/storage/DiskDeviceVisitor.cpp | 5 +- src/kits/storage/Partition.cpp | 70 +++++++++++++------ .../storage/disk_device/DiskDeviceTest.cpp | 60 +++++++++------- 10 files changed, 134 insertions(+), 90 deletions(-) diff --git a/headers/private/storage/DiskDevice.h b/headers/private/storage/DiskDevice.h index aaae7f37d8..0ccc5dba9d 100644 --- a/headers/private/storage/DiskDevice.h +++ b/headers/private/storage/DiskDevice.h @@ -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; }; diff --git a/headers/private/storage/DiskDevicePrivate.h b/headers/private/storage/DiskDevicePrivate.h index 1d6168171d..0f786495ee 100644 --- a/headers/private/storage/DiskDevicePrivate.h +++ b/headers/private/storage/DiskDevicePrivate.h @@ -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; diff --git a/headers/private/storage/DiskDeviceVisitor.h b/headers/private/storage/DiskDeviceVisitor.h index 3fca072c30..e89a1c8f99 100644 --- a/headers/private/storage/DiskDeviceVisitor.h +++ b/headers/private/storage/DiskDeviceVisitor.h @@ -6,6 +6,8 @@ #ifndef _DISK_DEVICE_VISITOR_H #define _DISK_DEVICE_VISITOR_H +#include + 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 diff --git a/headers/private/storage/Partition.h b/headers/private/storage/Partition.h index 06034cba25..5e30aba646 100644 --- a/headers/private/storage/Partition.h +++ b/headers/private/storage/Partition.h @@ -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; diff --git a/src/kits/storage/DiskDevice.cpp b/src/kits/storage/DiskDevice.cpp index c55de5f354..89530ece44 100644 --- a/src/kits/storage/DiskDevice.cpp +++ b/src/kits/storage/DiskDevice.cpp @@ -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 diff --git a/src/kits/storage/DiskDevicePrivate.cpp b/src/kits/storage/DiskDevicePrivate.cpp index 211cc60925..8472a311d5 100644 --- a/src/kits/storage/DiskDevicePrivate.cpp +++ b/src/kits/storage/DiskDevicePrivate.cpp @@ -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); } diff --git a/src/kits/storage/DiskDeviceRoster.cpp b/src/kits/storage/DiskDeviceRoster.cpp index 754d8793de..83ffab1304 100644 --- a/src/kits/storage/DiskDeviceRoster.cpp +++ b/src/kits/storage/DiskDeviceRoster.cpp @@ -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); diff --git a/src/kits/storage/DiskDeviceVisitor.cpp b/src/kits/storage/DiskDeviceVisitor.cpp index 9e43c6d384..71fcfd369d 100644 --- a/src/kits/storage/DiskDeviceVisitor.cpp +++ b/src/kits/storage/DiskDeviceVisitor.cpp @@ -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; } diff --git a/src/kits/storage/Partition.cpp b/src/kits/storage/Partition.cpp index 684d9e6924..b2a058d071 100644 --- a/src/kits/storage/Partition.cpp +++ b/src/kits/storage/Partition.cpp @@ -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 diff --git a/src/tests/kits/storage/disk_device/DiskDeviceTest.cpp b/src/tests/kits/storage/disk_device/DiskDeviceTest.cpp index 5542af0791..5dc65ee62e 100644 --- a/src/tests/kits/storage/disk_device/DiskDeviceTest.cpp +++ b/src/tests/kits/storage/disk_device/DiskDeviceTest.cpp @@ -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; }