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
|
AttributeCookie.cpp
|
||||||
AttributeDirectoryCookie.cpp
|
AttributeDirectoryCookie.cpp
|
||||||
AttributeIndex.cpp
|
AttributeIndex.cpp
|
||||||
|
AutoPackageAttributeDirectoryCookie.cpp
|
||||||
AutoPackageAttributes.cpp
|
AutoPackageAttributes.cpp
|
||||||
BlockBufferPoolKernel.cpp
|
BlockBufferPoolKernel.cpp
|
||||||
CachedDataReader.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 "DebugSupport.h"
|
||||||
#include "PackageNode.h"
|
#include "PackageNode.h"
|
||||||
#include "Utils.h"
|
|
||||||
|
|
||||||
|
|
||||||
UnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie(
|
UnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie(
|
||||||
PackageNode* packageNode)
|
PackageNode* packageNode)
|
||||||
:
|
:
|
||||||
|
AutoPackageAttributeDirectoryCookie(),
|
||||||
fPackageNode(packageNode),
|
fPackageNode(packageNode),
|
||||||
fAttribute(NULL),
|
fAttribute(NULL)
|
||||||
fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST)
|
|
||||||
{
|
{
|
||||||
if (fPackageNode != NULL) {
|
if (fPackageNode != NULL) {
|
||||||
fPackageNode->AcquireReference();
|
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
|
status_t
|
||||||
UnpackingAttributeDirectoryCookie::Rewind()
|
UnpackingAttributeDirectoryCookie::Rewind()
|
||||||
{
|
{
|
||||||
if (fPackageNode != NULL)
|
if (fPackageNode != NULL)
|
||||||
fAttribute = fPackageNode->Attributes().Head();
|
fAttribute = fPackageNode->Attributes().Head();
|
||||||
|
|
||||||
fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST;
|
return AutoPackageAttributeDirectoryCookie::Rewind();
|
||||||
|
}
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
|
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
|
#define UNPACKING_ATTRIBUTE_DIRECTORY_COOKIE_H
|
||||||
|
|
||||||
|
|
||||||
#include "AttributeDirectoryCookie.h"
|
#include "AutoPackageAttributeDirectoryCookie.h"
|
||||||
#include "AutoPackageAttributes.h"
|
|
||||||
|
|
||||||
|
|
||||||
struct dirent;
|
|
||||||
|
|
||||||
class PackageNode;
|
class PackageNode;
|
||||||
class PackageNodeAttribute;
|
class PackageNodeAttribute;
|
||||||
|
|
||||||
|
|
||||||
class UnpackingAttributeDirectoryCookie : public AttributeDirectoryCookie {
|
class UnpackingAttributeDirectoryCookie
|
||||||
|
: public AutoPackageAttributeDirectoryCookie {
|
||||||
public:
|
public:
|
||||||
UnpackingAttributeDirectoryCookie(
|
UnpackingAttributeDirectoryCookie(
|
||||||
PackageNode* packageNode);
|
PackageNode* packageNode);
|
||||||
@@ -25,15 +23,15 @@ public:
|
|||||||
static status_t Open(PackageNode* packageNode,
|
static status_t Open(PackageNode* packageNode,
|
||||||
AttributeDirectoryCookie*& _cookie);
|
AttributeDirectoryCookie*& _cookie);
|
||||||
|
|
||||||
virtual status_t Read(dev_t volumeID, ino_t nodeID,
|
|
||||||
struct dirent* buffer, size_t bufferSize,
|
|
||||||
uint32* _count);
|
|
||||||
virtual status_t Rewind();
|
virtual status_t Rewind();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual String CurrentCustomAttributeName();
|
||||||
|
virtual String NextCustomAttributeName();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PackageNode* fPackageNode;
|
PackageNode* fPackageNode;
|
||||||
PackageNodeAttribute* fAttribute;
|
PackageNodeAttribute* fAttribute;
|
||||||
uint32 fState;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user