Implemented high-level iteration code. Various fixes.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2666 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2003-02-08 23:34:47 +00:00
parent f0bc031212
commit 03fa4a4f9c
8 changed files with 310 additions and 21 deletions

View File

@ -50,6 +50,9 @@ public:
BPartition *VisitEachPartition(BDiskDeviceVisitor *visitor);
bool Traverse(BDiskDeviceVisitor *visitor);
BSession *SessionWithID(int32 id);
BPartition *PartitionWithID(int32 id);
private:
BDiskDevice(const BDiskDevice &);
BDiskDevice &operator=(const BDiskDevice &);

View File

@ -55,6 +55,9 @@ public:
bool VisitEachDevice(BDiskDeviceVisitor *visitor,
BDiskDevice *device = NULL);
bool VisitEachSession(BDiskDeviceVisitor *visitor,
BDiskDevice *device = NULL,
BSession **session = NULL);
bool VisitEachPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device = NULL,
BPartition **partition = NULL);
@ -81,6 +84,10 @@ public:
uint32 eventMask = B_DEVICE_REQUEST_ALL);
status_t StopWatching(BMessenger target);
private:
status_t _GetObjectWithID(const char *fieldName, int32 id,
BDiskDevice *device) const;
private:
BMessenger fManager;
int32 fCookie;

View File

