* 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"
#include "StringConstants.h"
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)
{
off_t size;
uint32 type;
const void* value = AutoPackageAttributes::GetAttributeValue(fPackage,
fAttribute, size, type);
if (value == NULL)
return B_BAD_VALUE;
if (offset < 0 || offset > size)
return B_BAD_VALUE;
size_t toCopy = *bufferSize;
if (offset + (off_t)toCopy > size)
toCopy = size - offset;
if (toCopy > 0 && user_memcpy(buffer, (const uint8*)value + offset,
toCopy) < B_OK) {
return B_BAD_ADDRESS;
}
*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;
};
bool
AutoPackageAttributes::AttributeForName(const StringKey& name,
AutoPackageAttribute& _attribute)
{
for (int i = 0; i < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT; i++) {
if (name == StringConstants::Get().kAutoPackageAttributeNames[i]) {
_attribute = (AutoPackageAttribute)i;
return true;
}
}
return false;
}
const String&
AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute)
{
ASSERT(attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT);
return StringConstants::Get().kAutoPackageAttributeNames[attribute];
}
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->VersionedName();
_size = strlen(value) + 1;
_type = B_STRING_TYPE;
return value;
}
case AUTO_PACKAGE_ATTRIBUTE_PACKAGE_FILE:
{
const char* value = package->FileName();
_size = strlen(value) + 1;
_type = B_STRING_TYPE;
return value;
}
default:
return NULL;
}
}
status_t
AutoPackageAttributes::OpenCookie(Package* package, const StringKey& name,
int openMode, AttributeCookie*& _cookie)
{
if (package == NULL)
return B_ENTRY_NOT_FOUND;
AutoPackageAttribute attribute;
if (!AttributeForName(name, attribute))
return B_ENTRY_NOT_FOUND;
AutoPackageAttributeCookie* cookie = new(std::nothrow)
AutoPackageAttributeCookie(package, attribute);
if (cookie == NULL)
RETURN_ERROR(B_NO_MEMORY);
_cookie = cookie;
return B_OK;
}