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