packagefs: Refactor UnpackingAttributeDirectoryCookie
Pull out a reusable base class AutoPackageAttributeDirectoryCookie.
This commit is contained in:
@@ -22,6 +22,7 @@ HAIKU_PACKAGE_FS_SOURCES =
|
||||
AttributeCookie.cpp
|
||||
AttributeDirectoryCookie.cpp
|
||||
AttributeIndex.cpp
|
||||
AutoPackageAttributeDirectoryCookie.cpp
|
||||
AutoPackageAttributes.cpp
|
||||
BlockBufferPoolKernel.cpp
|
||||
CachedDataReader.cpp
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2011-2013, Ingo Weinhold, [email protected].
|
||||
* 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();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011-2013, Ingo Weinhold, [email protected].
|
||||
* 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
|
||||
+19
-68
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user