xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 50f17542c22223d6976bb1ce131bf988bb22d0fa)
121881ce5SIngo Weinhold //----------------------------------------------------------------------
221881ce5SIngo Weinhold //  This software is part of the OpenBeOS distribution and is covered
321881ce5SIngo Weinhold //  by the OpenBeOS 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 
24*50f17542Shaydentech using namespace std;
25*50f17542Shaydentech 
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 
55d6b205f3SIngo Weinhold 
56d6b205f3SIngo Weinhold enum {
57d6b205f3SIngo Weinhold 	NOT_IMPLEMENTED	= B_ERROR,
58d6b205f3SIngo Weinhold };
59d6b205f3SIngo Weinhold 
60d6b205f3SIngo Weinhold // constructor
61d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
62d6b205f3SIngo Weinhold */
63d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
64d6b205f3SIngo Weinhold 			: fResources(NULL),
65d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
66d6b205f3SIngo Weinhold {
67d6b205f3SIngo Weinhold }
68d6b205f3SIngo Weinhold 
69d6b205f3SIngo Weinhold // constructor
70d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
71d6b205f3SIngo Weinhold 		   file.
72d6b205f3SIngo Weinhold 
73d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
74d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
75d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
76d6b205f3SIngo Weinhold 
77d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
78d6b205f3SIngo Weinhold */
79d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
80d6b205f3SIngo Weinhold 			: fResources(NULL),
81d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
82d6b205f3SIngo Weinhold {
8398da112cSIngo Weinhold 	SetTo(file);
84d6b205f3SIngo Weinhold }
85d6b205f3SIngo Weinhold 
86d6b205f3SIngo Weinhold // destructor
87d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
88d6b205f3SIngo Weinhold 
89d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
90d6b205f3SIngo Weinhold */
91d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
92d6b205f3SIngo Weinhold {
9398da112cSIngo Weinhold 	if (fResources)
9498da112cSIngo Weinhold 		delete fResources;
95d6b205f3SIngo Weinhold }
96d6b205f3SIngo Weinhold 
97d6b205f3SIngo Weinhold // SetTo
98d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
99d6b205f3SIngo Weinhold 
100d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
101d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
102d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
103d6b205f3SIngo Weinhold 
104d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
105d6b205f3SIngo Weinhold 
106d6b205f3SIngo Weinhold 	\return
107d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
108d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
109d6b205f3SIngo Weinhold */
110d6b205f3SIngo Weinhold status_t
111d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
112d6b205f3SIngo Weinhold {
11398da112cSIngo Weinhold 	// unset the old file
11498da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
11598da112cSIngo Weinhold 	if (fResources) {
11698da112cSIngo Weinhold 		delete fResources;
11798da112cSIngo Weinhold 		fResources = NULL;
11898da112cSIngo Weinhold 	}
11998da112cSIngo Weinhold 	// check param
12098da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
12198da112cSIngo Weinhold 	// create resources
12298da112cSIngo Weinhold 	if (error == B_OK) {
12398da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
12498da112cSIngo Weinhold 		if (fResources)
12598da112cSIngo Weinhold 			error = fResources->SetTo(file);
12698da112cSIngo Weinhold 		else
12798da112cSIngo Weinhold 			error = B_NO_MEMORY;
12898da112cSIngo Weinhold 	}
12998da112cSIngo Weinhold 	// set node info
13098da112cSIngo Weinhold 	if (error == B_OK)
13198da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
13298da112cSIngo Weinhold 	// clean up on error
13398da112cSIngo Weinhold 	if (error != B_OK) {
13498da112cSIngo Weinhold 		if (fResources) {
13598da112cSIngo Weinhold 			delete fResources;
13698da112cSIngo Weinhold 			fResources = NULL;
13798da112cSIngo Weinhold 		}
13898da112cSIngo Weinhold 		if (InitCheck() == B_OK)
13998da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
14098da112cSIngo Weinhold 	}
14198da112cSIngo Weinhold 	// set data location
14298da112cSIngo Weinhold 	if (error == B_OK)
14398da112cSIngo Weinhold 		SetInfoLocation(B_USE_BOTH_LOCATIONS);
14498da112cSIngo Weinhold 	// set error
14598da112cSIngo Weinhold 	fCStatus = error;
14698da112cSIngo Weinhold 	return error;
147d6b205f3SIngo Weinhold }
148d6b205f3SIngo Weinhold 
149d6b205f3SIngo Weinhold // GetType
150d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
151d6b205f3SIngo Weinhold 
152d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
153d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
154d6b205f3SIngo Weinhold 		   file shall be written.
155d6b205f3SIngo Weinhold 	\return
156d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
157d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
158d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
159d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
160d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
161d6b205f3SIngo Weinhold 	  the wrong type.
162d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
163d6b205f3SIngo Weinhold 	- other error codes
164d6b205f3SIngo Weinhold */
165d6b205f3SIngo Weinhold status_t
166d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
167d6b205f3SIngo Weinhold {
16898da112cSIngo Weinhold 	// check param and initialization
16998da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
17098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
17198da112cSIngo Weinhold 		error = B_NO_INIT;
17298da112cSIngo Weinhold 	// read the data
17398da112cSIngo Weinhold 	size_t read = 0;
17498da112cSIngo Weinhold 	if (error == B_OK) {
17598da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
17698da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
17798da112cSIngo Weinhold 	}
17898da112cSIngo Weinhold 	// check the read data -- null terminate the string
17998da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
18098da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
18198da112cSIngo Weinhold 			error = B_ERROR;
18298da112cSIngo Weinhold 		else
18398da112cSIngo Weinhold 			type[read] = '\0';
18498da112cSIngo Weinhold 	}
18598da112cSIngo Weinhold 	return error;
186d6b205f3SIngo Weinhold }
187d6b205f3SIngo Weinhold 
188d6b205f3SIngo Weinhold // SetType
189d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
190d6b205f3SIngo Weinhold 
191d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
192d6b205f3SIngo Weinhold 
193d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
194d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
195d6b205f3SIngo Weinhold 		   May be \c NULL.
196d6b205f3SIngo Weinhold 	\return
197d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
198d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
199d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
200d6b205f3SIngo Weinhold 	- other error codes
201d6b205f3SIngo Weinhold */
202d6b205f3SIngo Weinhold status_t
203d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
204d6b205f3SIngo Weinhold {
20598da112cSIngo Weinhold 	// check initialization
20698da112cSIngo Weinhold 	status_t error = B_OK;
20798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
20898da112cSIngo Weinhold 		error = B_NO_INIT;
20998da112cSIngo Weinhold 	if (error == B_OK) {
21098da112cSIngo Weinhold 		if (type) {
21198da112cSIngo Weinhold 			// check param
21298da112cSIngo Weinhold 			size_t typeLen = strlen(type);
21398da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
21498da112cSIngo Weinhold 				error = B_BAD_VALUE;
21598da112cSIngo Weinhold 			// write the data
21698da112cSIngo Weinhold 			if (error == B_OK) {
21798da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
21898da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
21998da112cSIngo Weinhold 			}
22098da112cSIngo Weinhold 		} else
22198da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
22298da112cSIngo Weinhold 	}
22398da112cSIngo Weinhold 	return error;
224d6b205f3SIngo Weinhold }
225d6b205f3SIngo Weinhold 
226d6b205f3SIngo Weinhold // GetSignature
227d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
228d6b205f3SIngo Weinhold 
229d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
230d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
231d6b205f3SIngo Weinhold 		   signature of the file shall be written.
232d6b205f3SIngo Weinhold 	\return
233d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
234d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
235d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
236d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
237d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
238d6b205f3SIngo Weinhold 	  the wrong type.
239d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
240d6b205f3SIngo Weinhold 	- other error codes
241d6b205f3SIngo Weinhold */
242d6b205f3SIngo Weinhold status_t
243d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
244d6b205f3SIngo Weinhold {
24598da112cSIngo Weinhold 	// check param and initialization
24698da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
24798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
24898da112cSIngo Weinhold 		error = B_NO_INIT;
24998da112cSIngo Weinhold 	// read the data
25098da112cSIngo Weinhold 	size_t read = 0;
25198da112cSIngo Weinhold 	if (error == B_OK) {
25298da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
25398da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
25498da112cSIngo Weinhold 						  read);
25598da112cSIngo Weinhold 	}
25698da112cSIngo Weinhold 	// check the read data -- null terminate the string
25798da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
25898da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
25998da112cSIngo Weinhold 			error = B_ERROR;
26098da112cSIngo Weinhold 		else
26198da112cSIngo Weinhold 			signature[read] = '\0';
26298da112cSIngo Weinhold 	}
26398da112cSIngo Weinhold 	return error;
264d6b205f3SIngo Weinhold }
265d6b205f3SIngo Weinhold 
266d6b205f3SIngo Weinhold // SetSignature
267d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
268d6b205f3SIngo Weinhold 
269d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
270d6b205f3SIngo Weinhold 
271d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
272d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
273d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
274d6b205f3SIngo Weinhold 	\return
275d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
276d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
277d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
278d6b205f3SIngo Weinhold 	- other error codes
279d6b205f3SIngo Weinhold */
280d6b205f3SIngo Weinhold status_t
281d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
282d6b205f3SIngo Weinhold {
28398da112cSIngo Weinhold 	// check initialization
28498da112cSIngo Weinhold 	status_t error = B_OK;
28598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
28698da112cSIngo Weinhold 		error = B_NO_INIT;
28798da112cSIngo Weinhold 	if (error == B_OK) {
28898da112cSIngo Weinhold 		if (signature) {
28998da112cSIngo Weinhold 			// check param
29098da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
29198da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
29298da112cSIngo Weinhold 				error = B_BAD_VALUE;
29398da112cSIngo Weinhold 			// write the data
29498da112cSIngo Weinhold 			if (error == B_OK) {
29598da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
29698da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
29798da112cSIngo Weinhold 								   signatureLen + 1);
29898da112cSIngo Weinhold 			}
29998da112cSIngo Weinhold 		} else
30098da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
30198da112cSIngo Weinhold 	}
30298da112cSIngo Weinhold 	return error;
303d6b205f3SIngo Weinhold }
304d6b205f3SIngo Weinhold 
305d6b205f3SIngo Weinhold // GetAppFlags
306d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
307d6b205f3SIngo Weinhold 
308d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
309d6b205f3SIngo Weinhold 		   flags of the file shall be written.
310d6b205f3SIngo Weinhold 	\return
311d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
312d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
313d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
314d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
315d6b205f3SIngo Weinhold 	  the wrong type.
316d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
317d6b205f3SIngo Weinhold 	- other error codes
318d6b205f3SIngo Weinhold */
319d6b205f3SIngo Weinhold status_t
320d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
321d6b205f3SIngo Weinhold {
32298da112cSIngo Weinhold 	// check param and initialization
32398da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
32498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
32598da112cSIngo Weinhold 		error = B_NO_INIT;
32698da112cSIngo Weinhold 	// read the data
32798da112cSIngo Weinhold 	size_t read = 0;
32898da112cSIngo Weinhold 	if (error == B_OK) {
32998da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
33098da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
33198da112cSIngo Weinhold 						  read);
33298da112cSIngo Weinhold 	}
33398da112cSIngo Weinhold 	// check the read data
33498da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
33598da112cSIngo Weinhold 		error = B_ERROR;
33698da112cSIngo Weinhold 	return error;
337d6b205f3SIngo Weinhold }
338d6b205f3SIngo Weinhold 
339d6b205f3SIngo Weinhold // SetAppFlags
340d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
341d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
342d6b205f3SIngo Weinhold 	\return
343d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
344d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
345d6b205f3SIngo Weinhold 	- other error codes
346d6b205f3SIngo Weinhold */
347d6b205f3SIngo Weinhold status_t
348d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
349d6b205f3SIngo Weinhold {
35098da112cSIngo Weinhold 	// check initialization
35198da112cSIngo Weinhold 	status_t error = B_OK;
35298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
35398da112cSIngo Weinhold 		error = B_NO_INIT;
35498da112cSIngo Weinhold 	if (error == B_OK) {
35598da112cSIngo Weinhold 		// write the data
35698da112cSIngo Weinhold 		if (error == B_OK) {
35798da112cSIngo Weinhold 			error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
35898da112cSIngo Weinhold 							   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
35998da112cSIngo Weinhold 		}
36098da112cSIngo Weinhold 	}
36198da112cSIngo Weinhold 	return error;
362d6b205f3SIngo Weinhold }
363d6b205f3SIngo Weinhold 
364d6b205f3SIngo Weinhold // GetSupportedTypes
365d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
366d6b205f3SIngo Weinhold 
367d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
368d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
369d6b205f3SIngo Weinhold 
370d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
371d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
372d6b205f3SIngo Weinhold 	\return
373d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
374d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
375d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
376d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
377d6b205f3SIngo Weinhold 	  have the wrong type.
378d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
379d6b205f3SIngo Weinhold 	- other error codes
380d6b205f3SIngo Weinhold */
381d6b205f3SIngo Weinhold status_t
382d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
383d6b205f3SIngo Weinhold {
38498da112cSIngo Weinhold 	// check param and initialization
38598da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
38698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
38798da112cSIngo Weinhold 		error = B_NO_INIT;
38898da112cSIngo Weinhold 	// read the data
38998da112cSIngo Weinhold 	size_t read = 0;
39098da112cSIngo Weinhold 	void *buffer = NULL;
39198da112cSIngo Weinhold 	if (error == B_OK) {
39298da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
39398da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
39498da112cSIngo Weinhold 	}
39598da112cSIngo Weinhold 	// unflatten the buffer
39698da112cSIngo Weinhold 	if (error == B_OK)
39798da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
39898da112cSIngo Weinhold 	// clean up
39998da112cSIngo Weinhold 	if (buffer)
40098da112cSIngo Weinhold 		free(buffer);
40198da112cSIngo Weinhold 	return error;
402d6b205f3SIngo Weinhold }
403d6b205f3SIngo Weinhold 
404d6b205f3SIngo Weinhold // SetSupportedTypes
405d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
406d6b205f3SIngo Weinhold 
407d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
408d6b205f3SIngo Weinhold 
409d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
410d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
411d6b205f3SIngo Weinhold 
41283a812a1SIngo Weinhold 	The method informs the registrar about this news.
41383a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
41483a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
41583a812a1SIngo Weinhold 	application file needs to have a signature set.
41683a812a1SIngo Weinhold 
41783a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
41883a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
41983a812a1SIngo Weinhold 	lists of supporting applications.
42083a812a1SIngo Weinhold 
421d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
422d6b205f3SIngo Weinhold 		   May be \c NULL.
42383a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
42483a812a1SIngo Weinhold 		   types, \c false otherwise.
425d6b205f3SIngo Weinhold 	\return
426d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
427d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
428d6b205f3SIngo Weinhold 	- other error codes
429d6b205f3SIngo Weinhold */
430d6b205f3SIngo Weinhold status_t
431d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
432d6b205f3SIngo Weinhold {
43398da112cSIngo Weinhold 	// check initialization
43498da112cSIngo Weinhold 	status_t error = B_OK;
43598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
43698da112cSIngo Weinhold 		error = B_NO_INIT;
43798da112cSIngo Weinhold 	BMimeType mimeType;
43898da112cSIngo Weinhold 	if (error == B_OK)
43998da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
44098da112cSIngo Weinhold 	if (error == B_OK) {
44198da112cSIngo Weinhold 		if (types) {
44217819be3SIngo Weinhold 			// check param -- supported types must be valid
44317819be3SIngo Weinhold 			const char *type;
44417819be3SIngo Weinhold 			for (int32 i = 0;
44517819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
44617819be3SIngo Weinhold 				 i++) {
44717819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
44817819be3SIngo Weinhold 					error = B_BAD_VALUE;
44917819be3SIngo Weinhold 			}
45017819be3SIngo Weinhold 			// get flattened size
45117819be3SIngo Weinhold 			ssize_t size = 0;
45217819be3SIngo Weinhold 			if (error == B_OK) {
45317819be3SIngo Weinhold 				size = types->FlattenedSize();
45498da112cSIngo Weinhold 				if (size < 0)
45598da112cSIngo Weinhold 					error = size;
45617819be3SIngo Weinhold 			}
45798da112cSIngo Weinhold 			// allocate a buffer for the flattened data
45898da112cSIngo Weinhold 			char *buffer = NULL;
45998da112cSIngo Weinhold 			if (error == B_OK) {
46098da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
46198da112cSIngo Weinhold 				if (!buffer)
46298da112cSIngo Weinhold 					error = B_NO_MEMORY;
46398da112cSIngo Weinhold 			}
46498da112cSIngo Weinhold 			// flatten the message
46598da112cSIngo Weinhold 			if (error == B_OK)
46698da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
46798da112cSIngo Weinhold 			// write the data
46898da112cSIngo Weinhold 			if (error == B_OK) {
46998da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
47098da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
47198da112cSIngo Weinhold 								   buffer, size);
47298da112cSIngo Weinhold 			}
47398da112cSIngo Weinhold 			// clean up
47498da112cSIngo Weinhold 			if (buffer)
47598da112cSIngo Weinhold 				delete[] buffer;
47698da112cSIngo Weinhold 		} else
47798da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
47898da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
47917819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
48017819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
48198da112cSIngo Weinhold 	}
48298da112cSIngo Weinhold 	return error;
483d6b205f3SIngo Weinhold }
484d6b205f3SIngo Weinhold 
485d6b205f3SIngo Weinhold // SetSupportedTypes
486d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
487d6b205f3SIngo Weinhold 
48898da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
48983a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
490d6b205f3SIngo Weinhold 
491d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
492d6b205f3SIngo Weinhold 		   May be \c NULL.
493d6b205f3SIngo Weinhold 	\return
494d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
495d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
496d6b205f3SIngo Weinhold 	- other error codes
497d6b205f3SIngo Weinhold */
498d6b205f3SIngo Weinhold status_t
499d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
500d6b205f3SIngo Weinhold {
50198da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
502d6b205f3SIngo Weinhold }
503d6b205f3SIngo Weinhold 
504d6b205f3SIngo Weinhold // IsSupportedType
505d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
506d6b205f3SIngo Weinhold 
507d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
508d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
509d6b205f3SIngo Weinhold 
510d6b205f3SIngo Weinhold 	\param type The MIME type in question.
511d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
512d6b205f3SIngo Weinhold 			the application, \c false otherwise.
513d6b205f3SIngo Weinhold */
514d6b205f3SIngo Weinhold bool
515d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
516d6b205f3SIngo Weinhold {
51798da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
51898da112cSIngo Weinhold 	// get the supported types
51998da112cSIngo Weinhold 	BMessage types;
52098da112cSIngo Weinhold 	if (error == B_OK)
52198da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
52298da112cSIngo Weinhold 	// turn type into a BMimeType
52398da112cSIngo Weinhold 	BMimeType mimeType;
52498da112cSIngo Weinhold 	if (error == B_OK)
52598da112cSIngo Weinhold 		error = mimeType.SetTo(type);
52698da112cSIngo Weinhold 	// iterate through the supported types
52798da112cSIngo Weinhold 	bool found = false;
52898da112cSIngo Weinhold 	if (error == B_OK) {
52998da112cSIngo Weinhold 		const char *supportedType;
53098da112cSIngo Weinhold 		for (int32 i = 0;
53198da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
53298da112cSIngo Weinhold 			 i++) {
53398da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
53498da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
53598da112cSIngo Weinhold 		}
53698da112cSIngo Weinhold 	}
53798da112cSIngo Weinhold 	return found;
538d6b205f3SIngo Weinhold }
539d6b205f3SIngo Weinhold 
540d6b205f3SIngo Weinhold // Supports
541d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
542d6b205f3SIngo Weinhold 		   explicitly.
543d6b205f3SIngo Weinhold 
544d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
545d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
546d6b205f3SIngo Weinhold 	"application/octet-stream".
547d6b205f3SIngo Weinhold 
548d6b205f3SIngo Weinhold 	\param type The MIME type in question.
549d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
550d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
551d6b205f3SIngo Weinhold */
552d6b205f3SIngo Weinhold bool
553d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
554d6b205f3SIngo Weinhold {
55598da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
55698da112cSIngo Weinhold 	// get the supported types
55798da112cSIngo Weinhold 	BMessage types;
55898da112cSIngo Weinhold 	if (error == B_OK)
55998da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
56098da112cSIngo Weinhold 	// iterate through the supported types
56198da112cSIngo Weinhold 	bool found = false;
56298da112cSIngo Weinhold 	if (error == B_OK) {
56398da112cSIngo Weinhold 		const char *supportedType;
56498da112cSIngo Weinhold 		for (int32 i = 0;
56598da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
56698da112cSIngo Weinhold 			 i++) {
56798da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
56898da112cSIngo Weinhold 		}
56998da112cSIngo Weinhold 	}
57098da112cSIngo Weinhold 	return found;
571d6b205f3SIngo Weinhold }
572d6b205f3SIngo Weinhold 
573d6b205f3SIngo Weinhold // GetIcon
574d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
575d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
576d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
577d6b205f3SIngo Weinhold 		   large icon).
578d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
579d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
580d6b205f3SIngo Weinhold 	\return
581d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
582d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
583d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
584d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
585d6b205f3SIngo Weinhold 	- other error codes
586d6b205f3SIngo Weinhold */
587d6b205f3SIngo Weinhold status_t
588d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
589d6b205f3SIngo Weinhold {
59098da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
591d6b205f3SIngo Weinhold }
592d6b205f3SIngo Weinhold 
593d6b205f3SIngo Weinhold // SetIcon
594d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
595d6b205f3SIngo Weinhold 
596d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
597d6b205f3SIngo Weinhold 
598d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
599d6b205f3SIngo Weinhold 		   May be \c NULL.
600d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
601d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
602d6b205f3SIngo Weinhold 	\return
603d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
604d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
605d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
606d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
607d6b205f3SIngo Weinhold 	- other error codes
608d6b205f3SIngo Weinhold */
609d6b205f3SIngo Weinhold status_t
610d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
611d6b205f3SIngo Weinhold {
61298da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
613d6b205f3SIngo Weinhold }
614d6b205f3SIngo Weinhold 
615d6b205f3SIngo Weinhold // GetVersionInfo
616d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
617d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
618d6b205f3SIngo Weinhold 		   the version info should be written.
619d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
620d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
621d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
622d6b205f3SIngo Weinhold 		   belongs to.
623d6b205f3SIngo Weinhold 	\return
624d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
625d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
626d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
627d6b205f3SIngo Weinhold 	- other error codes
628d6b205f3SIngo Weinhold */
629d6b205f3SIngo Weinhold status_t
630d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
631d6b205f3SIngo Weinhold {
63298da112cSIngo Weinhold 	// check params and initialization
63398da112cSIngo Weinhold 	status_t error = (info ? B_OK : B_BAD_VALUE);
63498da112cSIngo Weinhold 	int32 index = 0;
63598da112cSIngo Weinhold 	if (error == B_OK) {
63698da112cSIngo Weinhold 		switch (kind) {
63798da112cSIngo Weinhold 			case B_APP_VERSION_KIND:
63898da112cSIngo Weinhold 				index = 0;
63998da112cSIngo Weinhold 				break;
64098da112cSIngo Weinhold 			case B_SYSTEM_VERSION_KIND:
64198da112cSIngo Weinhold 				index = 1;
64298da112cSIngo Weinhold 				break;
64398da112cSIngo Weinhold 			default:
64498da112cSIngo Weinhold 				error = B_BAD_VALUE;
64598da112cSIngo Weinhold 				break;
64698da112cSIngo Weinhold 		}
64798da112cSIngo Weinhold 	}
64898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
64998da112cSIngo Weinhold 		error = B_NO_INIT;
65098da112cSIngo Weinhold 	// read the data
65198da112cSIngo Weinhold 	size_t read = 0;
65298da112cSIngo Weinhold 	version_info infos[2];
65398da112cSIngo Weinhold 	if (error == B_OK) {
65498da112cSIngo Weinhold 		error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
65598da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
65698da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
65798da112cSIngo Weinhold 	}
65898da112cSIngo Weinhold 	// check the read data -- null terminate the string
65998da112cSIngo Weinhold 	if (error == B_OK && read != 2 * sizeof(version_info))
66098da112cSIngo Weinhold 		error = B_ERROR;
66198da112cSIngo Weinhold 	if (error == B_OK)
66298da112cSIngo Weinhold 		*info = infos[index];
66398da112cSIngo Weinhold 	return error;
664d6b205f3SIngo Weinhold }
665d6b205f3SIngo Weinhold 
666d6b205f3SIngo Weinhold // SetVersionInfo
667d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
668d6b205f3SIngo Weinhold 
669d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
670d6b205f3SIngo Weinhold 
671d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
672d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
673d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
674d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
675d6b205f3SIngo Weinhold 		   belongs to.
676d6b205f3SIngo Weinhold 	\return
677d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
678d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
679d6b205f3SIngo Weinhold 	- other error codes
680d6b205f3SIngo Weinhold */
681d6b205f3SIngo Weinhold status_t
682d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
683d6b205f3SIngo Weinhold {
68498da112cSIngo Weinhold 	// check initialization
68598da112cSIngo Weinhold 	status_t error = B_OK;
68698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
68798da112cSIngo Weinhold 		error = B_NO_INIT;
68898da112cSIngo Weinhold 	if (error == B_OK) {
68998da112cSIngo Weinhold 		if (info) {
69098da112cSIngo Weinhold 			// check param
69198da112cSIngo Weinhold 			int32 index = 0;
69298da112cSIngo Weinhold 			if (error == B_OK) {
69398da112cSIngo Weinhold 				switch (kind) {
69498da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
69598da112cSIngo Weinhold 						index = 0;
69698da112cSIngo Weinhold 						break;
69798da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
69898da112cSIngo Weinhold 						index = 1;
69998da112cSIngo Weinhold 						break;
70098da112cSIngo Weinhold 					default:
70198da112cSIngo Weinhold 						error = B_BAD_VALUE;
70298da112cSIngo Weinhold 						break;
70398da112cSIngo Weinhold 				}
70498da112cSIngo Weinhold 			}
70598da112cSIngo Weinhold 			// read both infos
70698da112cSIngo Weinhold 			version_info infos[2];
70798da112cSIngo Weinhold 			if (error == B_OK) {
70898da112cSIngo Weinhold 				size_t read;
70998da112cSIngo Weinhold 				_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
71098da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
71198da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
71298da112cSIngo Weinhold 			}
71398da112cSIngo Weinhold 			infos[index] = *info;
71498da112cSIngo Weinhold 			// write the data
71598da112cSIngo Weinhold 			if (error == B_OK) {
71698da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
71798da112cSIngo Weinhold 								   kVersionInfoResourceID,
71898da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
71998da112cSIngo Weinhold 								   2 * sizeof(version_info));
72098da112cSIngo Weinhold 			}
72198da112cSIngo Weinhold 		} else
72298da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
72398da112cSIngo Weinhold 	}
72498da112cSIngo Weinhold 	return error;
725d6b205f3SIngo Weinhold }
726d6b205f3SIngo Weinhold 
727d6b205f3SIngo Weinhold // GetIconForType
728d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
72998da112cSIngo Weinhold 
73098da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
73198da112cSIngo Weinhold 
73298da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
733d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
734d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
735d6b205f3SIngo Weinhold 		   large icon).
736d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
737d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
738d6b205f3SIngo Weinhold 	\return
739d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
740d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
74198da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
742d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
743d6b205f3SIngo Weinhold 		 not match.
744d6b205f3SIngo Weinhold 	- other error codes
745d6b205f3SIngo Weinhold */
746d6b205f3SIngo Weinhold status_t
747d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
748d6b205f3SIngo Weinhold 							 icon_size which) const
749d6b205f3SIngo Weinhold {
75098da112cSIngo Weinhold 	status_t error = B_OK;
75198da112cSIngo Weinhold 	// set some icon size related variables
75298da112cSIngo Weinhold 	BString attributeString;
75398da112cSIngo Weinhold 	BRect bounds;
754a04efc92SIngo Weinhold 	uint32 attrType = 0;
755a04efc92SIngo Weinhold 	size_t attrSize = 0;
75698da112cSIngo Weinhold 	switch (which) {
75798da112cSIngo Weinhold 		case B_MINI_ICON:
75898da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
75998da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
76098da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
76198da112cSIngo Weinhold 			attrSize = 16 * 16;
76298da112cSIngo Weinhold 			break;
76398da112cSIngo Weinhold 		case B_LARGE_ICON:
76498da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
76598da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
76698da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
76798da112cSIngo Weinhold 			attrSize = 32 * 32;
76898da112cSIngo Weinhold 			break;
76998da112cSIngo Weinhold 		default:
77098da112cSIngo Weinhold 			error = B_BAD_VALUE;
77198da112cSIngo Weinhold 			break;
77298da112cSIngo Weinhold 	}
77398da112cSIngo Weinhold 	// check type param
77498da112cSIngo Weinhold 	if (error == B_OK) {
77598da112cSIngo Weinhold 		if (type) {
77617819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
77717819be3SIngo Weinhold 				attributeString += type;
77817819be3SIngo Weinhold 			else
77998da112cSIngo Weinhold 				error = B_BAD_VALUE;
78098da112cSIngo Weinhold 		} else
78117819be3SIngo Weinhold 			attributeString += kStandardIconType;
78298da112cSIngo Weinhold 	}
78398da112cSIngo Weinhold 	const char *attribute = attributeString.String();
78417819be3SIngo Weinhold 
78598da112cSIngo Weinhold 	// check parameter and initialization
78698da112cSIngo Weinhold 	if (error == B_OK
78798da112cSIngo Weinhold 		&& (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
78898da112cSIngo Weinhold 		error = B_BAD_VALUE;
78998da112cSIngo Weinhold 	}
79098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
79198da112cSIngo Weinhold 		error = B_NO_INIT;
79298da112cSIngo Weinhold 	// read the data
79398da112cSIngo Weinhold 	if (error == B_OK) {
79498da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
79598da112cSIngo Weinhold 		char *buffer = NULL;
79698da112cSIngo Weinhold 		size_t read;
79798da112cSIngo Weinhold 		if (otherColorSpace) {
79898da112cSIngo Weinhold 			// other color space than stored in attribute
79998da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
80098da112cSIngo Weinhold 			if (!buffer)
80198da112cSIngo Weinhold 				error = B_NO_MEMORY;
80298da112cSIngo Weinhold 			if (error == B_OK) {
80398da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
80498da112cSIngo Weinhold 								  read);
80598da112cSIngo Weinhold 			}
80698da112cSIngo Weinhold 		} else {
80798da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
80898da112cSIngo Weinhold 							  read);
80998da112cSIngo Weinhold 		}
81098da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
81198da112cSIngo Weinhold 			error = B_ERROR;
81298da112cSIngo Weinhold 		if (otherColorSpace) {
81398da112cSIngo Weinhold 			// other color space than stored in attribute
81476ba3434SIngo Weinhold 			if (error == B_OK) {
81576ba3434SIngo Weinhold 				error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
81676ba3434SIngo Weinhold 										 0, B_CMAP8);
81776ba3434SIngo Weinhold 			}
81898da112cSIngo Weinhold 			delete[] buffer;
81998da112cSIngo Weinhold 		}
82098da112cSIngo Weinhold 	}
82198da112cSIngo Weinhold 	return error;
822d6b205f3SIngo Weinhold }
823d6b205f3SIngo Weinhold 
824d6b205f3SIngo Weinhold // SetIconForType
825d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
826d6b205f3SIngo Weinhold 
82798da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
828d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
829d6b205f3SIngo Weinhold 
83098da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
83198da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
83298da112cSIngo Weinhold 	before.
83398da112cSIngo Weinhold 
83498da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
835d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
836d6b205f3SIngo Weinhold 		   May be \c NULL.
837d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
838d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
839d6b205f3SIngo Weinhold 	\return
840d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
841d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
842d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
843d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
844d6b205f3SIngo Weinhold 	- other error codes
845d6b205f3SIngo Weinhold */
846d6b205f3SIngo Weinhold status_t
847d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
848d6b205f3SIngo Weinhold 							 icon_size which)
849d6b205f3SIngo Weinhold {
85098da112cSIngo Weinhold 	status_t error = B_OK;
85198da112cSIngo Weinhold 	// set some icon size related variables
85298da112cSIngo Weinhold 	BString attributeString;
85398da112cSIngo Weinhold 	BRect bounds;
854a04efc92SIngo Weinhold 	uint32 attrType = 0;
855a04efc92SIngo Weinhold 	size_t attrSize = 0;
856a04efc92SIngo Weinhold 	int32 resourceID = 0;
85798da112cSIngo Weinhold 	switch (which) {
85898da112cSIngo Weinhold 		case B_MINI_ICON:
85998da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
86098da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
86198da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
86298da112cSIngo Weinhold 			attrSize = 16 * 16;
86398da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
86498da112cSIngo Weinhold 							   : kMiniIconResourceID);
86598da112cSIngo Weinhold 			break;
86698da112cSIngo Weinhold 		case B_LARGE_ICON:
86798da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
86898da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
86998da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
87098da112cSIngo Weinhold 			attrSize = 32 * 32;
87198da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
87298da112cSIngo Weinhold 							   : kLargeIconResourceID);
87398da112cSIngo Weinhold 			break;
87498da112cSIngo Weinhold 		default:
87598da112cSIngo Weinhold 			error = B_BAD_VALUE;
87698da112cSIngo Weinhold 			break;
87798da112cSIngo Weinhold 	}
87898da112cSIngo Weinhold 	// check type param
87998da112cSIngo Weinhold 	if (error == B_OK) {
88098da112cSIngo Weinhold 		if (type) {
88117819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
88298da112cSIngo Weinhold 				attributeString += type;
88317819be3SIngo Weinhold 			else
88417819be3SIngo Weinhold 				error = B_BAD_VALUE;
88598da112cSIngo Weinhold 		} else
88698da112cSIngo Weinhold 			attributeString += kStandardIconType;
88798da112cSIngo Weinhold 	}
88898da112cSIngo Weinhold 	const char *attribute = attributeString.String();
88998da112cSIngo Weinhold 	// check parameter and initialization
89098da112cSIngo Weinhold 	if (error == B_OK && icon
89198da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
89298da112cSIngo Weinhold 		error = B_BAD_VALUE;
89398da112cSIngo Weinhold 	}
89498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
89598da112cSIngo Weinhold 		error = B_NO_INIT;
89698da112cSIngo Weinhold 	// write/remove the attribute
89798da112cSIngo Weinhold 	if (error == B_OK) {
89898da112cSIngo Weinhold 		if (icon) {
89998da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
90098da112cSIngo Weinhold 			if (otherColorSpace) {
90198da112cSIngo Weinhold 				BBitmap bitmap(bounds, B_CMAP8);
90298da112cSIngo Weinhold 				error = bitmap.InitCheck();
90376ba3434SIngo Weinhold 				if (error == B_OK)
90476ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
90598da112cSIngo Weinhold 				if (error == B_OK) {
90698da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
90798da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
90898da112cSIngo Weinhold 				}
90998da112cSIngo Weinhold 			} else {
91098da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
91198da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
91298da112cSIngo Weinhold 			}
91398da112cSIngo Weinhold 		} else	// no icon given => remove
91498da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
91598da112cSIngo Weinhold 	}
91698da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
91798da112cSIngo Weinhold 	BMimeType mimeType;
91898da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
91998da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
92098da112cSIngo Weinhold 			error = mimeType.Install();
92198da112cSIngo Weinhold 		if (error == B_OK)
92298da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
92398da112cSIngo Weinhold 	}
92498da112cSIngo Weinhold 	return error;
925d6b205f3SIngo Weinhold }
926d6b205f3SIngo Weinhold 
927d6b205f3SIngo Weinhold // SetInfoLocation
928d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
929d6b205f3SIngo Weinhold 
930d6b205f3SIngo Weinhold 	The options for \a location are:
931d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
932d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
933d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
934d6b205f3SIngo Weinhold 
935d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
936d6b205f3SIngo Weinhold */
937d6b205f3SIngo Weinhold void
938d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
939d6b205f3SIngo Weinhold {
94098da112cSIngo Weinhold 	fWhere = location;
941d6b205f3SIngo Weinhold }
942d6b205f3SIngo Weinhold 
943d6b205f3SIngo Weinhold // IsUsingAttributes
944d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
945d6b205f3SIngo Weinhold 		   file's attributes.
946d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
947d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
948d6b205f3SIngo Weinhold */
949d6b205f3SIngo Weinhold bool
950d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
951d6b205f3SIngo Weinhold {
95298da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
953d6b205f3SIngo Weinhold }
954d6b205f3SIngo Weinhold 
955d6b205f3SIngo Weinhold // IsUsingResources
956d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
957d6b205f3SIngo Weinhold 		   file's resources.
958d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
959d6b205f3SIngo Weinhold 			resources, \c false otherwise.
960d6b205f3SIngo Weinhold */
961d6b205f3SIngo Weinhold bool
962d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
963d6b205f3SIngo Weinhold {
96498da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
965d6b205f3SIngo Weinhold }
966d6b205f3SIngo Weinhold 
967d6b205f3SIngo Weinhold // FBC
968d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
969d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
970d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
971d6b205f3SIngo Weinhold 
972d6b205f3SIngo Weinhold // =
973d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
974d6b205f3SIngo Weinhold */
975d6b205f3SIngo Weinhold BAppFileInfo &
976d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
977d6b205f3SIngo Weinhold {
978d6b205f3SIngo Weinhold 	return *this;
979d6b205f3SIngo Weinhold }
980d6b205f3SIngo Weinhold 
981d6b205f3SIngo Weinhold // copy constructor
982d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
983d6b205f3SIngo Weinhold */
984d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
985d6b205f3SIngo Weinhold {
986d6b205f3SIngo Weinhold }
987d6b205f3SIngo Weinhold 
98898da112cSIngo Weinhold // GetMetaMime
98998da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
99098da112cSIngo Weinhold 
99198da112cSIngo Weinhold 	The parameter \a meta is not checked.
99298da112cSIngo Weinhold 
99398da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
99498da112cSIngo Weinhold 		   initialized to the file's signature.
99598da112cSIngo Weinhold 	\return
99698da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
99798da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
99898da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
99998da112cSIngo Weinhold (	  not installed in the MIME database.)
100098da112cSIngo Weinhold 	  no valid MIME string.
100198da112cSIngo Weinhold 	- other error codes
100298da112cSIngo Weinhold */
100398da112cSIngo Weinhold status_t
100498da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
100598da112cSIngo Weinhold {
100698da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
100798da112cSIngo Weinhold 	status_t error = GetSignature(signature);
100898da112cSIngo Weinhold 	if (error == B_OK)
100998da112cSIngo Weinhold 		error = meta->SetTo(signature);
101098da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
101198da112cSIngo Weinhold 		error = B_BAD_VALUE;
101298da112cSIngo Weinhold 	return error;
101398da112cSIngo Weinhold }
101498da112cSIngo Weinhold 
101598da112cSIngo Weinhold // _ReadData
101698da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
101798da112cSIngo Weinhold 
101898da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
101998da112cSIngo Weinhold 
102098da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
102198da112cSIngo Weinhold 
102298da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
102398da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
102498da112cSIngo Weinhold 		   < 0.
102598da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
102698da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
102798da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
102898da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
102998da112cSIngo Weinhold 		   actually read.
103098da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
103198da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
103298da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
103398da112cSIngo Weinhold 	\return
103498da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
103598da112cSIngo Weinhold 	- error code
103698da112cSIngo Weinhold */
103798da112cSIngo Weinhold status_t
103898da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
103998da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
104098da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
104198da112cSIngo Weinhold {
104298da112cSIngo Weinhold 	status_t error = B_OK;
104398da112cSIngo Weinhold 	if (allocatedBuffer)
104498da112cSIngo Weinhold 		buffer = NULL;
104598da112cSIngo Weinhold 	if (IsUsingAttributes()) {
104698da112cSIngo Weinhold 		// get an attribute info
104798da112cSIngo Weinhold 		attr_info info;
104898da112cSIngo Weinhold 		if (error == B_OK)
104998da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
105098da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
105198da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
105298da112cSIngo Weinhold 			error = B_BAD_VALUE;
105398da112cSIngo Weinhold 		if (allocatedBuffer) {
105498da112cSIngo Weinhold 			buffer = malloc(info.size);
105598da112cSIngo Weinhold 			if (!buffer)
105698da112cSIngo Weinhold 				error = B_NO_MEMORY;
105798da112cSIngo Weinhold 			bufferSize = info.size;
105898da112cSIngo Weinhold 		}
105998da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
106098da112cSIngo Weinhold 			error = B_BAD_VALUE;
106198da112cSIngo Weinhold 		// read the data
106298da112cSIngo Weinhold 		if (error == B_OK) {
106398da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
106498da112cSIngo Weinhold 			if (read < 0)
106598da112cSIngo Weinhold 				error = read;
106698da112cSIngo Weinhold 			else if (read != info.size)
106798da112cSIngo Weinhold 				error = B_ERROR;
106898da112cSIngo Weinhold 			else
106998da112cSIngo Weinhold 				bytesRead = read;
107098da112cSIngo Weinhold 		}
107198da112cSIngo Weinhold 	} else if (IsUsingResources()) {
107298da112cSIngo Weinhold 		// get a resource info
107398da112cSIngo Weinhold 		int32 idFound;
107498da112cSIngo Weinhold 		size_t sizeFound;
107598da112cSIngo Weinhold 		if (error == B_OK) {
107698da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
107798da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
107898da112cSIngo Weinhold 		}
107998da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
108098da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
108198da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
108298da112cSIngo Weinhold 		if (allocatedBuffer) {
108398da112cSIngo Weinhold 			buffer = malloc(sizeFound);
108498da112cSIngo Weinhold 			if (!buffer)
108598da112cSIngo Weinhold 				error = B_NO_MEMORY;
108698da112cSIngo Weinhold 			bufferSize = sizeFound;
108798da112cSIngo Weinhold 		}
108898da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
108998da112cSIngo Weinhold 			error = B_BAD_VALUE;
109098da112cSIngo Weinhold 		// load resource
109198da112cSIngo Weinhold 		const void *resourceData = NULL;
109298da112cSIngo Weinhold 		if (error == B_OK) {
109398da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
109498da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
109598da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
109698da112cSIngo Weinhold 			else
109798da112cSIngo Weinhold 				error = B_ERROR;
109898da112cSIngo Weinhold 		}
109998da112cSIngo Weinhold 	} else
110098da112cSIngo Weinhold 		error = B_BAD_VALUE;
110198da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
110298da112cSIngo Weinhold 	if (allocatedBuffer) {
110398da112cSIngo Weinhold 		if (error == B_OK)
110498da112cSIngo Weinhold 			*allocatedBuffer = buffer;
110598da112cSIngo Weinhold 		else
110698da112cSIngo Weinhold 			free(buffer);
110798da112cSIngo Weinhold 	}
110898da112cSIngo Weinhold 	return error;
110998da112cSIngo Weinhold }
111098da112cSIngo Weinhold 
111198da112cSIngo Weinhold // _WriteData
111298da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
111398da112cSIngo Weinhold 
111498da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
111598da112cSIngo Weinhold 
111698da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
111798da112cSIngo Weinhold 
111898da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
111998da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
112098da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
112198da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
112298da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
112398da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
112498da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
112598da112cSIngo Weinhold 		   If \c false, \a id is used.
112698da112cSIngo Weinhold 	If \a id is already in use and .
112798da112cSIngo Weinhold 	\return
112898da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
112998da112cSIngo Weinhold 	- error code
113098da112cSIngo Weinhold */
113198da112cSIngo Weinhold status_t
113298da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
113398da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
113498da112cSIngo Weinhold {
113598da112cSIngo Weinhold 	status_t error = B_OK;
113698da112cSIngo Weinhold 	// write to attribute
113798da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
113898da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
113998da112cSIngo Weinhold 		if (written < 0)
114098da112cSIngo Weinhold 			error = written;
114198da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
114298da112cSIngo Weinhold 			error = B_ERROR;
114398da112cSIngo Weinhold 	}
114498da112cSIngo Weinhold 	// write to resource
114598da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
114698da112cSIngo Weinhold 		if (findID) {
114798da112cSIngo Weinhold 			// get the resource info
114898da112cSIngo Weinhold 			int32 idFound;
114998da112cSIngo Weinhold 			size_t sizeFound;
115098da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
115198da112cSIngo Weinhold 				id = idFound;
115298da112cSIngo Weinhold 			else {
115398da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
115498da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
115598da112cSIngo Weinhold 					id++;
115698da112cSIngo Weinhold 			}
115798da112cSIngo Weinhold 		}
115898da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
115998da112cSIngo Weinhold 	}
116098da112cSIngo Weinhold 	return error;
116198da112cSIngo Weinhold }
116298da112cSIngo Weinhold 
116398da112cSIngo Weinhold // _RemoveData
116498da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
116598da112cSIngo Weinhold 
116698da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
116798da112cSIngo Weinhold 
116898da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
116998da112cSIngo Weinhold 
117098da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
117198da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
117298da112cSIngo Weinhold 	\return
117398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
117498da112cSIngo Weinhold 	- error code
117598da112cSIngo Weinhold */
117698da112cSIngo Weinhold status_t
117798da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
117898da112cSIngo Weinhold {
117998da112cSIngo Weinhold 	status_t error = B_OK;
118098da112cSIngo Weinhold 	// remove the attribute
118198da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
118298da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
118398da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
118498da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
118598da112cSIngo Weinhold 			error = B_OK;
118698da112cSIngo Weinhold 	}
118798da112cSIngo Weinhold 	// remove the resource
118898da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
118998da112cSIngo Weinhold 		// get a resource info
119098da112cSIngo Weinhold 		int32 idFound;
119198da112cSIngo Weinhold 		size_t sizeFound;
119298da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
119398da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
119498da112cSIngo Weinhold 	}
119598da112cSIngo Weinhold 	return error;
119698da112cSIngo Weinhold }
119798da112cSIngo Weinhold 
1198