xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision b1970bb8d83df7a5cbfe7c15946166f0d2317378)
121881ce5SIngo Weinhold //----------------------------------------------------------------------
288706bbeSAxel Dörfler //  This software is part of the Haiku distribution and is covered
388706bbeSAxel Dörfler //  by the MIT license.
421881ce5SIngo Weinhold //---------------------------------------------------------------------
521881ce5SIngo Weinhold /*!
621881ce5SIngo Weinhold 	\file AppFileInfo.cpp
721881ce5SIngo Weinhold 	BAppFileInfo and related structures' implementation.
821881ce5SIngo Weinhold */
9d6b205f3SIngo Weinhold 
1098da112cSIngo Weinhold #include <new>
1198da112cSIngo Weinhold #include <set>
1298da112cSIngo Weinhold #include <string>
1398da112cSIngo Weinhold 
14d6b205f3SIngo Weinhold #include <AppFileInfo.h>
1598da112cSIngo Weinhold #include <Bitmap.h>
1698da112cSIngo Weinhold #include <File.h>
1798da112cSIngo Weinhold #include <fs_attr.h>
1898da112cSIngo Weinhold #include <MimeType.h>
1998da112cSIngo Weinhold #include <RegistrarDefs.h>
2098da112cSIngo Weinhold #include <Resources.h>
2198da112cSIngo Weinhold #include <Roster.h>
2298da112cSIngo Weinhold #include <String.h>
2398da112cSIngo Weinhold 
2450f17542Shaydentech using namespace std;
2550f17542Shaydentech 
2698da112cSIngo Weinhold // attributes
2798da112cSIngo Weinhold static const char *kTypeAttribute				= "BEOS:TYPE";
2898da112cSIngo Weinhold static const char *kSignatureAttribute			= "BEOS:APP_SIG";
2998da112cSIngo Weinhold static const char *kAppFlagsAttribute			= "BEOS:APP_FLAGS";
3098da112cSIngo Weinhold static const char *kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
3198da112cSIngo Weinhold static const char *kVersionInfoAttribute		= "BEOS:APP_VERSION";
3298da112cSIngo Weinhold static const char *kMiniIconAttribute			= "BEOS:M:";
3398da112cSIngo Weinhold static const char *kLargeIconAttribute			= "BEOS:L:";
3498da112cSIngo Weinhold static const char *kStandardIconType			= "STD_ICON";
3598da112cSIngo Weinhold 
3698da112cSIngo Weinhold // resource IDs
3798da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
3898da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
3998da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
4098da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
4198da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
4298da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
4398da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
4498da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
4598da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
4698da112cSIngo Weinhold 
4798da112cSIngo Weinhold // type codes
4898da112cSIngo Weinhold enum {
4998da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
5098da112cSIngo Weinhold 	B_MINI_ICON_TYPE	= 'MICN',
5198da112cSIngo Weinhold 	B_LARGE_ICON_TYPE	= 'ICON',
5298da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
5398da112cSIngo Weinhold };
5498da112cSIngo Weinhold 
5588706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
5688706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
5788706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
5888706bbeSAxel Dörfler // Tracker when compiled for Haiku)
5988706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
6088706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
6188706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
6288706bbeSAxel Dörfler 
6378b31a7cSIngo Weinhold // debugging
6478b31a7cSIngo Weinhold //#define DBG(x) x
6578b31a7cSIngo Weinhold #define DBG(x)
6678b31a7cSIngo Weinhold #define OUT	printf
67d6b205f3SIngo Weinhold 
68d6b205f3SIngo Weinhold // constructor
69d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
70d6b205f3SIngo Weinhold */
71d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
72d6b205f3SIngo Weinhold 			: fResources(NULL),
73d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
74d6b205f3SIngo Weinhold {
75d6b205f3SIngo Weinhold }
76d6b205f3SIngo Weinhold 
77d6b205f3SIngo Weinhold // constructor
78d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
79d6b205f3SIngo Weinhold 		   file.
80d6b205f3SIngo Weinhold 
81d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
82d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
83d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
84d6b205f3SIngo Weinhold 
85d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
86d6b205f3SIngo Weinhold */
87d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
88d6b205f3SIngo Weinhold 			: fResources(NULL),
89d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
90d6b205f3SIngo Weinhold {
9198da112cSIngo Weinhold 	SetTo(file);
92d6b205f3SIngo Weinhold }
93d6b205f3SIngo Weinhold 
94d6b205f3SIngo Weinhold // destructor
95d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
96d6b205f3SIngo Weinhold 
97d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
98d6b205f3SIngo Weinhold */
99d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
100d6b205f3SIngo Weinhold {
10198da112cSIngo Weinhold 	if (fResources)
10298da112cSIngo Weinhold 		delete fResources;
103d6b205f3SIngo Weinhold }
104d6b205f3SIngo Weinhold 
105d6b205f3SIngo Weinhold // SetTo
106d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
107d6b205f3SIngo Weinhold 
108d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
109d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
110d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
111d6b205f3SIngo Weinhold 
112d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
113d6b205f3SIngo Weinhold 
114d6b205f3SIngo Weinhold 	\return
115d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
116d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
117d6b205f3SIngo Weinhold */
118d6b205f3SIngo Weinhold status_t
119d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
120d6b205f3SIngo Weinhold {
12198da112cSIngo Weinhold 	// unset the old file
12298da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
12398da112cSIngo Weinhold 	if (fResources) {
12498da112cSIngo Weinhold 		delete fResources;
12598da112cSIngo Weinhold 		fResources = NULL;
12698da112cSIngo Weinhold 	}
12798da112cSIngo Weinhold 	// check param
12898da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
12998da112cSIngo Weinhold 	// create resources
13098da112cSIngo Weinhold 	if (error == B_OK) {
13198da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
13298da112cSIngo Weinhold 		if (fResources)
13398da112cSIngo Weinhold 			error = fResources->SetTo(file);
13498da112cSIngo Weinhold 		else
13598da112cSIngo Weinhold 			error = B_NO_MEMORY;
13698da112cSIngo Weinhold 	}
13798da112cSIngo Weinhold 	// set node info
13898da112cSIngo Weinhold 	if (error == B_OK)
13998da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
14098da112cSIngo Weinhold 	// clean up on error
14198da112cSIngo Weinhold 	if (error != B_OK) {
14298da112cSIngo Weinhold 		if (fResources) {
14398da112cSIngo Weinhold 			delete fResources;
14498da112cSIngo Weinhold 			fResources = NULL;
14598da112cSIngo Weinhold 		}
14698da112cSIngo Weinhold 		if (InitCheck() == B_OK)
14798da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
14898da112cSIngo Weinhold 	}
14998da112cSIngo Weinhold 	// set data location
15098da112cSIngo Weinhold 	if (error == B_OK)
15198da112cSIngo Weinhold 		SetInfoLocation(B_USE_BOTH_LOCATIONS);
15298da112cSIngo Weinhold 	// set error
15398da112cSIngo Weinhold 	fCStatus = error;
15498da112cSIngo Weinhold 	return error;
155d6b205f3SIngo Weinhold }
156d6b205f3SIngo Weinhold 
157d6b205f3SIngo Weinhold // GetType
158d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
159d6b205f3SIngo Weinhold 
160d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
161d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
162d6b205f3SIngo Weinhold 		   file shall be written.
163d6b205f3SIngo Weinhold 	\return
164d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
165d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
166d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
167d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
168d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
169d6b205f3SIngo Weinhold 	  the wrong type.
170d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
171d6b205f3SIngo Weinhold 	- other error codes
172d6b205f3SIngo Weinhold */
173d6b205f3SIngo Weinhold status_t
174d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
175d6b205f3SIngo Weinhold {
17698da112cSIngo Weinhold 	// check param and initialization
17798da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
17898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
17998da112cSIngo Weinhold 		error = B_NO_INIT;
18098da112cSIngo Weinhold 	// read the data
18198da112cSIngo Weinhold 	size_t read = 0;
18298da112cSIngo Weinhold 	if (error == B_OK) {
18398da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
18498da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
18598da112cSIngo Weinhold 	}
18698da112cSIngo Weinhold 	// check the read data -- null terminate the string
18798da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
18898da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
18998da112cSIngo Weinhold 			error = B_ERROR;
19098da112cSIngo Weinhold 		else
19198da112cSIngo Weinhold 			type[read] = '\0';
19298da112cSIngo Weinhold 	}
19398da112cSIngo Weinhold 	return error;
194d6b205f3SIngo Weinhold }
195d6b205f3SIngo Weinhold 
196d6b205f3SIngo Weinhold // SetType
197d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
198d6b205f3SIngo Weinhold 
199d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
200d6b205f3SIngo Weinhold 
201d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
202d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
203d6b205f3SIngo Weinhold 		   May be \c NULL.
204d6b205f3SIngo Weinhold 	\return
205d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
206d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
207d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
208d6b205f3SIngo Weinhold 	- other error codes
209d6b205f3SIngo Weinhold */
210d6b205f3SIngo Weinhold status_t
211d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
212d6b205f3SIngo Weinhold {
21398da112cSIngo Weinhold 	// check initialization
21498da112cSIngo Weinhold 	status_t error = B_OK;
21598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
21698da112cSIngo Weinhold 		error = B_NO_INIT;
21798da112cSIngo Weinhold 	if (error == B_OK) {
21898da112cSIngo Weinhold 		if (type) {
21998da112cSIngo Weinhold 			// check param
22098da112cSIngo Weinhold 			size_t typeLen = strlen(type);
22198da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
22298da112cSIngo Weinhold 				error = B_BAD_VALUE;
22398da112cSIngo Weinhold 			// write the data
22498da112cSIngo Weinhold 			if (error == B_OK) {
22598da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
22698da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
22798da112cSIngo Weinhold 			}
22898da112cSIngo Weinhold 		} else
22998da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
23098da112cSIngo Weinhold 	}
23198da112cSIngo Weinhold 	return error;
232d6b205f3SIngo Weinhold }
233d6b205f3SIngo Weinhold 
234d6b205f3SIngo Weinhold // GetSignature
235d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
236d6b205f3SIngo Weinhold 
237d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
238d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
239d6b205f3SIngo Weinhold 		   signature of the file shall be written.
240d6b205f3SIngo Weinhold 	\return
241d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
242d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
243d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
244d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
245d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
246d6b205f3SIngo Weinhold 	  the wrong type.
247d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
248d6b205f3SIngo Weinhold 	- other error codes
249d6b205f3SIngo Weinhold */
250d6b205f3SIngo Weinhold status_t
251d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
252d6b205f3SIngo Weinhold {
25398da112cSIngo Weinhold 	// check param and initialization
25498da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
25598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
25698da112cSIngo Weinhold 		error = B_NO_INIT;
25798da112cSIngo Weinhold 	// read the data
25898da112cSIngo Weinhold 	size_t read = 0;
25998da112cSIngo Weinhold 	if (error == B_OK) {
26098da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
26198da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
26298da112cSIngo Weinhold 						  read);
26398da112cSIngo Weinhold 	}
26498da112cSIngo Weinhold 	// check the read data -- null terminate the string
26598da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
26698da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
26798da112cSIngo Weinhold 			error = B_ERROR;
26898da112cSIngo Weinhold 		else
26998da112cSIngo Weinhold 			signature[read] = '\0';
27098da112cSIngo Weinhold 	}
27198da112cSIngo Weinhold 	return error;
272d6b205f3SIngo Weinhold }
273d6b205f3SIngo Weinhold 
274d6b205f3SIngo Weinhold // SetSignature
275d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
276d6b205f3SIngo Weinhold 
277d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
278d6b205f3SIngo Weinhold 
279d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
280d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
281d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
282d6b205f3SIngo Weinhold 	\return
283d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
284d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
285d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
286d6b205f3SIngo Weinhold 	- other error codes
287d6b205f3SIngo Weinhold */
288d6b205f3SIngo Weinhold status_t
289d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
290d6b205f3SIngo Weinhold {
29198da112cSIngo Weinhold 	// check initialization
29298da112cSIngo Weinhold 	status_t error = B_OK;
29398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
29498da112cSIngo Weinhold 		error = B_NO_INIT;
29598da112cSIngo Weinhold 	if (error == B_OK) {
29698da112cSIngo Weinhold 		if (signature) {
29798da112cSIngo Weinhold 			// check param
29898da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
29998da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
30098da112cSIngo Weinhold 				error = B_BAD_VALUE;
30198da112cSIngo Weinhold 			// write the data
30298da112cSIngo Weinhold 			if (error == B_OK) {
30398da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
30498da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
30598da112cSIngo Weinhold 								   signatureLen + 1);
30698da112cSIngo Weinhold 			}
30798da112cSIngo Weinhold 		} else
30898da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
30998da112cSIngo Weinhold 	}
31098da112cSIngo Weinhold 	return error;
311d6b205f3SIngo Weinhold }
312d6b205f3SIngo Weinhold 
313d6b205f3SIngo Weinhold // GetAppFlags
314d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
315d6b205f3SIngo Weinhold 
316d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
317d6b205f3SIngo Weinhold 		   flags of the file shall be written.
318d6b205f3SIngo Weinhold 	\return
319d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
320d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
321d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
322d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
323d6b205f3SIngo Weinhold 	  the wrong type.
324d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
325d6b205f3SIngo Weinhold 	- other error codes
326d6b205f3SIngo Weinhold */
327d6b205f3SIngo Weinhold status_t
328d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
329d6b205f3SIngo Weinhold {
33098da112cSIngo Weinhold 	// check param and initialization
33198da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
33298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
33398da112cSIngo Weinhold 		error = B_NO_INIT;
33498da112cSIngo Weinhold 	// read the data
33598da112cSIngo Weinhold 	size_t read = 0;
33698da112cSIngo Weinhold 	if (error == B_OK) {
33798da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
33898da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
33998da112cSIngo Weinhold 						  read);
34098da112cSIngo Weinhold 	}
34198da112cSIngo Weinhold 	// check the read data
34298da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
34398da112cSIngo Weinhold 		error = B_ERROR;
34498da112cSIngo Weinhold 	return error;
345d6b205f3SIngo Weinhold }
346d6b205f3SIngo Weinhold 
347d6b205f3SIngo Weinhold // SetAppFlags
348d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
349d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
350d6b205f3SIngo Weinhold 	\return
351d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
352d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
353d6b205f3SIngo Weinhold 	- other error codes
354d6b205f3SIngo Weinhold */
355d6b205f3SIngo Weinhold status_t
356d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
357d6b205f3SIngo Weinhold {
35898da112cSIngo Weinhold 	// check initialization
35998da112cSIngo Weinhold 	status_t error = B_OK;
36098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
36198da112cSIngo Weinhold 		error = B_NO_INIT;
36298da112cSIngo Weinhold 	if (error == B_OK) {
36398da112cSIngo Weinhold 		// write the data
36498da112cSIngo Weinhold 		if (error == B_OK) {
36598da112cSIngo Weinhold 			error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
36698da112cSIngo Weinhold 							   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
36798da112cSIngo Weinhold 		}
36898da112cSIngo Weinhold 	}
36998da112cSIngo Weinhold 	return error;
370d6b205f3SIngo Weinhold }
371d6b205f3SIngo Weinhold 
372d6b205f3SIngo Weinhold // GetSupportedTypes
373d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
374d6b205f3SIngo Weinhold 
375d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
376d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
377d6b205f3SIngo Weinhold 
378d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
379d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
380d6b205f3SIngo Weinhold 	\return
381d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
382d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
383d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
384d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
385d6b205f3SIngo Weinhold 	  have the wrong type.
386d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
387d6b205f3SIngo Weinhold 	- other error codes
388d6b205f3SIngo Weinhold */
389d6b205f3SIngo Weinhold status_t
390d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
391d6b205f3SIngo Weinhold {
39298da112cSIngo Weinhold 	// check param and initialization
39398da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
39498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
39598da112cSIngo Weinhold 		error = B_NO_INIT;
39698da112cSIngo Weinhold 	// read the data
39798da112cSIngo Weinhold 	size_t read = 0;
39898da112cSIngo Weinhold 	void *buffer = NULL;
39998da112cSIngo Weinhold 	if (error == B_OK) {
40098da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
40198da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
40298da112cSIngo Weinhold 	}
40398da112cSIngo Weinhold 	// unflatten the buffer
40498da112cSIngo Weinhold 	if (error == B_OK)
40598da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
40698da112cSIngo Weinhold 	// clean up
40798da112cSIngo Weinhold 	if (buffer)
40898da112cSIngo Weinhold 		free(buffer);
40998da112cSIngo Weinhold 	return error;
410d6b205f3SIngo Weinhold }
411d6b205f3SIngo Weinhold 
412d6b205f3SIngo Weinhold // SetSupportedTypes
413d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
414d6b205f3SIngo Weinhold 
415d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
416d6b205f3SIngo Weinhold 
417d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
418d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
419d6b205f3SIngo Weinhold 
42083a812a1SIngo Weinhold 	The method informs the registrar about this news.
42183a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
42283a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
42383a812a1SIngo Weinhold 	application file needs to have a signature set.
42483a812a1SIngo Weinhold 
42583a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
42683a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
42783a812a1SIngo Weinhold 	lists of supporting applications.
42883a812a1SIngo Weinhold 
429d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
430d6b205f3SIngo Weinhold 		   May be \c NULL.
43183a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
43283a812a1SIngo Weinhold 		   types, \c false otherwise.
433d6b205f3SIngo Weinhold 	\return
434d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
435d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
436d6b205f3SIngo Weinhold 	- other error codes
437d6b205f3SIngo Weinhold */
438d6b205f3SIngo Weinhold status_t
439d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
440d6b205f3SIngo Weinhold {
44198da112cSIngo Weinhold 	// check initialization
44298da112cSIngo Weinhold 	status_t error = B_OK;
44398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
44498da112cSIngo Weinhold 		error = B_NO_INIT;
44598da112cSIngo Weinhold 	BMimeType mimeType;
44698da112cSIngo Weinhold 	if (error == B_OK)
44798da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
44898da112cSIngo Weinhold 	if (error == B_OK) {
44998da112cSIngo Weinhold 		if (types) {
45017819be3SIngo Weinhold 			// check param -- supported types must be valid
45117819be3SIngo Weinhold 			const char *type;
45217819be3SIngo Weinhold 			for (int32 i = 0;
45317819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
45417819be3SIngo Weinhold 				 i++) {
45517819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
45617819be3SIngo Weinhold 					error = B_BAD_VALUE;
45717819be3SIngo Weinhold 			}
45817819be3SIngo Weinhold 			// get flattened size
45917819be3SIngo Weinhold 			ssize_t size = 0;
46017819be3SIngo Weinhold 			if (error == B_OK) {
46117819be3SIngo Weinhold 				size = types->FlattenedSize();
46298da112cSIngo Weinhold 				if (size < 0)
46398da112cSIngo Weinhold 					error = size;
46417819be3SIngo Weinhold 			}
46598da112cSIngo Weinhold 			// allocate a buffer for the flattened data
46698da112cSIngo Weinhold 			char *buffer = NULL;
46798da112cSIngo Weinhold 			if (error == B_OK) {
46898da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
46998da112cSIngo Weinhold 				if (!buffer)
47098da112cSIngo Weinhold 					error = B_NO_MEMORY;
47198da112cSIngo Weinhold 			}
47298da112cSIngo Weinhold 			// flatten the message
47398da112cSIngo Weinhold 			if (error == B_OK)
47498da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
47598da112cSIngo Weinhold 			// write the data
47698da112cSIngo Weinhold 			if (error == B_OK) {
47798da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
47898da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
47998da112cSIngo Weinhold 								   buffer, size);
48098da112cSIngo Weinhold 			}
48198da112cSIngo Weinhold 			// clean up
48298da112cSIngo Weinhold 			if (buffer)
48398da112cSIngo Weinhold 				delete[] buffer;
48498da112cSIngo Weinhold 		} else
48598da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
48698da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
48717819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
48817819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
48998da112cSIngo Weinhold 	}
49098da112cSIngo Weinhold 	return error;
491d6b205f3SIngo Weinhold }
492d6b205f3SIngo Weinhold 
493d6b205f3SIngo Weinhold // SetSupportedTypes
494d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
495d6b205f3SIngo Weinhold 
49698da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
49783a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
498d6b205f3SIngo Weinhold 
499d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
500d6b205f3SIngo Weinhold 		   May be \c NULL.
501d6b205f3SIngo Weinhold 	\return
502d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
503d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
504d6b205f3SIngo Weinhold 	- other error codes
505d6b205f3SIngo Weinhold */
506d6b205f3SIngo Weinhold status_t
507d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
508d6b205f3SIngo Weinhold {
50998da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
510d6b205f3SIngo Weinhold }
511d6b205f3SIngo Weinhold 
512d6b205f3SIngo Weinhold // IsSupportedType
513d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
514d6b205f3SIngo Weinhold 
515d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
516d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
517d6b205f3SIngo Weinhold 
518d6b205f3SIngo Weinhold 	\param type The MIME type in question.
519d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
520d6b205f3SIngo Weinhold 			the application, \c false otherwise.
521d6b205f3SIngo Weinhold */
522d6b205f3SIngo Weinhold bool
523d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
524d6b205f3SIngo Weinhold {
52598da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
52698da112cSIngo Weinhold 	// get the supported types
52798da112cSIngo Weinhold 	BMessage types;
52898da112cSIngo Weinhold 	if (error == B_OK)
52998da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
53098da112cSIngo Weinhold 	// turn type into a BMimeType
53198da112cSIngo Weinhold 	BMimeType mimeType;
53298da112cSIngo Weinhold 	if (error == B_OK)
53398da112cSIngo Weinhold 		error = mimeType.SetTo(type);
53498da112cSIngo Weinhold 	// iterate through the supported types
53598da112cSIngo Weinhold 	bool found = false;
53698da112cSIngo Weinhold 	if (error == B_OK) {
53798da112cSIngo Weinhold 		const char *supportedType;
53898da112cSIngo Weinhold 		for (int32 i = 0;
53998da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
54098da112cSIngo Weinhold 			 i++) {
54198da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
54298da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
54398da112cSIngo Weinhold 		}
54498da112cSIngo Weinhold 	}
54598da112cSIngo Weinhold 	return found;
546d6b205f3SIngo Weinhold }
547d6b205f3SIngo Weinhold 
548d6b205f3SIngo Weinhold // Supports
549d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
550d6b205f3SIngo Weinhold 		   explicitly.
551d6b205f3SIngo Weinhold 
552d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
553d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
554d6b205f3SIngo Weinhold 	"application/octet-stream".
555d6b205f3SIngo Weinhold 
556d6b205f3SIngo Weinhold 	\param type The MIME type in question.
557d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
558d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
559d6b205f3SIngo Weinhold */
560d6b205f3SIngo Weinhold bool
561d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
562d6b205f3SIngo Weinhold {
56398da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
56498da112cSIngo Weinhold 	// get the supported types
56598da112cSIngo Weinhold 	BMessage types;
56698da112cSIngo Weinhold 	if (error == B_OK)
56798da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
56898da112cSIngo Weinhold 	// iterate through the supported types
56998da112cSIngo Weinhold 	bool found = false;
57098da112cSIngo Weinhold 	if (error == B_OK) {
57198da112cSIngo Weinhold 		const char *supportedType;
57298da112cSIngo Weinhold 		for (int32 i = 0;
57398da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
57498da112cSIngo Weinhold 			 i++) {
57598da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
57698da112cSIngo Weinhold 		}
57798da112cSIngo Weinhold 	}
57898da112cSIngo Weinhold 	return found;
579d6b205f3SIngo Weinhold }
580d6b205f3SIngo Weinhold 
581d6b205f3SIngo Weinhold // GetIcon
582d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
583d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
584d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
585d6b205f3SIngo Weinhold 		   large icon).
586d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
587d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
588d6b205f3SIngo Weinhold 	\return
589d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
590d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
591d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
592d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
593d6b205f3SIngo Weinhold 	- other error codes
594d6b205f3SIngo Weinhold */
595d6b205f3SIngo Weinhold status_t
596d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
597d6b205f3SIngo Weinhold {
59898da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
599d6b205f3SIngo Weinhold }
600d6b205f3SIngo Weinhold 
601d6b205f3SIngo Weinhold // SetIcon
602d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
603d6b205f3SIngo Weinhold 
604d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
605d6b205f3SIngo Weinhold 
606d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
607d6b205f3SIngo Weinhold 		   May be \c NULL.
608d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
609d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
610d6b205f3SIngo Weinhold 	\return
611d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
612d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
613d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
614d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
615d6b205f3SIngo Weinhold 	- other error codes
616d6b205f3SIngo Weinhold */
617d6b205f3SIngo Weinhold status_t
618d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
619d6b205f3SIngo Weinhold {
62098da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
621d6b205f3SIngo Weinhold }
622d6b205f3SIngo Weinhold 
623d6b205f3SIngo Weinhold // GetVersionInfo
624d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
625d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
626d6b205f3SIngo Weinhold 		   the version info should be written.
627d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
628d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
629d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
630d6b205f3SIngo Weinhold 		   belongs to.
631d6b205f3SIngo Weinhold 	\return
632d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
633d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
634d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
635d6b205f3SIngo Weinhold 	- other error codes
636d6b205f3SIngo Weinhold */
637d6b205f3SIngo Weinhold status_t
638d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
639d6b205f3SIngo Weinhold {
64098da112cSIngo Weinhold 	// check params and initialization
641*b1970bb8SIngo Weinhold 	if (!info)
642*b1970bb8SIngo Weinhold 		return B_BAD_VALUE;
643*b1970bb8SIngo Weinhold 
64498da112cSIngo Weinhold 	int32 index = 0;
64598da112cSIngo Weinhold 	switch (kind) {
64698da112cSIngo Weinhold 		case B_APP_VERSION_KIND:
64798da112cSIngo Weinhold 			index = 0;
64898da112cSIngo Weinhold 			break;
64998da112cSIngo Weinhold 		case B_SYSTEM_VERSION_KIND:
65098da112cSIngo Weinhold 			index = 1;
65198da112cSIngo Weinhold 			break;
65298da112cSIngo Weinhold 		default:
653*b1970bb8SIngo Weinhold 			return B_BAD_VALUE;
65498da112cSIngo Weinhold 	}
655*b1970bb8SIngo Weinhold 
656*b1970bb8SIngo Weinhold 	if (InitCheck() != B_OK)
657*b1970bb8SIngo Weinhold 		return B_NO_INIT;
658*b1970bb8SIngo Weinhold 
65998da112cSIngo Weinhold 	// read the data
66098da112cSIngo Weinhold 	size_t read = 0;
66198da112cSIngo Weinhold 	version_info infos[2];
662*b1970bb8SIngo Weinhold 	status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
663*b1970bb8SIngo Weinhold 		B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read);
664*b1970bb8SIngo Weinhold 	if (error != B_OK)
66598da112cSIngo Weinhold 		return error;
666*b1970bb8SIngo Weinhold 
667*b1970bb8SIngo Weinhold 	// check the read data
668*b1970bb8SIngo Weinhold 	if (read == sizeof(version_info)) {
669*b1970bb8SIngo Weinhold 		// only the app version info is there -- return a cleared system info
670*b1970bb8SIngo Weinhold 		if (index == 0)
671*b1970bb8SIngo Weinhold 			*info = infos[index];
672*b1970bb8SIngo Weinhold 		else if (index == 1)
673*b1970bb8SIngo Weinhold 			memset(info, 0, sizeof(version_info));
674*b1970bb8SIngo Weinhold 	} else if (read == 2 * sizeof(version_info)) {
675*b1970bb8SIngo Weinhold 		*info = infos[index];
676*b1970bb8SIngo Weinhold 	} else
677*b1970bb8SIngo Weinhold 		return B_ERROR;
678*b1970bb8SIngo Weinhold 
679*b1970bb8SIngo Weinhold 	// return result
680*b1970bb8SIngo Weinhold 	return B_OK;
681d6b205f3SIngo Weinhold }
682d6b205f3SIngo Weinhold 
683d6b205f3SIngo Weinhold // SetVersionInfo
684d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
685d6b205f3SIngo Weinhold 
686d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
687d6b205f3SIngo Weinhold 
688d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
689d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
690d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
691d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
692d6b205f3SIngo Weinhold 		   belongs to.
693d6b205f3SIngo Weinhold 	\return
694d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
695d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
696d6b205f3SIngo Weinhold 	- other error codes
697d6b205f3SIngo Weinhold */
698d6b205f3SIngo Weinhold status_t
699d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
700d6b205f3SIngo Weinhold {
70198da112cSIngo Weinhold 	// check initialization
70298da112cSIngo Weinhold 	status_t error = B_OK;
70398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
70498da112cSIngo Weinhold 		error = B_NO_INIT;
70598da112cSIngo Weinhold 	if (error == B_OK) {
70698da112cSIngo Weinhold 		if (info) {
70798da112cSIngo Weinhold 			// check param
70898da112cSIngo Weinhold 			int32 index = 0;
70998da112cSIngo Weinhold 			if (error == B_OK) {
71098da112cSIngo Weinhold 				switch (kind) {
71198da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
71298da112cSIngo Weinhold 						index = 0;
71398da112cSIngo Weinhold 						break;
71498da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
71598da112cSIngo Weinhold 						index = 1;
71698da112cSIngo Weinhold 						break;
71798da112cSIngo Weinhold 					default:
71898da112cSIngo Weinhold 						error = B_BAD_VALUE;
71998da112cSIngo Weinhold 						break;
72098da112cSIngo Weinhold 				}
72198da112cSIngo Weinhold 			}
72298da112cSIngo Weinhold 			// read both infos
72398da112cSIngo Weinhold 			version_info infos[2];
72498da112cSIngo Weinhold 			if (error == B_OK) {
72598da112cSIngo Weinhold 				size_t read;
726*b1970bb8SIngo Weinhold 				if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
727*b1970bb8SIngo Weinhold 						B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info),
728*b1970bb8SIngo Weinhold 						read) == B_OK) {
729*b1970bb8SIngo Weinhold 					// clear the part that hasn't been read
730*b1970bb8SIngo Weinhold 					if (read < sizeof(infos))
731*b1970bb8SIngo Weinhold 						memset((char*)infos + read, 0, sizeof(infos) - read);
732*b1970bb8SIngo Weinhold 				} else {
733*b1970bb8SIngo Weinhold 					// failed to read -- clear
734*b1970bb8SIngo Weinhold 					memset(infos, 0, sizeof(infos));
735*b1970bb8SIngo Weinhold 				}
73698da112cSIngo Weinhold 			}
73798da112cSIngo Weinhold 			infos[index] = *info;
73898da112cSIngo Weinhold 			// write the data
73998da112cSIngo Weinhold 			if (error == B_OK) {
74098da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
74198da112cSIngo Weinhold 								   kVersionInfoResourceID,
74298da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
74398da112cSIngo Weinhold 								   2 * sizeof(version_info));
74498da112cSIngo Weinhold 			}
74598da112cSIngo Weinhold 		} else
74698da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
74798da112cSIngo Weinhold 	}
74898da112cSIngo Weinhold 	return error;
749d6b205f3SIngo Weinhold }
750d6b205f3SIngo Weinhold 
751d6b205f3SIngo Weinhold // GetIconForType
752d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
75398da112cSIngo Weinhold 
75498da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
75598da112cSIngo Weinhold 
75698da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
757d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
758d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
759d6b205f3SIngo Weinhold 		   large icon).
760d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
761d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
762d6b205f3SIngo Weinhold 	\return
763d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
764d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
76598da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
766d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
767d6b205f3SIngo Weinhold 		 not match.
768d6b205f3SIngo Weinhold 	- other error codes
769d6b205f3SIngo Weinhold */
770d6b205f3SIngo Weinhold status_t
771d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
772d6b205f3SIngo Weinhold 							 icon_size which) const
773d6b205f3SIngo Weinhold {
77498da112cSIngo Weinhold 	status_t error = B_OK;
77598da112cSIngo Weinhold 	// set some icon size related variables
77698da112cSIngo Weinhold 	BString attributeString;
77798da112cSIngo Weinhold 	BRect bounds;
778a04efc92SIngo Weinhold 	uint32 attrType = 0;
779a04efc92SIngo Weinhold 	size_t attrSize = 0;
78098da112cSIngo Weinhold 	switch (which) {
78198da112cSIngo Weinhold 		case B_MINI_ICON:
78298da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
78398da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
78498da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
78598da112cSIngo Weinhold 			attrSize = 16 * 16;
78698da112cSIngo Weinhold 			break;
78798da112cSIngo Weinhold 		case B_LARGE_ICON:
78898da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
78998da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
79098da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
79198da112cSIngo Weinhold 			attrSize = 32 * 32;
79298da112cSIngo Weinhold 			break;
79398da112cSIngo Weinhold 		default:
79498da112cSIngo Weinhold 			error = B_BAD_VALUE;
79598da112cSIngo Weinhold 			break;
79698da112cSIngo Weinhold 	}
79798da112cSIngo Weinhold 	// check type param
79898da112cSIngo Weinhold 	if (error == B_OK) {
79998da112cSIngo Weinhold 		if (type) {
80017819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
80117819be3SIngo Weinhold 				attributeString += type;
80217819be3SIngo Weinhold 			else
80398da112cSIngo Weinhold 				error = B_BAD_VALUE;
80498da112cSIngo Weinhold 		} else
80517819be3SIngo Weinhold 			attributeString += kStandardIconType;
80698da112cSIngo Weinhold 	}
80798da112cSIngo Weinhold 	const char *attribute = attributeString.String();
80817819be3SIngo Weinhold 
80998da112cSIngo Weinhold 	// check parameter and initialization
81098da112cSIngo Weinhold 	if (error == B_OK
81198da112cSIngo Weinhold 		&& (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
81298da112cSIngo Weinhold 		error = B_BAD_VALUE;
81398da112cSIngo Weinhold 	}
81498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
81598da112cSIngo Weinhold 		error = B_NO_INIT;
81698da112cSIngo Weinhold 	// read the data
81798da112cSIngo Weinhold 	if (error == B_OK) {
81898da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
81998da112cSIngo Weinhold 		char *buffer = NULL;
82098da112cSIngo Weinhold 		size_t read;
82198da112cSIngo Weinhold 		if (otherColorSpace) {
82298da112cSIngo Weinhold 			// other color space than stored in attribute
82398da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
82498da112cSIngo Weinhold 			if (!buffer)
82598da112cSIngo Weinhold 				error = B_NO_MEMORY;
82698da112cSIngo Weinhold 			if (error == B_OK) {
82798da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
82898da112cSIngo Weinhold 								  read);
82998da112cSIngo Weinhold 			}
83098da112cSIngo Weinhold 		} else {
83198da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
83298da112cSIngo Weinhold 							  read);
83398da112cSIngo Weinhold 		}
83498da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
83598da112cSIngo Weinhold 			error = B_ERROR;
83698da112cSIngo Weinhold 		if (otherColorSpace) {
83798da112cSIngo Weinhold 			// other color space than stored in attribute
83876ba3434SIngo Weinhold 			if (error == B_OK) {
83976ba3434SIngo Weinhold 				error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
84076ba3434SIngo Weinhold 										 0, B_CMAP8);
84176ba3434SIngo Weinhold 			}
84298da112cSIngo Weinhold 			delete[] buffer;
84398da112cSIngo Weinhold 		}
84498da112cSIngo Weinhold 	}
84598da112cSIngo Weinhold 	return error;
846d6b205f3SIngo Weinhold }
847d6b205f3SIngo Weinhold 
848d6b205f3SIngo Weinhold // SetIconForType
849d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
850d6b205f3SIngo Weinhold 
85198da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
852d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
853d6b205f3SIngo Weinhold 
85498da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
85598da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
85698da112cSIngo Weinhold 	before.
85798da112cSIngo Weinhold 
85898da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
859d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
860d6b205f3SIngo Weinhold 		   May be \c NULL.
861d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
862d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
863d6b205f3SIngo Weinhold 	\return
864d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
865d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
866d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
867d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
868d6b205f3SIngo Weinhold 	- other error codes
869d6b205f3SIngo Weinhold */
870d6b205f3SIngo Weinhold status_t
871d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
872d6b205f3SIngo Weinhold 							 icon_size which)
873d6b205f3SIngo Weinhold {
87498da112cSIngo Weinhold 	status_t error = B_OK;
87598da112cSIngo Weinhold 	// set some icon size related variables
87698da112cSIngo Weinhold 	BString attributeString;
87798da112cSIngo Weinhold 	BRect bounds;
878a04efc92SIngo Weinhold 	uint32 attrType = 0;
879a04efc92SIngo Weinhold 	size_t attrSize = 0;
880a04efc92SIngo Weinhold 	int32 resourceID = 0;
88198da112cSIngo Weinhold 	switch (which) {
88298da112cSIngo Weinhold 		case B_MINI_ICON:
88398da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
88498da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
88598da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
88698da112cSIngo Weinhold 			attrSize = 16 * 16;
88798da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
88898da112cSIngo Weinhold 							   : kMiniIconResourceID);
88998da112cSIngo Weinhold 			break;
89098da112cSIngo Weinhold 		case B_LARGE_ICON:
89198da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
89298da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
89398da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
89498da112cSIngo Weinhold 			attrSize = 32 * 32;
89598da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
89698da112cSIngo Weinhold 							   : kLargeIconResourceID);
89798da112cSIngo Weinhold 			break;
89898da112cSIngo Weinhold 		default:
89998da112cSIngo Weinhold 			error = B_BAD_VALUE;
90098da112cSIngo Weinhold 			break;
90198da112cSIngo Weinhold 	}
90298da112cSIngo Weinhold 	// check type param
90398da112cSIngo Weinhold 	if (error == B_OK) {
90498da112cSIngo Weinhold 		if (type) {
90517819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
90698da112cSIngo Weinhold 				attributeString += type;
90717819be3SIngo Weinhold 			else
90817819be3SIngo Weinhold 				error = B_BAD_VALUE;
90998da112cSIngo Weinhold 		} else
91098da112cSIngo Weinhold 			attributeString += kStandardIconType;
91198da112cSIngo Weinhold 	}
91298da112cSIngo Weinhold 	const char *attribute = attributeString.String();
91398da112cSIngo Weinhold 	// check parameter and initialization
91498da112cSIngo Weinhold 	if (error == B_OK && icon
91598da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
91698da112cSIngo Weinhold 		error = B_BAD_VALUE;
91798da112cSIngo Weinhold 	}
91898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
91998da112cSIngo Weinhold 		error = B_NO_INIT;
92098da112cSIngo Weinhold 	// write/remove the attribute
92198da112cSIngo Weinhold 	if (error == B_OK) {
92298da112cSIngo Weinhold 		if (icon) {
92398da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
92498da112cSIngo Weinhold 			if (otherColorSpace) {
925290bc091SIngo Weinhold 				BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8);
92698da112cSIngo Weinhold 				error = bitmap.InitCheck();
92776ba3434SIngo Weinhold 				if (error == B_OK)
92876ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
92998da112cSIngo Weinhold 				if (error == B_OK) {
93098da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
93198da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
93298da112cSIngo Weinhold 				}
93398da112cSIngo Weinhold 			} else {
93498da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
93598da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
93698da112cSIngo Weinhold 			}
93798da112cSIngo Weinhold 		} else	// no icon given => remove
93898da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
93998da112cSIngo Weinhold 	}
94098da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
94198da112cSIngo Weinhold 	BMimeType mimeType;
94298da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
94398da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
94498da112cSIngo Weinhold 			error = mimeType.Install();
94598da112cSIngo Weinhold 		if (error == B_OK)
94698da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
94798da112cSIngo Weinhold 	}
94898da112cSIngo Weinhold 	return error;
949d6b205f3SIngo Weinhold }
950d6b205f3SIngo Weinhold 
951d6b205f3SIngo Weinhold // SetInfoLocation
952d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
953d6b205f3SIngo Weinhold 
954d6b205f3SIngo Weinhold 	The options for \a location are:
955d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
956d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
957d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
958d6b205f3SIngo Weinhold 
959d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
960d6b205f3SIngo Weinhold */
961d6b205f3SIngo Weinhold void
962d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
963d6b205f3SIngo Weinhold {
96498da112cSIngo Weinhold 	fWhere = location;
965d6b205f3SIngo Weinhold }
966d6b205f3SIngo Weinhold 
967d6b205f3SIngo Weinhold // IsUsingAttributes
968d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
969d6b205f3SIngo Weinhold 		   file's attributes.
970d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
971d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
972d6b205f3SIngo Weinhold */
973d6b205f3SIngo Weinhold bool
974d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
975d6b205f3SIngo Weinhold {
97698da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
977d6b205f3SIngo Weinhold }
978d6b205f3SIngo Weinhold 
979d6b205f3SIngo Weinhold // IsUsingResources
980d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
981d6b205f3SIngo Weinhold 		   file's resources.
982d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
983d6b205f3SIngo Weinhold 			resources, \c false otherwise.
984d6b205f3SIngo Weinhold */
985d6b205f3SIngo Weinhold bool
986d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
987d6b205f3SIngo Weinhold {
98898da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
989d6b205f3SIngo Weinhold }
990d6b205f3SIngo Weinhold 
991d6b205f3SIngo Weinhold // FBC
992d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
993d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
994d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
995d6b205f3SIngo Weinhold 
996d6b205f3SIngo Weinhold // =
997d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
998d6b205f3SIngo Weinhold */
999d6b205f3SIngo Weinhold BAppFileInfo &
1000d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
1001d6b205f3SIngo Weinhold {
1002d6b205f3SIngo Weinhold 	return *this;
1003d6b205f3SIngo Weinhold }
1004d6b205f3SIngo Weinhold 
1005d6b205f3SIngo Weinhold // copy constructor
1006d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1007d6b205f3SIngo Weinhold */
1008d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
1009d6b205f3SIngo Weinhold {
1010d6b205f3SIngo Weinhold }
1011d6b205f3SIngo Weinhold 
101298da112cSIngo Weinhold // GetMetaMime
101398da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
101498da112cSIngo Weinhold 
101598da112cSIngo Weinhold 	The parameter \a meta is not checked.
101698da112cSIngo Weinhold 
101798da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
101898da112cSIngo Weinhold 		   initialized to the file's signature.
101998da112cSIngo Weinhold 	\return
102098da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
102198da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
102298da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
102398da112cSIngo Weinhold (	  not installed in the MIME database.)
102498da112cSIngo Weinhold 	  no valid MIME string.
102598da112cSIngo Weinhold 	- other error codes
102698da112cSIngo Weinhold */
102798da112cSIngo Weinhold status_t
102898da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
102998da112cSIngo Weinhold {
103098da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
103198da112cSIngo Weinhold 	status_t error = GetSignature(signature);
103298da112cSIngo Weinhold 	if (error == B_OK)
103398da112cSIngo Weinhold 		error = meta->SetTo(signature);
103498da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
103598da112cSIngo Weinhold 		error = B_BAD_VALUE;
103698da112cSIngo Weinhold 	return error;
103798da112cSIngo Weinhold }
103898da112cSIngo Weinhold 
103998da112cSIngo Weinhold // _ReadData
104098da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
104198da112cSIngo Weinhold 
104298da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
104398da112cSIngo Weinhold 
104498da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
104598da112cSIngo Weinhold 
104698da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
104798da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
104898da112cSIngo Weinhold 		   < 0.
104998da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
105098da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
105198da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
105298da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
105398da112cSIngo Weinhold 		   actually read.
105498da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
105598da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
105698da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
105798da112cSIngo Weinhold 	\return
105898da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
105998da112cSIngo Weinhold 	- error code
106098da112cSIngo Weinhold */
106198da112cSIngo Weinhold status_t
106298da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
106398da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
106498da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
106598da112cSIngo Weinhold {
106698da112cSIngo Weinhold 	status_t error = B_OK;
1067338b8dc3SIngo Weinhold 
106898da112cSIngo Weinhold 	if (allocatedBuffer)
106998da112cSIngo Weinhold 		buffer = NULL;
1070338b8dc3SIngo Weinhold 
1071338b8dc3SIngo Weinhold 	bool foundData = false;
1072338b8dc3SIngo Weinhold 
107398da112cSIngo Weinhold 	if (IsUsingAttributes()) {
107498da112cSIngo Weinhold 		// get an attribute info
107598da112cSIngo Weinhold 		attr_info info;
107698da112cSIngo Weinhold 		if (error == B_OK)
107798da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1078338b8dc3SIngo Weinhold 
107998da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
108098da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
108198da112cSIngo Weinhold 			error = B_BAD_VALUE;
1082b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
108398da112cSIngo Weinhold 			buffer = malloc(info.size);
108498da112cSIngo Weinhold 			if (!buffer)
108598da112cSIngo Weinhold 				error = B_NO_MEMORY;
108698da112cSIngo Weinhold 			bufferSize = info.size;
108798da112cSIngo Weinhold 		}
108898da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
108998da112cSIngo Weinhold 			error = B_BAD_VALUE;
1090338b8dc3SIngo Weinhold 
109198da112cSIngo Weinhold 		// read the data
109298da112cSIngo Weinhold 		if (error == B_OK) {
109398da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
109498da112cSIngo Weinhold 			if (read < 0)
109598da112cSIngo Weinhold 				error = read;
109698da112cSIngo Weinhold 			else if (read != info.size)
109798da112cSIngo Weinhold 				error = B_ERROR;
109898da112cSIngo Weinhold 			else
109998da112cSIngo Weinhold 				bytesRead = read;
110098da112cSIngo Weinhold 		}
1101338b8dc3SIngo Weinhold 
1102338b8dc3SIngo Weinhold 		foundData = (error == B_OK);
1103b4598d95SIngo Weinhold 
1104b4598d95SIngo Weinhold 		// free the allocated buffer on error
1105b4598d95SIngo Weinhold 		if (!foundData && allocatedBuffer && buffer) {
1106b4598d95SIngo Weinhold 			free(buffer);
1107b4598d95SIngo Weinhold 			buffer = NULL;
1108b4598d95SIngo Weinhold 		}
1109338b8dc3SIngo Weinhold 	}
1110338b8dc3SIngo Weinhold 
1111338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
111298da112cSIngo Weinhold 		// get a resource info
1113338b8dc3SIngo Weinhold 		error = B_OK;
111498da112cSIngo Weinhold 		int32 idFound;
111598da112cSIngo Weinhold 		size_t sizeFound;
111698da112cSIngo Weinhold 		if (error == B_OK) {
111798da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
111898da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
111998da112cSIngo Weinhold 		}
1120338b8dc3SIngo Weinhold 
112198da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
112298da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
112398da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1124b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
112598da112cSIngo Weinhold 			buffer = malloc(sizeFound);
112698da112cSIngo Weinhold 			if (!buffer)
112798da112cSIngo Weinhold 				error = B_NO_MEMORY;
112898da112cSIngo Weinhold 			bufferSize = sizeFound;
112998da112cSIngo Weinhold 		}
113098da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
113198da112cSIngo Weinhold 			error = B_BAD_VALUE;
1132338b8dc3SIngo Weinhold 
113398da112cSIngo Weinhold 		// load resource
113498da112cSIngo Weinhold 		const void *resourceData = NULL;
113598da112cSIngo Weinhold 		if (error == B_OK) {
113698da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
113798da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
113898da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
113998da112cSIngo Weinhold 			else
114098da112cSIngo Weinhold 				error = B_ERROR;
114198da112cSIngo Weinhold 		}
1142773be699SAxel Dörfler 	} else if (!foundData)
114398da112cSIngo Weinhold 		error = B_BAD_VALUE;
1144338b8dc3SIngo Weinhold 
114598da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
114698da112cSIngo Weinhold 	if (allocatedBuffer) {
114798da112cSIngo Weinhold 		if (error == B_OK)
114898da112cSIngo Weinhold 			*allocatedBuffer = buffer;
114998da112cSIngo Weinhold 		else
115098da112cSIngo Weinhold 			free(buffer);
115198da112cSIngo Weinhold 	}
1152338b8dc3SIngo Weinhold 
115398da112cSIngo Weinhold 	return error;
115498da112cSIngo Weinhold }
115598da112cSIngo Weinhold 
115698da112cSIngo Weinhold // _WriteData
115798da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
115898da112cSIngo Weinhold 
115998da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
116098da112cSIngo Weinhold 
116198da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
116298da112cSIngo Weinhold 
116398da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
116498da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
116598da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
116698da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
116798da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
116898da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
116998da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
117098da112cSIngo Weinhold 		   If \c false, \a id is used.
117198da112cSIngo Weinhold 	If \a id is already in use and .
117298da112cSIngo Weinhold 	\return
117398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
117498da112cSIngo Weinhold 	- error code
117598da112cSIngo Weinhold */
117698da112cSIngo Weinhold status_t
117798da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
117898da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
117998da112cSIngo Weinhold {
118098da112cSIngo Weinhold 	status_t error = B_OK;
118198da112cSIngo Weinhold 	// write to attribute
118298da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
118398da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
118498da112cSIngo Weinhold 		if (written < 0)
118598da112cSIngo Weinhold 			error = written;
118698da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
118798da112cSIngo Weinhold 			error = B_ERROR;
118898da112cSIngo Weinhold 	}
118998da112cSIngo Weinhold 	// write to resource
119098da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
119198da112cSIngo Weinhold 		if (findID) {
119298da112cSIngo Weinhold 			// get the resource info
119398da112cSIngo Weinhold 			int32 idFound;
119498da112cSIngo Weinhold 			size_t sizeFound;
119598da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
119698da112cSIngo Weinhold 				id = idFound;
119798da112cSIngo Weinhold 			else {
119898da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
119998da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
120098da112cSIngo Weinhold 					id++;
120198da112cSIngo Weinhold 			}
120298da112cSIngo Weinhold 		}
120398da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
120498da112cSIngo Weinhold 	}
120598da112cSIngo Weinhold 	return error;
120698da112cSIngo Weinhold }
120798da112cSIngo Weinhold 
120898da112cSIngo Weinhold // _RemoveData
120998da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
121098da112cSIngo Weinhold 
121198da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
121298da112cSIngo Weinhold 
121398da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
121498da112cSIngo Weinhold 
121598da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
121698da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
121798da112cSIngo Weinhold 	\return
121898da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
121998da112cSIngo Weinhold 	- error code
122098da112cSIngo Weinhold */
122198da112cSIngo Weinhold status_t
122298da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
122398da112cSIngo Weinhold {
122498da112cSIngo Weinhold 	status_t error = B_OK;
122598da112cSIngo Weinhold 	// remove the attribute
122698da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
122798da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
122898da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
122998da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
123098da112cSIngo Weinhold 			error = B_OK;
123198da112cSIngo Weinhold 	}
123298da112cSIngo Weinhold 	// remove the resource
123398da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
123498da112cSIngo Weinhold 		// get a resource info
123598da112cSIngo Weinhold 		int32 idFound;
123698da112cSIngo Weinhold 		size_t sizeFound;
123798da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
123898da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
123998da112cSIngo Weinhold 	}
124098da112cSIngo Weinhold 	return error;
124198da112cSIngo Weinhold }
124298da112cSIngo Weinhold 
1243