1/* 2 * Copyright 2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "AutoPackageAttributes.h" 8 9#include <algorithm> 10#include <new> 11 12#include <TypeConstants.h> 13 14#include <AutoDeleter.h> 15 16#include "AttributeCookie.h" 17#include "DebugSupport.h" 18#include "Package.h" 19 20 21static const char* const kAttributeNames[AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT] = { 22 "SYS:PACKAGE" 23}; 24 25 26class AutoPackageAttributeCookie : public AttributeCookie { 27public: 28 AutoPackageAttributeCookie(Package* package, AutoPackageAttribute attribute) 29 : 30 fPackage(package), 31 fAttribute(attribute) 32 { 33 fPackage->AcquireReference(); 34 } 35 36 virtual ~AutoPackageAttributeCookie() 37 { 38 fPackage->ReleaseReference(); 39 } 40 41 virtual status_t ReadAttribute(off_t offset, void* buffer, 42 size_t* bufferSize) 43 { 44 // get the attribute 45 off_t size; 46 uint32 type; 47 const void* value = AutoPackageAttributes::GetAttributeValue(fPackage, 48 fAttribute, size, type); 49 if (value == NULL) 50 return B_BAD_VALUE; 51 52 // check and clamp offset and size 53 if (offset < 0 || offset > size) 54 return B_BAD_VALUE; 55 56 size_t toCopy = *bufferSize; 57 if (offset + toCopy > size) 58 toCopy = size - offset; 59 60 if (toCopy > 0) 61 memcpy(buffer, (const uint8*)value + offset, toCopy); 62 63 *bufferSize = toCopy; 64 return B_OK; 65 } 66 67 virtual status_t ReadAttributeStat(struct stat* st) 68 { 69 if (AutoPackageAttributes::GetAttributeValue(fPackage, fAttribute, 70 st->st_size, st->st_type) == NULL) { 71 return B_BAD_VALUE; 72 } 73 74 return B_OK; 75 } 76 77private: 78 Package* fPackage; 79 AutoPackageAttribute fAttribute; 80}; 81 82 83/*static*/ bool 84AutoPackageAttributes::AttributeForName(const char* name, 85 AutoPackageAttribute& _attribute) 86{ 87 for (int i = 0; i < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT; i++) { 88 if (strcmp(name, kAttributeNames[i]) == 0) { 89 _attribute = (AutoPackageAttribute)i; 90 return true; 91 } 92 } 93 94 return false; 95} 96 97 98/*static*/ const char* 99AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute) 100{ 101 if (attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) 102 return kAttributeNames[attribute]; 103 return NULL; 104} 105 106 107/*static*/ const void* 108AutoPackageAttributes::GetAttributeValue(const Package* package, 109 AutoPackageAttribute attribute, off_t& _size, uint32& _type) 110{ 111 switch (attribute) { 112 case AUTO_PACKAGE_ATTRIBUTE_PACKAGE: 113 { 114 const char* value = package->FileName(); 115 _size = strlen(value) + 1; 116 _type = B_STRING_TYPE; 117 return value; 118 } 119 120 default: 121 return NULL; 122 } 123} 124 125 126/*static*/ status_t 127AutoPackageAttributes::OpenCookie(Package* package, const char* name, 128 int openMode, AttributeCookie*& _cookie) 129{ 130 if (package == NULL) 131 return B_ENTRY_NOT_FOUND; 132 133 // get the attribute 134 AutoPackageAttribute attribute; 135 if (!AttributeForName(name, attribute)) 136 return B_ENTRY_NOT_FOUND; 137 138 // allocate the cookie 139 AutoPackageAttributeCookie* cookie = new(std::nothrow) 140 AutoPackageAttributeCookie(package, attribute); 141 if (cookie == NULL) 142 RETURN_ERROR(B_NO_MEMORY); 143 144 _cookie = cookie; 145 return B_OK; 146} 147