* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <MutablePartition.h>
#include <stdlib.h>
#include <string.h>
#include <new>
#include <Partition.h>
#include <ddm_userland_interface_defs.h>
#include "DiskDeviceUtils.h"
#include "PartitionDelegate.h"
using std::nothrow;
void
BMutablePartition::UninitializeContents()
{
DeleteAllChildren();
SetVolumeID(-1);
SetContentName(NULL);
SetContentParameters(NULL);
SetContentSize(0);
SetBlockSize(Parent()->BlockSize());
SetContentType(NULL);
SetStatus(B_PARTITION_UNINITIALIZED);
ClearFlags(B_PARTITION_FILE_SYSTEM | B_PARTITION_PARTITIONING_SYSTEM);
}
off_t
BMutablePartition::Offset() const
{
return fData->offset;
}
void
BMutablePartition::SetOffset(off_t offset)
{
if (fData->offset != offset) {
fData->offset = offset;
Changed(B_PARTITION_CHANGED_OFFSET);
}
}
off_t
BMutablePartition::Size() const
{
return fData->size;
}
void
BMutablePartition::SetSize(off_t size)
{
if (fData->size != size) {
fData->size = size;
Changed(B_PARTITION_CHANGED_SIZE);
}
}
off_t
BMutablePartition::ContentSize() const
{
return fData->content_size;
}
void
BMutablePartition::SetContentSize(off_t size)
{
if (fData->content_size != size) {
fData->content_size = size;
Changed(B_PARTITION_CHANGED_CONTENT_SIZE);
}
}
off_t
BMutablePartition::BlockSize() const
{
return fData->block_size;
}
void
BMutablePartition::SetBlockSize(off_t blockSize)
{
if (fData->block_size != blockSize) {
fData->block_size = blockSize;
Changed(B_PARTITION_CHANGED_BLOCK_SIZE);
}
}
uint32
BMutablePartition::Status() const
{
return fData->status;
}
void
BMutablePartition::SetStatus(uint32 status)
{
if (fData->status != status) {
fData->status = status;
Changed(B_PARTITION_CHANGED_STATUS);
}
}
uint32
BMutablePartition::Flags() const
{
return fData->flags;
}
void
BMutablePartition::SetFlags(uint32 flags)
{
if (fData->flags != flags) {
fData->flags = flags;
Changed(B_PARTITION_CHANGED_FLAGS);
}
}
void
BMutablePartition::ClearFlags(uint32 flags)
{
if (flags & fData->flags) {
fData->flags &= ~flags;
Changed(B_PARTITION_CHANGED_FLAGS);
}
}
dev_t
BMutablePartition::VolumeID() const
{
return fData->volume;
}
void
BMutablePartition::SetVolumeID(dev_t volumeID)
{
if (fData->volume != volumeID) {
fData->volume = volumeID;
Changed(B_PARTITION_CHANGED_VOLUME);
}
}
int32
BMutablePartition::Index() const
{
return fData->index;
}
const char*
BMutablePartition::Name() const
{
return fData->name;
}
status_t
BMutablePartition::SetName(const char* name)
{
if (compare_string(name, fData->name) == 0)
return B_OK;
if (set_string(fData->name, name) != B_OK)
return B_NO_MEMORY;
Changed(B_PARTITION_CHANGED_NAME);
return B_OK;
}
BString
BMutablePartition::ContentName() const
{
return fData->content_name;
}
status_t
BMutablePartition::SetContentName(const char* name)
{
if (compare_string(name, fData->content_name) == 0)
return B_OK;
if (set_string(fData->content_name, name) != B_OK)
return B_NO_MEMORY;
Changed(B_PARTITION_CHANGED_CONTENT_NAME);
return B_OK;
}
const char*
BMutablePartition::Type() const
{
return fData->type;
}
status_t
BMutablePartition::SetType(const char* type)
{
if (compare_string(type, fData->type) == 0)
return B_OK;
if (set_string(fData->type, type) != B_OK)
return B_NO_MEMORY;
Changed(B_PARTITION_CHANGED_TYPE);
return B_OK;
}
const char*
BMutablePartition::ContentType() const
{
return fData->content_type;
}
status_t
BMutablePartition::SetContentType(const char* type)
{
if (compare_string(type, fData->content_type) == 0)
return B_OK;
if (set_string(fData->content_type, type) != B_OK)
return B_NO_MEMORY;
Changed(B_PARTITION_CHANGED_CONTENT_TYPE
| B_PARTITION_CHANGED_INITIALIZATION);
return B_OK;
}
const char*
BMutablePartition::Parameters() const
{
return fData->parameters;
}
status_t
BMutablePartition::SetParameters(const char* parameters)
{
if (compare_string(parameters, fData->parameters) == 0)
return B_OK;
if (set_string(fData->parameters, parameters) != B_OK)
return B_NO_MEMORY;
Changed(B_PARTITION_CHANGED_PARAMETERS);
return B_OK;
}
const char*
BMutablePartition::ContentParameters() const
{
return fData->content_parameters;
}
status_t
BMutablePartition::SetContentParameters(const char* parameters)
{
if (compare_string(parameters, fData->content_parameters) == 0)
return B_OK;
if (set_string(fData->content_parameters, parameters) != B_OK)
return B_NO_MEMORY;
Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS);
return B_OK;
}
status_t
BMutablePartition::CreateChild(int32 index, BMutablePartition** _child)
{
if (index < 0)
index = fChildren.CountItems();
else if (index > fChildren.CountItems())
return B_BAD_VALUE;
BPartition* partition = new(nothrow) BPartition;
if (!partition)
return B_NO_MEMORY;
BPartition::Delegate* delegate
= new(nothrow) BPartition::Delegate(partition);
if (!delegate) {
delete partition;
return B_NO_MEMORY;
}
partition->fDelegate = delegate;
BMutablePartition* child = delegate->MutablePartition();
if (!fChildren.AddItem(child, index)) {
delete partition;
return B_NO_MEMORY;
}
child->fParent = this;
child->fData = new(nothrow) user_partition_data;
if (!child->fData) {
fChildren.RemoveItem(child);
delete partition;
return B_NO_MEMORY;
}
memset(child->fData, 0, sizeof(user_partition_data));
child->fData->id = -1;
child->fData->status = B_PARTITION_UNINITIALIZED;
child->fData->volume = -1;
child->fData->index = -1;
child->fData->disk_system = -1;
*_child = child;
Changed(B_PARTITION_CHANGED_CHILDREN);
return B_OK;
}
status_t
BMutablePartition::CreateChild(int32 index, const char* type, const char* name,
const char* parameters, BMutablePartition** _child)
{
BMutablePartition* child;
status_t error = CreateChild(index, &child);
if (error != B_OK)
return error;
error = child->SetType(type);
if (error == B_OK)
error = child->SetName(name);
if (error == B_OK)
error = child->SetParameters(parameters);
if (error != B_OK) {
DeleteChild(child);
return error;
}
*_child = child;
Changed(B_PARTITION_CHANGED_CHILDREN);
return B_OK;
}
status_t
BMutablePartition::DeleteChild(int32 index)
{
BMutablePartition* child = (BMutablePartition*)fChildren.RemoveItem(index);
if (!child)
return B_BAD_VALUE;
child->fDelegate->Partition()->_DeleteDelegates();
Changed(B_PARTITION_CHANGED_CHILDREN);
return B_OK;
}
status_t
BMutablePartition::DeleteChild(BMutablePartition* child)
{
return DeleteChild(IndexOfChild(child));
}
void
BMutablePartition::DeleteAllChildren()
{
int32 count = CountChildren();
for (int32 i = count - 1; i >= 0; i--)
DeleteChild(i);
}
BMutablePartition*
BMutablePartition::Parent() const
{
return fParent;
}
BMutablePartition*
BMutablePartition::ChildAt(int32 index) const
{
return (BMutablePartition*)fChildren.ItemAt(index);
}
int32
BMutablePartition::CountChildren() const
{
return fChildren.CountItems();
}
int32
BMutablePartition::IndexOfChild(BMutablePartition* child) const
{
if (!child)
return -1;
return fChildren.IndexOf(child);
}
void
BMutablePartition::SetChangeFlags(uint32 flags)
{
fChangeFlags = flags;
}
uint32
BMutablePartition::ChangeFlags() const
{
return fChangeFlags;
}
void
BMutablePartition::Changed(uint32 flags, uint32 clearFlags)
{
fChangeFlags &= ~clearFlags;
fChangeFlags |= flags;
if (Parent())
Parent()->Changed(B_PARTITION_CHANGED_DESCENDANTS);
}
void*
BMutablePartition::ChildCookie() const
{
return fChildCookie;
}
void
BMutablePartition::SetChildCookie(void* cookie)
{
fChildCookie = cookie;
}
BMutablePartition::BMutablePartition(BPartition::Delegate* delegate)
: fDelegate(delegate),
fData(NULL),
fParent(NULL),
fChangeFlags(0),
fChildCookie(NULL)
{
}
status_t
BMutablePartition::Init(const user_partition_data* partitionData,
BMutablePartition* parent)
{
fParent = parent;
if (fParent) {
if (!fParent->fChildren.AddItem(this))
return B_NO_MEMORY;
}
fData = new(nothrow) user_partition_data;
if (!fData)
return B_NO_MEMORY;
memset(fData, 0, sizeof(user_partition_data));
fData->id = partitionData->id;
fData->offset = partitionData->offset;
fData->size = partitionData->size;
fData->content_size = partitionData->content_size;
fData->block_size = partitionData->block_size;
fData->physical_block_size = partitionData->physical_block_size;
fData->status = partitionData->status;
fData->flags = partitionData->flags;
fData->volume = partitionData->volume;
fData->index = partitionData->index;
fData->change_counter = partitionData->change_counter;
fData->disk_system = partitionData->disk_system;
SET_STRING_RETURN_ON_ERROR(fData->name, partitionData->name);
SET_STRING_RETURN_ON_ERROR(fData->content_name,
partitionData->content_name);
SET_STRING_RETURN_ON_ERROR(fData->type, partitionData->type);
SET_STRING_RETURN_ON_ERROR(fData->content_type,
partitionData->content_type);
SET_STRING_RETURN_ON_ERROR(fData->parameters, partitionData->parameters);
SET_STRING_RETURN_ON_ERROR(fData->content_parameters,
partitionData->content_parameters);
return B_OK;
}
BMutablePartition::~BMutablePartition()
{
if (fData) {
free(fData->name);
free(fData->content_name);
free(fData->type);
free(fData->content_type);
free(fData->parameters);
free(fData->content_parameters);
delete fData;
}
}
const user_partition_data*
BMutablePartition::PartitionData() const
{
return fData;
}
BPartition::Delegate*
BMutablePartition::GetDelegate() const
{
return fDelegate;
}