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 =
|
HAIKU_PACKAGE_FS_SOURCES =
|
||||||
AttributeCookie.cpp
|
AttributeCookie.cpp
|
||||||
AttributeDirectoryCookie.cpp
|
AttributeDirectoryCookie.cpp
|
||||||
|
AutoPackageAttributes.cpp
|
||||||
BlockBufferCacheKernel.cpp
|
BlockBufferCacheKernel.cpp
|
||||||
DebugSupport.cpp
|
DebugSupport.cpp
|
||||||
Dependency.cpp
|
Dependency.cpp
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
|
||||||
|
#include "AutoPackageAttributes.h"
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "GlobalFactory.h"
|
#include "GlobalFactory.h"
|
||||||
#include "Package.h"
|
#include "Package.h"
|
||||||
@ -86,8 +87,11 @@ UnpackingAttributeCookie::Open(PackageNode* packageNode, const char* name,
|
|||||||
|
|
||||||
// get the attribute
|
// get the attribute
|
||||||
PackageNodeAttribute* attribute = packageNode->FindAttribute(name);
|
PackageNodeAttribute* attribute = packageNode->FindAttribute(name);
|
||||||
if (attribute == NULL)
|
if (attribute == NULL) {
|
||||||
return B_ENTRY_NOT_FOUND;
|
// We don't know the attribute -- maybe it's an auto-generated one.
|
||||||
|
return AutoPackageAttributes::OpenCookie(packageNode->GetPackage(),
|
||||||
|
name, openMode, _cookie);
|
||||||
|
}
|
||||||
|
|
||||||
// allocate the cookie
|
// allocate the cookie
|
||||||
UnpackingAttributeCookie* cookie = new(std::nothrow)
|
UnpackingAttributeCookie* cookie = new(std::nothrow)
|
||||||
|
@ -15,7 +15,8 @@ UnpackingAttributeDirectoryCookie::UnpackingAttributeDirectoryCookie(
|
|||||||
PackageNode* packageNode)
|
PackageNode* packageNode)
|
||||||
:
|
:
|
||||||
fPackageNode(packageNode),
|
fPackageNode(packageNode),
|
||||||
fAttribute(NULL)
|
fAttribute(NULL),
|
||||||
|
fState(AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST)
|
||||||
{
|
{
|
||||||
if (fPackageNode != NULL) {
|
if (fPackageNode != NULL) {
|
||||||
fPackageNode->AcquireReference();
|
fPackageNode->AcquireReference();
|
||||||
@ -54,7 +55,7 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
|
|||||||
|
|
||||||
dirent* previousEntry = NULL;
|
dirent* previousEntry = NULL;
|
||||||
|
|
||||||
while (fAttribute != NULL) {
|
while (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT || fAttribute != NULL) {
|
||||||
// don't read more entries than requested
|
// don't read more entries than requested
|
||||||
if (count >= maxCount)
|
if (count >= maxCount)
|
||||||
break;
|
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
|
// fill in the entry name -- checks whether the entry fits into the
|
||||||
// buffer
|
// buffer
|
||||||
const char* name = fAttribute->Name();
|
|
||||||
if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) {
|
if (!set_dirent_name(buffer, bufferSize, name, strlen(name))) {
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
RETURN_ERROR(B_BUFFER_OVERFLOW);
|
RETURN_ERROR(B_BUFFER_OVERFLOW);
|
||||||
@ -91,6 +99,9 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
|
|||||||
bufferSize -= buffer->d_reclen;
|
bufferSize -= buffer->d_reclen;
|
||||||
buffer = (dirent*)((addr_t)buffer + 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);
|
fAttribute = fPackageNode->Attributes().GetNext(fAttribute);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,5 +116,7 @@ UnpackingAttributeDirectoryCookie::Rewind()
|
|||||||
if (fPackageNode != NULL)
|
if (fPackageNode != NULL)
|
||||||
fAttribute = fPackageNode->Attributes().Head();
|
fAttribute = fPackageNode->Attributes().Head();
|
||||||
|
|
||||||
|
fState = AUTO_PACKAGE_ATTRIBUTE_ENUM_FIRST;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "AttributeDirectoryCookie.h"
|
#include "AttributeDirectoryCookie.h"
|
||||||
|
#include "AutoPackageAttributes.h"
|
||||||
|
|
||||||
|
|
||||||
struct dirent;
|
struct dirent;
|
||||||
@ -32,6 +33,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PackageNode* fPackageNode;
|
PackageNode* fPackageNode;
|
||||||
PackageNodeAttribute* fAttribute;
|
PackageNodeAttribute* fAttribute;
|
||||||
|
uint32 fState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user