xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 88706bbe114653946d4c580b10f5cf036bee3033)
121881ce5SIngo Weinhold //----------------------------------------------------------------------
2*88706bbeSAxel Dörfler //  This software is part of the Haiku distribution and is covered
3*88706bbeSAxel 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 
55*88706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
56*88706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
57*88706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
58*88706bbeSAxel Dörfler // Tracker when compiled for Haiku)
59*88706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
60*88706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
61*88706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
62*88706bbeSAxel 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
64198da112cSIngo Weinhold 	status_t error = (info ? B_OK : B_BAD_VALUE);
64298da112cSIngo Weinhold 	int32 index = 0;
64398da112cSIngo Weinhold 	if (error == B_OK) {
64498da112cSIngo Weinhold 		switch (kind) {
64598da112cSIngo Weinhold 			case B_APP_VERSION_KIND:
64698da112cSIngo Weinhold 				index = 0;
64798da112cSIngo Weinhold 				break;
64898da112cSIngo Weinhold 			case B_SYSTEM_VERSION_KIND:
64998da112cSIngo Weinhold 				index = 1;
65098da112cSIngo Weinhold 				break;
65198da112cSIngo Weinhold 			default:
65298da112cSIngo Weinhold 				error = B_BAD_VALUE;
65398da112cSIngo Weinhold 				break;
65498da112cSIngo Weinhold 		}
65598da112cSIngo Weinhold 	}
65698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
65798da112cSIngo Weinhold 		error = B_NO_INIT;
65898da112cSIngo Weinhold 	// read the data
65998da112cSIngo Weinhold 	size_t read = 0;
66098da112cSIngo Weinhold 	version_info infos[2];
66198da112cSIngo Weinhold 	if (error == B_OK) {
66298da112cSIngo Weinhold 		error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
66398da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
66498da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
66598da112cSIngo Weinhold 	}
66698da112cSIngo Weinhold 	// check the read data -- null terminate the string
66798da112cSIngo Weinhold 	if (error == B_OK && read != 2 * sizeof(version_info))
66898da112cSIngo Weinhold 		error = B_ERROR;
66998da112cSIngo Weinhold 	if (error == B_OK)
67098da112cSIngo Weinhold 		*info = infos[index];
67198da112cSIngo Weinhold 	return error;
672d6b205f3SIngo Weinhold }
673d6b205f3SIngo Weinhold 
674d6b205f3SIngo Weinhold // SetVersionInfo
675d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
676d6b205f3SIngo Weinhold 
677d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
678d6b205f3SIngo Weinhold 
679d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
680d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
681d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
682d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
683d6b205f3SIngo Weinhold 		   belongs to.
684d6b205f3SIngo Weinhold 	\return
685d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
686d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
687d6b205f3SIngo Weinhold 	- other error codes
688d6b205f3SIngo Weinhold */
689d6b205f3SIngo Weinhold status_t
690d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
691d6b205f3SIngo Weinhold {
69298da112cSIngo Weinhold 	// check initialization
69398da112cSIngo Weinhold 	status_t error = B_OK;
69498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
69598da112cSIngo Weinhold 		error = B_NO_INIT;
69698da112cSIngo Weinhold 	if (error == B_OK) {
69798da112cSIngo Weinhold 		if (info) {
69898da112cSIngo Weinhold 			// check param
69998da112cSIngo Weinhold 			int32 index = 0;
70098da112cSIngo Weinhold 			if (error == B_OK) {
70198da112cSIngo Weinhold 				switch (kind) {
70298da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
70398da112cSIngo Weinhold 						index = 0;
70498da112cSIngo Weinhold 						break;
70598da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
70698da112cSIngo Weinhold 						index = 1;
70798da112cSIngo Weinhold 						break;
70898da112cSIngo Weinhold 					default:
70998da112cSIngo Weinhold 						error = B_BAD_VALUE;
71098da112cSIngo Weinhold 						break;
71198da112cSIngo Weinhold 				}
71298da112cSIngo Weinhold 			}
71398da112cSIngo Weinhold 			// read both infos
71498da112cSIngo Weinhold 			version_info infos[2];
71598da112cSIngo Weinhold 			if (error == B_OK) {
71698da112cSIngo Weinhold 				size_t read;
71798da112cSIngo Weinhold 				_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
71898da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
71998da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
72098da112cSIngo Weinhold 			}
72198da112cSIngo Weinhold 			infos[index] = *info;
72298da112cSIngo Weinhold 			// write the data
72398da112cSIngo Weinhold 			if (error == B_OK) {
72498da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
72598da112cSIngo Weinhold 								   kVersionInfoResourceID,
72698da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
72798da112cSIngo Weinhold 								   2 * sizeof(version_info));
72898da112cSIngo Weinhold 			}
72998da112cSIngo Weinhold 		} else
73098da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
73198da112cSIngo Weinhold 	}
73298da112cSIngo Weinhold 	return error;
733d6b205f3SIngo Weinhold }
734d6b205f3SIngo Weinhold 
735d6b205f3SIngo Weinhold // GetIconForType
736d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
73798da112cSIngo Weinhold 
73898da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
73998da112cSIngo Weinhold 
74098da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
741d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
742d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
743d6b205f3SIngo Weinhold 		   large icon).
744d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
745d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
746d6b205f3SIngo Weinhold 	\return
747d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
748d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
74998da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
750d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
751d6b205f3SIngo Weinhold 		 not match.
752d6b205f3SIngo Weinhold 	- other error codes
753d6b205f3SIngo Weinhold */
754d6b205f3SIngo Weinhold status_t
755d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
756d6b205f3SIngo Weinhold 							 icon_size which) const
757d6b205f3SIngo Weinhold {
75898da112cSIngo Weinhold 	status_t error = B_OK;
75998da112cSIngo Weinhold 	// set some icon size related variables
76098da112cSIngo Weinhold 	BString attributeString;
76198da112cSIngo Weinhold 	BRect bounds;
762a04efc92SIngo Weinhold 	uint32 attrType = 0;
763a04efc92SIngo Weinhold 	size_t attrSize = 0;
76498da112cSIngo Weinhold 	switch (which) {
76598da112cSIngo Weinhold 		case B_MINI_ICON:
76698da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
76798da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
76898da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
76998da112cSIngo Weinhold 			attrSize = 16 * 16;
77098da112cSIngo Weinhold 			break;
77198da112cSIngo Weinhold 		case B_LARGE_ICON:
77298da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
77398da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
77498da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
77598da112cSIngo Weinhold 			attrSize = 32 * 32;
77698da112cSIngo Weinhold 			break;
77798da112cSIngo Weinhold 		default:
77898da112cSIngo Weinhold 			error = B_BAD_VALUE;
77998da112cSIngo Weinhold 			break;
78098da112cSIngo Weinhold 	}
78198da112cSIngo Weinhold 	// check type param
78298da112cSIngo Weinhold 	if (error == B_OK) {
78398da112cSIngo Weinhold 		if (type) {
78417819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
78517819be3SIngo Weinhold 				attributeString += type;
78617819be3SIngo Weinhold 			else
78798da112cSIngo Weinhold 				error = B_BAD_VALUE;
78898da112cSIngo Weinhold 		} else
78917819be3SIngo Weinhold 			attributeString += kStandardIconType;
79098da112cSIngo Weinhold 	}
79198da112cSIngo Weinhold 	const char *attribute = attributeString.String();
79217819be3SIngo Weinhold 
79398da112cSIngo Weinhold 	// check parameter and initialization
79498da112cSIngo Weinhold 	if (error == B_OK
79598da112cSIngo Weinhold 		&& (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
79698da112cSIngo Weinhold 		error = B_BAD_VALUE;
79798da112cSIngo Weinhold 	}
79898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
79998da112cSIngo Weinhold 		error = B_NO_INIT;
80098da112cSIngo Weinhold 	// read the data
80198da112cSIngo Weinhold 	if (error == B_OK) {
80298da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
80398da112cSIngo Weinhold 		char *buffer = NULL;
80498da112cSIngo Weinhold 		size_t read;
80598da112cSIngo Weinhold 		if (otherColorSpace) {
80698da112cSIngo Weinhold 			// other color space than stored in attribute
80798da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
80898da112cSIngo Weinhold 			if (!buffer)
80998da112cSIngo Weinhold 				error = B_NO_MEMORY;
81098da112cSIngo Weinhold 			if (error == B_OK) {
81198da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
81298da112cSIngo Weinhold 								  read);
81398da112cSIngo Weinhold 			}
81498da112cSIngo Weinhold 		} else {
81598da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
81698da112cSIngo Weinhold 							  read);
81798da112cSIngo Weinhold 		}
81898da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
81998da112cSIngo Weinhold 			error = B_ERROR;
82098da112cSIngo Weinhold 		if (otherColorSpace) {
82198da112cSIngo Weinhold 			// other color space than stored in attribute
82276ba3434SIngo Weinhold 			if (error == B_OK) {
82376ba3434SIngo Weinhold 				error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
82476ba3434SIngo Weinhold 										 0, B_CMAP8);
82576ba3434SIngo Weinhold 			}
82698da112cSIngo Weinhold 			delete[] buffer;
82798da112cSIngo Weinhold 		}
82898da112cSIngo Weinhold 	}
82998da112cSIngo Weinhold 	return error;
830d6b205f3SIngo Weinhold }
831d6b205f3SIngo Weinhold 
832d6b205f3SIngo Weinhold // SetIconForType
833d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
834d6b205f3SIngo Weinhold 
83598da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
836d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
837d6b205f3SIngo Weinhold 
83898da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
83998da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
84098da112cSIngo Weinhold 	before.
84198da112cSIngo Weinhold 
84298da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
843d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
844d6b205f3SIngo Weinhold 		   May be \c NULL.
845d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
846d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
847d6b205f3SIngo Weinhold 	\return
848d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
849d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
850d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
851d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
852d6b205f3SIngo Weinhold 	- other error codes
853d6b205f3SIngo Weinhold */
854d6b205f3SIngo Weinhold status_t
855d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
856d6b205f3SIngo Weinhold 							 icon_size which)
857d6b205f3SIngo Weinhold {
85898da112cSIngo Weinhold 	status_t error = B_OK;
85998da112cSIngo Weinhold 	// set some icon size related variables
86098da112cSIngo Weinhold 	BString attributeString;
86198da112cSIngo Weinhold 	BRect bounds;
862a04efc92SIngo Weinhold 	uint32 attrType = 0;
863a04efc92SIngo Weinhold 	size_t attrSize = 0;
864a04efc92SIngo Weinhold 	int32 resourceID = 0;
86598da112cSIngo Weinhold 	switch (which) {
86698da112cSIngo Weinhold 		case B_MINI_ICON:
86798da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
86898da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
86998da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
87098da112cSIngo Weinhold 			attrSize = 16 * 16;
87198da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
87298da112cSIngo Weinhold 							   : kMiniIconResourceID);
87398da112cSIngo Weinhold 			break;
87498da112cSIngo Weinhold 		case B_LARGE_ICON:
87598da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
87698da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
87798da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
87898da112cSIngo Weinhold 			attrSize = 32 * 32;
87998da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
88098da112cSIngo Weinhold 							   : kLargeIconResourceID);
88198da112cSIngo Weinhold 			break;
88298da112cSIngo Weinhold 		default:
88398da112cSIngo Weinhold 			error = B_BAD_VALUE;
88498da112cSIngo Weinhold 			break;
88598da112cSIngo Weinhold 	}
88698da112cSIngo Weinhold 	// check type param
88798da112cSIngo Weinhold 	if (error == B_OK) {
88898da112cSIngo Weinhold 		if (type) {
88917819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
89098da112cSIngo Weinhold 				attributeString += type;
89117819be3SIngo Weinhold 			else
89217819be3SIngo Weinhold 				error = B_BAD_VALUE;
89398da112cSIngo Weinhold 		} else
89498da112cSIngo Weinhold 			attributeString += kStandardIconType;
89598da112cSIngo Weinhold 	}
89698da112cSIngo Weinhold 	const char *attribute = attributeString.String();
89798da112cSIngo Weinhold 	// check parameter and initialization
89898da112cSIngo Weinhold 	if (error == B_OK && icon
89998da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
90098da112cSIngo Weinhold 		error = B_BAD_VALUE;
90198da112cSIngo Weinhold 	}
90298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
90398da112cSIngo Weinhold 		error = B_NO_INIT;
90498da112cSIngo Weinhold 	// write/remove the attribute
90598da112cSIngo Weinhold 	if (error == B_OK) {
90698da112cSIngo Weinhold 		if (icon) {
90798da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
90898da112cSIngo Weinhold 			if (otherColorSpace) {
90998da112cSIngo Weinhold 				BBitmap bitmap(bounds, B_CMAP8);
91098da112cSIngo Weinhold 				error = bitmap.InitCheck();
91176ba3434SIngo Weinhold 				if (error == B_OK)
91276ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
91398da112cSIngo Weinhold 				if (error == B_OK) {
91498da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
91598da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
91698da112cSIngo Weinhold 				}
91798da112cSIngo Weinhold 			} else {
91898da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
91998da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
92098da112cSIngo Weinhold 			}
92198da112cSIngo Weinhold 		} else	// no icon given => remove
92298da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
92398da112cSIngo Weinhold 	}
92498da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
92598da112cSIngo Weinhold 	BMimeType mimeType;
92698da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
92798da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
92898da112cSIngo Weinhold 			error = mimeType.Install();
92998da112cSIngo Weinhold 		if (error == B_OK)
93098da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
93198da112cSIngo Weinhold 	}
93298da112cSIngo Weinhold 	return error;
933d6b205f3SIngo Weinhold }
934d6b205f3SIngo Weinhold 
935d6b205f3SIngo Weinhold // SetInfoLocation
936d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
937d6b205f3SIngo Weinhold 
938d6b205f3SIngo Weinhold 	The options for \a location are:
939d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
940d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
941d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
942d6b205f3SIngo Weinhold 
943d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
944d6b205f3SIngo Weinhold */
945d6b205f3SIngo Weinhold void
946d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
947d6b205f3SIngo Weinhold {
94898da112cSIngo Weinhold 	fWhere = location;
949d6b205f3SIngo Weinhold }
950d6b205f3SIngo Weinhold 
951d6b205f3SIngo Weinhold // IsUsingAttributes
952d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
953d6b205f3SIngo Weinhold 		   file's attributes.
954d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
955d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
956d6b205f3SIngo Weinhold */
957d6b205f3SIngo Weinhold bool
958d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
959d6b205f3SIngo Weinhold {
96098da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
961d6b205f3SIngo Weinhold }
962d6b205f3SIngo Weinhold 
963d6b205f3SIngo Weinhold // IsUsingResources
964d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
965d6b205f3SIngo Weinhold 		   file's resources.
966d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
967d6b205f3SIngo Weinhold 			resources, \c false otherwise.
968d6b205f3SIngo Weinhold */
969d6b205f3SIngo Weinhold bool
970d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
971d6b205f3SIngo Weinhold {
97298da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
973d6b205f3SIngo Weinhold }
974d6b205f3SIngo Weinhold 
975d6b205f3SIngo Weinhold // FBC
976d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
977d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
978d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
979d6b205f3SIngo Weinhold 
980d6b205f3SIngo Weinhold // =
981d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
982d6b205f3SIngo Weinhold */
983d6b205f3SIngo Weinhold BAppFileInfo &
984d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
985d6b205f3SIngo Weinhold {
986d6b205f3SIngo Weinhold 	return *this;
987d6b205f3SIngo Weinhold }
988d6b205f3SIngo Weinhold 
989d6b205f3SIngo Weinhold // copy constructor
990d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
991d6b205f3SIngo Weinhold */
992d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
993d6b205f3SIngo Weinhold {
994d6b205f3SIngo Weinhold }
995d6b205f3SIngo Weinhold 
99698da112cSIngo Weinhold // GetMetaMime
99798da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
99898da112cSIngo Weinhold 
99998da112cSIngo Weinhold 	The parameter \a meta is not checked.
100098da112cSIngo Weinhold 
100198da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
100298da112cSIngo Weinhold 		   initialized to the file's signature.
100398da112cSIngo Weinhold 	\return
100498da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
100598da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
100698da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
100798da112cSIngo Weinhold (	  not installed in the MIME database.)
100898da112cSIngo Weinhold 	  no valid MIME string.
100998da112cSIngo Weinhold 	- other error codes
101098da112cSIngo Weinhold */
101198da112cSIngo Weinhold status_t
101298da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
101398da112cSIngo Weinhold {
101498da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
101598da112cSIngo Weinhold 	status_t error = GetSignature(signature);
101698da112cSIngo Weinhold 	if (error == B_OK)
101798da112cSIngo Weinhold 		error = meta->SetTo(signature);
101898da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
101998da112cSIngo Weinhold 		error = B_BAD_VALUE;
102098da112cSIngo Weinhold 	return error;
102198da112cSIngo Weinhold }
102298da112cSIngo Weinhold 
102398da112cSIngo Weinhold // _ReadData
102498da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
102598da112cSIngo Weinhold 
102698da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
102798da112cSIngo Weinhold 
102898da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
102998da112cSIngo Weinhold 
103098da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
103198da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
103298da112cSIngo Weinhold 		   < 0.
103398da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
103498da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
103598da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
103698da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
103798da112cSIngo Weinhold 		   actually read.
103898da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
103998da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
104098da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
104198da112cSIngo Weinhold 	\return
104298da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
104398da112cSIngo Weinhold 	- error code
104498da112cSIngo Weinhold */
104598da112cSIngo Weinhold status_t
104698da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
104798da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
104898da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
104998da112cSIngo Weinhold {
105098da112cSIngo Weinhold 	status_t error = B_OK;
105198da112cSIngo Weinhold 	if (allocatedBuffer)
105298da112cSIngo Weinhold 		buffer = NULL;
105398da112cSIngo Weinhold 	if (IsUsingAttributes()) {
105498da112cSIngo Weinhold 		// get an attribute info
105598da112cSIngo Weinhold 		attr_info info;
105698da112cSIngo Weinhold 		if (error == B_OK)
105798da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
105898da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
105998da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
106098da112cSIngo Weinhold 			error = B_BAD_VALUE;
106198da112cSIngo Weinhold 		if (allocatedBuffer) {
106298da112cSIngo Weinhold 			buffer = malloc(info.size);
106398da112cSIngo Weinhold 			if (!buffer)
106498da112cSIngo Weinhold 				error = B_NO_MEMORY;
106598da112cSIngo Weinhold 			bufferSize = info.size;
106698da112cSIngo Weinhold 		}
106798da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
106898da112cSIngo Weinhold 			error = B_BAD_VALUE;
106998da112cSIngo Weinhold 		// read the data
107098da112cSIngo Weinhold 		if (error == B_OK) {
107198da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
107298da112cSIngo Weinhold 			if (read < 0)
107398da112cSIngo Weinhold 				error = read;
107498da112cSIngo Weinhold 			else if (read != info.size)
107598da112cSIngo Weinhold 				error = B_ERROR;
107698da112cSIngo Weinhold 			else
107798da112cSIngo Weinhold 				bytesRead = read;
107898da112cSIngo Weinhold 		}
107998da112cSIngo Weinhold 	} else if (IsUsingResources()) {
108098da112cSIngo Weinhold 		// get a resource info
108198da112cSIngo Weinhold 		int32 idFound;
108298da112cSIngo Weinhold 		size_t sizeFound;
108398da112cSIngo Weinhold 		if (error == B_OK) {
108498da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
108598da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
108698da112cSIngo Weinhold 		}
108798da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
108898da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
108998da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
109098da112cSIngo Weinhold 		if (allocatedBuffer) {
109198da112cSIngo Weinhold 			buffer = malloc(sizeFound);
109298da112cSIngo Weinhold 			if (!buffer)
109398da112cSIngo Weinhold 				error = B_NO_MEMORY;
109498da112cSIngo Weinhold 			bufferSize = sizeFound;
109598da112cSIngo Weinhold 		}
109698da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
109798da112cSIngo Weinhold 			error = B_BAD_VALUE;
109898da112cSIngo Weinhold 		// load resource
109998da112cSIngo Weinhold 		const void *resourceData = NULL;
110098da112cSIngo Weinhold 		if (error == B_OK) {
110198da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
110298da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
110398da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
110498da112cSIngo Weinhold 			else
110598da112cSIngo Weinhold 				error = B_ERROR;
110698da112cSIngo Weinhold 		}
110798da112cSIngo Weinhold 	} else
110898da112cSIngo Weinhold 		error = B_BAD_VALUE;
110998da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
111098da112cSIngo Weinhold 	if (allocatedBuffer) {
111198da112cSIngo Weinhold 		if (error == B_OK)
111298da112cSIngo Weinhold 			*allocatedBuffer = buffer;
111398da112cSIngo Weinhold 		else
111498da112cSIngo Weinhold 			free(buffer);
111598da112cSIngo Weinhold 	}
111698da112cSIngo Weinhold 	return error;
111798da112cSIngo Weinhold }
111898da112cSIngo Weinhold 
111998da112cSIngo Weinhold // _WriteData
112098da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
112198da112cSIngo Weinhold 
112298da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
112398da112cSIngo Weinhold 
112498da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
112598da112cSIngo Weinhold 
112698da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
112798da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
112898da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
112998da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
113098da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
113198da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
113298da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
113398da112cSIngo Weinhold 		   If \c false, \a id is used.
113498da112cSIngo Weinhold 	If \a id is already in use and .
113598da112cSIngo Weinhold 	\return
113698da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
113798da112cSIngo Weinhold 	- error code
113898da112cSIngo Weinhold */
113998da112cSIngo Weinhold status_t
114098da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
114198da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
114298da112cSIngo Weinhold {
114398da112cSIngo Weinhold 	status_t error = B_OK;
114498da112cSIngo Weinhold 	// write to attribute
114598da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
114698da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
114798da112cSIngo Weinhold 		if (written < 0)
114898da112cSIngo Weinhold 			error = written;
114998da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
115098da112cSIngo Weinhold 			error = B_ERROR;
115198da112cSIngo Weinhold 	}
115298da112cSIngo Weinhold 	// write to resource
115398da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
115498da112cSIngo Weinhold 		if (findID) {
115598da112cSIngo Weinhold 			// get the resource info
115698da112cSIngo Weinhold 			int32 idFound;
115798da112cSIngo Weinhold 			size_t sizeFound;
115898da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
115998da112cSIngo Weinhold 				id = idFound;
116098da112cSIngo Weinhold 			else {
116198da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
116298da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
116398da112cSIngo Weinhold 					id++;
116498da112cSIngo Weinhold 			}
116598da112cSIngo Weinhold 		}
116698da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
116798da112cSIngo Weinhold 	}
116898da112cSIngo Weinhold 	return error;
116998da112cSIngo Weinhold }
117098da112cSIngo Weinhold 
117198da112cSIngo Weinhold // _RemoveData
117298da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
117398da112cSIngo Weinhold 
117498da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
117598da112cSIngo Weinhold 
117698da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
117798da112cSIngo Weinhold 
117898da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
117998da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
118098da112cSIngo Weinhold 	\return
118198da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
118298da112cSIngo Weinhold 	- error code
118398da112cSIngo Weinhold */
118498da112cSIngo Weinhold status_t
118598da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
118698da112cSIngo Weinhold {
118798da112cSIngo Weinhold 	status_t error = B_OK;
118898da112cSIngo Weinhold 	// remove the attribute
118998da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
119098da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
119198da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
119298da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
119398da112cSIngo Weinhold 			error = B_OK;
119498da112cSIngo Weinhold 	}
119598da112cSIngo Weinhold 	// remove the resource
119698da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
119798da112cSIngo Weinhold 		// get a resource info
119898da112cSIngo Weinhold 		int32 idFound;
119998da112cSIngo Weinhold 		size_t sizeFound;
120098da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
120198da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
120298da112cSIngo Weinhold 	}
120398da112cSIngo Weinhold 	return error;
120498da112cSIngo Weinhold }
120598da112cSIngo Weinhold 
1206