xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 76ba3434f81d65243dbc5512872b7da262103396)
1d6b205f3SIngo Weinhold // BAppFileInfo.cpp
2d6b205f3SIngo Weinhold 
398da112cSIngo Weinhold #include <new>
498da112cSIngo Weinhold #include <set>
598da112cSIngo Weinhold #include <string>
698da112cSIngo Weinhold 
7d6b205f3SIngo Weinhold #include <AppFileInfo.h>
898da112cSIngo Weinhold #include <Bitmap.h>
998da112cSIngo Weinhold #include <File.h>
1098da112cSIngo Weinhold #include <fs_attr.h>
1198da112cSIngo Weinhold #include <MimeType.h>
1298da112cSIngo Weinhold #include <RegistrarDefs.h>
1398da112cSIngo Weinhold #include <Resources.h>
1498da112cSIngo Weinhold #include <Roster.h>
1598da112cSIngo Weinhold #include <String.h>
1698da112cSIngo Weinhold 
1798da112cSIngo Weinhold // attributes
1898da112cSIngo Weinhold static const char *kTypeAttribute				= "BEOS:TYPE";
1998da112cSIngo Weinhold static const char *kSignatureAttribute			= "BEOS:APP_SIG";
2098da112cSIngo Weinhold static const char *kAppFlagsAttribute			= "BEOS:APP_FLAGS";
2198da112cSIngo Weinhold static const char *kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
2298da112cSIngo Weinhold static const char *kVersionInfoAttribute		= "BEOS:APP_VERSION";
2398da112cSIngo Weinhold static const char *kMiniIconAttribute			= "BEOS:M:";
2498da112cSIngo Weinhold static const char *kLargeIconAttribute			= "BEOS:L:";
2598da112cSIngo Weinhold static const char *kStandardIconType			= "STD_ICON";
2698da112cSIngo Weinhold 
2798da112cSIngo Weinhold // resource IDs
2898da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
2998da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
3098da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
3198da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
3298da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
3398da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
3498da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
3598da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
3698da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
3798da112cSIngo Weinhold 
3898da112cSIngo Weinhold // type codes
3998da112cSIngo Weinhold enum {
4098da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
4198da112cSIngo Weinhold 	B_MINI_ICON_TYPE	= 'MICN',
4298da112cSIngo Weinhold 	B_LARGE_ICON_TYPE	= 'ICON',
4398da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
4498da112cSIngo Weinhold };
4598da112cSIngo Weinhold 
46d6b205f3SIngo Weinhold 
47d6b205f3SIngo Weinhold enum {
48d6b205f3SIngo Weinhold 	NOT_IMPLEMENTED	= B_ERROR,
49d6b205f3SIngo Weinhold };
50d6b205f3SIngo Weinhold 
51d6b205f3SIngo Weinhold // constructor
52d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
53d6b205f3SIngo Weinhold */
54d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
55d6b205f3SIngo Weinhold 			: fResources(NULL),
56d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
57d6b205f3SIngo Weinhold {
58d6b205f3SIngo Weinhold }
59d6b205f3SIngo Weinhold 
60d6b205f3SIngo Weinhold // constructor
61d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
62d6b205f3SIngo Weinhold 		   file.
63d6b205f3SIngo Weinhold 
64d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
65d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
66d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
67d6b205f3SIngo Weinhold 
68d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
69d6b205f3SIngo Weinhold */
70d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
71d6b205f3SIngo Weinhold 			: fResources(NULL),
72d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
73d6b205f3SIngo Weinhold {
7498da112cSIngo Weinhold 	SetTo(file);
75d6b205f3SIngo Weinhold }
76d6b205f3SIngo Weinhold 
77d6b205f3SIngo Weinhold // destructor
78d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
79d6b205f3SIngo Weinhold 
80d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
81d6b205f3SIngo Weinhold */
82d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
83d6b205f3SIngo Weinhold {
8498da112cSIngo Weinhold 	if (fResources)
8598da112cSIngo Weinhold 		delete fResources;
86d6b205f3SIngo Weinhold }
87d6b205f3SIngo Weinhold 
88d6b205f3SIngo Weinhold // SetTo
89d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
90d6b205f3SIngo Weinhold 
91d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
92d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
93d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
94d6b205f3SIngo Weinhold 
95d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
96d6b205f3SIngo Weinhold 
97d6b205f3SIngo Weinhold 	\return
98d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
99d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
100d6b205f3SIngo Weinhold */
101d6b205f3SIngo Weinhold status_t
102d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
103d6b205f3SIngo Weinhold {
10498da112cSIngo Weinhold 	// unset the old file
10598da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
10698da112cSIngo Weinhold 	if (fResources) {
10798da112cSIngo Weinhold 		delete fResources;
10898da112cSIngo Weinhold 		fResources = NULL;
10998da112cSIngo Weinhold 	}
11098da112cSIngo Weinhold 	// check param
11198da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
11298da112cSIngo Weinhold 	// create resources
11398da112cSIngo Weinhold 	if (error == B_OK) {
11498da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
11598da112cSIngo Weinhold 		if (fResources)
11698da112cSIngo Weinhold 			error = fResources->SetTo(file);
11798da112cSIngo Weinhold 		else
11898da112cSIngo Weinhold 			error = B_NO_MEMORY;
11998da112cSIngo Weinhold 	}
12098da112cSIngo Weinhold 	// set node info
12198da112cSIngo Weinhold 	if (error == B_OK)
12298da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
12398da112cSIngo Weinhold 	// clean up on error
12498da112cSIngo Weinhold 	if (error != B_OK) {
12598da112cSIngo Weinhold 		if (fResources) {
12698da112cSIngo Weinhold 			delete fResources;
12798da112cSIngo Weinhold 			fResources = NULL;
12898da112cSIngo Weinhold 		}
12998da112cSIngo Weinhold 		if (InitCheck() == B_OK)
13098da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
13198da112cSIngo Weinhold 	}
13298da112cSIngo Weinhold 	// set data location
13398da112cSIngo Weinhold 	if (error == B_OK)
13498da112cSIngo Weinhold 		SetInfoLocation(B_USE_BOTH_LOCATIONS);
13598da112cSIngo Weinhold 	// set error
13698da112cSIngo Weinhold 	fCStatus = error;
13798da112cSIngo Weinhold 	return error;
138d6b205f3SIngo Weinhold }
139d6b205f3SIngo Weinhold 
140d6b205f3SIngo Weinhold // GetType
141d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
142d6b205f3SIngo Weinhold 
143d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
144d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
145d6b205f3SIngo Weinhold 		   file shall be written.
146d6b205f3SIngo Weinhold 	\return
147d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
148d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
149d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
150d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
151d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
152d6b205f3SIngo Weinhold 	  the wrong type.
153d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
154d6b205f3SIngo Weinhold 	- other error codes
155d6b205f3SIngo Weinhold */
156d6b205f3SIngo Weinhold status_t
157d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
158d6b205f3SIngo Weinhold {
15998da112cSIngo Weinhold 	// check param and initialization
16098da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
16198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
16298da112cSIngo Weinhold 		error = B_NO_INIT;
16398da112cSIngo Weinhold 	// read the data
16498da112cSIngo Weinhold 	size_t read = 0;
16598da112cSIngo Weinhold 	if (error == B_OK) {
16698da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
16798da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
16898da112cSIngo Weinhold 	}
16998da112cSIngo Weinhold 	// check the read data -- null terminate the string
17098da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
17198da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
17298da112cSIngo Weinhold 			error = B_ERROR;
17398da112cSIngo Weinhold 		else
17498da112cSIngo Weinhold 			type[read] = '\0';
17598da112cSIngo Weinhold 	}
17698da112cSIngo Weinhold 	return error;
177d6b205f3SIngo Weinhold }
178d6b205f3SIngo Weinhold 
179d6b205f3SIngo Weinhold // SetType
180d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
181d6b205f3SIngo Weinhold 
182d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
183d6b205f3SIngo Weinhold 
184d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
185d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
186d6b205f3SIngo Weinhold 		   May be \c NULL.
187d6b205f3SIngo Weinhold 	\return
188d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
189d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
190d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
191d6b205f3SIngo Weinhold 	- other error codes
192d6b205f3SIngo Weinhold */
193d6b205f3SIngo Weinhold status_t
194d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
195d6b205f3SIngo Weinhold {
19698da112cSIngo Weinhold 	// check initialization
19798da112cSIngo Weinhold 	status_t error = B_OK;
19898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
19998da112cSIngo Weinhold 		error = B_NO_INIT;
20098da112cSIngo Weinhold 	if (error == B_OK) {
20198da112cSIngo Weinhold 		if (type) {
20298da112cSIngo Weinhold 			// check param
20398da112cSIngo Weinhold 			size_t typeLen = strlen(type);
20498da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
20598da112cSIngo Weinhold 				error = B_BAD_VALUE;
20698da112cSIngo Weinhold 			// write the data
20798da112cSIngo Weinhold 			if (error == B_OK) {
20898da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
20998da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
21098da112cSIngo Weinhold 			}
21198da112cSIngo Weinhold 		} else
21298da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
21398da112cSIngo Weinhold 	}
21498da112cSIngo Weinhold 	return error;
215d6b205f3SIngo Weinhold }
216d6b205f3SIngo Weinhold 
217d6b205f3SIngo Weinhold // GetSignature
218d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
219d6b205f3SIngo Weinhold 
220d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
221d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
222d6b205f3SIngo Weinhold 		   signature of the file shall be written.
223d6b205f3SIngo Weinhold 	\return
224d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
225d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
226d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
227d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
228d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
229d6b205f3SIngo Weinhold 	  the wrong type.
230d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
231d6b205f3SIngo Weinhold 	- other error codes
232d6b205f3SIngo Weinhold */
233d6b205f3SIngo Weinhold status_t
234d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
235d6b205f3SIngo Weinhold {
23698da112cSIngo Weinhold 	// check param and initialization
23798da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
23898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
23998da112cSIngo Weinhold 		error = B_NO_INIT;
24098da112cSIngo Weinhold 	// read the data
24198da112cSIngo Weinhold 	size_t read = 0;
24298da112cSIngo Weinhold 	if (error == B_OK) {
24398da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
24498da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
24598da112cSIngo Weinhold 						  read);
24698da112cSIngo Weinhold 	}
24798da112cSIngo Weinhold 	// check the read data -- null terminate the string
24898da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
24998da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
25098da112cSIngo Weinhold 			error = B_ERROR;
25198da112cSIngo Weinhold 		else
25298da112cSIngo Weinhold 			signature[read] = '\0';
25398da112cSIngo Weinhold 	}
25498da112cSIngo Weinhold 	return error;
255d6b205f3SIngo Weinhold }
256d6b205f3SIngo Weinhold 
257d6b205f3SIngo Weinhold // SetSignature
258d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
259d6b205f3SIngo Weinhold 
260d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
261d6b205f3SIngo Weinhold 
262d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
263d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
264d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
265d6b205f3SIngo Weinhold 	\return
266d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
267d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
268d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
269d6b205f3SIngo Weinhold 	- other error codes
270d6b205f3SIngo Weinhold */
271d6b205f3SIngo Weinhold status_t
272d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
273d6b205f3SIngo Weinhold {
27498da112cSIngo Weinhold 	// check initialization
27598da112cSIngo Weinhold 	status_t error = B_OK;
27698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
27798da112cSIngo Weinhold 		error = B_NO_INIT;
27898da112cSIngo Weinhold 	if (error == B_OK) {
27998da112cSIngo Weinhold 		if (signature) {
28098da112cSIngo Weinhold 			// check param
28198da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
28298da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
28398da112cSIngo Weinhold 				error = B_BAD_VALUE;
28498da112cSIngo Weinhold 			// write the data
28598da112cSIngo Weinhold 			if (error == B_OK) {
28698da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
28798da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
28898da112cSIngo Weinhold 								   signatureLen + 1);
28998da112cSIngo Weinhold 			}
29098da112cSIngo Weinhold 		} else
29198da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
29298da112cSIngo Weinhold 	}
29398da112cSIngo Weinhold 	return error;
294d6b205f3SIngo Weinhold }
295d6b205f3SIngo Weinhold 
296d6b205f3SIngo Weinhold // GetAppFlags
297d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
298d6b205f3SIngo Weinhold 
299d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
300d6b205f3SIngo Weinhold 		   flags of the file shall be written.
301d6b205f3SIngo Weinhold 	\return
302d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
303d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
304d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
305d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
306d6b205f3SIngo Weinhold 	  the wrong type.
307d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
308d6b205f3SIngo Weinhold 	- other error codes
309d6b205f3SIngo Weinhold */
310d6b205f3SIngo Weinhold status_t
311d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
312d6b205f3SIngo Weinhold {
31398da112cSIngo Weinhold 	// check param and initialization
31498da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
31598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
31698da112cSIngo Weinhold 		error = B_NO_INIT;
31798da112cSIngo Weinhold 	// read the data
31898da112cSIngo Weinhold 	size_t read = 0;
31998da112cSIngo Weinhold 	if (error == B_OK) {
32098da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
32198da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
32298da112cSIngo Weinhold 						  read);
32398da112cSIngo Weinhold 	}
32498da112cSIngo Weinhold 	// check the read data
32598da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
32698da112cSIngo Weinhold 		error = B_ERROR;
32798da112cSIngo Weinhold 	return error;
328d6b205f3SIngo Weinhold }
329d6b205f3SIngo Weinhold 
330d6b205f3SIngo Weinhold // SetAppFlags
331d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
332d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
333d6b205f3SIngo Weinhold 	\return
334d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
335d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
336d6b205f3SIngo Weinhold 	- other error codes
337d6b205f3SIngo Weinhold */
338d6b205f3SIngo Weinhold status_t
339d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
340d6b205f3SIngo Weinhold {
34198da112cSIngo Weinhold 	// check initialization
34298da112cSIngo Weinhold 	status_t error = B_OK;
34398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
34498da112cSIngo Weinhold 		error = B_NO_INIT;
34598da112cSIngo Weinhold 	if (error == B_OK) {
34698da112cSIngo Weinhold 		// write the data
34798da112cSIngo Weinhold 		if (error == B_OK) {
34898da112cSIngo Weinhold 			error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
34998da112cSIngo Weinhold 							   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
35098da112cSIngo Weinhold 		}
35198da112cSIngo Weinhold 	}
35298da112cSIngo Weinhold 	return error;
353d6b205f3SIngo Weinhold }
354d6b205f3SIngo Weinhold 
355d6b205f3SIngo Weinhold // GetSupportedTypes
356d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
357d6b205f3SIngo Weinhold 
358d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
359d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
360d6b205f3SIngo Weinhold 
361d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
362d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
363d6b205f3SIngo Weinhold 	\return
364d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
365d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
366d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
367d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
368d6b205f3SIngo Weinhold 	  have the wrong type.
369d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
370d6b205f3SIngo Weinhold 	- other error codes
371d6b205f3SIngo Weinhold */
372d6b205f3SIngo Weinhold status_t
373d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
374d6b205f3SIngo Weinhold {
37598da112cSIngo Weinhold 	// check param and initialization
37698da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
37798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
37898da112cSIngo Weinhold 		error = B_NO_INIT;
37998da112cSIngo Weinhold 	// read the data
38098da112cSIngo Weinhold 	size_t read = 0;
38198da112cSIngo Weinhold 	void *buffer = NULL;
38298da112cSIngo Weinhold 	if (error == B_OK) {
38398da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
38498da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
38598da112cSIngo Weinhold 	}
38698da112cSIngo Weinhold 	// unflatten the buffer
38798da112cSIngo Weinhold 	if (error == B_OK)
38898da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
38998da112cSIngo Weinhold 	// clean up
39098da112cSIngo Weinhold 	if (buffer)
39198da112cSIngo Weinhold 		free(buffer);
39298da112cSIngo Weinhold 	return error;
393d6b205f3SIngo Weinhold }
394d6b205f3SIngo Weinhold 
395d6b205f3SIngo Weinhold // SetSupportedTypes
396d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
397d6b205f3SIngo Weinhold 
398d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
399d6b205f3SIngo Weinhold 
400d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
401d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
402d6b205f3SIngo Weinhold 
40383a812a1SIngo Weinhold 	The method informs the registrar about this news.
40483a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
40583a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
40683a812a1SIngo Weinhold 	application file needs to have a signature set.
40783a812a1SIngo Weinhold 
40883a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
40983a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
41083a812a1SIngo Weinhold 	lists of supporting applications.
41183a812a1SIngo Weinhold 
412d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
413d6b205f3SIngo Weinhold 		   May be \c NULL.
41483a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
41583a812a1SIngo Weinhold 		   types, \c false otherwise.
416d6b205f3SIngo Weinhold 	\return
417d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
418d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
419d6b205f3SIngo Weinhold 	- other error codes
420d6b205f3SIngo Weinhold */
421d6b205f3SIngo Weinhold status_t
422d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
423d6b205f3SIngo Weinhold {
42498da112cSIngo Weinhold 	// check initialization
42598da112cSIngo Weinhold 	status_t error = B_OK;
42698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
42798da112cSIngo Weinhold 		error = B_NO_INIT;
42898da112cSIngo Weinhold 	BMimeType mimeType;
42998da112cSIngo Weinhold 	if (error == B_OK)
43098da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
43198da112cSIngo Weinhold 	if (error == B_OK) {
43298da112cSIngo Weinhold 		if (types) {
43317819be3SIngo Weinhold 			// check param -- supported types must be valid
43417819be3SIngo Weinhold 			const char *type;
43517819be3SIngo Weinhold 			for (int32 i = 0;
43617819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
43717819be3SIngo Weinhold 				 i++) {
43817819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
43917819be3SIngo Weinhold 					error = B_BAD_VALUE;
44017819be3SIngo Weinhold 			}
44117819be3SIngo Weinhold 			// get flattened size
44217819be3SIngo Weinhold 			ssize_t size = 0;
44317819be3SIngo Weinhold 			if (error == B_OK) {
44417819be3SIngo Weinhold 				size = types->FlattenedSize();
44598da112cSIngo Weinhold 				if (size < 0)
44698da112cSIngo Weinhold 					error = size;
44717819be3SIngo Weinhold 			}
44898da112cSIngo Weinhold 			// allocate a buffer for the flattened data
44998da112cSIngo Weinhold 			char *buffer = NULL;
45098da112cSIngo Weinhold 			if (error == B_OK) {
45198da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
45298da112cSIngo Weinhold 				if (!buffer)
45398da112cSIngo Weinhold 					error = B_NO_MEMORY;
45498da112cSIngo Weinhold 			}
45598da112cSIngo Weinhold 			// flatten the message
45698da112cSIngo Weinhold 			if (error == B_OK)
45798da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
45898da112cSIngo Weinhold 			// write the data
45998da112cSIngo Weinhold 			if (error == B_OK) {
46098da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
46198da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
46298da112cSIngo Weinhold 								   buffer, size);
46398da112cSIngo Weinhold 			}
46498da112cSIngo Weinhold 			// clean up
46598da112cSIngo Weinhold 			if (buffer)
46698da112cSIngo Weinhold 				delete[] buffer;
46798da112cSIngo Weinhold 		} else
46898da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
46998da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
47017819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
47117819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
47298da112cSIngo Weinhold 	}
47398da112cSIngo Weinhold 	return error;
474d6b205f3SIngo Weinhold }
475d6b205f3SIngo Weinhold 
476d6b205f3SIngo Weinhold // SetSupportedTypes
477d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
478d6b205f3SIngo Weinhold 
47998da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
48083a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
481d6b205f3SIngo Weinhold 
482d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
483d6b205f3SIngo Weinhold 		   May be \c NULL.
484d6b205f3SIngo Weinhold 	\return
485d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
486d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
487d6b205f3SIngo Weinhold 	- other error codes
488d6b205f3SIngo Weinhold */
489d6b205f3SIngo Weinhold status_t
490d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
491d6b205f3SIngo Weinhold {
49298da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
493d6b205f3SIngo Weinhold }
494d6b205f3SIngo Weinhold 
495d6b205f3SIngo Weinhold // IsSupportedType
496d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
497d6b205f3SIngo Weinhold 
498d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
499d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
500d6b205f3SIngo Weinhold 
501d6b205f3SIngo Weinhold 	\param type The MIME type in question.
502d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
503d6b205f3SIngo Weinhold 			the application, \c false otherwise.
504d6b205f3SIngo Weinhold */
505d6b205f3SIngo Weinhold bool
506d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
507d6b205f3SIngo Weinhold {
50898da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
50998da112cSIngo Weinhold 	// get the supported types
51098da112cSIngo Weinhold 	BMessage types;
51198da112cSIngo Weinhold 	if (error == B_OK)
51298da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
51398da112cSIngo Weinhold 	// turn type into a BMimeType
51498da112cSIngo Weinhold 	BMimeType mimeType;
51598da112cSIngo Weinhold 	if (error == B_OK)
51698da112cSIngo Weinhold 		error = mimeType.SetTo(type);
51798da112cSIngo Weinhold 	// iterate through the supported types
51898da112cSIngo Weinhold 	bool found = false;
51998da112cSIngo Weinhold 	if (error == B_OK) {
52098da112cSIngo Weinhold 		const char *supportedType;
52198da112cSIngo Weinhold 		for (int32 i = 0;
52298da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
52398da112cSIngo Weinhold 			 i++) {
52498da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
52598da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
52698da112cSIngo Weinhold 		}
52798da112cSIngo Weinhold 	}
52898da112cSIngo Weinhold 	return found;
529d6b205f3SIngo Weinhold }
530d6b205f3SIngo Weinhold 
531d6b205f3SIngo Weinhold // Supports
532d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
533d6b205f3SIngo Weinhold 		   explicitly.
534d6b205f3SIngo Weinhold 
535d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
536d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
537d6b205f3SIngo Weinhold 	"application/octet-stream".
538d6b205f3SIngo Weinhold 
539d6b205f3SIngo Weinhold 	\param type The MIME type in question.
540d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
541d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
542d6b205f3SIngo Weinhold */
543d6b205f3SIngo Weinhold bool
544d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
545d6b205f3SIngo Weinhold {
54698da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
54798da112cSIngo Weinhold 	// get the supported types
54898da112cSIngo Weinhold 	BMessage types;
54998da112cSIngo Weinhold 	if (error == B_OK)
55098da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
55198da112cSIngo Weinhold 	// iterate through the supported types
55298da112cSIngo Weinhold 	bool found = false;
55398da112cSIngo Weinhold 	if (error == B_OK) {
55498da112cSIngo Weinhold 		const char *supportedType;
55598da112cSIngo Weinhold 		for (int32 i = 0;
55698da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
55798da112cSIngo Weinhold 			 i++) {
55898da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
55998da112cSIngo Weinhold 		}
56098da112cSIngo Weinhold 	}
56198da112cSIngo Weinhold 	return found;
562d6b205f3SIngo Weinhold }
563d6b205f3SIngo Weinhold 
564d6b205f3SIngo Weinhold // GetIcon
565d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
566d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
567d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
568d6b205f3SIngo Weinhold 		   large icon).
569d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
570d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
571d6b205f3SIngo Weinhold 	\return
572d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
573d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
574d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
575d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
576d6b205f3SIngo Weinhold 	- other error codes
577d6b205f3SIngo Weinhold */
578d6b205f3SIngo Weinhold status_t
579d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
580d6b205f3SIngo Weinhold {
58198da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
582d6b205f3SIngo Weinhold }
583d6b205f3SIngo Weinhold 
584d6b205f3SIngo Weinhold // SetIcon
585d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
586d6b205f3SIngo Weinhold 
587d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
588d6b205f3SIngo Weinhold 
589d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
590d6b205f3SIngo Weinhold 		   May be \c NULL.
591d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
592d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
593d6b205f3SIngo Weinhold 	\return
594d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
595d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
596d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
597d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
598d6b205f3SIngo Weinhold 	- other error codes
599d6b205f3SIngo Weinhold */
600d6b205f3SIngo Weinhold status_t
601d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
602d6b205f3SIngo Weinhold {
60398da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
604d6b205f3SIngo Weinhold }
605d6b205f3SIngo Weinhold 
606d6b205f3SIngo Weinhold // GetVersionInfo
607d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
608d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
609d6b205f3SIngo Weinhold 		   the version info should be written.
610d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
611d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
612d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
613d6b205f3SIngo Weinhold 		   belongs to.
614d6b205f3SIngo Weinhold 	\return
615d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
616d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
617d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
618d6b205f3SIngo Weinhold 	- other error codes
619d6b205f3SIngo Weinhold */
620d6b205f3SIngo Weinhold status_t
621d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
622d6b205f3SIngo Weinhold {
62398da112cSIngo Weinhold 	// check params and initialization
62498da112cSIngo Weinhold 	status_t error = (info ? B_OK : B_BAD_VALUE);
62598da112cSIngo Weinhold 	int32 index = 0;
62698da112cSIngo Weinhold 	if (error == B_OK) {
62798da112cSIngo Weinhold 		switch (kind) {
62898da112cSIngo Weinhold 			case B_APP_VERSION_KIND:
62998da112cSIngo Weinhold 				index = 0;
63098da112cSIngo Weinhold 				break;
63198da112cSIngo Weinhold 			case B_SYSTEM_VERSION_KIND:
63298da112cSIngo Weinhold 				index = 1;
63398da112cSIngo Weinhold 				break;
63498da112cSIngo Weinhold 			default:
63598da112cSIngo Weinhold 				error = B_BAD_VALUE;
63698da112cSIngo Weinhold 				break;
63798da112cSIngo Weinhold 		}
63898da112cSIngo Weinhold 	}
63998da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
64098da112cSIngo Weinhold 		error = B_NO_INIT;
64198da112cSIngo Weinhold 	// read the data
64298da112cSIngo Weinhold 	size_t read = 0;
64398da112cSIngo Weinhold 	version_info infos[2];
64498da112cSIngo Weinhold 	if (error == B_OK) {
64598da112cSIngo Weinhold 		error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
64698da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
64798da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
64898da112cSIngo Weinhold 	}
64998da112cSIngo Weinhold 	// check the read data -- null terminate the string
65098da112cSIngo Weinhold 	if (error == B_OK && read != 2 * sizeof(version_info))
65198da112cSIngo Weinhold 		error = B_ERROR;
65298da112cSIngo Weinhold 	if (error == B_OK)
65398da112cSIngo Weinhold 		*info = infos[index];
65498da112cSIngo Weinhold 	return error;
655d6b205f3SIngo Weinhold }
656d6b205f3SIngo Weinhold 
657d6b205f3SIngo Weinhold // SetVersionInfo
658d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
659d6b205f3SIngo Weinhold 
660d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
661d6b205f3SIngo Weinhold 
662d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
663d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
664d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
665d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
666d6b205f3SIngo Weinhold 		   belongs to.
667d6b205f3SIngo Weinhold 	\return
668d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
669d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
670d6b205f3SIngo Weinhold 	- other error codes
671d6b205f3SIngo Weinhold */
672d6b205f3SIngo Weinhold status_t
673d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
674d6b205f3SIngo Weinhold {
67598da112cSIngo Weinhold 	// check initialization
67698da112cSIngo Weinhold 	status_t error = B_OK;
67798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
67898da112cSIngo Weinhold 		error = B_NO_INIT;
67998da112cSIngo Weinhold 	if (error == B_OK) {
68098da112cSIngo Weinhold 		if (info) {
68198da112cSIngo Weinhold 			// check param
68298da112cSIngo Weinhold 			int32 index = 0;
68398da112cSIngo Weinhold 			if (error == B_OK) {
68498da112cSIngo Weinhold 				switch (kind) {
68598da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
68698da112cSIngo Weinhold 						index = 0;
68798da112cSIngo Weinhold 						break;
68898da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
68998da112cSIngo Weinhold 						index = 1;
69098da112cSIngo Weinhold 						break;
69198da112cSIngo Weinhold 					default:
69298da112cSIngo Weinhold 						error = B_BAD_VALUE;
69398da112cSIngo Weinhold 						break;
69498da112cSIngo Weinhold 				}
69598da112cSIngo Weinhold 			}
69698da112cSIngo Weinhold 			// read both infos
69798da112cSIngo Weinhold 			version_info infos[2];
69898da112cSIngo Weinhold 			if (error == B_OK) {
69998da112cSIngo Weinhold 				size_t read;
70098da112cSIngo Weinhold 				_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
70198da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
70298da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
70398da112cSIngo Weinhold 			}
70498da112cSIngo Weinhold 			infos[index] = *info;
70598da112cSIngo Weinhold 			// write the data
70698da112cSIngo Weinhold 			if (error == B_OK) {
70798da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
70898da112cSIngo Weinhold 								   kVersionInfoResourceID,
70998da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
71098da112cSIngo Weinhold 								   2 * sizeof(version_info));
71198da112cSIngo Weinhold 			}
71298da112cSIngo Weinhold 		} else
71398da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
71498da112cSIngo Weinhold 	}
71598da112cSIngo Weinhold 	return error;
716d6b205f3SIngo Weinhold }
717d6b205f3SIngo Weinhold 
718d6b205f3SIngo Weinhold // GetIconForType
719d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
72098da112cSIngo Weinhold 
72198da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
72298da112cSIngo Weinhold 
72398da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
724d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
725d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
726d6b205f3SIngo Weinhold 		   large icon).
727d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
728d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
729d6b205f3SIngo Weinhold 	\return
730d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
731d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
73298da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
733d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
734d6b205f3SIngo Weinhold 		 not match.
735d6b205f3SIngo Weinhold 	- other error codes
736d6b205f3SIngo Weinhold */
737d6b205f3SIngo Weinhold status_t
738d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
739d6b205f3SIngo Weinhold 							 icon_size which) const
740d6b205f3SIngo Weinhold {
74198da112cSIngo Weinhold 	status_t error = B_OK;
74298da112cSIngo Weinhold 	// set some icon size related variables
74398da112cSIngo Weinhold 	BString attributeString;
74498da112cSIngo Weinhold 	BRect bounds;
74598da112cSIngo Weinhold 	uint32 attrType;
74698da112cSIngo Weinhold 	size_t attrSize;
74798da112cSIngo Weinhold 	switch (which) {
74898da112cSIngo Weinhold 		case B_MINI_ICON:
74998da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
75098da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
75198da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
75298da112cSIngo Weinhold 			attrSize = 16 * 16;
75398da112cSIngo Weinhold 			break;
75498da112cSIngo Weinhold 		case B_LARGE_ICON:
75598da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
75698da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
75798da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
75898da112cSIngo Weinhold 			attrSize = 32 * 32;
75998da112cSIngo Weinhold 			break;
76098da112cSIngo Weinhold 		default:
76198da112cSIngo Weinhold 			error = B_BAD_VALUE;
76298da112cSIngo Weinhold 			break;
76398da112cSIngo Weinhold 	}
76498da112cSIngo Weinhold 	// check type param
76598da112cSIngo Weinhold 	if (error == B_OK) {
76698da112cSIngo Weinhold 		if (type) {
76717819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
76817819be3SIngo Weinhold 				attributeString += type;
76917819be3SIngo Weinhold 			else
77098da112cSIngo Weinhold 				error = B_BAD_VALUE;
77198da112cSIngo Weinhold 		} else
77217819be3SIngo Weinhold 			attributeString += kStandardIconType;
77398da112cSIngo Weinhold 	}
77498da112cSIngo Weinhold 	const char *attribute = attributeString.String();
77517819be3SIngo Weinhold 
77698da112cSIngo Weinhold 	// check parameter and initialization
77798da112cSIngo Weinhold 	if (error == B_OK
77898da112cSIngo Weinhold 		&& (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
77998da112cSIngo Weinhold 		error = B_BAD_VALUE;
78098da112cSIngo Weinhold 	}
78198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
78298da112cSIngo Weinhold 		error = B_NO_INIT;
78398da112cSIngo Weinhold 	// read the data
78498da112cSIngo Weinhold 	if (error == B_OK) {
78598da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
78698da112cSIngo Weinhold 		char *buffer = NULL;
78798da112cSIngo Weinhold 		size_t read;
78898da112cSIngo Weinhold 		if (otherColorSpace) {
78998da112cSIngo Weinhold 			// other color space than stored in attribute
79098da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
79198da112cSIngo Weinhold 			if (!buffer)
79298da112cSIngo Weinhold 				error = B_NO_MEMORY;
79398da112cSIngo Weinhold 			if (error == B_OK) {
79498da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
79598da112cSIngo Weinhold 								  read);
79698da112cSIngo Weinhold 			}
79798da112cSIngo Weinhold 		} else {
79898da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
79998da112cSIngo Weinhold 							  read);
80098da112cSIngo Weinhold 		}
80198da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
80298da112cSIngo Weinhold 			error = B_ERROR;
80398da112cSIngo Weinhold 		if (otherColorSpace) {
80498da112cSIngo Weinhold 			// other color space than stored in attribute
805*76ba3434SIngo Weinhold 			if (error == B_OK) {
806*76ba3434SIngo Weinhold 				error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
807*76ba3434SIngo Weinhold 										 0, B_CMAP8);
808*76ba3434SIngo Weinhold 			}
80998da112cSIngo Weinhold 			delete[] buffer;
81098da112cSIngo Weinhold 		}
81198da112cSIngo Weinhold 	}
81298da112cSIngo Weinhold 	return error;
813d6b205f3SIngo Weinhold }
814d6b205f3SIngo Weinhold 
815d6b205f3SIngo Weinhold // SetIconForType
816d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
817d6b205f3SIngo Weinhold 
81898da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
819d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
820d6b205f3SIngo Weinhold 
82198da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
82298da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
82398da112cSIngo Weinhold 	before.
82498da112cSIngo Weinhold 
82598da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
826d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
827d6b205f3SIngo Weinhold 		   May be \c NULL.
828d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
829d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
830d6b205f3SIngo Weinhold 	\return
831d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
832d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
833d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
834d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
835d6b205f3SIngo Weinhold 	- other error codes
836d6b205f3SIngo Weinhold */
837d6b205f3SIngo Weinhold status_t
838d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
839d6b205f3SIngo Weinhold 							 icon_size which)
840d6b205f3SIngo Weinhold {
84198da112cSIngo Weinhold 	status_t error = B_OK;
84298da112cSIngo Weinhold 	// set some icon size related variables
84398da112cSIngo Weinhold 	BString attributeString;
84498da112cSIngo Weinhold 	BRect bounds;
84598da112cSIngo Weinhold 	uint32 attrType;
84698da112cSIngo Weinhold 	size_t attrSize;
84798da112cSIngo Weinhold 	int32 resourceID;
84898da112cSIngo Weinhold 	switch (which) {
84998da112cSIngo Weinhold 		case B_MINI_ICON:
85098da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
85198da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
85298da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
85398da112cSIngo Weinhold 			attrSize = 16 * 16;
85498da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
85598da112cSIngo Weinhold 							   : kMiniIconResourceID);
85698da112cSIngo Weinhold 			break;
85798da112cSIngo Weinhold 		case B_LARGE_ICON:
85898da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
85998da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
86098da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
86198da112cSIngo Weinhold 			attrSize = 32 * 32;
86298da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
86398da112cSIngo Weinhold 							   : kLargeIconResourceID);
86498da112cSIngo Weinhold 			break;
86598da112cSIngo Weinhold 		default:
86698da112cSIngo Weinhold 			error = B_BAD_VALUE;
86798da112cSIngo Weinhold 			break;
86898da112cSIngo Weinhold 	}
86998da112cSIngo Weinhold 	// check type param
87098da112cSIngo Weinhold 	if (error == B_OK) {
87198da112cSIngo Weinhold 		if (type) {
87217819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
87398da112cSIngo Weinhold 				attributeString += type;
87417819be3SIngo Weinhold 			else
87517819be3SIngo Weinhold 				error = B_BAD_VALUE;
87698da112cSIngo Weinhold 		} else
87798da112cSIngo Weinhold 			attributeString += kStandardIconType;
87898da112cSIngo Weinhold 	}
87998da112cSIngo Weinhold 	const char *attribute = attributeString.String();
88098da112cSIngo Weinhold 	// check parameter and initialization
88198da112cSIngo Weinhold 	if (error == B_OK && icon
88298da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
88398da112cSIngo Weinhold 		error = B_BAD_VALUE;
88498da112cSIngo Weinhold 	}
88598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
88698da112cSIngo Weinhold 		error = B_NO_INIT;
88798da112cSIngo Weinhold 	// write/remove the attribute
88898da112cSIngo Weinhold 	if (error == B_OK) {
88998da112cSIngo Weinhold 		if (icon) {
89098da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
89198da112cSIngo Weinhold 			if (otherColorSpace) {
89298da112cSIngo Weinhold 				BBitmap bitmap(bounds, B_CMAP8);
89398da112cSIngo Weinhold 				error = bitmap.InitCheck();
894*76ba3434SIngo Weinhold 				if (error == B_OK)
895*76ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
89698da112cSIngo Weinhold 				if (error == B_OK) {
89798da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
89898da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
89998da112cSIngo Weinhold 				}
90098da112cSIngo Weinhold 			} else {
90198da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
90298da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
90398da112cSIngo Weinhold 			}
90498da112cSIngo Weinhold 		} else	// no icon given => remove
90598da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
90698da112cSIngo Weinhold 	}
90798da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
90898da112cSIngo Weinhold 	BMimeType mimeType;
90998da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
91098da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
91198da112cSIngo Weinhold 			error = mimeType.Install();
91298da112cSIngo Weinhold 		if (error == B_OK)
91398da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
91498da112cSIngo Weinhold 	}
91598da112cSIngo Weinhold 	return error;
916d6b205f3SIngo Weinhold }
917d6b205f3SIngo Weinhold 
918d6b205f3SIngo Weinhold // SetInfoLocation
919d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
920d6b205f3SIngo Weinhold 
921d6b205f3SIngo Weinhold 	The options for \a location are:
922d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
923d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
924d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
925d6b205f3SIngo Weinhold 
926d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
927d6b205f3SIngo Weinhold */
928d6b205f3SIngo Weinhold void
929d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
930d6b205f3SIngo Weinhold {
93198da112cSIngo Weinhold 	fWhere = location;
932d6b205f3SIngo Weinhold }
933d6b205f3SIngo Weinhold 
934d6b205f3SIngo Weinhold // IsUsingAttributes
935d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
936d6b205f3SIngo Weinhold 		   file's attributes.
937d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
938d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
939d6b205f3SIngo Weinhold */
940d6b205f3SIngo Weinhold bool
941d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
942d6b205f3SIngo Weinhold {
94398da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
944d6b205f3SIngo Weinhold }
945d6b205f3SIngo Weinhold 
946d6b205f3SIngo Weinhold // IsUsingResources
947d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
948d6b205f3SIngo Weinhold 		   file's resources.
949d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
950d6b205f3SIngo Weinhold 			resources, \c false otherwise.
951d6b205f3SIngo Weinhold */
952d6b205f3SIngo Weinhold bool
953d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
954d6b205f3SIngo Weinhold {
95598da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
956d6b205f3SIngo Weinhold }
957d6b205f3SIngo Weinhold 
958d6b205f3SIngo Weinhold // FBC
959d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
960d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
961d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
962d6b205f3SIngo Weinhold 
963d6b205f3SIngo Weinhold // =
964d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
965d6b205f3SIngo Weinhold */
966d6b205f3SIngo Weinhold BAppFileInfo &
967d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
968d6b205f3SIngo Weinhold {
969d6b205f3SIngo Weinhold 	return *this;
970d6b205f3SIngo Weinhold }
971d6b205f3SIngo Weinhold 
972d6b205f3SIngo Weinhold // copy constructor
973d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
974d6b205f3SIngo Weinhold */
975d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
976d6b205f3SIngo Weinhold {
977d6b205f3SIngo Weinhold }
978d6b205f3SIngo Weinhold 
97998da112cSIngo Weinhold // GetMetaMime
98098da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
98198da112cSIngo Weinhold 
98298da112cSIngo Weinhold 	The parameter \a meta is not checked.
98398da112cSIngo Weinhold 
98498da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
98598da112cSIngo Weinhold 		   initialized to the file's signature.
98698da112cSIngo Weinhold 	\return
98798da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
98898da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
98998da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
99098da112cSIngo Weinhold (	  not installed in the MIME database.)
99198da112cSIngo Weinhold 	  no valid MIME string.
99298da112cSIngo Weinhold 	- other error codes
99398da112cSIngo Weinhold */
99498da112cSIngo Weinhold status_t
99598da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
99698da112cSIngo Weinhold {
99798da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
99898da112cSIngo Weinhold 	status_t error = GetSignature(signature);
99998da112cSIngo Weinhold 	if (error == B_OK)
100098da112cSIngo Weinhold 		error = meta->SetTo(signature);
100198da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
100298da112cSIngo Weinhold 		error = B_BAD_VALUE;
100398da112cSIngo Weinhold 	return error;
100498da112cSIngo Weinhold }
100598da112cSIngo Weinhold 
100698da112cSIngo Weinhold // _ReadData
100798da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
100898da112cSIngo Weinhold 
100998da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
101098da112cSIngo Weinhold 
101198da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
101298da112cSIngo Weinhold 
101398da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
101498da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
101598da112cSIngo Weinhold 		   < 0.
101698da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
101798da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
101898da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
101998da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
102098da112cSIngo Weinhold 		   actually read.
102198da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
102298da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
102398da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
102498da112cSIngo Weinhold 	\return
102598da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
102698da112cSIngo Weinhold 	- error code
102798da112cSIngo Weinhold */
102898da112cSIngo Weinhold status_t
102998da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
103098da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
103198da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
103298da112cSIngo Weinhold {
103398da112cSIngo Weinhold 	status_t error = B_OK;
103498da112cSIngo Weinhold 	if (allocatedBuffer)
103598da112cSIngo Weinhold 		buffer = NULL;
103698da112cSIngo Weinhold 	if (IsUsingAttributes()) {
103798da112cSIngo Weinhold 		// get an attribute info
103898da112cSIngo Weinhold 		attr_info info;
103998da112cSIngo Weinhold 		if (error == B_OK)
104098da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
104198da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
104298da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
104398da112cSIngo Weinhold 			error = B_BAD_VALUE;
104498da112cSIngo Weinhold 		if (allocatedBuffer) {
104598da112cSIngo Weinhold 			buffer = malloc(info.size);
104698da112cSIngo Weinhold 			if (!buffer)
104798da112cSIngo Weinhold 				error = B_NO_MEMORY;
104898da112cSIngo Weinhold 			bufferSize = info.size;
104998da112cSIngo Weinhold 		}
105098da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
105198da112cSIngo Weinhold 			error = B_BAD_VALUE;
105298da112cSIngo Weinhold 		// read the data
105398da112cSIngo Weinhold 		if (error == B_OK) {
105498da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
105598da112cSIngo Weinhold 			if (read < 0)
105698da112cSIngo Weinhold 				error = read;
105798da112cSIngo Weinhold 			else if (read != info.size)
105898da112cSIngo Weinhold 				error = B_ERROR;
105998da112cSIngo Weinhold 			else
106098da112cSIngo Weinhold 				bytesRead = read;
106198da112cSIngo Weinhold 		}
106298da112cSIngo Weinhold 	} else if (IsUsingResources()) {
106398da112cSIngo Weinhold 		// get a resource info
106498da112cSIngo Weinhold 		int32 idFound;
106598da112cSIngo Weinhold 		size_t sizeFound;
106698da112cSIngo Weinhold 		if (error == B_OK) {
106798da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
106898da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
106998da112cSIngo Weinhold 		}
107098da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
107198da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
107298da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
107398da112cSIngo Weinhold 		if (allocatedBuffer) {
107498da112cSIngo Weinhold 			buffer = malloc(sizeFound);
107598da112cSIngo Weinhold 			if (!buffer)
107698da112cSIngo Weinhold 				error = B_NO_MEMORY;
107798da112cSIngo Weinhold 			bufferSize = sizeFound;
107898da112cSIngo Weinhold 		}
107998da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
108098da112cSIngo Weinhold 			error = B_BAD_VALUE;
108198da112cSIngo Weinhold 		// load resource
108298da112cSIngo Weinhold 		const void *resourceData = NULL;
108398da112cSIngo Weinhold 		if (error == B_OK) {
108498da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
108598da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
108698da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
108798da112cSIngo Weinhold 			else
108898da112cSIngo Weinhold 				error = B_ERROR;
108998da112cSIngo Weinhold 		}
109098da112cSIngo Weinhold 	} else
109198da112cSIngo Weinhold 		error = B_BAD_VALUE;
109298da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
109398da112cSIngo Weinhold 	if (allocatedBuffer) {
109498da112cSIngo Weinhold 		if (error == B_OK)
109598da112cSIngo Weinhold 			*allocatedBuffer = buffer;
109698da112cSIngo Weinhold 		else
109798da112cSIngo Weinhold 			free(buffer);
109898da112cSIngo Weinhold 	}
109998da112cSIngo Weinhold 	return error;
110098da112cSIngo Weinhold }
110198da112cSIngo Weinhold 
110298da112cSIngo Weinhold // _WriteData
110398da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
110498da112cSIngo Weinhold 
110598da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
110698da112cSIngo Weinhold 
110798da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
110898da112cSIngo Weinhold 
110998da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
111098da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
111198da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
111298da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
111398da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
111498da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
111598da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
111698da112cSIngo Weinhold 		   If \c false, \a id is used.
111798da112cSIngo Weinhold 	If \a id is already in use and .
111898da112cSIngo Weinhold 	\return
111998da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
112098da112cSIngo Weinhold 	- error code
112198da112cSIngo Weinhold */
112298da112cSIngo Weinhold status_t
112398da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
112498da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
112598da112cSIngo Weinhold {
112698da112cSIngo Weinhold 	status_t error = B_OK;
112798da112cSIngo Weinhold 	// write to attribute
112898da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
112998da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
113098da112cSIngo Weinhold 		if (written < 0)
113198da112cSIngo Weinhold 			error = written;
113298da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
113398da112cSIngo Weinhold 			error = B_ERROR;
113498da112cSIngo Weinhold 	}
113598da112cSIngo Weinhold 	// write to resource
113698da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
113798da112cSIngo Weinhold 		if (findID) {
113898da112cSIngo Weinhold 			// get the resource info
113998da112cSIngo Weinhold 			int32 idFound;
114098da112cSIngo Weinhold 			size_t sizeFound;
114198da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
114298da112cSIngo Weinhold 				id = idFound;
114398da112cSIngo Weinhold 			else {
114498da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
114598da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
114698da112cSIngo Weinhold 					id++;
114798da112cSIngo Weinhold 			}
114898da112cSIngo Weinhold 		}
114998da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
115098da112cSIngo Weinhold 	}
115198da112cSIngo Weinhold 	return error;
115298da112cSIngo Weinhold }
115398da112cSIngo Weinhold 
115498da112cSIngo Weinhold // _RemoveData
115598da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
115698da112cSIngo Weinhold 
115798da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
115898da112cSIngo Weinhold 
115998da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
116098da112cSIngo Weinhold 
116198da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
116298da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
116398da112cSIngo Weinhold 	\return
116498da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
116598da112cSIngo Weinhold 	- error code
116698da112cSIngo Weinhold */
116798da112cSIngo Weinhold status_t
116898da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
116998da112cSIngo Weinhold {
117098da112cSIngo Weinhold 	status_t error = B_OK;
117198da112cSIngo Weinhold 	// remove the attribute
117298da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
117398da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
117498da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
117598da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
117698da112cSIngo Weinhold 			error = B_OK;
117798da112cSIngo Weinhold 	}
117898da112cSIngo Weinhold 	// remove the resource
117998da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
118098da112cSIngo Weinhold 		// get a resource info
118198da112cSIngo Weinhold 		int32 idFound;
118298da112cSIngo Weinhold 		size_t sizeFound;
118398da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
118498da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
118598da112cSIngo Weinhold 	}
118698da112cSIngo Weinhold 	return error;
118798da112cSIngo Weinhold }
118898da112cSIngo Weinhold 
1189