@ -12,6 +12,7 @@ class BSession;
// BDiskDeviceVisitor
class BDiskDeviceVisitor {
public:
BDiskDeviceVisitor();
virtual ~BDiskDeviceVisitor();

View File

@ -43,6 +43,8 @@ public:
BPartition *VisitEachPartition(BDiskDeviceVisitor *visitor);
BPartition *PartitionWithID(int32 id);
status_t GetPartitioningParameters(const char *partitioningSystem,
BString *parameters,
BPoint dialogCenter = BPoint(-1, -1),

View File

@ -6,6 +6,7 @@
#include <new.h>
#include <DiskDevice.h>
#include <DiskDevicePrivate.h>
#include <Message.h>
#include <Partition.h>
#include <Session.h>
@ -295,7 +296,13 @@ BDiskDevice::Update()
BSession *
BDiskDevice::VisitEachSession(BDiskDeviceVisitor *visitor)
{
return NULL; // not implemented
if (visitor) {
for (int32 i = 0; BSession *session = SessionAt(i); i++) {
if (visitor->Visit(session))
return session;
}
}
return NULL;
}
// VisitEachPartition
@ -312,7 +319,13 @@ BDiskDevice::VisitEachSession(BDiskDeviceVisitor *visitor)
BPartition *
BDiskDevice::VisitEachPartition(BDiskDeviceVisitor *visitor)
{
return NULL; // not implemented
if (visitor) {
for (int32 i = 0; BSession *session = SessionAt(i); i++) {
if (BPartition *partition = session->VisitEachPartition(visitor))
return partition;
}
}
return NULL;
}
// Traverse
@ -330,7 +343,46 @@ BDiskDevice::VisitEachPartition(BDiskDeviceVisitor *visitor)
bool
BDiskDevice::Traverse(BDiskDeviceVisitor *visitor)
{
return false; // not implemented
if (visitor) {
// visit the device itself
if (visitor->Visit(this))
return true;
for (int32 i = 0; BSession *session = SessionAt(i); i++) {
// visit the session
if (visitor->Visit(session))
return true;
// visit all partitions on the session
if (session->VisitEachPartition(visitor))
return true;
}
}
return false;
}
// SessionWithID
/*! \brief Returns the session on the device, that has a certain ID.
\param id The ID of the session to be returned.
\return The session with ID \a id, or \c NULL, if a session with that
ID does not exist on this device.
*/
BSession *
BDiskDevice::SessionWithID(int32 id)
{
IDFinderVisitor visitor(id);
return VisitEachSession(&visitor);
}
// PartitionWithID
/*! \brief Returns the partition on the device, that has a certain ID.
\param id The ID of the partition to be returned.
\return The partition with ID \a id, or \c NULL, if a partition with that
ID does not exist on this device.
*/
BPartition *
BDiskDevice::PartitionWithID(int32 id)
{
IDFinderVisitor visitor(id);
return VisitEachPartition(&visitor);
}
// copy constructor
@ -356,7 +408,7 @@ find_string(BMessage *message, const char *name, char *buffer)
{
const char *str;
status_t error = message->FindString(name, &str);
if (error != B_OK)
if (error == B_OK)
strcpy(buffer, str);
return error;
}
@ -365,6 +417,8 @@ find_string(BMessage *message, const char *name, char *buffer)
status_t
BDiskDevice::_Unarchive(BMessage *archive)
{
//printf("BDiskDevice::_Unarchive()\n");
//archive->PrintToStream();
Unset();
status_t error = (archive ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
@ -373,33 +427,46 @@ BDiskDevice::_Unarchive(BMessage *archive)
error = archive->FindInt32("id", &fUniqueID);
if (error == B_OK)
error = archive->FindInt32("change_counter", &fChangeCounter);
//printf(" check: %s\n", strerror(error));
// geometry
if (error == B_OK)
error = archive->FindInt64("size", &fSize);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = archive->FindInt32("block_size", &fBlockSize);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = archive->FindInt8("type", (int8*)&fType);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = archive->FindBool("removable", &fRemovable);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = archive->FindBool("read_only", fReadOnly);
error = archive->FindBool("read_only", &fReadOnly);
// if (error == B_OK)
// error = archive->FindBool("write_once", fGeometry.write_once);
// other data
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = find_string(archive, "path", fPath);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = archive->FindInt32("media_status", &fMediaStatus);
//printf(" check: %s\n", strerror(error));
// sessions
type_code fieldType;
int32 count = 0;
if (error == B_OK)
error = archive->GetInfo("sessions", &fieldType, &count);
if (error == B_OK) {
if (archive->GetInfo("sessions", &fieldType, &count) != B_OK)
count = 0;
}
//printf(" check: %s\n", strerror(error));
for (int32 i = 0; error == B_OK && i < count; i++) {
//printf(" check1: %s\n", strerror(error));
// get the archived session
BMessage sessionArchive;
error = archive->FindMessage("sessions", i, &sessionArchive);
//printf(" check1.1: %s\n", strerror(error));
// allocate a session object
BSession *session = NULL;
if (error == B_OK) {
@ -407,12 +474,15 @@ BDiskDevice::_Unarchive(BMessage *archive)
if (!session)
error = B_NO_MEMORY;
}
//printf(" check1.1: %s\n", strerror(error));
// unarchive the session
if (error == B_OK)
error = session->_Unarchive(&sessionArchive);
//printf(" check1.1: %s\n", strerror(error));
// add the session
if (error == B_OK && !_AddSession(session))
error = B_NO_MEMORY;
//printf(" check1.1: %s\n", strerror(error));
// cleanup on error
if (error != B_OK && session)
delete session;
@ -421,6 +491,7 @@ BDiskDevice::_Unarchive(BMessage *archive)
// cleanup on error
if (error != B_OK)
Unset();
//printf("BDiskDevice::_Unarchive() done: %s\n", strerror(error));
return error;
}

View File

@ -7,9 +7,11 @@
#include <DiskDeviceRoster.h>
#include <DiskDevice.h>
#include <DiskDevicePrivate.h>
#include <Message.h>
#include <Partition.h>
#include <RegistrarDefs.h>
#include <RosterPrivate.h>
#include <Session.h>
/*! \class BDiskDeviceRoster
@ -29,7 +31,7 @@ BDiskDeviceRoster::BDiskDeviceRoster()
{
BMessage request(B_REG_GET_DISK_DEVICE_MESSENGER);
BMessage reply;
if (_send_to_roster_(&request, &reply, false) == B_OK
if (BRoster::Private().SendTo(&request, &reply, false) == B_OK
&& reply.what == B_REG_SUCCESS) {
reply.FindMessenger("messenger", &fManager);
}
@ -55,6 +57,7 @@ BDiskDeviceRoster::~BDiskDeviceRoster()
status_t
BDiskDeviceRoster::GetNextDevice(BDiskDevice *device)
{
//printf("BDiskDeviceRoster::GetNextDevice()\n");
status_t error = (device ? B_OK : B_BAD_VALUE);
// compose request message
BMessage request(B_REG_NEXT_DISK_DEVICE);
@ -66,21 +69,28 @@ BDiskDeviceRoster::GetNextDevice(BDiskDevice *device)
error = fManager.SendMessage(&request, &reply);
// analyze reply
if (error == B_OK) {
//reply.PrintToStream();
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = result;
//printf(" check: %s\n", strerror(error));
// cookie
if (error == B_OK)
error = reply.FindInt32("cookie", &fCookie);
//printf(" check: %s\n", strerror(error));
// device
BMessage archive;
if (error == B_OK)
error = reply.FindMessage("device", &archive);
//printf(" check: %s\n", strerror(error));
if (error == B_OK)
error = device->_Unarchive(&archive);
//printf(" check: %s\n", strerror(error));
}
//printf("BDiskDeviceRoster::GetNextDevice() done: %s\n", strerror(error));
return error;
}
@ -112,7 +122,58 @@ bool
BDiskDeviceRoster::VisitEachDevice(BDiskDeviceVisitor *visitor,
BDiskDevice *device)
{
return false; // not implemented
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fCookie;
fCookie = 0;
BDiskDevice deviceOnStack;
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
while (!terminatedEarly && GetNextDevice(useDevice) == B_OK)
terminatedEarly = visitor->Visit(useDevice);
fCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
}
return terminatedEarly;
}
// VisitEachSession
/*! \brief Iterates through the all devices' sessions.
The supplied visitor's Visit(BSession*) is invoked for each session.
If Visit() returns \c true, the iteration is terminated and this method
returns \c true. If supplied, \a device is set to the concerned device
and in \a session the pointer to the session object is returned.
\param visitor The visitor.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device at which the iteration was terminated.
May be \c NULL.
\param session Pointer to a pre-allocated BSession pointer to be set
to the session at which the iteration was terminated.
May be \c NULL.
\return \c true, if the iteration was terminated, \c false otherwise.
*/
bool
BDiskDeviceRoster::VisitEachSession(BDiskDeviceVisitor *visitor,
BDiskDevice *device, BSession **session)
{
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fCookie;
fCookie = 0;
BDiskDevice deviceOnStack;
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
BSession *foundSession = NULL;
while (!foundSession && GetNextDevice(useDevice) == B_OK)
foundSession = useDevice->VisitEachSession(visitor);
fCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
else if (device && session)
*session = foundSession;
}
return terminatedEarly;
}
// VisitEachPartition
@ -137,7 +198,22 @@ BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
return false; // not implemented
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fCookie;
fCookie = 0;
BDiskDevice deviceOnStack;
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
BPartition *foundPartition = NULL;
while (!foundPartition && GetNextDevice(useDevice) == B_OK)
foundPartition = useDevice->VisitEachPartition(visitor);
fCookie = oldCookie;
if (!terminatedEarly)
useDevice->Unset();
else if (device && partition)
*partition = foundPartition;
}
return terminatedEarly;
}
// Traverse
@ -155,7 +231,16 @@ BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
bool
BDiskDeviceRoster::Traverse(BDiskDeviceVisitor *visitor)
{
return false; // not implemented
bool terminatedEarly = false;
if (visitor) {
int32 oldCookie = fCookie;
fCookie = 0;
BDiskDevice device;
while (!terminatedEarly && GetNextDevice(&device) == B_OK)
terminatedEarly = device.Traverse(visitor);
fCookie = oldCookie;
}
return terminatedEarly;
}
// VisitEachMountedPartition
@ -181,7 +266,17 @@ BDiskDeviceRoster::VisitEachMountedPartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
return false; // not implemented
bool terminatedEarly = false;
if (visitor) {
struct MountedPartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
{ return partition->IsMounted(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
= VisitEachPartition(&filterVisitor, device, partition);
}
return terminatedEarly;
}
// VisitEachMountablePartition
@ -207,7 +302,17 @@ BDiskDeviceRoster::VisitEachMountablePartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
return false; // not implemented
bool terminatedEarly = false;
if (visitor) {
struct MountablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
{ return partition->ContainsFileSystem(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
= VisitEachPartition(&filterVisitor, device, partition);
}
return terminatedEarly;
}
// VisitEachInitializablePartition
@ -233,7 +338,17 @@ BDiskDeviceRoster::VisitEachInitializablePartition(BDiskDeviceVisitor *visitor,
BDiskDevice *device,
BPartition **partition)
{
return false; // not implemented
bool terminatedEarly = false;
if (visitor) {
struct InitializablePartitionFilter : public PartitionFilter {
virtual bool Filter(BPartition *partition)
{ return !partition->IsHidden(); }
} filter;
PartitionFilterVisitor filterVisitor(visitor, &filter);
terminatedEarly
= VisitEachPartition(&filterVisitor, device, partition);
}
return terminatedEarly;
}
// GetDeviceWithID
@ -252,7 +367,7 @@ BDiskDeviceRoster::VisitEachInitializablePartition(BDiskDeviceVisitor *visitor,
status_t
BDiskDeviceRoster::GetDeviceWithID(int32 id, BDiskDevice *device) const
{
return B_ERROR; // not implemented
return _GetObjectWithID("device_id", id, device);
}
// GetSessionWithID
@ -276,7 +391,12 @@ status_t
BDiskDeviceRoster::GetSessionWithID(int32 id, BDiskDevice *device,
BSession **session) const
{
return B_ERROR; // not implemented
status_t error = (device && session ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = _GetObjectWithID("session_id", id, device);
if (error == B_OK)
*session = device->SessionWithID(id);
return error;
}
// GetPartitionWithID
@ -300,6 +420,12 @@ status_t
BDiskDeviceRoster::GetPartitionWithID(int32 id, BDiskDevice *device,
BPartition **partition) const
{
status_t error = (device && partition ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = _GetObjectWithID("partition_id", id, device);
if (error == B_OK)
*partition = device->PartitionWithID(id);
return error;
}
// StartWatching
@ -337,3 +463,50 @@ BDiskDeviceRoster::StopWatching(BMessenger target)
return B_ERROR; // not implemented
}
// _GetObjectWithID
/*! \brief Returns a BDiskDevice for a given device, session or partition ID.
The supplied \a device is initialized to the device the object identified
by \a id belongs to.
\param fieldName "device_id", "sesison_id" or "partition_id" according to
the type of object the device shall be retrieved for.
\param id The ID of the device, session or partition to be retrieved.
\param device Pointer to a pre-allocated BDiskDevice to be initialized
to the device to be retrieved.
\return
- \c B_OK: Everything went fine.
- \c B_ENTRY_NOT_FOUND: A device, session or partition respectively with
ID \a id could not be found.
- other error codes
*/
status_t
BDiskDeviceRoster::_GetObjectWithID(const char *fieldName, int32 id,
BDiskDevice *device) const
{
status_t error = (device ? B_OK : B_BAD_VALUE);
// compose request message
BMessage request(B_REG_GET_DISK_DEVICE);
if (error == B_OK)
error = request.AddInt32(fieldName, id);
// send request
BMessage reply;
if (error == B_OK)
error = fManager.SendMessage(&request, &reply);
// analyze reply
if (error == B_OK) {
// result
status_t result = B_OK;
error = reply.FindInt32("result", &result);
if (error == B_OK)
error = result;
// device
BMessage archive;
if (error == B_OK)
error = reply.FindMessage("device", &archive);
if (error == B_OK)
error = device->_Unarchive(&archive);
}
return error;
}

View File

@ -531,7 +531,7 @@ find_string(BMessage *message, const char *name, char *buffer)
{
const char *str;
status_t error = message->FindString(name, &str);
if (error != B_OK)
if (error == B_OK)
strcpy(buffer, str);
return error;
}
@ -540,6 +540,7 @@ find_string(BMessage *message, const char *name, char *buffer)
status_t
BPartition::_Unarchive(BMessage *archive)
{
//printf("BPartition::_Unarchive()\n");
_Unset();
status_t error = (archive ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
@ -550,11 +551,13 @@ BPartition::_Unarchive(BMessage *archive)
error = archive->FindInt32("change_counter", &fChangeCounter);
if (error == B_OK)
error = archive->FindInt32("index", &fIndex);
//printf(" check: %s\n", strerror(error));
// fInfo.info.*
if (error == B_OK)
error = archive->FindInt64("offset", &fInfo.info.offset);
if (error == B_OK)
error = archive->FindInt64("size", &fInfo.info.size);
//printf(" check: %s\n", strerror(error));
// fInfo.*
if (error == B_OK)
error = archive->FindInt32("flags", (int32*)&fInfo.flags);
@ -576,6 +579,7 @@ BPartition::_Unarchive(BMessage *archive)
error = archive->FindInt32("fs_flags",
(int32*)&fInfo.file_system_flags);
}
//printf(" check: %s\n", strerror(error));
// dev_t, if mounted
if (error == B_OK) {
if (archive->FindInt32("volume_id", &fVolumeID) != B_OK)
@ -585,6 +589,7 @@ BPartition::_Unarchive(BMessage *archive)
// cleanup on error
if (error != B_OK)
_Unset();
//printf("BPartition::_Unarchive() done: %s\n", strerror(error));
return error;
}

View File

@ -7,6 +7,7 @@
#include <Session.h>
#include <DiskDevice.h>
#include <DiskDevicePrivate.h>
#include <Message.h>
#include <Partition.h>
@ -60,7 +61,7 @@ BSession::Offset() const
off_t
BSession::Size() const
{
return fInfo.offset;
return fInfo.size;
}
// BlockSize
@ -200,7 +201,26 @@ BSession::UniqueID() const
BPartition *
BSession::VisitEachPartition(BDiskDeviceVisitor *visitor)
{
return NULL; // not implemented
if (visitor) {
for (int32 i = 0; BPartition *partition = PartitionAt(i); i++) {
if (visitor->Visit(partition))
return partition;
}
}
return NULL;
}
// PartitionWithID
/*! \brief Returns the partition on the session, that has a certain ID.
\param id The ID of the partition to be returned.
\return The partition with ID \a id, or \c NULL, if a partition with that
ID does not exist on this session.
*/
BPartition *
BSession::PartitionWithID(int32 id)
{
IDFinderVisitor visitor(id);
return VisitEachPartition(&visitor);
}
// GetPartitioningParameters
@ -356,6 +376,7 @@ BSession::_Unset()
status_t
BSession::_Unarchive(BMessage *archive)
{
//printf("BSession::_Unarchive()\n");
_Unset();
status_t error = (archive ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
@ -366,6 +387,7 @@ BSession::_Unarchive(BMessage *archive)
error = archive->FindInt32("change_counter", &fChangeCounter);
if (error == B_OK)
error = archive->FindInt32("index", &fIndex);
//printf(" check: %s\n", strerror(error));
// fInfo.*
if (error == B_OK)
error = archive->FindInt64("offset", &fInfo.offset);
@ -373,14 +395,18 @@ BSession::_Unarchive(BMessage *archive)
error = archive->FindInt64("size", &fInfo.size);
if (error == B_OK)
error = archive->FindInt32("flags", (int32*)&fInfo.flags);
//printf(" check: %s\n", strerror(error));
// other data
if (error == B_OK)
error = archive->FindString("partitioning", &fPartitioningSystem);
//printf(" check: %s\n", strerror(error));
// partitions
type_code fieldType;
int32 count = 0;
if (error == B_OK)
error = archive->GetInfo("partitions", &fieldType, &count);
if (error == B_OK) {
if (archive->GetInfo("partitions", &fieldType, &count) != B_OK)
count = 0;
}
for (int32 i = 0; error == B_OK && i < count; i++) {
// get the archived partitions
BMessage partitionArchive;
@ -406,6 +432,7 @@ BSession::_Unarchive(BMessage *archive)
// cleanup on error
if (error != B_OK)
_Unset();
//printf("BSession::_Unarchive() done: %s\n", strerror(error));
return error;
}