xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 82e7ef6709f5e5a6c88df15f66565244a106d6fc)
131dc79a1SAxel Dörfler /*
2d0c290bfSAxel Dörfler  * Copyright 2002-2007, Haiku Inc.
331dc79a1SAxel Dörfler  * Distributed under the terms of the MIT License.
431dc79a1SAxel Dörfler  *
531dc79a1SAxel Dörfler  * Authors:
631dc79a1SAxel Dörfler  *		Ingo Weinhold, bonefish@users.sf.net
721881ce5SIngo Weinhold  */
8d6b205f3SIngo Weinhold 
931dc79a1SAxel Dörfler 
1098da112cSIngo Weinhold #include <new>
1198da112cSIngo Weinhold #include <set>
1218cd67c7SMichael Lotz #include <stdlib.h>
1398da112cSIngo Weinhold #include <string>
1498da112cSIngo Weinhold 
15d6b205f3SIngo Weinhold #include <AppFileInfo.h>
1698da112cSIngo Weinhold #include <Bitmap.h>
1798da112cSIngo Weinhold #include <File.h>
1898da112cSIngo Weinhold #include <fs_attr.h>
199ecf9d1cSIngo Weinhold #include <IconUtils.h>
2098da112cSIngo Weinhold #include <MimeType.h>
2198da112cSIngo Weinhold #include <RegistrarDefs.h>
2298da112cSIngo Weinhold #include <Resources.h>
2398da112cSIngo Weinhold #include <Roster.h>
2498da112cSIngo Weinhold #include <String.h>
2598da112cSIngo Weinhold 
2650f17542Shaydentech using namespace std;
2750f17542Shaydentech 
2898da112cSIngo Weinhold // attributes
2998da112cSIngo Weinhold static const char *kTypeAttribute				= "BEOS:TYPE";
3098da112cSIngo Weinhold static const char *kSignatureAttribute			= "BEOS:APP_SIG";
3198da112cSIngo Weinhold static const char *kAppFlagsAttribute			= "BEOS:APP_FLAGS";
3298da112cSIngo Weinhold static const char *kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
3398da112cSIngo Weinhold static const char *kVersionInfoAttribute		= "BEOS:APP_VERSION";
3498da112cSIngo Weinhold static const char *kMiniIconAttribute			= "BEOS:M:";
3598da112cSIngo Weinhold static const char *kLargeIconAttribute			= "BEOS:L:";
369ecf9d1cSIngo Weinhold static const char *kIconAttribute				= "BEOS:";
3798da112cSIngo Weinhold static const char *kStandardIconType			= "STD_ICON";
389ecf9d1cSIngo Weinhold static const char *kIconType					= "ICON";
39*82e7ef67SJonas Sundström static const char *kCatalogEntryAttribute		= "SYS:NAME";
4098da112cSIngo Weinhold 
4198da112cSIngo Weinhold // resource IDs
4298da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
4398da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
4498da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
4598da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
4698da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
4798da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
487fb6186fSStephan Aßmus static const int32 kIconResourceID				= 101;
4998da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
5098da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
5198da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
527fb6186fSStephan Aßmus static const int32 kIconForTypeResourceID		= 0;
53*82e7ef67SJonas Sundström static const int32 kCatalogEntryResourceID		= 1;
5498da112cSIngo Weinhold 
5598da112cSIngo Weinhold // type codes
5698da112cSIngo Weinhold enum {
5798da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
5898da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
5998da112cSIngo Weinhold };
6098da112cSIngo Weinhold 
6188706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
6288706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
6388706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
6488706bbeSAxel Dörfler // Tracker when compiled for Haiku)
6588706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
6688706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
6788706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
6888706bbeSAxel Dörfler 
6978b31a7cSIngo Weinhold // debugging
7078b31a7cSIngo Weinhold //#define DBG(x) x
7178b31a7cSIngo Weinhold #define DBG(x)
7278b31a7cSIngo Weinhold #define OUT	printf
73d6b205f3SIngo Weinhold 
74d6b205f3SIngo Weinhold // constructor
75d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
76d6b205f3SIngo Weinhold */
77d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
78d6b205f3SIngo Weinhold 	: fResources(NULL),
79d6b205f3SIngo Weinhold 	fWhere(B_USE_BOTH_LOCATIONS)
80d6b205f3SIngo Weinhold {
81d6b205f3SIngo Weinhold }
82d6b205f3SIngo Weinhold 
83d6b205f3SIngo Weinhold // constructor
84d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
85d6b205f3SIngo Weinhold 		   file.
86d6b205f3SIngo Weinhold 
87d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
88d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
89d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
90d6b205f3SIngo Weinhold 
91d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
92d6b205f3SIngo Weinhold */
93d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
94d6b205f3SIngo Weinhold 	: fResources(NULL),
95d6b205f3SIngo Weinhold 	fWhere(B_USE_BOTH_LOCATIONS)
96d6b205f3SIngo Weinhold {
9798da112cSIngo Weinhold 	SetTo(file);
98d6b205f3SIngo Weinhold }
99d6b205f3SIngo Weinhold 
100d6b205f3SIngo Weinhold // destructor
101d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
102d6b205f3SIngo Weinhold 
103d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
104d6b205f3SIngo Weinhold */
105d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
106d6b205f3SIngo Weinhold {
10798da112cSIngo Weinhold 	delete fResources;
108d6b205f3SIngo Weinhold }
109d6b205f3SIngo Weinhold 
110d6b205f3SIngo Weinhold // SetTo
111d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
112d6b205f3SIngo Weinhold 
113d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
114d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
115d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
116d6b205f3SIngo Weinhold 
117d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
118d6b205f3SIngo Weinhold 
119d6b205f3SIngo Weinhold 	\return
120d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
121d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
122d6b205f3SIngo Weinhold */
123d6b205f3SIngo Weinhold status_t
124d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
125d6b205f3SIngo Weinhold {
12698da112cSIngo Weinhold 	// unset the old file
12798da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
12898da112cSIngo Weinhold 	if (fResources) {
12998da112cSIngo Weinhold 		delete fResources;
13098da112cSIngo Weinhold 		fResources = NULL;
13198da112cSIngo Weinhold 	}
132c2a2369dSAxel Dörfler 
13398da112cSIngo Weinhold 	// check param
13498da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
135c2a2369dSAxel Dörfler 
136c2a2369dSAxel Dörfler 	info_location where = B_USE_BOTH_LOCATIONS;
137c2a2369dSAxel Dörfler 
13898da112cSIngo Weinhold 	// create resources
13998da112cSIngo Weinhold 	if (error == B_OK) {
14098da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
141c2a2369dSAxel Dörfler 		if (fResources) {
14298da112cSIngo Weinhold 			error = fResources->SetTo(file);
143c2a2369dSAxel Dörfler 			if (error != B_OK) {
144c2a2369dSAxel Dörfler 				// no resources - this is no critical error, we'll just use
145c2a2369dSAxel Dörfler 				// attributes only, then
146c2a2369dSAxel Dörfler 				where = B_USE_ATTRIBUTES;
147c2a2369dSAxel Dörfler 				error = B_OK;
148c2a2369dSAxel Dörfler 			}
149c2a2369dSAxel Dörfler 		} else
15098da112cSIngo Weinhold 			error = B_NO_MEMORY;
15198da112cSIngo Weinhold 	}
152c2a2369dSAxel Dörfler 
15398da112cSIngo Weinhold 	// set node info
15498da112cSIngo Weinhold 	if (error == B_OK)
15598da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
156c2a2369dSAxel Dörfler 
157c2a2369dSAxel Dörfler 	if (error != B_OK || (where & B_USE_RESOURCES) == 0) {
15898da112cSIngo Weinhold 		delete fResources;
15998da112cSIngo Weinhold 		fResources = NULL;
16098da112cSIngo Weinhold 	}
161c2a2369dSAxel Dörfler 
162c2a2369dSAxel Dörfler 	// clean up on error
163c2a2369dSAxel Dörfler 	if (error != B_OK) {
16498da112cSIngo Weinhold 		if (InitCheck() == B_OK)
16598da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
16698da112cSIngo Weinhold 	}
167c2a2369dSAxel Dörfler 
16898da112cSIngo Weinhold 	// set data location
16998da112cSIngo Weinhold 	if (error == B_OK)
170c2a2369dSAxel Dörfler 		SetInfoLocation(where);
171c2a2369dSAxel Dörfler 
17298da112cSIngo Weinhold 	// set error
17398da112cSIngo Weinhold 	fCStatus = error;
17498da112cSIngo Weinhold 	return error;
175d6b205f3SIngo Weinhold }
176d6b205f3SIngo Weinhold 
177d6b205f3SIngo Weinhold // GetType
178d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
179d6b205f3SIngo Weinhold 
180d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
181d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
182d6b205f3SIngo Weinhold 		   file shall be written.
183d6b205f3SIngo Weinhold 	\return
184d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
185d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
186d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
187d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
188d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
189d6b205f3SIngo Weinhold 	  the wrong type.
190d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
191d6b205f3SIngo Weinhold 	- other error codes
192d6b205f3SIngo Weinhold */
193d6b205f3SIngo Weinhold status_t
194d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
195d6b205f3SIngo Weinhold {
19698da112cSIngo Weinhold 	// check param and initialization
19798da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
19898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
19998da112cSIngo Weinhold 		error = B_NO_INIT;
20098da112cSIngo Weinhold 	// read the data
20198da112cSIngo Weinhold 	size_t read = 0;
20298da112cSIngo Weinhold 	if (error == B_OK) {
20398da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
20498da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
20598da112cSIngo Weinhold 	}
20698da112cSIngo Weinhold 	// check the read data -- null terminate the string
20798da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
20898da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
20998da112cSIngo Weinhold 			error = B_ERROR;
21098da112cSIngo Weinhold 		else
21198da112cSIngo Weinhold 			type[read] = '\0';
21298da112cSIngo Weinhold 	}
21398da112cSIngo Weinhold 	return error;
214d6b205f3SIngo Weinhold }
215d6b205f3SIngo Weinhold 
216d6b205f3SIngo Weinhold // SetType
217d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
218d6b205f3SIngo Weinhold 
219d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
220d6b205f3SIngo Weinhold 
221d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
222d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
223d6b205f3SIngo Weinhold 		   May be \c NULL.
224d6b205f3SIngo Weinhold 	\return
225d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
226d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
227d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
228d6b205f3SIngo Weinhold 	- other error codes
229d6b205f3SIngo Weinhold */
230d6b205f3SIngo Weinhold status_t
231d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
232d6b205f3SIngo Weinhold {
23398da112cSIngo Weinhold 	// check initialization
23498da112cSIngo Weinhold 	status_t error = B_OK;
23598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
23698da112cSIngo Weinhold 		error = B_NO_INIT;
23798da112cSIngo Weinhold 	if (error == B_OK) {
23898da112cSIngo Weinhold 		if (type) {
23998da112cSIngo Weinhold 			// check param
24098da112cSIngo Weinhold 			size_t typeLen = strlen(type);
24198da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
24298da112cSIngo Weinhold 				error = B_BAD_VALUE;
24398da112cSIngo Weinhold 			// write the data
24498da112cSIngo Weinhold 			if (error == B_OK) {
24598da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
24698da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
24798da112cSIngo Weinhold 			}
24898da112cSIngo Weinhold 		} else
24998da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
25098da112cSIngo Weinhold 	}
25198da112cSIngo Weinhold 	return error;
252d6b205f3SIngo Weinhold }
253d6b205f3SIngo Weinhold 
254d6b205f3SIngo Weinhold // GetSignature
255d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
256d6b205f3SIngo Weinhold 
257d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
258d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
259d6b205f3SIngo Weinhold 		   signature of the file shall be written.
260d6b205f3SIngo Weinhold 	\return
261d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
262d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
263d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
264d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
265d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
266d6b205f3SIngo Weinhold 	  the wrong type.
267d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
268d6b205f3SIngo Weinhold 	- other error codes
269d6b205f3SIngo Weinhold */
270d6b205f3SIngo Weinhold status_t
271d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
272d6b205f3SIngo Weinhold {
27398da112cSIngo Weinhold 	// check param and initialization
27498da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
27598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
27698da112cSIngo Weinhold 		error = B_NO_INIT;
27798da112cSIngo Weinhold 	// read the data
27898da112cSIngo Weinhold 	size_t read = 0;
27998da112cSIngo Weinhold 	if (error == B_OK) {
28098da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
28198da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
28298da112cSIngo Weinhold 						  read);
28398da112cSIngo Weinhold 	}
28498da112cSIngo Weinhold 	// check the read data -- null terminate the string
28598da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
28698da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
28798da112cSIngo Weinhold 			error = B_ERROR;
28898da112cSIngo Weinhold 		else
28998da112cSIngo Weinhold 			signature[read] = '\0';
29098da112cSIngo Weinhold 	}
29198da112cSIngo Weinhold 	return error;
292d6b205f3SIngo Weinhold }
293d6b205f3SIngo Weinhold 
294d6b205f3SIngo Weinhold // SetSignature
295d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
296d6b205f3SIngo Weinhold 
297d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
298d6b205f3SIngo Weinhold 
299d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
300d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
301d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
302d6b205f3SIngo Weinhold 	\return
303d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
304d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
305d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
306d6b205f3SIngo Weinhold 	- other error codes
307d6b205f3SIngo Weinhold */
308d6b205f3SIngo Weinhold status_t
309d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
310d6b205f3SIngo Weinhold {
31198da112cSIngo Weinhold 	// check initialization
31298da112cSIngo Weinhold 	status_t error = B_OK;
31398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
31498da112cSIngo Weinhold 		error = B_NO_INIT;
31598da112cSIngo Weinhold 	if (error == B_OK) {
31698da112cSIngo Weinhold 		if (signature) {
31798da112cSIngo Weinhold 			// check param
31898da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
31998da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
32098da112cSIngo Weinhold 				error = B_BAD_VALUE;
32198da112cSIngo Weinhold 			// write the data
32298da112cSIngo Weinhold 			if (error == B_OK) {
32398da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
32498da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
32598da112cSIngo Weinhold 								   signatureLen + 1);
32698da112cSIngo Weinhold 			}
32798da112cSIngo Weinhold 		} else
32898da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
32998da112cSIngo Weinhold 	}
33098da112cSIngo Weinhold 	return error;
331d6b205f3SIngo Weinhold }
332d6b205f3SIngo Weinhold 
333*82e7ef67SJonas Sundström 
334*82e7ef67SJonas Sundström // GetCatalogEntry
335*82e7ef67SJonas Sundström /*!	\brief Gets the file's catalog entry. (localization)
336*82e7ef67SJonas Sundström 
337*82e7ef67SJonas Sundström 	\param catalogEntry A pointer to a pre-allocated character buffer of size
338*82e7ef67SJonas Sundström 		   \c B_MIME_TYPE_LENGTH * 3 or larger into which the catalog entry
339*82e7ef67SJonas Sundström 		   of the file shall be written.
340*82e7ef67SJonas Sundström 	\return
341*82e7ef67SJonas Sundström 	- \c B_OK: Everything went fine.
342*82e7ef67SJonas Sundström 	- \c B_NO_INIT: The object is not properly initialized.
343*82e7ef67SJonas Sundström 	- \c B_BAD_VALUE: \c NULL \a catalogEntry or the entry stored in the
344*82e7ef67SJonas Sundström 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH * 3.
345*82e7ef67SJonas Sundström 	- \c B_BAD_TYPE: The attribute/resources the entry is stored in have
346*82e7ef67SJonas Sundström 	  the wrong type.
347*82e7ef67SJonas Sundström 	- \c B_ENTRY_NOT_FOUND: No catalog entry is set on the file.
348*82e7ef67SJonas Sundström 	- other error codes
349*82e7ef67SJonas Sundström */
350*82e7ef67SJonas Sundström status_t
351*82e7ef67SJonas Sundström BAppFileInfo::GetCatalogEntry(char *catalogEntry) const
352*82e7ef67SJonas Sundström {
353*82e7ef67SJonas Sundström 	if (catalogEntry == NULL)
354*82e7ef67SJonas Sundström 		return B_BAD_VALUE;
355*82e7ef67SJonas Sundström 
356*82e7ef67SJonas Sundström 	if (InitCheck() != B_OK)
357*82e7ef67SJonas Sundström 		return B_NO_INIT;
358*82e7ef67SJonas Sundström 
359*82e7ef67SJonas Sundström 	size_t read = 0;
360*82e7ef67SJonas Sundström 	status_t error = _ReadData(kCatalogEntryAttribute, kCatalogEntryResourceID,
361*82e7ef67SJonas Sundström 		B_STRING_TYPE, catalogEntry, B_MIME_TYPE_LENGTH * 3, read);
362*82e7ef67SJonas Sundström 
363*82e7ef67SJonas Sundström 	if (error != B_OK)
364*82e7ef67SJonas Sundström 		return error;
365*82e7ef67SJonas Sundström 
366*82e7ef67SJonas Sundström 	if (read >= B_MIME_TYPE_LENGTH * 3)
367*82e7ef67SJonas Sundström 		return B_ERROR;
368*82e7ef67SJonas Sundström 
369*82e7ef67SJonas Sundström 	catalogEntry[read] = '\0';
370*82e7ef67SJonas Sundström 
371*82e7ef67SJonas Sundström 	return B_OK;
372*82e7ef67SJonas Sundström }
373*82e7ef67SJonas Sundström 
374*82e7ef67SJonas Sundström 
375*82e7ef67SJonas Sundström // SetCatalogEntry
376*82e7ef67SJonas Sundström /*!	\brief Sets the file's catalog entry. (localization)
377*82e7ef67SJonas Sundström 
378*82e7ef67SJonas Sundström 	If \a catalogEntry is \c NULL the file's catalog entry is unset.
379*82e7ef67SJonas Sundström 
380*82e7ef67SJonas Sundström 	\param catalogEntry The catalog entry to be assigned to the file.
381*82e7ef67SJonas Sundström 		Of the form "x-vnd.Haiku-app:context:name".
382*82e7ef67SJonas Sundström 		Must not be longer than \c B_MIME_TYPE_LENGTH * 3
383*82e7ef67SJonas Sundström 		(including the terminating null). May be \c NULL.
384*82e7ef67SJonas Sundström 	\return
385*82e7ef67SJonas Sundström 	- \c B_OK: Everything went fine.
386*82e7ef67SJonas Sundström 	- \c B_NO_INIT: The object is not properly initialized.
387*82e7ef67SJonas Sundström 	- \c B_BAD_VALUE: \a catalogEntry is longer than \c B_MIME_TYPE_LENGTH * 3.
388*82e7ef67SJonas Sundström 	- other error codes
389*82e7ef67SJonas Sundström */
390*82e7ef67SJonas Sundström status_t
391*82e7ef67SJonas Sundström BAppFileInfo::SetCatalogEntry(const char *catalogEntry)
392*82e7ef67SJonas Sundström {
393*82e7ef67SJonas Sundström 	if (InitCheck() != B_OK)
394*82e7ef67SJonas Sundström 		return B_NO_INIT;
395*82e7ef67SJonas Sundström 
396*82e7ef67SJonas Sundström 	if (catalogEntry == NULL)
397*82e7ef67SJonas Sundström 		return _RemoveData(kCatalogEntryAttribute, B_STRING_TYPE);
398*82e7ef67SJonas Sundström 
399*82e7ef67SJonas Sundström 	size_t nameLength = strlen(catalogEntry);
400*82e7ef67SJonas Sundström 	if (nameLength > B_MIME_TYPE_LENGTH * 3)
401*82e7ef67SJonas Sundström 		return B_BAD_VALUE;
402*82e7ef67SJonas Sundström 
403*82e7ef67SJonas Sundström 	return _WriteData(kCatalogEntryAttribute, kCatalogEntryResourceID,
404*82e7ef67SJonas Sundström 		B_STRING_TYPE, catalogEntry, nameLength + 1);
405*82e7ef67SJonas Sundström }
406*82e7ef67SJonas Sundström 
407*82e7ef67SJonas Sundström 
408d6b205f3SIngo Weinhold // GetAppFlags
409d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
410d6b205f3SIngo Weinhold 
411d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
412d6b205f3SIngo Weinhold 		   flags of the file shall be written.
413d6b205f3SIngo Weinhold 	\return
414d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
415d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
416d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
417d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
418d6b205f3SIngo Weinhold 	  the wrong type.
419d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
420d6b205f3SIngo Weinhold 	- other error codes
421d6b205f3SIngo Weinhold */
422d6b205f3SIngo Weinhold status_t
423d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
424d6b205f3SIngo Weinhold {
42598da112cSIngo Weinhold 	// check param and initialization
42698da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
42798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
42898da112cSIngo Weinhold 		error = B_NO_INIT;
42998da112cSIngo Weinhold 	// read the data
43098da112cSIngo Weinhold 	size_t read = 0;
43198da112cSIngo Weinhold 	if (error == B_OK) {
43298da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
43398da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
43498da112cSIngo Weinhold 						  read);
43598da112cSIngo Weinhold 	}
43698da112cSIngo Weinhold 	// check the read data
43798da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
43898da112cSIngo Weinhold 		error = B_ERROR;
43998da112cSIngo Weinhold 	return error;
440d6b205f3SIngo Weinhold }
441d6b205f3SIngo Weinhold 
442d6b205f3SIngo Weinhold // SetAppFlags
443d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
444d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
445d6b205f3SIngo Weinhold 	\return
446d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
447d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
448d6b205f3SIngo Weinhold 	- other error codes
449d6b205f3SIngo Weinhold */
450d6b205f3SIngo Weinhold status_t
451d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
452d6b205f3SIngo Weinhold {
45398da112cSIngo Weinhold 	// check initialization
45498da112cSIngo Weinhold 	status_t error = B_OK;
45598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
45698da112cSIngo Weinhold 		error = B_NO_INIT;
45798da112cSIngo Weinhold 	if (error == B_OK) {
45898da112cSIngo Weinhold 		// write the data
45998da112cSIngo Weinhold 		error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
46098da112cSIngo Weinhold 						   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
46198da112cSIngo Weinhold 	}
46222920adfSStephan Aßmus 	return error;
46322920adfSStephan Aßmus }
46422920adfSStephan Aßmus 
46522920adfSStephan Aßmus // RemoveAppFlags
46622920adfSStephan Aßmus /*!	\brief Removes the file's application flags.
46722920adfSStephan Aßmus 	\return
46822920adfSStephan Aßmus 	- \c B_OK: Everything went fine.
46922920adfSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
47022920adfSStephan Aßmus 	- other error codes
47122920adfSStephan Aßmus */
47222920adfSStephan Aßmus status_t
47322920adfSStephan Aßmus BAppFileInfo::RemoveAppFlags()
47422920adfSStephan Aßmus {
47522920adfSStephan Aßmus 	// check initialization
47622920adfSStephan Aßmus 	status_t error = B_OK;
47722920adfSStephan Aßmus 	if (error == B_OK && InitCheck() != B_OK)
47822920adfSStephan Aßmus 		error = B_NO_INIT;
47922920adfSStephan Aßmus 	if (error == B_OK) {
48022920adfSStephan Aßmus 		// remove the data
48122920adfSStephan Aßmus 		error = _RemoveData(kAppFlagsAttribute, B_APP_FLAGS_TYPE);
48298da112cSIngo Weinhold 	}
48398da112cSIngo Weinhold 	return error;
484d6b205f3SIngo Weinhold }
485d6b205f3SIngo Weinhold 
486d6b205f3SIngo Weinhold // GetSupportedTypes
487d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
488d6b205f3SIngo Weinhold 
489d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
490d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
491d6b205f3SIngo Weinhold 
492d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
493d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
494d6b205f3SIngo Weinhold 	\return
495d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
496d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
497d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
498d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
499d6b205f3SIngo Weinhold 	  have the wrong type.
500d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
501d6b205f3SIngo Weinhold 	- other error codes
502d6b205f3SIngo Weinhold */
503d6b205f3SIngo Weinhold status_t
504d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
505d6b205f3SIngo Weinhold {
50698da112cSIngo Weinhold 	// check param and initialization
50798da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
50898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
50998da112cSIngo Weinhold 		error = B_NO_INIT;
51098da112cSIngo Weinhold 	// read the data
51198da112cSIngo Weinhold 	size_t read = 0;
51298da112cSIngo Weinhold 	void *buffer = NULL;
51398da112cSIngo Weinhold 	if (error == B_OK) {
51498da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
51598da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
51698da112cSIngo Weinhold 	}
51798da112cSIngo Weinhold 	// unflatten the buffer
51898da112cSIngo Weinhold 	if (error == B_OK)
51998da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
52098da112cSIngo Weinhold 	// clean up
52198da112cSIngo Weinhold 	free(buffer);
52298da112cSIngo Weinhold 	return error;
523d6b205f3SIngo Weinhold }
524d6b205f3SIngo Weinhold 
525d6b205f3SIngo Weinhold // SetSupportedTypes
526d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
527d6b205f3SIngo Weinhold 
528d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
529d6b205f3SIngo Weinhold 
530d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
531d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
532d6b205f3SIngo Weinhold 
53383a812a1SIngo Weinhold 	The method informs the registrar about this news.
53483a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
53583a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
53683a812a1SIngo Weinhold 	application file needs to have a signature set.
53783a812a1SIngo Weinhold 
53883a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
53983a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
54083a812a1SIngo Weinhold 	lists of supporting applications.
54183a812a1SIngo Weinhold 
542d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
543d6b205f3SIngo Weinhold 		   May be \c NULL.
54483a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
54583a812a1SIngo Weinhold 		   types, \c false otherwise.
546d6b205f3SIngo Weinhold 	\return
547d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
548d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
549d6b205f3SIngo Weinhold 	- other error codes
550d6b205f3SIngo Weinhold */
551d6b205f3SIngo Weinhold status_t
552d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
553d6b205f3SIngo Weinhold {
55498da112cSIngo Weinhold 	// check initialization
55598da112cSIngo Weinhold 	status_t error = B_OK;
55698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
55798da112cSIngo Weinhold 		error = B_NO_INIT;
55898da112cSIngo Weinhold 	BMimeType mimeType;
55998da112cSIngo Weinhold 	if (error == B_OK)
56098da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
5617f20062dSJérôme Duval 	if (error == B_OK || error == B_ENTRY_NOT_FOUND) {
5627f20062dSJérôme Duval 		error = B_OK;
56398da112cSIngo Weinhold 		if (types) {
56417819be3SIngo Weinhold 			// check param -- supported types must be valid
56517819be3SIngo Weinhold 			const char *type;
56617819be3SIngo Weinhold 			for (int32 i = 0;
56717819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
56817819be3SIngo Weinhold 				 i++) {
56917819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
57017819be3SIngo Weinhold 					error = B_BAD_VALUE;
57117819be3SIngo Weinhold 			}
57217819be3SIngo Weinhold 			// get flattened size
57317819be3SIngo Weinhold 			ssize_t size = 0;
57417819be3SIngo Weinhold 			if (error == B_OK) {
57517819be3SIngo Weinhold 				size = types->FlattenedSize();
57698da112cSIngo Weinhold 				if (size < 0)
57798da112cSIngo Weinhold 					error = size;
57817819be3SIngo Weinhold 			}
57998da112cSIngo Weinhold 			// allocate a buffer for the flattened data
58098da112cSIngo Weinhold 			char *buffer = NULL;
58198da112cSIngo Weinhold 			if (error == B_OK) {
58298da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
58398da112cSIngo Weinhold 				if (!buffer)
58498da112cSIngo Weinhold 					error = B_NO_MEMORY;
58598da112cSIngo Weinhold 			}
58698da112cSIngo Weinhold 			// flatten the message
58798da112cSIngo Weinhold 			if (error == B_OK)
58898da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
58998da112cSIngo Weinhold 			// write the data
59098da112cSIngo Weinhold 			if (error == B_OK) {
59198da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
59298da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
59398da112cSIngo Weinhold 								   buffer, size);
59498da112cSIngo Weinhold 			}
59598da112cSIngo Weinhold 			// clean up
59698da112cSIngo Weinhold 			delete[] buffer;
59798da112cSIngo Weinhold 		} else
59898da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
59998da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
60017819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
60117819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
60298da112cSIngo Weinhold 	}
60398da112cSIngo Weinhold 	return error;
604d6b205f3SIngo Weinhold }
605d6b205f3SIngo Weinhold 
606d6b205f3SIngo Weinhold // SetSupportedTypes
607d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
608d6b205f3SIngo Weinhold 
60998da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
61083a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
611d6b205f3SIngo Weinhold 
612d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
613d6b205f3SIngo Weinhold 		   May be \c NULL.
614d6b205f3SIngo Weinhold 	\return
615d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
616d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
617d6b205f3SIngo Weinhold 	- other error codes
618d6b205f3SIngo Weinhold */
619d6b205f3SIngo Weinhold status_t
620d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
621d6b205f3SIngo Weinhold {
62298da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
623d6b205f3SIngo Weinhold }
624d6b205f3SIngo Weinhold 
625d6b205f3SIngo Weinhold // IsSupportedType
626d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
627d6b205f3SIngo Weinhold 
628d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
629d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
630d6b205f3SIngo Weinhold 
631d6b205f3SIngo Weinhold 	\param type The MIME type in question.
632d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
633d6b205f3SIngo Weinhold 			the application, \c false otherwise.
634d6b205f3SIngo Weinhold */
635d6b205f3SIngo Weinhold bool
636d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
637d6b205f3SIngo Weinhold {
63898da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
63998da112cSIngo Weinhold 	// get the supported types
64098da112cSIngo Weinhold 	BMessage types;
64198da112cSIngo Weinhold 	if (error == B_OK)
64298da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
64398da112cSIngo Weinhold 	// turn type into a BMimeType
64498da112cSIngo Weinhold 	BMimeType mimeType;
64598da112cSIngo Weinhold 	if (error == B_OK)
64698da112cSIngo Weinhold 		error = mimeType.SetTo(type);
64798da112cSIngo Weinhold 	// iterate through the supported types
64898da112cSIngo Weinhold 	bool found = false;
64998da112cSIngo Weinhold 	if (error == B_OK) {
65098da112cSIngo Weinhold 		const char *supportedType;
65198da112cSIngo Weinhold 		for (int32 i = 0;
65298da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
65398da112cSIngo Weinhold 			 i++) {
65498da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
65598da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
65698da112cSIngo Weinhold 		}
65798da112cSIngo Weinhold 	}
65898da112cSIngo Weinhold 	return found;
659d6b205f3SIngo Weinhold }
660d6b205f3SIngo Weinhold 
661d6b205f3SIngo Weinhold // Supports
662d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
663d6b205f3SIngo Weinhold 		   explicitly.
664d6b205f3SIngo Weinhold 
665d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
666d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
667d6b205f3SIngo Weinhold 	"application/octet-stream".
668d6b205f3SIngo Weinhold 
669d6b205f3SIngo Weinhold 	\param type The MIME type in question.
670d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
671d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
672d6b205f3SIngo Weinhold */
673d6b205f3SIngo Weinhold bool
674d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
675d6b205f3SIngo Weinhold {
67698da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
67798da112cSIngo Weinhold 	// get the supported types
67898da112cSIngo Weinhold 	BMessage types;
67998da112cSIngo Weinhold 	if (error == B_OK)
68098da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
68198da112cSIngo Weinhold 	// iterate through the supported types
68298da112cSIngo Weinhold 	bool found = false;
68398da112cSIngo Weinhold 	if (error == B_OK) {
68498da112cSIngo Weinhold 		const char *supportedType;
68598da112cSIngo Weinhold 		for (int32 i = 0;
68698da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
68798da112cSIngo Weinhold 			 i++) {
68898da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
68998da112cSIngo Weinhold 		}
69098da112cSIngo Weinhold 	}
69198da112cSIngo Weinhold 	return found;
692d6b205f3SIngo Weinhold }
693d6b205f3SIngo Weinhold 
694d6b205f3SIngo Weinhold // GetIcon
695d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
696d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
697d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
698d6b205f3SIngo Weinhold 		   large icon).
699d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
700d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
701d6b205f3SIngo Weinhold 	\return
702d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
703d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
704d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
705d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
706d6b205f3SIngo Weinhold 	- other error codes
707d6b205f3SIngo Weinhold */
708d6b205f3SIngo Weinhold status_t
709d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
710d6b205f3SIngo Weinhold {
71198da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
712d6b205f3SIngo Weinhold }
713d6b205f3SIngo Weinhold 
7147fb6186fSStephan Aßmus // GetIcon
7157fb6186fSStephan Aßmus /*!	\brief Gets the file's icon.
7167fb6186fSStephan Aßmus 	\param data The pointer in which the flat icon data will be returned.
7177fb6186fSStephan Aßmus 	\param size The pointer in which the size of the data found will be returned.
7187fb6186fSStephan Aßmus 	\return
7197fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
7207fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
7217fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: \c NULL \a data or \c NULL size.
7227fb6186fSStephan Aßmus 	- other error codes
7237fb6186fSStephan Aßmus */
7247fb6186fSStephan Aßmus status_t
7257fb6186fSStephan Aßmus BAppFileInfo::GetIcon(uint8** data, size_t* size) const
7267fb6186fSStephan Aßmus {
7277fb6186fSStephan Aßmus 	return GetIconForType(NULL, data, size);
7287fb6186fSStephan Aßmus }
7297fb6186fSStephan Aßmus 
730d6b205f3SIngo Weinhold // SetIcon
731d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
732d6b205f3SIngo Weinhold 
733d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
734d6b205f3SIngo Weinhold 
735d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
736d6b205f3SIngo Weinhold 		   May be \c NULL.
737d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
738d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
739d6b205f3SIngo Weinhold 	\return
740d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
741d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
742d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
743d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
744d6b205f3SIngo Weinhold 	- other error codes
745d6b205f3SIngo Weinhold */
746d6b205f3SIngo Weinhold status_t
747d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
748d6b205f3SIngo Weinhold {
74998da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
750d6b205f3SIngo Weinhold }
751d6b205f3SIngo Weinhold 
7527fb6186fSStephan Aßmus // SetIcon
7537fb6186fSStephan Aßmus /*!	\brief Sets the file's icon.
7547fb6186fSStephan Aßmus 
7557fb6186fSStephan Aßmus 	If \a icon is \c NULL the file's icon is unset.
7567fb6186fSStephan Aßmus 
7577fb6186fSStephan Aßmus 	\param data A pointer to the data buffer containing the vector icon
7587fb6186fSStephan Aßmus 		   to be set. May be \c NULL.
7597fb6186fSStephan Aßmus 	\param size Specifies the size of buffer pointed to by \a data.
7607fb6186fSStephan Aßmus 	\return
7617fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
7627fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
7637fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: \c NULL data.
7647fb6186fSStephan Aßmus 	- other error codes
7657fb6186fSStephan Aßmus */
7667fb6186fSStephan Aßmus status_t
7677fb6186fSStephan Aßmus BAppFileInfo::SetIcon(const uint8* data, size_t size)
7687fb6186fSStephan Aßmus {
7697fb6186fSStephan Aßmus 	return SetIconForType(NULL, data, size);
7707fb6186fSStephan Aßmus }
7717fb6186fSStephan Aßmus 
772d6b205f3SIngo Weinhold // GetVersionInfo
773d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
774d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
775d6b205f3SIngo Weinhold 		   the version info should be written.
776d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
777d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
778d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
779d6b205f3SIngo Weinhold 		   belongs to.
780d6b205f3SIngo Weinhold 	\return
781d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
782d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
783d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
784d6b205f3SIngo Weinhold 	- other error codes
785d6b205f3SIngo Weinhold */
786d6b205f3SIngo Weinhold status_t
787d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
788d6b205f3SIngo Weinhold {
78998da112cSIngo Weinhold 	// check params and initialization
790b1970bb8SIngo Weinhold 	if (!info)
791b1970bb8SIngo Weinhold 		return B_BAD_VALUE;
792b1970bb8SIngo Weinhold 
79398da112cSIngo Weinhold 	int32 index = 0;
79498da112cSIngo Weinhold 	switch (kind) {
79598da112cSIngo Weinhold 		case B_APP_VERSION_KIND:
79698da112cSIngo Weinhold 			index = 0;
79798da112cSIngo Weinhold 			break;
79898da112cSIngo Weinhold 		case B_SYSTEM_VERSION_KIND:
79998da112cSIngo Weinhold 			index = 1;
80098da112cSIngo Weinhold 			break;
80198da112cSIngo Weinhold 		default:
802b1970bb8SIngo Weinhold 			return B_BAD_VALUE;
80398da112cSIngo Weinhold 	}
804b1970bb8SIngo Weinhold 
805b1970bb8SIngo Weinhold 	if (InitCheck() != B_OK)
806b1970bb8SIngo Weinhold 		return B_NO_INIT;
807b1970bb8SIngo Weinhold 
80898da112cSIngo Weinhold 	// read the data
80998da112cSIngo Weinhold 	size_t read = 0;
81098da112cSIngo Weinhold 	version_info infos[2];
811b1970bb8SIngo Weinhold 	status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
812b1970bb8SIngo Weinhold 		B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read);
813b1970bb8SIngo Weinhold 	if (error != B_OK)
81498da112cSIngo Weinhold 		return error;
815b1970bb8SIngo Weinhold 
816b1970bb8SIngo Weinhold 	// check the read data
817b1970bb8SIngo Weinhold 	if (read == sizeof(version_info)) {
818b1970bb8SIngo Weinhold 		// only the app version info is there -- return a cleared system info
819b1970bb8SIngo Weinhold 		if (index == 0)
820b1970bb8SIngo Weinhold 			*info = infos[index];
821b1970bb8SIngo Weinhold 		else if (index == 1)
822b1970bb8SIngo Weinhold 			memset(info, 0, sizeof(version_info));
823b1970bb8SIngo Weinhold 	} else if (read == 2 * sizeof(version_info)) {
824b1970bb8SIngo Weinhold 		*info = infos[index];
825b1970bb8SIngo Weinhold 	} else
826b1970bb8SIngo Weinhold 		return B_ERROR;
827b1970bb8SIngo Weinhold 
828b1970bb8SIngo Weinhold 	// return result
829b1970bb8SIngo Weinhold 	return B_OK;
830d6b205f3SIngo Weinhold }
831d6b205f3SIngo Weinhold 
832d6b205f3SIngo Weinhold // SetVersionInfo
833d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
834d6b205f3SIngo Weinhold 
835d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
836d6b205f3SIngo Weinhold 
837d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
838d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
839d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
840d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
841d6b205f3SIngo Weinhold 		   belongs to.
842d6b205f3SIngo Weinhold 	\return
843d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
844d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
845d6b205f3SIngo Weinhold 	- other error codes
846d6b205f3SIngo Weinhold */
847d6b205f3SIngo Weinhold status_t
848d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
849d6b205f3SIngo Weinhold {
85098da112cSIngo Weinhold 	// check initialization
85198da112cSIngo Weinhold 	status_t error = B_OK;
85298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
85398da112cSIngo Weinhold 		error = B_NO_INIT;
85498da112cSIngo Weinhold 	if (error == B_OK) {
85598da112cSIngo Weinhold 		if (info) {
85698da112cSIngo Weinhold 			// check param
85798da112cSIngo Weinhold 			int32 index = 0;
85898da112cSIngo Weinhold 			if (error == B_OK) {
85998da112cSIngo Weinhold 				switch (kind) {
86098da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
86198da112cSIngo Weinhold 						index = 0;
86298da112cSIngo Weinhold 						break;
86398da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
86498da112cSIngo Weinhold 						index = 1;
86598da112cSIngo Weinhold 						break;
86698da112cSIngo Weinhold 					default:
86798da112cSIngo Weinhold 						error = B_BAD_VALUE;
86898da112cSIngo Weinhold 						break;
86998da112cSIngo Weinhold 				}
87098da112cSIngo Weinhold 			}
87198da112cSIngo Weinhold 			// read both infos
87298da112cSIngo Weinhold 			version_info infos[2];
87398da112cSIngo Weinhold 			if (error == B_OK) {
87498da112cSIngo Weinhold 				size_t read;
875b1970bb8SIngo Weinhold 				if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
876b1970bb8SIngo Weinhold 						B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info),
877b1970bb8SIngo Weinhold 						read) == B_OK) {
878b1970bb8SIngo Weinhold 					// clear the part that hasn't been read
879b1970bb8SIngo Weinhold 					if (read < sizeof(infos))
880b1970bb8SIngo Weinhold 						memset((char*)infos + read, 0, sizeof(infos) - read);
881b1970bb8SIngo Weinhold 				} else {
882b1970bb8SIngo Weinhold 					// failed to read -- clear
883b1970bb8SIngo Weinhold 					memset(infos, 0, sizeof(infos));
884b1970bb8SIngo Weinhold 				}
88598da112cSIngo Weinhold 			}
88698da112cSIngo Weinhold 			infos[index] = *info;
88798da112cSIngo Weinhold 			// write the data
88898da112cSIngo Weinhold 			if (error == B_OK) {
88998da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
89098da112cSIngo Weinhold 								   kVersionInfoResourceID,
89198da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
89298da112cSIngo Weinhold 								   2 * sizeof(version_info));
89398da112cSIngo Weinhold 			}
89498da112cSIngo Weinhold 		} else
89598da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
89698da112cSIngo Weinhold 	}
89798da112cSIngo Weinhold 	return error;
898d6b205f3SIngo Weinhold }
899d6b205f3SIngo Weinhold 
900d6b205f3SIngo Weinhold // GetIconForType
901d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
90298da112cSIngo Weinhold 
90398da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
90498da112cSIngo Weinhold 
90598da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
906d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
907d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
908d6b205f3SIngo Weinhold 		   large icon).
909d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
910d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
911d6b205f3SIngo Weinhold 	\return
912d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
913d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
91498da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
915d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
916d6b205f3SIngo Weinhold 		 not match.
917d6b205f3SIngo Weinhold 	- other error codes
918d6b205f3SIngo Weinhold */
919d6b205f3SIngo Weinhold status_t
920d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char* type, BBitmap* icon,
9219f507806SStephan Aßmus 							 icon_size size) const
922d6b205f3SIngo Weinhold {
9239ecf9d1cSIngo Weinhold 	if (InitCheck() != B_OK)
9249ecf9d1cSIngo Weinhold 		return B_NO_INIT;
9259ecf9d1cSIngo Weinhold 
9269ecf9d1cSIngo Weinhold 	if (!icon || icon->InitCheck() != B_OK)
9279ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
9289ecf9d1cSIngo Weinhold 
9292a74c553SStephan Aßmus 	// TODO: for consistency with attribute based icon reading, we
9302a74c553SStephan Aßmus 	// could also prefer B_CMAP8 icons here if the provided bitmap
9312a74c553SStephan Aßmus 	// is in that format. Right now, an existing B_CMAP8 icon resource
9322a74c553SStephan Aßmus 	// would be ignored as soon as a vector icon is present. On the other
9332a74c553SStephan Aßmus 	// hand, maybe this still results in a more consistent user interface,
9342a74c553SStephan Aßmus 	// since Tracker/Deskbar would surely show the vector icon.
9352a74c553SStephan Aßmus 
9369ecf9d1cSIngo Weinhold 	// try vector icon first
9379ecf9d1cSIngo Weinhold 	BString vectorAttributeName(kIconAttribute);
9389ecf9d1cSIngo Weinhold 
9399ecf9d1cSIngo Weinhold 	// check type param
9409ecf9d1cSIngo Weinhold 	if (type) {
9419ecf9d1cSIngo Weinhold 		if (BMimeType::IsValid(type))
9429ecf9d1cSIngo Weinhold 			vectorAttributeName += type;
9439ecf9d1cSIngo Weinhold 		else
9449ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
9459ecf9d1cSIngo Weinhold 	} else {
9469ecf9d1cSIngo Weinhold 		vectorAttributeName += kIconType;
9479ecf9d1cSIngo Weinhold 	}
9489ecf9d1cSIngo Weinhold 	const char* attribute = vectorAttributeName.String();
9499ecf9d1cSIngo Weinhold 
9509ecf9d1cSIngo Weinhold 	size_t bytesRead;
9519ecf9d1cSIngo Weinhold 	void* allocatedBuffer;
952bae87c91SAxel Dörfler 	status_t error = _ReadData(attribute, -1, B_VECTOR_ICON_TYPE, NULL, 0,
9539ecf9d1cSIngo Weinhold 							   bytesRead, &allocatedBuffer);
9549ecf9d1cSIngo Weinhold 	if (error == B_OK) {
9557fb6186fSStephan Aßmus 		error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer,
9569ecf9d1cSIngo Weinhold 										  bytesRead, icon);
9577fb6186fSStephan Aßmus 		free(allocatedBuffer);
9587fb6186fSStephan Aßmus 		return error;
9599ecf9d1cSIngo Weinhold 	}
9609ecf9d1cSIngo Weinhold 
9619f507806SStephan Aßmus 	// no vector icon if we got this far,
9629f507806SStephan Aßmus 	// align size argument just in case
9639f507806SStephan Aßmus 	if (size < B_LARGE_ICON)
9649f507806SStephan Aßmus 		size = B_MINI_ICON;
9659f507806SStephan Aßmus 	else
9669f507806SStephan Aßmus 		size = B_LARGE_ICON;
9679ecf9d1cSIngo Weinhold 
9689ecf9d1cSIngo Weinhold 	error = B_OK;
96998da112cSIngo Weinhold 	// set some icon size related variables
97098da112cSIngo Weinhold 	BString attributeString;
97198da112cSIngo Weinhold 	BRect bounds;
972a04efc92SIngo Weinhold 	uint32 attrType = 0;
973a04efc92SIngo Weinhold 	size_t attrSize = 0;
9749f507806SStephan Aßmus 	switch (size) {
97598da112cSIngo Weinhold 		case B_MINI_ICON:
97698da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
97798da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
97898da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
97998da112cSIngo Weinhold 			attrSize = 16 * 16;
98098da112cSIngo Weinhold 			break;
98198da112cSIngo Weinhold 		case B_LARGE_ICON:
98298da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
98398da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
98498da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
98598da112cSIngo Weinhold 			attrSize = 32 * 32;
98698da112cSIngo Weinhold 			break;
98798da112cSIngo Weinhold 		default:
9889ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
98998da112cSIngo Weinhold 	}
99098da112cSIngo Weinhold 	// check type param
99198da112cSIngo Weinhold 	if (type) {
99217819be3SIngo Weinhold 		if (BMimeType::IsValid(type))
99317819be3SIngo Weinhold 			attributeString += type;
99417819be3SIngo Weinhold 		else
9959ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
99698da112cSIngo Weinhold 	} else
99717819be3SIngo Weinhold 		attributeString += kStandardIconType;
9989ecf9d1cSIngo Weinhold 
9999ecf9d1cSIngo Weinhold 	attribute = attributeString.String();
100017819be3SIngo Weinhold 
10019f507806SStephan Aßmus 	// check parameters
10029f507806SStephan Aßmus 	// currently, scaling B_CMAP8 icons is not supported
10039f507806SStephan Aßmus 	if (icon->ColorSpace() == B_CMAP8 && icon->Bounds() != bounds)
10049ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
10059ecf9d1cSIngo Weinhold 
100698da112cSIngo Weinhold 	// read the data
100798da112cSIngo Weinhold 	if (error == B_OK) {
10089f507806SStephan Aßmus 		bool tempBuffer = (icon->ColorSpace() != B_CMAP8
10099f507806SStephan Aßmus 						   || icon->Bounds() != bounds);
10109f507806SStephan Aßmus 		uint8* buffer = NULL;
101198da112cSIngo Weinhold 		size_t read;
10129f507806SStephan Aßmus 		if (tempBuffer) {
10139f507806SStephan Aßmus 			// other color space or bitmap size than stored in attribute
10149f507806SStephan Aßmus 			buffer = new(nothrow) uint8[attrSize];
10159f507806SStephan Aßmus 			if (!buffer) {
101698da112cSIngo Weinhold 				error = B_NO_MEMORY;
10179f507806SStephan Aßmus 			} else {
101898da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
101998da112cSIngo Weinhold 								  read);
102098da112cSIngo Weinhold 			}
102198da112cSIngo Weinhold 		} else {
102298da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
102398da112cSIngo Weinhold 							  read);
102498da112cSIngo Weinhold 		}
102598da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
102698da112cSIngo Weinhold 			error = B_ERROR;
10279f507806SStephan Aßmus 		if (tempBuffer) {
102898da112cSIngo Weinhold 			// other color space than stored in attribute
102976ba3434SIngo Weinhold 			if (error == B_OK) {
10309f507806SStephan Aßmus 				error = BIconUtils::ConvertFromCMAP8(buffer,
10319f507806SStephan Aßmus 													 (uint32)size,
10329f507806SStephan Aßmus 													 (uint32)size,
10339f507806SStephan Aßmus 													 (uint32)size,
10349f507806SStephan Aßmus 													 icon);
103576ba3434SIngo Weinhold 			}
103698da112cSIngo Weinhold 			delete[] buffer;
103798da112cSIngo Weinhold 		}
103898da112cSIngo Weinhold 	}
103998da112cSIngo Weinhold 	return error;
1040d6b205f3SIngo Weinhold }
1041d6b205f3SIngo Weinhold 
10427fb6186fSStephan Aßmus // GetIconForType
10437fb6186fSStephan Aßmus /*!	\brief Gets the icon the application provides for a given MIME type.
10447fb6186fSStephan Aßmus 
10457fb6186fSStephan Aßmus 	If \a type is \c NULL, the application's icon is retrieved.
10467fb6186fSStephan Aßmus 
10477fb6186fSStephan Aßmus 	\param type The MIME type in question. May be \c NULL.
10487fb6186fSStephan Aßmus 	\param data A pointer in which the icon data will be returned. When you
10497fb6186fSStephan Aßmus 	are done with the data, you should use free() to deallocate it.
10507fb6186fSStephan Aßmus 	\param size A pointer in which the size of the retrieved data is returned.
10517fb6186fSStephan Aßmus 	\return
10527fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
10537fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
10547fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: \c NULL \a data and/or \a size. Or the supplied
10557fb6186fSStephan Aßmus 	\a type is not a valid MIME type.
10567fb6186fSStephan Aßmus 	- other error codes
10577fb6186fSStephan Aßmus */
10587fb6186fSStephan Aßmus status_t
10597fb6186fSStephan Aßmus BAppFileInfo::GetIconForType(const char *type, uint8** data,
10607fb6186fSStephan Aßmus 							 size_t* size) const
10617fb6186fSStephan Aßmus {
10627fb6186fSStephan Aßmus 	if (InitCheck() != B_OK)
10637fb6186fSStephan Aßmus 		return B_NO_INIT;
10647fb6186fSStephan Aßmus 
10657fb6186fSStephan Aßmus 	if (!data || !size)
10667fb6186fSStephan Aßmus 		return B_BAD_VALUE;
10677fb6186fSStephan Aßmus 
10687fb6186fSStephan Aßmus 	// get vector icon
10697fb6186fSStephan Aßmus 	BString attributeName(kIconAttribute);
10707fb6186fSStephan Aßmus 
10717fb6186fSStephan Aßmus 	// check type param
10727fb6186fSStephan Aßmus 	if (type) {
10737fb6186fSStephan Aßmus 		if (BMimeType::IsValid(type))
10747fb6186fSStephan Aßmus 			attributeName += type;
10757fb6186fSStephan Aßmus 		else
10767fb6186fSStephan Aßmus 			return B_BAD_VALUE;
10777fb6186fSStephan Aßmus 	} else {
10787fb6186fSStephan Aßmus 		attributeName += kIconType;
10797fb6186fSStephan Aßmus 	}
10807fb6186fSStephan Aßmus 
10817fb6186fSStephan Aßmus 	void* allocatedBuffer = NULL;
10827fb6186fSStephan Aßmus 	status_t ret = _ReadData(attributeName.String(), -1,
1083bae87c91SAxel Dörfler 							 B_VECTOR_ICON_TYPE, NULL, 0, *size, &allocatedBuffer);
10847fb6186fSStephan Aßmus 
10857fb6186fSStephan Aßmus 	if (ret < B_OK)
10867fb6186fSStephan Aßmus 		return ret;
10877fb6186fSStephan Aßmus 
10887fb6186fSStephan Aßmus 	*data = (uint8*)allocatedBuffer;
10897fb6186fSStephan Aßmus 	return B_OK;
10907fb6186fSStephan Aßmus }
10917fb6186fSStephan Aßmus 
1092d6b205f3SIngo Weinhold // SetIconForType
1093d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
1094d6b205f3SIngo Weinhold 
109598da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
1096d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
1097d6b205f3SIngo Weinhold 
109898da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
109998da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
110098da112cSIngo Weinhold 	before.
110198da112cSIngo Weinhold 
110298da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
1103d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
1104d6b205f3SIngo Weinhold 		   May be \c NULL.
1105d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
1106d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
1107d6b205f3SIngo Weinhold 	\return
1108d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
1109d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
11107fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: Either the icon size \a which is unkown, bitmap dimensions (\a icon)
11117fb6186fSStephan Aßmus 		 and icon size (\a which) do not match, or the provided \a type is
11127fb6186fSStephan Aßmus 		 not a valid MIME type.
1113d6b205f3SIngo Weinhold 	- other error codes
1114d6b205f3SIngo Weinhold */
1115d6b205f3SIngo Weinhold status_t
1116d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
1117d6b205f3SIngo Weinhold 							 icon_size which)
1118d6b205f3SIngo Weinhold {
111998da112cSIngo Weinhold 	status_t error = B_OK;
112098da112cSIngo Weinhold 	// set some icon size related variables
112198da112cSIngo Weinhold 	BString attributeString;
112298da112cSIngo Weinhold 	BRect bounds;
1123a04efc92SIngo Weinhold 	uint32 attrType = 0;
1124a04efc92SIngo Weinhold 	size_t attrSize = 0;
1125a04efc92SIngo Weinhold 	int32 resourceID = 0;
112698da112cSIngo Weinhold 	switch (which) {
112798da112cSIngo Weinhold 		case B_MINI_ICON:
112898da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
112998da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
113098da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
113198da112cSIngo Weinhold 			attrSize = 16 * 16;
113298da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
113398da112cSIngo Weinhold 							   : kMiniIconResourceID);
113498da112cSIngo Weinhold 			break;
113598da112cSIngo Weinhold 		case B_LARGE_ICON:
113698da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
113798da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
113898da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
113998da112cSIngo Weinhold 			attrSize = 32 * 32;
114098da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
114198da112cSIngo Weinhold 							   : kLargeIconResourceID);
114298da112cSIngo Weinhold 			break;
114398da112cSIngo Weinhold 		default:
114498da112cSIngo Weinhold 			error = B_BAD_VALUE;
114598da112cSIngo Weinhold 			break;
114698da112cSIngo Weinhold 	}
114798da112cSIngo Weinhold 	// check type param
114898da112cSIngo Weinhold 	if (error == B_OK) {
114998da112cSIngo Weinhold 		if (type) {
115017819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
115198da112cSIngo Weinhold 				attributeString += type;
115217819be3SIngo Weinhold 			else
115317819be3SIngo Weinhold 				error = B_BAD_VALUE;
115498da112cSIngo Weinhold 		} else
115598da112cSIngo Weinhold 			attributeString += kStandardIconType;
115698da112cSIngo Weinhold 	}
115798da112cSIngo Weinhold 	const char *attribute = attributeString.String();
115898da112cSIngo Weinhold 	// check parameter and initialization
115998da112cSIngo Weinhold 	if (error == B_OK && icon
116098da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
116198da112cSIngo Weinhold 		error = B_BAD_VALUE;
116298da112cSIngo Weinhold 	}
116398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
116498da112cSIngo Weinhold 		error = B_NO_INIT;
116598da112cSIngo Weinhold 	// write/remove the attribute
116698da112cSIngo Weinhold 	if (error == B_OK) {
116798da112cSIngo Weinhold 		if (icon) {
116898da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
116998da112cSIngo Weinhold 			if (otherColorSpace) {
1170290bc091SIngo Weinhold 				BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8);
117198da112cSIngo Weinhold 				error = bitmap.InitCheck();
117276ba3434SIngo Weinhold 				if (error == B_OK)
117376ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
117498da112cSIngo Weinhold 				if (error == B_OK) {
117598da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
117698da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
117798da112cSIngo Weinhold 				}
117898da112cSIngo Weinhold 			} else {
117998da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
118098da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
118198da112cSIngo Weinhold 			}
118298da112cSIngo Weinhold 		} else	// no icon given => remove
118398da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
118498da112cSIngo Weinhold 	}
118598da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
118698da112cSIngo Weinhold 	BMimeType mimeType;
118798da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
118898da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
118998da112cSIngo Weinhold 			error = mimeType.Install();
119098da112cSIngo Weinhold 		if (error == B_OK)
119198da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
119298da112cSIngo Weinhold 	}
119398da112cSIngo Weinhold 	return error;
1194d6b205f3SIngo Weinhold }
1195d6b205f3SIngo Weinhold 
11967fb6186fSStephan Aßmus // SetIconForType
11977fb6186fSStephan Aßmus /*!	\brief Sets the icon the application provides for a given MIME type.
11987fb6186fSStephan Aßmus 
11997fb6186fSStephan Aßmus 	If \a type is \c NULL, the application's icon is set.
12007fb6186fSStephan Aßmus 	If \a data is \c NULL the icon is unset.
12017fb6186fSStephan Aßmus 
12027fb6186fSStephan Aßmus 	If the file has a signature, then the icon is also set on the MIME type.
12037fb6186fSStephan Aßmus 	If the type for the signature has not been installed yet, it is installed
12047fb6186fSStephan Aßmus 	before.
12057fb6186fSStephan Aßmus 
12067fb6186fSStephan Aßmus 	\param type The MIME type in question. May be \c NULL.
12077fb6186fSStephan Aßmus 	\param data A pointer to the data containing the icon to be set.
12087fb6186fSStephan Aßmus 		   May be \c NULL.
12097fb6186fSStephan Aßmus 	\param size Specifies the size of buffer provided in \a data.
12107fb6186fSStephan Aßmus 	\return
12117fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
12127fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
12137fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: The provided \a type is not a valid MIME type.
12147fb6186fSStephan Aßmus 	- other error codes
12157fb6186fSStephan Aßmus */
12167fb6186fSStephan Aßmus status_t
12177fb6186fSStephan Aßmus BAppFileInfo::SetIconForType(const char* type, const uint8* data,
12187fb6186fSStephan Aßmus 							 size_t size)
12197fb6186fSStephan Aßmus {
12207fb6186fSStephan Aßmus 	if (InitCheck() != B_OK)
12217fb6186fSStephan Aßmus 		return B_NO_INIT;
12227fb6186fSStephan Aßmus 
12237fb6186fSStephan Aßmus 	// set some icon related variables
12247fb6186fSStephan Aßmus 	BString attributeString = kIconAttribute;
12257fb6186fSStephan Aßmus 	int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID;
1226bae87c91SAxel Dörfler 	uint32 attrType = B_VECTOR_ICON_TYPE;
12277fb6186fSStephan Aßmus 
12287fb6186fSStephan Aßmus 	// check type param
12297fb6186fSStephan Aßmus 	if (type) {
12307fb6186fSStephan Aßmus 		if (BMimeType::IsValid(type))
12317fb6186fSStephan Aßmus 			attributeString += type;
12327fb6186fSStephan Aßmus 		else
12337fb6186fSStephan Aßmus 			return B_BAD_VALUE;
12347fb6186fSStephan Aßmus 	} else
12357fb6186fSStephan Aßmus 		attributeString += kIconType;
12367fb6186fSStephan Aßmus 
12377fb6186fSStephan Aßmus 	const char *attribute = attributeString.String();
12387fb6186fSStephan Aßmus 
12397fb6186fSStephan Aßmus 	status_t error;
12407fb6186fSStephan Aßmus 	// write/remove the attribute
12417fb6186fSStephan Aßmus 	if (data)
12427fb6186fSStephan Aßmus 		error = _WriteData(attribute, resourceID, attrType, data, size, true);
12437fb6186fSStephan Aßmus 	else	// no icon given => remove
12447fb6186fSStephan Aßmus 		error = _RemoveData(attribute, attrType);
12457fb6186fSStephan Aßmus 
12467fb6186fSStephan Aßmus 	// set the attribute on the MIME type, if the file has a signature
12477fb6186fSStephan Aßmus 	BMimeType mimeType;
12487fb6186fSStephan Aßmus 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
12497fb6186fSStephan Aßmus 		if (!mimeType.IsInstalled())
12507fb6186fSStephan Aßmus 			error = mimeType.Install();
12517fb6186fSStephan Aßmus 		if (error == B_OK)
12527fb6186fSStephan Aßmus 			error = mimeType.SetIconForType(type, data, size);
12537fb6186fSStephan Aßmus 	}
12547fb6186fSStephan Aßmus 	return error;
12557fb6186fSStephan Aßmus }
12567fb6186fSStephan Aßmus 
1257d6b205f3SIngo Weinhold // SetInfoLocation
1258d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
1259d6b205f3SIngo Weinhold 
1260d6b205f3SIngo Weinhold 	The options for \a location are:
1261d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
1262d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
1263d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
1264d6b205f3SIngo Weinhold 
1265d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
1266d6b205f3SIngo Weinhold */
1267d6b205f3SIngo Weinhold void
1268d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
1269d6b205f3SIngo Weinhold {
1270d0c290bfSAxel Dörfler 	// if the resources failed to initialize, we must not use them
1271d0c290bfSAxel Dörfler 	if (fResources == NULL)
1272d0c290bfSAxel Dörfler 		location = info_location(location & ~B_USE_RESOURCES);
1273d0c290bfSAxel Dörfler 
127498da112cSIngo Weinhold 	fWhere = location;
1275d6b205f3SIngo Weinhold }
1276d6b205f3SIngo Weinhold 
1277d6b205f3SIngo Weinhold // IsUsingAttributes
1278d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
1279d6b205f3SIngo Weinhold 		   file's attributes.
1280d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
1281d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
1282d6b205f3SIngo Weinhold */
1283d6b205f3SIngo Weinhold bool
1284d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
1285d6b205f3SIngo Weinhold {
1286d0c290bfSAxel Dörfler 	return (fWhere & B_USE_ATTRIBUTES) != 0;
1287d6b205f3SIngo Weinhold }
1288d6b205f3SIngo Weinhold 
1289d6b205f3SIngo Weinhold // IsUsingResources
1290d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
1291d6b205f3SIngo Weinhold 		   file's resources.
1292d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
1293d6b205f3SIngo Weinhold 			resources, \c false otherwise.
1294d6b205f3SIngo Weinhold */
1295d6b205f3SIngo Weinhold bool
1296d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
1297d6b205f3SIngo Weinhold {
1298d0c290bfSAxel Dörfler 	return (fWhere & B_USE_RESOURCES) != 0;
1299d6b205f3SIngo Weinhold }
1300d6b205f3SIngo Weinhold 
1301d6b205f3SIngo Weinhold // FBC
1302d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
1303d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
1304d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
1305d6b205f3SIngo Weinhold 
1306d6b205f3SIngo Weinhold // =
1307d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
1308d6b205f3SIngo Weinhold */
1309d6b205f3SIngo Weinhold BAppFileInfo &
1310d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
1311d6b205f3SIngo Weinhold {
1312d6b205f3SIngo Weinhold 	return *this;
1313d6b205f3SIngo Weinhold }
1314d6b205f3SIngo Weinhold 
1315d6b205f3SIngo Weinhold // copy constructor
1316d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1317d6b205f3SIngo Weinhold */
1318d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
1319d6b205f3SIngo Weinhold {
1320d6b205f3SIngo Weinhold }
1321d6b205f3SIngo Weinhold 
132298da112cSIngo Weinhold // GetMetaMime
132398da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
132498da112cSIngo Weinhold 
132598da112cSIngo Weinhold 	The parameter \a meta is not checked.
132698da112cSIngo Weinhold 
132798da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
132898da112cSIngo Weinhold 		   initialized to the file's signature.
132998da112cSIngo Weinhold 	\return
133098da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
133198da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
133298da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
133398da112cSIngo Weinhold (	  not installed in the MIME database.)
133498da112cSIngo Weinhold 	  no valid MIME string.
133598da112cSIngo Weinhold 	- other error codes
133698da112cSIngo Weinhold */
133798da112cSIngo Weinhold status_t
133898da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
133998da112cSIngo Weinhold {
134098da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
134198da112cSIngo Weinhold 	status_t error = GetSignature(signature);
134298da112cSIngo Weinhold 	if (error == B_OK)
134398da112cSIngo Weinhold 		error = meta->SetTo(signature);
13447f20062dSJérôme Duval 	else if (error == B_BAD_VALUE)
13457f20062dSJérôme Duval 		error = B_ENTRY_NOT_FOUND;
134698da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
134798da112cSIngo Weinhold 		error = B_BAD_VALUE;
134898da112cSIngo Weinhold 	return error;
134998da112cSIngo Weinhold }
135098da112cSIngo Weinhold 
135198da112cSIngo Weinhold // _ReadData
135298da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
135398da112cSIngo Weinhold 
135498da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
135598da112cSIngo Weinhold 
135698da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
135798da112cSIngo Weinhold 
135898da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
135998da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
136098da112cSIngo Weinhold 		   < 0.
136198da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
136298da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
136398da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
136498da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
136598da112cSIngo Weinhold 		   actually read.
136698da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
136798da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
136898da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
136998da112cSIngo Weinhold 	\return
137098da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
137198da112cSIngo Weinhold 	- error code
137298da112cSIngo Weinhold */
137398da112cSIngo Weinhold status_t
137498da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
137598da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
137698da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
137798da112cSIngo Weinhold {
137898da112cSIngo Weinhold 	status_t error = B_OK;
1379338b8dc3SIngo Weinhold 
138098da112cSIngo Weinhold 	if (allocatedBuffer)
138198da112cSIngo Weinhold 		buffer = NULL;
1382338b8dc3SIngo Weinhold 
1383338b8dc3SIngo Weinhold 	bool foundData = false;
1384338b8dc3SIngo Weinhold 
138598da112cSIngo Weinhold 	if (IsUsingAttributes()) {
138698da112cSIngo Weinhold 		// get an attribute info
138798da112cSIngo Weinhold 		attr_info info;
138898da112cSIngo Weinhold 		if (error == B_OK)
138998da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1390338b8dc3SIngo Weinhold 
139198da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
139298da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
139398da112cSIngo Weinhold 			error = B_BAD_VALUE;
1394b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
139598da112cSIngo Weinhold 			buffer = malloc(info.size);
139698da112cSIngo Weinhold 			if (!buffer)
139798da112cSIngo Weinhold 				error = B_NO_MEMORY;
139898da112cSIngo Weinhold 			bufferSize = info.size;
139998da112cSIngo Weinhold 		}
140098da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
140198da112cSIngo Weinhold 			error = B_BAD_VALUE;
1402338b8dc3SIngo Weinhold 
140398da112cSIngo Weinhold 		// read the data
140498da112cSIngo Weinhold 		if (error == B_OK) {
140598da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
140698da112cSIngo Weinhold 			if (read < 0)
140798da112cSIngo Weinhold 				error = read;
140898da112cSIngo Weinhold 			else if (read != info.size)
140998da112cSIngo Weinhold 				error = B_ERROR;
141098da112cSIngo Weinhold 			else
141198da112cSIngo Weinhold 				bytesRead = read;
141298da112cSIngo Weinhold 		}
1413338b8dc3SIngo Weinhold 
1414338b8dc3SIngo Weinhold 		foundData = (error == B_OK);
1415b4598d95SIngo Weinhold 
1416b4598d95SIngo Weinhold 		// free the allocated buffer on error
1417b4598d95SIngo Weinhold 		if (!foundData && allocatedBuffer && buffer) {
1418b4598d95SIngo Weinhold 			free(buffer);
1419b4598d95SIngo Weinhold 			buffer = NULL;
1420b4598d95SIngo Weinhold 		}
1421338b8dc3SIngo Weinhold 	}
1422338b8dc3SIngo Weinhold 
1423338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
142498da112cSIngo Weinhold 		// get a resource info
1425338b8dc3SIngo Weinhold 		error = B_OK;
142698da112cSIngo Weinhold 		int32 idFound;
142798da112cSIngo Weinhold 		size_t sizeFound;
142898da112cSIngo Weinhold 		if (error == B_OK) {
142998da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
143098da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
143198da112cSIngo Weinhold 		}
1432338b8dc3SIngo Weinhold 
143398da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
143498da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
143598da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1436b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
143798da112cSIngo Weinhold 			buffer = malloc(sizeFound);
143898da112cSIngo Weinhold 			if (!buffer)
143998da112cSIngo Weinhold 				error = B_NO_MEMORY;
144098da112cSIngo Weinhold 			bufferSize = sizeFound;
144198da112cSIngo Weinhold 		}
144298da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
144398da112cSIngo Weinhold 			error = B_BAD_VALUE;
1444338b8dc3SIngo Weinhold 
144598da112cSIngo Weinhold 		// load resource
144698da112cSIngo Weinhold 		const void *resourceData = NULL;
144798da112cSIngo Weinhold 		if (error == B_OK) {
144898da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
144998da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
145098da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
145198da112cSIngo Weinhold 			else
145298da112cSIngo Weinhold 				error = B_ERROR;
145398da112cSIngo Weinhold 		}
1454773be699SAxel Dörfler 	} else if (!foundData)
145598da112cSIngo Weinhold 		error = B_BAD_VALUE;
1456338b8dc3SIngo Weinhold 
145798da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
145898da112cSIngo Weinhold 	if (allocatedBuffer) {
145998da112cSIngo Weinhold 		if (error == B_OK)
146098da112cSIngo Weinhold 			*allocatedBuffer = buffer;
146198da112cSIngo Weinhold 		else
146298da112cSIngo Weinhold 			free(buffer);
146398da112cSIngo Weinhold 	}
1464338b8dc3SIngo Weinhold 
146598da112cSIngo Weinhold 	return error;
146698da112cSIngo Weinhold }
146798da112cSIngo Weinhold 
146898da112cSIngo Weinhold // _WriteData
146998da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
147098da112cSIngo Weinhold 
147198da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
147298da112cSIngo Weinhold 
147398da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
147498da112cSIngo Weinhold 
147598da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
147698da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
147798da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
147898da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
147998da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
148098da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
148198da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
148298da112cSIngo Weinhold 		   If \c false, \a id is used.
148398da112cSIngo Weinhold 	If \a id is already in use and .
148498da112cSIngo Weinhold 	\return
148598da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
148698da112cSIngo Weinhold 	- error code
148798da112cSIngo Weinhold */
148898da112cSIngo Weinhold status_t
148998da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
149098da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
149198da112cSIngo Weinhold {
1492d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1493d0c290bfSAxel Dörfler 		return B_NO_INIT;
1494d0c290bfSAxel Dörfler 
149598da112cSIngo Weinhold 	status_t error = B_OK;
1496d0c290bfSAxel Dörfler 
149798da112cSIngo Weinhold 	// write to attribute
1498d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
149998da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
150098da112cSIngo Weinhold 		if (written < 0)
150198da112cSIngo Weinhold 			error = written;
150298da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
150398da112cSIngo Weinhold 			error = B_ERROR;
150498da112cSIngo Weinhold 	}
150598da112cSIngo Weinhold 	// write to resource
150698da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
150798da112cSIngo Weinhold 		if (findID) {
150898da112cSIngo Weinhold 			// get the resource info
150998da112cSIngo Weinhold 			int32 idFound;
151098da112cSIngo Weinhold 			size_t sizeFound;
151198da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
151298da112cSIngo Weinhold 				id = idFound;
151398da112cSIngo Weinhold 			else {
151498da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
151598da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
151698da112cSIngo Weinhold 					id++;
151798da112cSIngo Weinhold 			}
151898da112cSIngo Weinhold 		}
151998da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
152098da112cSIngo Weinhold 	}
152198da112cSIngo Weinhold 	return error;
152298da112cSIngo Weinhold }
152398da112cSIngo Weinhold 
152498da112cSIngo Weinhold // _RemoveData
152598da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
152698da112cSIngo Weinhold 
152798da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
152898da112cSIngo Weinhold 
152998da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
153098da112cSIngo Weinhold 
153198da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
153298da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
153398da112cSIngo Weinhold 	\return
153498da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
153598da112cSIngo Weinhold 	- error code
153698da112cSIngo Weinhold */
153798da112cSIngo Weinhold status_t
153898da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
153998da112cSIngo Weinhold {
1540d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1541d0c290bfSAxel Dörfler 		return B_NO_INIT;
1542d0c290bfSAxel Dörfler 
154398da112cSIngo Weinhold 	status_t error = B_OK;
1544d0c290bfSAxel Dörfler 
154598da112cSIngo Weinhold 	// remove the attribute
1546d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
154798da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
154898da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
154998da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
155098da112cSIngo Weinhold 			error = B_OK;
155198da112cSIngo Weinhold 	}
155298da112cSIngo Weinhold 	// remove the resource
155398da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
155498da112cSIngo Weinhold 		// get a resource info
155598da112cSIngo Weinhold 		int32 idFound;
155698da112cSIngo Weinhold 		size_t sizeFound;
155798da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
155898da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
155998da112cSIngo Weinhold 	}
156098da112cSIngo Weinhold 	return error;
156198da112cSIngo Weinhold }
156298da112cSIngo Weinhold 
1563