/* * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #include "AutoPackageAttributes.h" #include #include #include #include #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) { // 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 + (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; }; /*static*/ 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; } /*static*/ const String& AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute) { ASSERT(attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT); return StringConstants::Get().kAutoPackageAttributeNames[attribute]; } /*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->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; } } /*static*/ status_t AutoPackageAttributes::OpenCookie(Package* package, const StringKey& 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; }