Fixed/rewrote the implementation. Added doxygen style documentation.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2207 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2002-12-09 12:49:44 +00:00
parent 21881ce58c
commit 0813d0d4b8
2 changed files with 527 additions and 610 deletions

View File

@ -6,615 +6,496 @@
//
// Description: BVolume class
// ----------------------------------------------------------------------
/*!
\file Volume.h
BVolume implementation.
*/
#include <Volume.h>
#include <Directory.h>
#include <Bitmap.h>
#include <Node.h>
#include <errno.h>
#include <Bitmap.h>
#include <Directory.h>
#include <fs_info.h>
#include <kernel_interface.h>
#include <Node.h>
#include <Volume.h>
#ifdef USE_OPENBEOS_NAMESPACE
namespace OpenBeOS {
#endif
// ----------------------------------------------------------------------
// BVolume (public)
// ----------------------------------------------------------------------
// Default constructor: does nothing and sets InitCheck() to B_NO_INIT.
/*!
\class BVolume
\brief Represents a disk volume
Provides an interface for querying information about a volume.
BVolume::BVolume(void)
{
Unset();
}
The class is a simple wrapper for a \c dev_t and the function
fs_stat_dev. The only exception is the method is SetName(), which
sets the name of the volume.
\author Vincent Dominguez
\author <a href='mailto:bonefish@users.sf.net'>Ingo Weinhold</a>
\version 0.0.0
*/
// ----------------------------------------------------------------------
// BVolume (public)
// ----------------------------------------------------------------------
// Device constructor: sets the BVolume to point to the volume
// represented by the argument. See the SetTo() function for
// status codes.
/*! \var dev_t BVolume::fDevice
\brief The volume's device ID.
*/
BVolume::BVolume(
dev_t dev)
{
#if !_PR3_COMPATIBLE_
// Initialize reserved class variables to "safe" values:
_reserved[0] = 0L;
_reserved[1] = 0L;
_reserved[2] = 0L;
_reserved[3] = 0L;
_reserved[4] = 0L;
_reserved[5] = 0L;
_reserved[6] = 0L;
_reserved[7] = 0L;
// Place this in a separate initialization method at
// a later time.
#endif
/*! \var dev_t BVolume::fCStatus
\brief The object's initialization status.
*/
SetTo(dev);
}
// constructor
/*! \brief Creates an uninitialized BVolume.
// ----------------------------------------------------------------------
// BVolume (public)
// ----------------------------------------------------------------------
// Copy constructor: sets the object to point to the same device as
// does the argument.
BVolume::BVolume(
const BVolume& vol)
{
#if !_PR3_COMPATIBLE_
// Initialize reserved class variables to "safe" values:
_reserved[0] = 0L;
_reserved[1] = 0L;
_reserved[2] = 0L;
_reserved[3] = 0L;
_reserved[4] = 0L;
_reserved[5] = 0L;
_reserved[6] = 0L;
_reserved[7] = 0L;
// Place this in a separate initialization method at
// a later time.
#endif
fDev = vol.Device();
fCStatus = vol.InitCheck();
}
// ----------------------------------------------------------------------
// ~BVolume (public, virtual)
// ----------------------------------------------------------------------
// Destructor: Destroys the BVolume object.
BVolume::~BVolume(void)
InitCheck() will return \c B_NO_INIT.
*/
BVolume::BVolume()
: fDevice(-1),
fCStatus(B_NO_INIT)
{
}
// constructor
/*! \brief Creates a BVolume and initializes it to the volume specified
by the supplied device ID.
// ----------------------------------------------------------------------
// InitCheck (public)
// ----------------------------------------------------------------------
// Returns the status of the last initialization (from either the
// constructor or SetTo()).
InitCheck() should be called to check whether the initialization was
successful.
\param device The device ID of the volume.
*/
BVolume::BVolume(dev_t device)
: fDevice(-1),
fCStatus(B_NO_INIT)
{
SetTo(device);
}
// copy constructor
/*! \brief Creates a BVolume and makes it a clone of the supplied one.
Afterwards the object refers to the same device the supplied object
does. If the latter is not properly initialized, this object isn't
either.
\param volume The volume object to be cloned.
*/
BVolume::BVolume(const BVolume &volume)
: fDevice(volume.fDevice),
fCStatus(volume.fCStatus)
{
}
// destructor
/*! \brief Frees all resources associated with the object.
Does nothing.
*/
BVolume::~BVolume()
{
}
// InitCheck
/*! \brief Returns the result of the last initialization.
\return
- \c B_OK: The object is properly initialized.
- an error code otherwise
*/
status_t
BVolume::InitCheck(void) const
BVolume::InitCheck(void) const
{
return fCStatus;
}
// ----------------------------------------------------------------------
// SetTo (public)
// ----------------------------------------------------------------------
// Initializes the BVolume object to represent the volume (device)
// identified by the argument.
// SetTo
/*! \brief Re-initializes the object to refer to the volume specified by
the supplied device ID.
\param device The device ID of the volume.
\param
- \c B_OK: Everything went fine.
- an error code otherwise
*/
status_t
BVolume::SetTo(
dev_t dev)
BVolume::SetTo(dev_t device)
{
fDev = dev;
// Call the kernel function that gets device information
// in order to determine the device status:
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(dev, &fsInfo);
if (err != 0) {
fCStatus = errno;
// uninitialize
Unset();
// check the parameter
status_t error = (device >= 0 ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
fs_info info;
if (fs_stat_dev(device, &info) != 0)
error = errno;
}
else {
fCStatus = B_OK;
}
// set the new value
if (error == B_OK)
fDevice = device;
// set the init status variable
fCStatus = error;
return fCStatus;
}
// ----------------------------------------------------------------------
// Unset (public)
// ----------------------------------------------------------------------
// Uninitializes the BVolume.
// Unset
/*! \brief Uninitialized the BVolume.
*/
void
BVolume::Unset(void)
BVolume::Unset()
{
fDev = 0L;
fDevice = -1;
fCStatus = B_NO_INIT;
}
// ----------------------------------------------------------------------
// Device (public)
// ----------------------------------------------------------------------
// Returns the object's dev_t number.
// Device
/*! \brief Returns the device ID of the volume the object refers to.
\return Returns the device ID of the volume the object refers to
or -1, if the object is not properly initialized.
*/
dev_t
BVolume::Device(void) const
BVolume::Device() const
{
return fDev;
return fDevice;
}
// ----------------------------------------------------------------------
// GetRootDirectory (public)
// ----------------------------------------------------------------------
// Initializes dir (which must be allocated) to refer to the volume's
// "root directory." The root directory stands at the "root" of the
// volume's file hierarchy.
//
// NOTE: This isn't necessarily the root of the entire file
// hierarchy, but only the root of the volume hierarchy.
//
// This function does not change fDev nor fCStatus.
// GetRootDirectory
/*! \brief Returns the root directory of the volume referred to by the object.
\param directory A pointer to a pre-allocated BDirectory to be initialized
to the volume's root directory.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \c NULL \a directory or the object is not properly
initialized.
- another error code
*/
status_t
BVolume::GetRootDirectory(
BDirectory* dir) const
BVolume::GetRootDirectory(BDirectory *directory) const
{
status_t currentStatus = fCStatus;
if ((dir != NULL) && (currentStatus == B_OK)){
// Obtain the device information for the current device
// and initialize the passed-in BDirectory object with
// the device and root node values.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err != 0) {
currentStatus = errno;
}
else {
node_ref nodeRef;
nodeRef.device = fsInfo.dev;
// NOTE: This should be the same as fDev.
nodeRef.node = fsInfo.root;
currentStatus = dir->SetTo(&nodeRef);
}
// check parameter and initialization
status_t error = (directory && InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
// init the directory
if (error == B_OK) {
node_ref ref;
ref.device = info.dev;
ref.node = info.root;
error = directory->SetTo(&ref);
}
return currentStatus;
return error;
}
// ----------------------------------------------------------------------
// Capacity (public)
// ----------------------------------------------------------------------
// Returns the volume's total storage capacity (in bytes).
// Capacity
/*! \brief Returns the volume's total storage capacity.
\return
- The volume's total storage capacity (in bytes), when the object is
properly initialized.
- \c B_BAD_VALUE otherwise.
*/
off_t
BVolume::Capacity(void) const
BVolume::Capacity() const
{
off_t totalBytes = 0;
if (fCStatus == B_OK){
// Obtain the device information for the current device
// and calculate the total storage capacity.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
totalBytes = fsInfo.block_size * fsInfo.total_blocks;
}
}
return totalBytes;
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK ? info.total_blocks * info.block_size : error);
}
// ----------------------------------------------------------------------
// FreeBytes (public)
// ----------------------------------------------------------------------
// Returns the amount of storage that's currently unused on the
// volume (in bytes).
// FreeBytes
/*! \brief Returns the amount of storage that's currently unused on the
volume (in bytes).
\return
- The amount of storage that's currently unused on the volume (in bytes),
when the object is properly initialized.
- \c B_BAD_VALUE otherwise.
*/
off_t
BVolume::FreeBytes(void) const
BVolume::FreeBytes() const
{
off_t remainingBytes = 0L;
if (fCStatus == B_OK){
// Obtain the device information for the current device
// and calculate the free storage available.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
remainingBytes = fsInfo.block_size * fsInfo.free_blocks;
}
}
return remainingBytes;
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK ? info.free_blocks * info.block_size : error);
}
// GetName
/*! \brief Returns the name of the volume.
// ----------------------------------------------------------------------
// GetName (public)
// ----------------------------------------------------------------------
// Copies the name of the volume into the supplied buffer.
//
// The string pointed to by \a name must be long enough to
// hold the entire volume name. A length of B_PATH_NAME_LENGTH
// is safe and reccommended.
The name of the volume is copied into the provided buffer.
\param name A pointer to a pre-allocated character buffer of size
\c B_FILE_NAME_LENGTH or larger into which the name of the
volume shall be written.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \c NULL \a name or the object is not properly
initialized.
- another error code
*/
status_t
BVolume::GetName(
char* name) const
BVolume::GetName(char *name) const
{
status_t currentStatus = fCStatus;
if ((name != NULL) && (currentStatus == B_OK)) {
// Obtain the device information for the current device
// and copies the device name into the buffer.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err != 0) {
currentStatus = errno;
}
else {
strcpy(name, fsInfo.volume_name);
currentStatus = B_OK;
}
}
return currentStatus;
// check parameter and initialization
status_t error = (name && InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
// copy the name
if (error == B_OK)
strncpy(name, info.volume_name, B_FILE_NAME_LENGTH);
return error;
}
// ----------------------------------------------------------------------
// SetName (public)
// ----------------------------------------------------------------------
// Sets the name of the volume to the supplied string.
// Setting the name is typically (and most politely) the user's
// responsibility (a task that's performed, most easily, through the
// Tracker). If you really want to set the name of the volume
// programmatically, you do so by renaming the volume's root directory.
// SetName
/*! \brief Sets the name of the volume referred to by this object.
\param name The volume's new name. Must not be longer than
\c B_FILE_NAME_LENGTH (including the terminating null).
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: \c NULL \a name or the object is not properly
initialized.
- another error code
*/
status_t
BVolume::SetName(
const char* name)
BVolume::SetName(const char *name)
{
status_t currentStatus = B_ERROR;
// *** Call a kernel or, more indirectly, a POSIX function
// that sets a volume name ***
return currentStatus;
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
if (error == B_OK)
error = BPrivate::Storage::set_volume_name(fDevice, name);
return error;
}
// ----------------------------------------------------------------------
// GetIcon (public)
// ----------------------------------------------------------------------
// Returns the volume's icon in icon. which specifies the icon to
// retrieve, either B_MINI_ICON (16x16) or B_LARGE_ICON (32x32).
// GetIcon
/*! \brief Returns the icon of the volume.
\param icon A pointer to a pre-allocated BBitmap of the correct dimension
to store the requested icon (16x16 for the mini and 32x32 for the
large icon).
\param which Specifies the size of the icon to be retrieved:
\c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
*/
status_t
BVolume::GetIcon(
BBitmap* icon,
icon_size which) const
BVolume::GetIcon(BBitmap *icon, icon_size which) const
{
status_t currentStatus = fCStatus;
if ((icon != NULL) && (currentStatus == B_OK)
&& ((which == B_MINI_ICON) || (which == B_LARGE_ICON))) {
char deviceName[B_DEV_NAME_LENGTH];
currentStatus = GetName(deviceName);
if (currentStatus == B_OK)
{
currentStatus = get_device_icon(deviceName, icon, which);
}
// check parameter and initialization
status_t error = (icon && InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
BRect rect;
if (error == B_OK) {
if (which == B_MINI_ICON)
rect.Set(0, 0, 15, 15);
else if (which == B_LARGE_ICON)
rect.Set(0, 0, 31, 31);
else
error = B_BAD_VALUE;
}
return (currentStatus);
// check whether icon size and bitmap dimensions do match
if (error == B_OK
&& (icon->Bounds() != rect || icon->ColorSpace() != B_CMAP8)) {
error = B_BAD_VALUE;
}
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
// get the icon
if (error == B_OK)
error = get_device_icon(info.device_name, icon->Bits(), which);
return error;
}
// ----------------------------------------------------------------------
// IsRemovable (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not it is removable.
// IsRemovable
/*! \brief Returns whether the volume is removable.
\return \c true, when the object is properly initialized and the
referred to volume is removable, \c false otherwise.
*/
bool
BVolume::IsRemovable(void) const
BVolume::IsRemovable() const
{
bool volumeIsRemovable = false;
// Obtain the device information for the current device
// and determines whether or not the device is removable.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeIsRemovable = (fsInfo.flags & B_FS_IS_REMOVABLE);
}
return (volumeIsRemovable);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_IS_REMOVABLE));
}
// ----------------------------------------------------------------------
// IsReadOnly (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not it is read-only.
// IsReadOnly
/*! \brief Returns whether the volume is read only.
\return \c true, when the object is properly initialized and the
referred to volume is read only, \c false otherwise.
*/
bool
BVolume::IsReadOnly(void) const
{
bool volumeIsReadOnly = false;
// Obtain the device information for the current device
// and determines whether or not the device is read-only.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeIsReadOnly = (fsInfo.flags & B_FS_IS_READONLY);
}
return (volumeIsReadOnly);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_IS_READONLY));
}
// ----------------------------------------------------------------------
// IsPersistent (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not it is persistent.
// IsPersistent
/*! \brief Returns whether the volume is persistent.
\return \c true, when the object is properly initialized and the
referred to volume is persistent, \c false otherwise.
*/
bool
BVolume::IsPersistent(void) const
{
bool volumeIsPersistent = false;
// Obtain the device information for the current device
// and determines whether or not the storage medium
// is persistent.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeIsPersistent = (fsInfo.flags & B_FS_IS_PERSISTENT);
}
return (volumeIsPersistent);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_IS_PERSISTENT));
}
// ----------------------------------------------------------------------
// IsShared (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not it is shared.
// IsShared
/*! \brief Returns whether the volume is shared.
\return \c true, when the object is properly initialized and the
referred to volume is shared, \c false otherwise.
*/
bool
BVolume::IsShared(void) const
{
bool volumeIsShared = false;
// Obtain the device information for the current device
// and determines whether or not the volume is shared
// over a network.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeIsShared = (fsInfo.flags & B_FS_IS_SHARED);
}
return (volumeIsShared);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_IS_SHARED));
}
// ----------------------------------------------------------------------
// KnowsMime (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not it uses MIME types.
// KnowsMime
/*! \brief Returns whether the volume supports MIME types.
\return \c true, when the object is properly initialized and the
referred to volume supports MIME types, \c false otherwise.
*/
bool
BVolume::KnowsMime(void) const
{
bool volumeKnowsMime = false;
// Obtain the device information for the current device
// and determines whether or not the volume supports
// MIME types.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeKnowsMime = (fsInfo.flags & B_FS_HAS_MIME);
}
return (volumeKnowsMime);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_HAS_MIME));
}
// ----------------------------------------------------------------------
// KnowsAttr (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not its files
// accept attributes.
// KnowsAttr
/*! \brief Returns whether the volume supports attributes.
\return \c true, when the object is properly initialized and the
referred to volume supports attributes, \c false otherwise.
*/
bool
BVolume::KnowsAttr(void) const
{
bool volumeKnowsAttr = false;
// Obtain the device information for the current device
// and determines whether or not the files on the
// volume accept attributes.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeKnowsAttr = (fsInfo.flags & B_FS_HAS_ATTR);
}
return (volumeKnowsAttr);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_HAS_ATTR));
}
// ----------------------------------------------------------------------
// KnowsQuery (public)
// ----------------------------------------------------------------------
// Tests the volume and returns whether or not it can respond
// to queries.
// KnowsQuery
/*! \brief Returns whether the volume supports queries.
\return \c true, when the object is properly initialized and the
referred to volume supports queries, \c false otherwise.
*/
bool
BVolume::KnowsQuery(void) const
{
bool volumeKnowsQuery = false;
// Obtain the device information for the current device
// and determines whether or not the volume can
// respond to queries.
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(fDev, &fsInfo);
if (err == 0) {
volumeKnowsQuery = (fsInfo.flags & B_FS_HAS_QUERY);
}
return (volumeKnowsQuery);
// check initialization
status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
// get FS stat
fs_info info;
if (error == B_OK && fs_stat_dev(fDevice, &info) != 0)
error = errno;
return (error == B_OK && (info.flags & B_FS_HAS_QUERY));
}
// ==
/*! \brief Returns whether two BVolume objects are equal.
// ----------------------------------------------------------------------
// operator == (public)
// ----------------------------------------------------------------------
// Two BVolume objects are said to be equal if they refer to the
// same volume, or if they're both uninitialized.
// Returns whether or not the volumes are equal.
Two volume objects are said to be equal, if they either are both
uninitialized, or both are initialized and refer to the same volume.
\param volume The object to be compared with.
\result \c true, if this object and the supplied one are equal, \c false
otherwise.
*/
bool
BVolume::operator==(
const BVolume& vol) const
BVolume::operator==(const BVolume &volume) const
{
// First determine whether both objects are uninitialized,
// since comparing the fDev members of uninitialized BVolume
// instances will return an invalid result.
bool areEqual = ((this->fCStatus == B_NO_INIT)
&& (vol.InitCheck() == B_NO_INIT));
if (!areEqual) {
// The BVolume instance are initialized, test the
// fDev member values:
areEqual = (this->fDev == vol.Device());
}
return (areEqual);
return (InitCheck() != B_OK && volume.InitCheck() != B_OK
|| fDevice == volume.fDevice);
}
// !=
/*! \brief Returns whether two BVolume objects are unequal.
// ----------------------------------------------------------------------
// operator != (public)
// ----------------------------------------------------------------------
// Two BVolume objects are said to be equal if they refer to the
// same volume, or if they're both uninitialized.
// Returns whether or not the volumes are not equal.
Two volume objects are said to be equal, if they either are both
uninitialized, or both are initialized and refer to the same volume.
\param volume The object to be compared with.
\result \c true, if this object and the supplied one are unequal, \c false
otherwise.
*/
bool
BVolume::operator!=(
const BVolume& vol) const
BVolume::operator!=(const BVolume &volume) const
{
bool areNotEqual = !(*this == vol);
return (areNotEqual);
return !(*this == volume);
}
// =
/*! \brief Assigns another BVolume object to this one.
// ----------------------------------------------------------------------
// operator = (public)
// ----------------------------------------------------------------------
// In the expression:
//
// BVolume a = b;
//
// BVolume a is initialized to refer to the same volume as b.
// To gauge the success of the assignment, you should call InitCheck()
// immediately afterwards.
//
// Assigning a BVolume to itself is safe.
// Assigning from an uninitialized BVolume is "successful":
// The assigned-to BVolume will also be uninitialized (B_NO_INIT).
This object is made an exact clone of the supplied one.
\param volume The volume from which shall be assigned.
\return A reference to this object.
*/
BVolume&
BVolume::operator=(
const BVolume& vol)
BVolume::operator=(const BVolume &volume)
{
this->fDev = vol.Device();
this->fCStatus = vol.InitCheck();
return (*this);
if (&volume != this) {
this->fDevice = volume.fDevice;
this->fCStatus = volume.fCStatus;
}
return *this;
}
// FBC
void BVolume::_TurnUpTheVolume1() {}
void BVolume::_TurnUpTheVolume2() {}
void BVolume::_TurnUpTheVolume3() {}
void BVolume::_TurnUpTheVolume4() {}
void BVolume::_TurnUpTheVolume5() {}
void BVolume::_TurnUpTheVolume6() {}
void BVolume::_TurnUpTheVolume7() {}
void BVolume::_TurnUpTheVolume8() {}
void BVolume::_ReservedVolume1() {}
void BVolume::_ReservedVolume2() {}
void BVolume::_ReservedVolume3() {}
void BVolume::_ReservedVolume4() {}
void BVolume::_ReservedVolume5() {}
void BVolume::_ReservedVolume6() {}
void BVolume::_ReservedVolume7() {}
void BVolume::_ReservedVolume8() {}
#ifdef USE_OPENBEOS_NAMESPACE
}
#endif

