From 4c61288e73ab85766ae2709a38809384cd7ed489 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 20 Nov 2013 23:50:30 +0100 Subject: [PATCH] packagefs: Refactor UnpackingAttributeDirectoryCookie Pull out a reusable base class AutoPackageAttributeDirectoryCookie. --- .../kernel/file_systems/packagefs/Jamfile | 1 + .../AutoPackageAttributeDirectoryCookie.cpp | 110 ++++++++++++++++++ .../AutoPackageAttributeDirectoryCookie.h | 41 +++++++ .../UnpackingAttributeDirectoryCookie.cpp | 87 +++----------- .../nodes/UnpackingAttributeDirectoryCookie.h | 16 ++- 5 files changed, 178 insertions(+), 77 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.cpp create mode 100644 src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.h diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index ee7f3f851b..2f3004a288 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -22,6 +22,7 @@ HAIKU_PACKAGE_FS_SOURCES = AttributeCookie.cpp AttributeDirectoryCookie.cpp AttributeIndex.cpp + AutoPackageAttributeDirectoryCookie.cpp AutoPackageAttributes.cpp BlockBufferPoolKernel.cpp CachedDataReader.cpp diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.cpp new file mode 100644 index 0000000000..6509c846b1 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.cpp @@ -0,0 +1,110 @@ +/* + * Copyright 2011-2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "AutoPackageAttributeDirectoryCookie.h" + +#include "DebugSupport.h" +#include "Utils.h" + + +AutoPackageAttributeDirectoryCookie::AutoPackageAttributeDirectoryCookie() + : + fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST) +{ +} + + +AutoPackageAttributeDirectoryCookie::~AutoPackageAttributeDirectoryCookie() +{ +} + + +status_t +AutoPackageAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID, + struct dirent* buffer, size_t bufferSize, uint32* _count) +{ + uint32 maxCount = *_count; + uint32 count = 0; + + dirent* previousEntry = NULL; + + String customAttributeName = CurrentCustomAttributeName(); + + while (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT + || !customAttributeName.IsEmpty()) { + // don't read more entries than requested + if (count >= maxCount) + break; + + // align the buffer for subsequent entries + if (count > 0) { + addr_t offset = (addr_t)buffer % 8; + if (offset > 0) { + offset = 8 - offset; + if (bufferSize <= offset) + break; + + previousEntry->d_reclen += offset; + buffer = (dirent*)((addr_t)buffer + offset); + bufferSize -= offset; + } + } + + // get the attribute name + const String& name = fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT + ? AutoPackageAttributes::NameForAttribute( + (AutoPackageAttribute)fState) + : customAttributeName; + + // fill in the entry name -- checks whether the entry fits into the + // buffer + if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) { + if (count == 0) + RETURN_ERROR(B_BUFFER_OVERFLOW); + break; + } + + // fill in the other data + buffer->d_dev = volumeID; + buffer->d_ino = nodeID; + + count++; + previousEntry = buffer; + bufferSize -= buffer->d_reclen; + buffer = (dirent*)((addr_t)buffer + buffer->d_reclen); + + if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) + fState++; + else + customAttributeName = NextCustomAttributeName(); + } + + *_count = count; + return B_OK; +} + + +status_t +AutoPackageAttributeDirectoryCookie::Rewind() +{ + fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST; + + return B_OK; +} + + +String +AutoPackageAttributeDirectoryCookie::CurrentCustomAttributeName() +{ + return String(); +} + + +String +AutoPackageAttributeDirectoryCookie::NextCustomAttributeName() +{ + return String(); +} diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.h b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.h new file mode 100644 index 0000000000..e91ce2a7c6 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributeDirectoryCookie.h @@ -0,0 +1,41 @@ +/* + * Copyright 2011-2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef AUTO_PACKAGE_ATTRIBUTE_DIRECTORY_COOKIE_H +#define AUTO_PACKAGE_ATTRIBUTE_DIRECTORY_COOKIE_H + + +#include "AttributeDirectoryCookie.h" +#include "AutoPackageAttributes.h" + + +/*! + When used for nodes that only have the automatic package attributes, the + class can be used as is. Otherwise subclassing is required. + Derived classes need to override Rewind() to rewind to their first + attribute, but also call the base class version. Furthermore they must + implement CurrentCustomAttributeName() to return the current attribute's + name and NextCustomAttributeName() to iterate to the next attribute and + return its name. +*/ +class AutoPackageAttributeDirectoryCookie : public AttributeDirectoryCookie { +public: + AutoPackageAttributeDirectoryCookie(); + virtual ~AutoPackageAttributeDirectoryCookie(); + + virtual status_t Read(dev_t volumeID, ino_t nodeID, + struct dirent* buffer, size_t bufferSize, + uint32* _count); + virtual status_t Rewind(); + +protected: + virtual String CurrentCustomAttributeName(); + virtual String NextCustomAttributeName(); + +private: + uint32 fState; +}; + + +#endif // AUTO_PACKAGE_ATTRIBUTE_DIRECTORY_COOKIE_H diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp index 9d757b224e..75db372bd0 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp @@ -8,15 +8,14 @@ #include "DebugSupport.h" #include "PackageNode.h" -#include "Utils.h" UnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie( PackageNode* packageNode) : + AutoPackageAttributeDirectoryCookie(), fPackageNode(packageNode), - fAttribute(NULL), - fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST) + fAttribute(NULL) { if (fPackageNode != NULL) { fPackageNode->AcquireReference(); @@ -46,75 +45,27 @@ UnpackingAttributeDirectoryCookie::Open(PackageNode* packageNode, } -status_t -UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID, - struct dirent* buffer, size_t bufferSize, uint32* _count) -{ - uint32 maxCount = *_count; - uint32 count = 0; - - dirent* previousEntry = NULL; - - while (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT || fAttribute != NULL) { - // don't read more entries than requested - if (count >= maxCount) - break; - - // align the buffer for subsequent entries - if (count > 0) { - addr_t offset = (addr_t)buffer % 8; - if (offset > 0) { - offset = 8 - offset; - if (bufferSize <= offset) - break; - - previousEntry->d_reclen += offset; - buffer = (dirent*)((addr_t)buffer + offset); - bufferSize -= offset; - } - } - - // get the attribute name - const String& name = fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT - ? AutoPackageAttributes::NameForAttribute( - (AutoPackageAttribute)fState) - : fAttribute->Name(); - - // fill in the entry name -- checks whether the entry fits into the - // buffer - if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) { - if (count == 0) - RETURN_ERROR(B_BUFFER_OVERFLOW); - break; - } - - // fill in the other data - buffer->d_dev = volumeID; - buffer->d_ino = nodeID; - - count++; - previousEntry = buffer; - bufferSize -= buffer->d_reclen; - buffer = (dirent*)((addr_t)buffer + buffer->d_reclen); - - if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) - fState++; - else - fAttribute = fPackageNode->Attributes().GetNext(fAttribute); - } - - *_count = count; - return B_OK; -} - - status_t UnpackingAttributeDirectoryCookie::Rewind() { if (fPackageNode != NULL) fAttribute = fPackageNode->Attributes().Head(); - fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST; - - return B_OK; + return AutoPackageAttributeDirectoryCookie::Rewind(); +} + + +String +UnpackingAttributeDirectoryCookie::CurrentCustomAttributeName() +{ + return fAttribute != NULL ? fAttribute->Name() : String(); +} + + +String +UnpackingAttributeDirectoryCookie::NextCustomAttributeName() +{ + if (fAttribute != NULL) + fAttribute = fPackageNode->Attributes().GetNext(fAttribute); + return fAttribute != NULL ? fAttribute->Name() : String(); } diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.h b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.h index e8ff28651e..ba491deae1 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.h @@ -6,17 +6,15 @@ #define UNPACKING_ATTRIBUTE_DIRECTORY_COOKIE_H -#include "AttributeDirectoryCookie.h" -#include "AutoPackageAttributes.h" +#include "AutoPackageAttributeDirectoryCookie.h" -struct dirent; - class PackageNode; class PackageNodeAttribute; -class UnpackingAttributeDirectoryCookie : public AttributeDirectoryCookie { +class UnpackingAttributeDirectoryCookie + : public AutoPackageAttributeDirectoryCookie { public: UnpackingAttributeDirectoryCookie( PackageNode* packageNode); @@ -25,15 +23,15 @@ public: static status_t Open(PackageNode* packageNode, AttributeDirectoryCookie*& _cookie); - virtual status_t Read(dev_t volumeID, ino_t nodeID, - struct dirent* buffer, size_t bufferSize, - uint32* _count); virtual status_t Rewind(); +protected: + virtual String CurrentCustomAttributeName(); + virtual String NextCustomAttributeName(); + private: PackageNode* fPackageNode; PackageNodeAttribute* fAttribute; - uint32 fState; };