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