View File

@ -6,180 +6,216 @@
//
// Description: BVolumeRoster class
// ----------------------------------------------------------------------
/*!
\file VolumeRoster.cpp
BVolumeRoster implementation.
*/
#include <VolumeRoster.h>
#include <Directory.h>
#include <Bitmap.h>
#include <Node.h>
#include <errno.h>
#include <new.h>
#include <Bitmap.h>
#include <Directory.h>
#include <fs_info.h>
#include <kernel_interface.h>
#include <Node.h>
#include <NodeMonitor.h>
#include <VolumeRoster.h>
static const char kBootVolumePath[] = "/boot";
#ifdef USE_OPENBEOS_NAMESPACE
namespace OpenBeOS {
#endif
// ----------------------------------------------------------------------
// BVolumeRoster (public)
// ----------------------------------------------------------------------
// Default constructor: creates a new BVolumeRoster object.
// You don't have to "initialize" the object before using it (as you do
// with most other Storage Kit classes). You can call GetNextVolume()
// (or another method) immediately after constructing.
BVolumeRoster::BVolumeRoster(void)
{
#if !_PR3_COMPATIBLE_
// Initialize reserved class variables to "safe" values:
_reserved[0] = 0L;
_reserved[1] = 0L;
_reserved[2] = 0L;
// Place this in a separate initialization method at
// a later time.
#endif
/*!
\class BVolumeRoster
\brief A roster of all volumes available in the system
fPos = 0;
fTarget = NULL;
}
Provides an interface for iterating through the volumes available in
the system and watching volume mounting/unmounting.
The class wraps the next_dev() function for iterating through the
volume list and the watch_node()/stop_watching() for the watching
features.
// ----------------------------------------------------------------------
// ~BVolumeRoster (public, virtual)
// ----------------------------------------------------------------------
// Destructor: Destroys the BVolumeRoster object.
// If this BVolumeRoster object was watching volumes,
// the watch is called off.
\author Vincent Dominguez
\author <a href='mailto:bonefish@users.sf.net'>Ingo Weinhold</a>
\version 0.0.0
*/
BVolumeRoster::~BVolumeRoster(void)
/*! \var dev_t BVolumeRoster::fCookie
\brief The iteration cookie for next_dev(). Initialized with 0.
*/
/*! \var dev_t BVolumeRoster::fTarget
\brief BMessenger referring to the target to which the watching
notification messages are sent.
The object is allocated and owned by the roster. \c NULL, if not watching.
*/
// constructor
/*! \brief Creates a new BVolumeRoster.
The object is ready to be used.
*/
BVolumeRoster::BVolumeRoster()
: fCookie(0),
fTarget(NULL)
{
}
// destructor
/*! \brief Frees all resources associated with this object.
// ----------------------------------------------------------------------
// GetNextVolume (public)
// ----------------------------------------------------------------------
// Retrieves the "next" volume from the volume list and uses it to
// initialize the argument (which must be allocated). When the function
// returns B_BAD_VALUE, you've reached the end of the list.
If a watching was activated on (StartWatching()), it is deactived.
*/
BVolumeRoster::~BVolumeRoster()
{
StopWatching();
}
// GetNextVolume
/*! \brief Returns the next volume in the list of available volumes.
\param volume A pointer to a pre-allocated BVolume to be initialized to
refer to the next volume in the list of available volumes.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: The last volume in the list has already been returned.
*/
status_t
BVolumeRoster::GetNextVolume(BVolume* vol)
BVolumeRoster::GetNextVolume(BVolume *volume)
{
status_t currentStatus = B_BAD_VALUE;
dev_t deviceID = next_dev(&fPos);
if ((deviceID >= 0) && (vol != NULL))
{
currentStatus = vol->SetTo(deviceID);
// check parameter
status_t error = (volume ? B_OK : B_BAD_VALUE);
// get next device
dev_t device;
if (error == B_OK) {
device = next_dev(&fCookie);
if (device < 0)
error = device;
}
return currentStatus;
// init volume
if (error == B_OK)
error = volume->SetTo(device);
return error;
}
// ----------------------------------------------------------------------
// Rewind (public)
// ----------------------------------------------------------------------
// Rewinds the volume list such that the next call to GetNextVolume()
// will return the first element in the list.
// Rewind
/*! \brief Rewinds the list of available volumes such that the next call to
GetNextVolume() will return the first element in the list.
*/
void
BVolumeRoster::Rewind(void)
BVolumeRoster::Rewind()
{
fPos = 0;
fCookie = 0;
}
// GetBootVolume
/*! \brief Returns the boot volume.
// ----------------------------------------------------------------------
// GetBootVolume (public)
// ----------------------------------------------------------------------
// Initializes boot_vol to refer to the "boot volume." This is the
// volume that was used to boot the computer. boot_vol must be
// allocated before you pass it in. If the boot volume can't be found,
// the argument is uninitialized.
//
// Currently, this function looks for the volume that is mounted at /boot.
// The only way to fool the system into thinking that there is not a boot
// volume is to rename /boot -- but, please refrain from doing so...(:o(
Currently, this function looks for the volume that is mounted at "/boot".
The only way to fool the system into thinking that there is not a boot
volume is to rename "/boot" -- but, please refrain from doing so...(:o(
\param volume A pointer to a pre-allocated BVolume to be initialized to
refer to the boot volume.
\return
- \c B_OK: Everything went fine.
- an error code otherwise
*/
status_t
BVolumeRoster::GetBootVolume(BVolume* boot_vol)
BVolumeRoster::GetBootVolume(BVolume *volume)
{
int32 pos = 0;
dev_t deviceID = 0;
status_t currentStatus = B_BAD_VALUE;
do {
deviceID = next_dev(&pos);
if(deviceID >= 0) {
fs_info fsInfo;
int err = BPrivate::Storage::stat_dev(deviceID, &fsInfo);
if (err == 0) {
if(std::strcmp(fsInfo.device_name, kBootVolumeName) == 0) {
fPos = pos;
currentStatus = boot_vol->SetTo(deviceID);
break;
}
}
}
} while(deviceID >= 0);
return currentStatus;
// check parameter
status_t error = (volume ? B_OK : B_BAD_VALUE);
// get device
dev_t device;
if (error == B_OK) {
device = dev_for_path(kBootVolumePath);
if (device < 0)
error = device;
}
// init volume
if (error == B_OK)
error = volume->SetTo(device);
return error;
}
// StartWatching
/*! \brief Starts watching the list of volumes available in the system.
// ----------------------------------------------------------------------
// StartWatching (public)
// ----------------------------------------------------------------------
// Registers a request for notifications of volume mounts and unmounts.
// The notifications are sent (as BMessages) to the BHandler/BLooper
// pair specified by the argument. There are separate messages for
// mounting and unmounting; their formats are described below.
//
// The caller retains possession of the BHandler/BLooper that the
// BMessenger represents. The volume watching continues until this
// BVolumeRoster object is destroyed, or until you call StopWatching().
Notifications are sent to the specified target whenever a volume is
mounted or unmounted. The format of the notification messages is
described under watch_node(). Actually BVolumeRoster just provides a
more convenient interface for it.
If StartWatching() has been called before with another target and no
StopWatching() since, StopWatching() is called first, so that the former
target won't receive any notifications anymore.
When the object is destroyed all watching has an end as well.
\param messenger The target to which the notification messages shall be
sent.
\return
- \c B_OK: Everything went fine.
- \c B_BAD_VALUE: The supplied BMessenger is invalid.
- \c B_NO_MEMORY: Insufficient memory to carry out this operation.
*/
status_t
BVolumeRoster::StartWatching(BMessenger msngr)
BVolumeRoster::StartWatching(BMessenger messenger)
{
return B_BAD_VALUE;
StopWatching();
status_t error = (messenger.IsValid() ? B_OK : B_ERROR);
// clone messenger
if (error == B_OK) {
fTarget = new(nothrow) BMessenger(messenger);
if (!fTarget)
error = B_NO_MEMORY;
}
// start watching
if (error == B_OK)
error = watch_node(NULL, B_WATCH_MOUNT, messenger);
// cleanup on failure
if (error != B_OK && fTarget) {
delete fTarget;
fTarget = NULL;
}
return error;
}
// ----------------------------------------------------------------------
// StopWatching (public)
// ----------------------------------------------------------------------
// Tells the volume-watcher to stop watching. Notifications of volume
// mounts and unmounts are no longer sent to the BVolumeRoster's target.
// StopWatching
/*! \brief Stops volume watching initiated with StartWatching() before.
*/
void
BVolumeRoster::StopWatching(void)
BVolumeRoster::StopWatching()
{
if (fTarget) {
stop_watching(*fTarget);
delete fTarget;
fTarget = NULL;
}
}
// ----------------------------------------------------------------------
// Messenger (public)
// ----------------------------------------------------------------------
// Returns a copy of the BMessenger object that was set in the
// previous StartWatching() call.
// Messenger
/*! \brief Returns a messenger to the target currently watching the volume
list.
\return A messenger to the target currently watching the volume list, or
an invalid messenger, if noone is currently watching.
*/
BMessenger
BVolumeRoster::Messenger(void) const
BVolumeRoster::Messenger() const
{
return *fTarget;
return (fTarget ? *fTarget : BMessenger());
}
// FBC
void BVolumeRoster::_ReservedVolumeRoster1() {}
void BVolumeRoster::_ReservedVolumeRoster2() {}
#ifdef USE_OPENBEOS_NAMESPACE
}
#endif