Support for auto-generated package node attributes
* Add utility class AutoPackageAttributes and AttributeCookie subclass AutoPackageAttributeCookie. * UnpackingAttributeCookie::Open() does now try to create a AutoPackageAttributeCookie, when it doesn't find the attribute in the PackageNode. * Adjust UnpackingAttributeDirectoryCookie to also list auto-generated attributes. Currently the only supported attribute is "SYS:PACKAGE", which is the file name of the package containing the node.
This commit is contained in:
parent
a83fe53dce
commit
59e76dbe41
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "AutoPackageAttributes.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
|
||||
#include <TypeConstants.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include "AttributeCookie.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "Package.h"
|
||||
|
||||
|
||||
static const char* const kAttributeNames[AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT] = {
|
||||
"SYS:PACKAGE"
|
||||
};
|
||||
|
||||
|
||||
class AutoPackageAttributeCookie : public AttributeCookie {
|
||||
public:
|
||||
AutoPackageAttributeCookie(Package* package, AutoPackageAttribute attribute)
|
||||
:
|
||||
fPackage(package),
|
||||
fAttribute(attribute)
|
||||
{
|
||||
fPackage->AcquireReference();
|
||||
}
|
||||
|
||||
virtual ~AutoPackageAttributeCookie()
|
||||
{
|
||||
fPackage->ReleaseReference();
|
||||
}
|
||||
|
||||
virtual status_t ReadAttribute(off_t offset, void* buffer,
|
||||
size_t* bufferSize)
|
||||
{
|
||||
// get the attribute
|
||||
off_t size;
|
||||
uint32 type;
|
||||
const void* value = AutoPackageAttributes::GetAttributeValue(fPackage,
|
||||
fAttribute, size, type);
|
||||
if (value == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check and clamp offset and size
|
||||
if (offset < 0 || offset > size)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
size_t toCopy = *bufferSize;
|
||||
if (offset + toCopy > size)
|
||||
toCopy = size - offset;
|
||||
|
||||
if (toCopy > 0)
|
||||
memcpy(buffer, (const uint8*)value + offset, toCopy);
|
||||
|
||||
*bufferSize = toCopy;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
virtual status_t ReadAttributeStat(struct stat* st)
|
||||
{
|
||||
if (AutoPackageAttributes::GetAttributeValue(fPackage, fAttribute,
|
||||
st->st_size, st->st_type) == NULL) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
Package* fPackage;
|
||||
AutoPackageAttribute fAttribute;
|
||||
};
|
||||
|
||||
|
||||
/*static*/ bool
|
||||
AutoPackageAttributes::AttributeForName(const char* name,
|
||||
AutoPackageAttribute& _attribute)
|
||||
{
|
||||
for (int i = 0; i < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT; i++) {
|
||||
if (strcmp(name, kAttributeNames[i]) == 0) {
|
||||
_attribute = (AutoPackageAttribute)i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ const char*
|
||||
AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute)
|
||||
{
|
||||
if (attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT)
|
||||
return kAttributeNames[attribute];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ const void*
|
||||
AutoPackageAttributes::GetAttributeValue(const Package* package,
|
||||
AutoPackageAttribute attribute, off_t& _size, uint32& _type)
|
||||
{
|
||||
switch (attribute) {
|
||||
case AUTO_PACKAGE_ATTRIBUTE_PACKAGE:
|
||||
{
|
||||
const char* value = package->FileName();
|
||||
_size = strlen(value) + 1;
|
||||
_type = B_STRING_TYPE;
|
||||
return value;
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
AutoPackageAttributes::OpenCookie(Package* package, const char* name,
|
||||
int openMode, AttributeCookie*& _cookie)
|
||||
{
|
||||
if (package == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// get the attribute
|
||||
AutoPackageAttribute attribute;
|
||||
if (!AttributeForName(name, attribute))
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// allocate the cookie
|
||||
AutoPackageAttributeCookie* cookie = new(std::nothrow)
|
||||
AutoPackageAttributeCookie(package, attribute);
|
||||
if (cookie == NULL)
|
||||
RETURN_ERROR(B_NO_MEMORY);
|
||||
|
||||
_cookie = cookie;
|
||||
return B_OK;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef AUTO_PACKAGE_ATTRIBUTES_H
|
||||
#define AUTO_PACKAGE_ATTRIBUTES_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
class AttributeCookie;
|
||||
class Package;
|
||||
|
||||
|
||||
enum AutoPackageAttribute {
|
||||
AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST,
|
||||
AUTO_PACKAGE_ATTRIBUTE_PACKAGE = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST,
|
||||
|
||||
AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT
|
||||
};
|
||||
|
||||
|
||||
struct AutoPackageAttributes {
|
||||
static bool AttributeForName(const char* name,
|
||||
AutoPackageAttribute& _attribute);
|
||||
static const char* NameForAttribute(
|
||||
AutoPackageAttribute attribute);
|
||||
static const void* GetAttributeValue(const Package* package,
|
||||
AutoPackageAttribute attribute,
|
||||
off_t& _size, uint32& _type);
|
||||
|
||||
static status_t OpenCookie(Package* package, const char* name,
|
||||
int openMode, AttributeCookie*& _cookie);
|
||||
};
|
||||
|
||||
|
||||
#endif // AUTO_PACKAGE_ATTRIBUTES_H
|
@ -9,6 +9,7 @@ UsePrivateHeaders shared ;
|
||||
HAIKU_PACKAGE_FS_SOURCES =
|
||||
AttributeCookie.cpp
|
||||
AttributeDirectoryCookie.cpp
|
||||
AutoPackageAttributes.cpp
|
||||
BlockBufferCacheKernel.cpp
|
||||
DebugSupport.cpp
|
||||
Dependency.cpp
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include "AutoPackageAttributes.h"
|
||||
#include "DebugSupport.h"
|
||||
#include "GlobalFactory.h"
|
||||
#include "Package.h"
|
||||
@ -86,8 +87,11 @@ UnpackingAttributeCookie::Open(PackageNode* packageNode, const char* name,
|
||||
|
||||
// get the attribute
|
||||
PackageNodeAttribute* attribute = packageNode->FindAttribute(name);
|
||||
if (attribute == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
if (attribute == NULL) {
|
||||
// We don't know the attribute -- maybe it's an auto-generated one.
|
||||
return AutoPackageAttributes::OpenCookie(packageNode->GetPackage(),
|
||||
name, openMode, _cookie);
|
||||
}
|
||||
|
||||
// allocate the cookie
|
||||
UnpackingAttributeCookie* cookie = new(std::nothrow)
|
||||
|
@ -15,7 +15,8 @@ UnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie(
|
||||
PackageNode* packageNode)
|
||||
:
|
||||
fPackageNode(packageNode),
|
||||
fAttribute(NULL)
|
||||
fAttribute(NULL),
|
||||
fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST)
|
||||
{
|
||||
if (fPackageNode != NULL) {
|
||||
fPackageNode->AcquireReference();
|
||||
@ -54,7 +55,7 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
|
||||
|
||||
dirent* previousEntry = NULL;
|
||||
|
||||
while (fAttribute != NULL) {
|
||||
while (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT || fAttribute != NULL) {
|
||||
// don't read more entries than requested
|
||||
if (count >= maxCount)
|
||||
break;
|
||||
@ -73,9 +74,16 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
|
||||
}
|
||||
}
|
||||
|
||||
// get the attribute name
|
||||
const char* name;
|
||||
if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) {
|
||||
name = AutoPackageAttributes::NameForAttribute(
|
||||
(AutoPackageAttribute)fState);
|
||||
} else
|
||||
name = fAttribute->Name();
|
||||
|
||||
// fill in the entry name -- checks whether the entry fits into the
|
||||
// buffer
|
||||
const char* name = fAttribute->Name();
|
||||
if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) {
|
||||
if (count == 0)
|
||||
RETURN_ERROR(B_BUFFER_OVERFLOW);
|
||||
@ -91,6 +99,9 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -105,5 +116,7 @@ UnpackingAttributeDirectoryCookie::Rewind()
|
||||
if (fPackageNode != NULL)
|
||||
fAttribute = fPackageNode->Attributes().Head();
|
||||
|
||||
fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include "AttributeDirectoryCookie.h"
|
||||
#include "AutoPackageAttributes.h"
|
||||
|
||||
|
||||
struct dirent;
|
||||
@ -32,6 +33,7 @@ public:
|
||||
private:
|
||||
PackageNode* fPackageNode;
|
||||
PackageNodeAttribute* fAttribute;
|
||||
uint32 fState;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user