Pull derived UnpackingDirectory out of Directory

Move all package specifics from now abstract Directory to new derived
class UnpackingDirectory and adjust the Volume implementation
accordingly. This concludes the Node/Directory refactoring. Neither
class is aware of packages anymore.
This commit is contained in:
Ingo Weinhold
2011-11-25 06:17:57 +01:00
parent 097e795f8e
commit e16ce53bcc
6 changed files with 263 additions and 175 deletions
@@ -54,111 +54,6 @@ Directory::VFSUninit()
}
mode_t
Directory::Mode() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->Mode();
return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
}
uid_t
Directory::UserID() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->UserID();
return 0;
}
gid_t
Directory::GroupID() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->GroupID();
return 0;
}
timespec
Directory::ModifiedTime() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->ModifiedTime();
timespec time = { 0, 0 };
return time;
}
off_t
Directory::FileSize() const
{
return 0;
}
Node*
Directory::GetNode()
{
return this;
}
status_t
Directory::AddPackageNode(PackageNode* packageNode)
{
if (!S_ISDIR(packageNode->Mode()))
return B_BAD_VALUE;
PackageDirectory* packageDirectory
= dynamic_cast<PackageDirectory*>(packageNode);
PackageDirectory* other = fPackageDirectories.Head();
bool isNewest = other == NULL
|| packageDirectory->ModifiedTime() > other->ModifiedTime();
if (isNewest)
fPackageDirectories.Insert(other, packageDirectory);
else
fPackageDirectories.Add(packageDirectory);
return B_OK;
}
void
Directory::RemovePackageNode(PackageNode* packageNode)
{
bool isNewest = packageNode == fPackageDirectories.Head();
fPackageDirectories.Remove(dynamic_cast<PackageDirectory*>(packageNode));
// when removing the newest node, we need to find the next node (the list
// is not sorted)
PackageDirectory* newestNode = fPackageDirectories.Head();
if (isNewest && newestNode != NULL) {
PackageDirectoryList::Iterator it = fPackageDirectories.GetIterator();
it.Next();
// skip the first one
while (PackageDirectory* otherNode = it.Next()) {
if (otherNode->ModifiedTime() > newestNode->ModifiedTime())
newestNode = otherNode;
}
fPackageDirectories.Remove(newestNode);
fPackageDirectories.Insert(fPackageDirectories.Head(), newestNode);
}
}
PackageNode*
Directory::GetPackageNode()
{
return fPackageDirectories.Head();
}
status_t
Directory::Read(off_t offset, void* buffer, size_t* bufferSize)
{
@@ -180,23 +75,6 @@ Directory::ReadSymlink(void* buffer, size_t* bufferSize)
}
status_t
Directory::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie)
{
return UnpackingAttributeDirectoryCookie::Open(fPackageDirectories.Head(),
_cookie);
}
status_t
Directory::OpenAttribute(const char* name, int openMode,
AttributeCookie*& _cookie)
{
return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name,
openMode, _cookie);
}
void
Directory::AddChild(Node* node)
{
@@ -243,18 +121,3 @@ Directory::RemoveDirectoryIterator(DirectoryIterator* iterator)
{
fIterators.Remove(iterator);
}
RootDirectory::RootDirectory(ino_t id, const timespec& modifiedTime)
:
Directory(id),
fModifiedTime(modifiedTime)
{
}
timespec
RootDirectory::ModifiedTime() const
{
return fModifiedTime;
}
@@ -7,8 +7,6 @@
#include "Node.h"
#include "PackageDirectory.h"
#include "UnpackingNode.h"
struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> {
@@ -24,7 +22,7 @@ struct DirectoryIterator : DoublyLinkedListLinkImpl<DirectoryIterator> {
typedef DoublyLinkedList<DirectoryIterator> DirectoryIteratorList;
class Directory : public Node, public UnpackingNode {
class Directory : public Node {
public:
Directory(ino_t id);
virtual ~Directory();
@@ -34,30 +32,11 @@ public:
virtual status_t VFSInit(dev_t deviceID);
virtual void VFSUninit();
virtual mode_t Mode() const;
virtual uid_t UserID() const;
virtual gid_t GroupID() const;
virtual timespec ModifiedTime() const;
virtual off_t FileSize() const;
virtual Node* GetNode();
virtual status_t AddPackageNode(PackageNode* packageNode);
virtual void RemovePackageNode(PackageNode* packageNode);
virtual PackageNode* GetPackageNode();
virtual status_t Read(off_t offset, void* buffer,
size_t* bufferSize);
virtual status_t Read(io_request* request);
virtual status_t ReadSymlink(void* buffer,
size_t* bufferSize);
virtual status_t OpenAttributeDirectory(
AttributeDirectoryCookie*& _cookie);
virtual status_t OpenAttribute(const char* name, int openMode,
AttributeCookie*& _cookie);
virtual status_t ReadSymlink(void* buffer, size_t* bufferSize);
void AddChild(Node* node);
void RemoveChild(Node* node);
@@ -74,7 +53,6 @@ public:
private:
NodeNameHashTable fChildTable;
NodeList fChildList;
PackageDirectoryList fPackageDirectories;
DirectoryIteratorList fIterators;
};
@@ -93,16 +71,4 @@ Directory::NextChild(Node* node) const
}
class RootDirectory : public Directory {
public:
RootDirectory(ino_t id,
const timespec& modifiedTime);
virtual timespec ModifiedTime() const;
private:
timespec fModifiedTime;
};
#endif // DIRECTORY_H
@@ -29,6 +29,7 @@ HAIKU_PACKAGE_FS_SOURCES =
Resolvable.cpp
UnpackingAttributeCookie.cpp
UnpackingAttributeDirectoryCookie.cpp
UnpackingDirectory.cpp
UnpackingLeafNode.cpp
UnpackingNode.cpp
Version.cpp
@@ -0,0 +1,195 @@
/*
* Copyright 2009-2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "UnpackingDirectory.h"
#include "DebugSupport.h"
#include "UnpackingAttributeCookie.h"
#include "UnpackingAttributeDirectoryCookie.h"
#include "Utils.h"
// #pragma mark - UnpackingDirectory
UnpackingDirectory::UnpackingDirectory(ino_t id)
:
Directory(id)
{
}
UnpackingDirectory::~UnpackingDirectory()
{
}
status_t
UnpackingDirectory::Init(Directory* parent, const char* name)
{
return Directory::Init(parent, name);
}
mode_t
UnpackingDirectory::Mode() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->Mode();
return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
}
uid_t
UnpackingDirectory::UserID() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->UserID();
return 0;
}
gid_t
UnpackingDirectory::GroupID() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->GroupID();
return 0;
}
timespec
UnpackingDirectory::ModifiedTime() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->ModifiedTime();
timespec time = { 0, 0 };
return time;
}
off_t
UnpackingDirectory::FileSize() const
{
return 0;
}
Node*
UnpackingDirectory::GetNode()
{
return this;
}
status_t
UnpackingDirectory::AddPackageNode(PackageNode* packageNode)
{
if (!S_ISDIR(packageNode->Mode()))
return B_BAD_VALUE;
PackageDirectory* packageDirectory
= dynamic_cast<PackageDirectory*>(packageNode);
PackageDirectory* other = fPackageDirectories.Head();
bool isNewest = other == NULL
|| packageDirectory->ModifiedTime() > other->ModifiedTime();
if (isNewest)
fPackageDirectories.Insert(other, packageDirectory);
else
fPackageDirectories.Add(packageDirectory);
return B_OK;
}
void
UnpackingDirectory::RemovePackageNode(PackageNode* packageNode)
{
bool isNewest = packageNode == fPackageDirectories.Head();
fPackageDirectories.Remove(dynamic_cast<PackageDirectory*>(packageNode));
// when removing the newest node, we need to find the next node (the list
// is not sorted)
PackageDirectory* newestNode = fPackageDirectories.Head();
if (isNewest && newestNode != NULL) {
PackageDirectoryList::Iterator it = fPackageDirectories.GetIterator();
it.Next();
// skip the first one
while (PackageDirectory* otherNode = it.Next()) {
if (otherNode->ModifiedTime() > newestNode->ModifiedTime())
newestNode = otherNode;
}
fPackageDirectories.Remove(newestNode);
fPackageDirectories.Insert(fPackageDirectories.Head(), newestNode);
}
}
PackageNode*
UnpackingDirectory::GetPackageNode()
{
return fPackageDirectories.Head();
}
status_t
UnpackingDirectory::Read(off_t offset, void* buffer, size_t* bufferSize)
{
return B_IS_A_DIRECTORY;
}
status_t
UnpackingDirectory::Read(io_request* request)
{
return B_IS_A_DIRECTORY;
}
status_t
UnpackingDirectory::ReadSymlink(void* buffer, size_t* bufferSize)
{
return B_IS_A_DIRECTORY;
}
status_t
UnpackingDirectory::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie)
{
return UnpackingAttributeDirectoryCookie::Open(fPackageDirectories.Head(),
_cookie);
}
status_t
UnpackingDirectory::OpenAttribute(const char* name, int openMode,
AttributeCookie*& _cookie)
{
return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name,
openMode, _cookie);
}
// #pragma mark - RootDirectory
RootDirectory::RootDirectory(ino_t id, const timespec& modifiedTime)
:
UnpackingDirectory(id),
fModifiedTime(modifiedTime)
{
}
timespec
RootDirectory::ModifiedTime() const
{
return fModifiedTime;
}
@@ -0,0 +1,63 @@
/*
* Copyright 2009-2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef UNPACKING_DIRECTORY_H
#define UNPACKING_DIRECTORY_H
#include "Directory.h"
#include "PackageDirectory.h"
#include "UnpackingNode.h"
class UnpackingDirectory : public Directory, public UnpackingNode {
public:
UnpackingDirectory(ino_t id);
virtual ~UnpackingDirectory();
virtual status_t Init(Directory* parent, const char* name);
virtual mode_t Mode() const;
virtual uid_t UserID() const;
virtual gid_t GroupID() const;
virtual timespec ModifiedTime() const;
virtual off_t FileSize() const;
virtual Node* GetNode();
virtual status_t AddPackageNode(PackageNode* packageNode);
virtual void RemovePackageNode(PackageNode* packageNode);
virtual PackageNode* GetPackageNode();
virtual status_t Read(off_t offset, void* buffer,
size_t* bufferSize);
virtual status_t Read(io_request* request);
virtual status_t ReadSymlink(void* buffer,
size_t* bufferSize);
virtual status_t OpenAttributeDirectory(
AttributeDirectoryCookie*& _cookie);
virtual status_t OpenAttribute(const char* name, int openMode,
AttributeCookie*& _cookie);
private:
PackageDirectoryList fPackageDirectories;
};
class RootDirectory : public UnpackingDirectory {
public:
RootDirectory(ino_t id,
const timespec& modifiedTime);
virtual timespec ModifiedTime() const;
private:
timespec fModifiedTime;
};
#endif // UNPACKING_DIRECTORY_H
@@ -31,7 +31,6 @@
#include <package/hpkg/PackageReaderImpl.h>
#include "DebugSupport.h"
#include "Directory.h"
#include "kernel_interface.h"
#include "PackageDirectory.h"
#include "PackageFile.h"
@@ -39,6 +38,7 @@
#include "PackageSymlink.h"
#include "Resolvable.h"
#include "UnpackingLeafNode.h"
#include "UnpackingDirectory.h"
#include "Version.h"
@@ -1070,7 +1070,7 @@ Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name,
if (S_ISREG(mode) || S_ISLNK(mode))
unpackingNode = new(std::nothrow) UnpackingLeafNode(fNextNodeID++);
else if (S_ISDIR(mode))
unpackingNode = new(std::nothrow) Directory(fNextNodeID++);
unpackingNode = new(std::nothrow) UnpackingDirectory(fNextNodeID++);
else
RETURN_ERROR(B_UNSUPPORTED);