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