xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
131dc79a1SAxel Dörfler /*
231dc79a1SAxel Dörfler  * Copyright 2002-2006, Haiku Inc.
331dc79a1SAxel Dörfler  * Distributed under the terms of the MIT License.
431dc79a1SAxel Dörfler  *
531dc79a1SAxel Dörfler  * Authors:
631dc79a1SAxel Dörfler  *		Ingo Weinhold, bonefish@users.sf.net
721881ce5SIngo Weinhold  */
8d6b205f3SIngo Weinhold 
931dc79a1SAxel Dörfler 
1098da112cSIngo Weinhold #include <new>
1198da112cSIngo Weinhold #include <set>
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>
18*9ecf9d1cSIngo Weinhold #include <IconUtils.h>
1998da112cSIngo Weinhold #include <MimeType.h>
2098da112cSIngo Weinhold #include <RegistrarDefs.h>
2198da112cSIngo Weinhold #include <Resources.h>
2298da112cSIngo Weinhold #include <Roster.h>
2398da112cSIngo Weinhold #include <String.h>
2498da112cSIngo Weinhold 
2550f17542Shaydentech using namespace std;
2650f17542Shaydentech 
2798da112cSIngo Weinhold // attributes
2898da112cSIngo Weinhold static const char *kTypeAttribute				= "BEOS:TYPE";
2998da112cSIngo Weinhold static const char *kSignatureAttribute			= "BEOS:APP_SIG";
3098da112cSIngo Weinhold static const char *kAppFlagsAttribute			= "BEOS:APP_FLAGS";
3198da112cSIngo Weinhold static const char *kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
3298da112cSIngo Weinhold static const char *kVersionInfoAttribute		= "BEOS:APP_VERSION";
3398da112cSIngo Weinhold static const char *kMiniIconAttribute			= "BEOS:M:";
3498da112cSIngo Weinhold static const char *kLargeIconAttribute			= "BEOS:L:";
35*9ecf9d1cSIngo Weinhold static const char *kIconAttribute				= "BEOS:";
3698da112cSIngo Weinhold static const char *kStandardIconType			= "STD_ICON";
37*9ecf9d1cSIngo Weinhold static const char *kIconType					= "ICON";
3898da112cSIngo Weinhold 
3998da112cSIngo Weinhold // resource IDs
4098da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
4198da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
4298da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
4398da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
4498da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
4598da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
4698da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
4798da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
4898da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
4998da112cSIngo Weinhold 
5098da112cSIngo Weinhold // type codes
5198da112cSIngo Weinhold enum {
5298da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
5398da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
5498da112cSIngo Weinhold };
5598da112cSIngo Weinhold 
5688706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
5788706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
5888706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
5988706bbeSAxel Dörfler // Tracker when compiled for Haiku)
6088706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
6188706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
6288706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
6388706bbeSAxel Dörfler 
6478b31a7cSIngo Weinhold // debugging
6578b31a7cSIngo Weinhold //#define DBG(x) x
6678b31a7cSIngo Weinhold #define DBG(x)
6778b31a7cSIngo Weinhold #define OUT	printf
68d6b205f3SIngo Weinhold 
69d6b205f3SIngo Weinhold // constructor
70d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
71d6b205f3SIngo Weinhold */
72d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
73d6b205f3SIngo Weinhold 			: fResources(NULL),
74d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
75d6b205f3SIngo Weinhold {
76d6b205f3SIngo Weinhold }
77d6b205f3SIngo Weinhold 
78d6b205f3SIngo Weinhold // constructor
79d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
80d6b205f3SIngo Weinhold 		   file.
81d6b205f3SIngo Weinhold 
82d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
83d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
84d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
85d6b205f3SIngo Weinhold 
86d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
87d6b205f3SIngo Weinhold */
88d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
89d6b205f3SIngo Weinhold 			: fResources(NULL),
90d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
91d6b205f3SIngo Weinhold {
9298da112cSIngo Weinhold 	SetTo(file);
93d6b205f3SIngo Weinhold }
94d6b205f3SIngo Weinhold 
95d6b205f3SIngo Weinhold // destructor
96d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
97d6b205f3SIngo Weinhold 
98d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
99d6b205f3SIngo Weinhold */
100d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
101d6b205f3SIngo Weinhold {
10298da112cSIngo Weinhold 	if (fResources)
10398da112cSIngo Weinhold 		delete fResources;
104d6b205f3SIngo Weinhold }
105d6b205f3SIngo Weinhold 
106d6b205f3SIngo Weinhold // SetTo
107d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
108d6b205f3SIngo Weinhold 
109d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
110d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
111d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
112d6b205f3SIngo Weinhold 
113d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
114d6b205f3SIngo Weinhold 
115d6b205f3SIngo Weinhold 	\return
116d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
117d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
118d6b205f3SIngo Weinhold */
119d6b205f3SIngo Weinhold status_t
120d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
121d6b205f3SIngo Weinhold {
12298da112cSIngo Weinhold 	// unset the old file
12398da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
12498da112cSIngo Weinhold 	if (fResources) {
12598da112cSIngo Weinhold 		delete fResources;
12698da112cSIngo Weinhold 		fResources = NULL;
12798da112cSIngo Weinhold 	}
128c2a2369dSAxel Dörfler 
12998da112cSIngo Weinhold 	// check param
13098da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
131c2a2369dSAxel Dörfler 
132c2a2369dSAxel Dörfler 	info_location where = B_USE_BOTH_LOCATIONS;
133c2a2369dSAxel Dörfler 
13498da112cSIngo Weinhold 	// create resources
13598da112cSIngo Weinhold 	if (error == B_OK) {
13698da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
137c2a2369dSAxel Dörfler 		if (fResources) {
13898da112cSIngo Weinhold 			error = fResources->SetTo(file);
139c2a2369dSAxel Dörfler 			if (error != B_OK) {
140c2a2369dSAxel Dörfler 				// no resources - this is no critical error, we'll just use
141c2a2369dSAxel Dörfler 				// attributes only, then
142c2a2369dSAxel Dörfler 				where = B_USE_ATTRIBUTES;
143c2a2369dSAxel Dörfler 				error = B_OK;
144c2a2369dSAxel Dörfler 			}
145c2a2369dSAxel Dörfler 		} else
14698da112cSIngo Weinhold 			error = B_NO_MEMORY;
14798da112cSIngo Weinhold 	}
148c2a2369dSAxel Dörfler 
14998da112cSIngo Weinhold 	// set node info
15098da112cSIngo Weinhold 	if (error == B_OK)
15198da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
152c2a2369dSAxel Dörfler 
153c2a2369dSAxel Dörfler 	if (error != B_OK || (where & B_USE_RESOURCES) == 0) {
15498da112cSIngo Weinhold 		delete fResources;
15598da112cSIngo Weinhold 		fResources = NULL;
15698da112cSIngo Weinhold 	}
157c2a2369dSAxel Dörfler 
158c2a2369dSAxel Dörfler 	// clean up on error
159c2a2369dSAxel Dörfler 	if (error != B_OK) {
16098da112cSIngo Weinhold 		if (InitCheck() == B_OK)
16198da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
16298da112cSIngo Weinhold 	}
163c2a2369dSAxel Dörfler 
16498da112cSIngo Weinhold 	// set data location
16598da112cSIngo Weinhold 	if (error == B_OK)
166c2a2369dSAxel Dörfler 		SetInfoLocation(where);
167c2a2369dSAxel Dörfler 
16898da112cSIngo Weinhold 	// set error
16998da112cSIngo Weinhold 	fCStatus = error;
17098da112cSIngo Weinhold 	return error;
171d6b205f3SIngo Weinhold }
172d6b205f3SIngo Weinhold 
173d6b205f3SIngo Weinhold // GetType
174d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
175d6b205f3SIngo Weinhold 
176d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
177d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
178d6b205f3SIngo Weinhold 		   file shall be written.
179d6b205f3SIngo Weinhold 	\return
180d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
181d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
182d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
183d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
184d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
185d6b205f3SIngo Weinhold 	  the wrong type.
186d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
187d6b205f3SIngo Weinhold 	- other error codes
188d6b205f3SIngo Weinhold */
189d6b205f3SIngo Weinhold status_t
190d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
191d6b205f3SIngo Weinhold {
19298da112cSIngo Weinhold 	// check param and initialization
19398da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
19498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
19598da112cSIngo Weinhold 		error = B_NO_INIT;
19698da112cSIngo Weinhold 	// read the data
19798da112cSIngo Weinhold 	size_t read = 0;
19898da112cSIngo Weinhold 	if (error == B_OK) {
19998da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
20098da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
20198da112cSIngo Weinhold 	}
20298da112cSIngo Weinhold 	// check the read data -- null terminate the string
20398da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
20498da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
20598da112cSIngo Weinhold 			error = B_ERROR;
20698da112cSIngo Weinhold 		else
20798da112cSIngo Weinhold 			type[read] = '\0';
20898da112cSIngo Weinhold 	}
20998da112cSIngo Weinhold 	return error;
210d6b205f3SIngo Weinhold }
211d6b205f3SIngo Weinhold 
212d6b205f3SIngo Weinhold // SetType
213d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
214d6b205f3SIngo Weinhold 
215d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
216d6b205f3SIngo Weinhold 
217d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
218d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
219d6b205f3SIngo Weinhold 		   May be \c NULL.
220d6b205f3SIngo Weinhold 	\return
221d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
222d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
223d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
224d6b205f3SIngo Weinhold 	- other error codes
225d6b205f3SIngo Weinhold */
226d6b205f3SIngo Weinhold status_t
227d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
228d6b205f3SIngo Weinhold {
22998da112cSIngo Weinhold 	// check initialization
23098da112cSIngo Weinhold 	status_t error = B_OK;
23198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
23298da112cSIngo Weinhold 		error = B_NO_INIT;
23398da112cSIngo Weinhold 	if (error == B_OK) {
23498da112cSIngo Weinhold 		if (type) {
23598da112cSIngo Weinhold 			// check param
23698da112cSIngo Weinhold 			size_t typeLen = strlen(type);
23798da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
23898da112cSIngo Weinhold 				error = B_BAD_VALUE;
23998da112cSIngo Weinhold 			// write the data
24098da112cSIngo Weinhold 			if (error == B_OK) {
24198da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
24298da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
24398da112cSIngo Weinhold 			}
24498da112cSIngo Weinhold 		} else
24598da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
24698da112cSIngo Weinhold 	}
24798da112cSIngo Weinhold 	return error;
248d6b205f3SIngo Weinhold }
249d6b205f3SIngo Weinhold 
250d6b205f3SIngo Weinhold // GetSignature
251d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
252d6b205f3SIngo Weinhold 
253d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
254d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
255d6b205f3SIngo Weinhold 		   signature of the file shall be written.
256d6b205f3SIngo Weinhold 	\return
257d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
258d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
259d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
260d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
261d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
262d6b205f3SIngo Weinhold 	  the wrong type.
263d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
264d6b205f3SIngo Weinhold 	- other error codes
265d6b205f3SIngo Weinhold */
266d6b205f3SIngo Weinhold status_t
267d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
268d6b205f3SIngo Weinhold {
26998da112cSIngo Weinhold 	// check param and initialization
27098da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
27198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
27298da112cSIngo Weinhold 		error = B_NO_INIT;
27398da112cSIngo Weinhold 	// read the data
27498da112cSIngo Weinhold 	size_t read = 0;
27598da112cSIngo Weinhold 	if (error == B_OK) {
27698da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
27798da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
27898da112cSIngo Weinhold 						  read);
27998da112cSIngo Weinhold 	}
28098da112cSIngo Weinhold 	// check the read data -- null terminate the string
28198da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
28298da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
28398da112cSIngo Weinhold 			error = B_ERROR;
28498da112cSIngo Weinhold 		else
28598da112cSIngo Weinhold 			signature[read] = '\0';
28698da112cSIngo Weinhold 	}
28798da112cSIngo Weinhold 	return error;
288d6b205f3SIngo Weinhold }
289d6b205f3SIngo Weinhold 
290d6b205f3SIngo Weinhold // SetSignature
291d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
292d6b205f3SIngo Weinhold 
293d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
294d6b205f3SIngo Weinhold 
295d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
296d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
297d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
298d6b205f3SIngo Weinhold 	\return
299d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
300d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
301d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
302d6b205f3SIngo Weinhold 	- other error codes
303d6b205f3SIngo Weinhold */
304d6b205f3SIngo Weinhold status_t
305d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
306d6b205f3SIngo Weinhold {
30798da112cSIngo Weinhold 	// check initialization
30898da112cSIngo Weinhold 	status_t error = B_OK;
30998da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
31098da112cSIngo Weinhold 		error = B_NO_INIT;
31198da112cSIngo Weinhold 	if (error == B_OK) {
31298da112cSIngo Weinhold 		if (signature) {
31398da112cSIngo Weinhold 			// check param
31498da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
31598da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
31698da112cSIngo Weinhold 				error = B_BAD_VALUE;
31798da112cSIngo Weinhold 			// write the data
31898da112cSIngo Weinhold 			if (error == B_OK) {
31998da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
32098da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
32198da112cSIngo Weinhold 								   signatureLen + 1);
32298da112cSIngo Weinhold 			}
32398da112cSIngo Weinhold 		} else
32498da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
32598da112cSIngo Weinhold 	}
32698da112cSIngo Weinhold 	return error;
327d6b205f3SIngo Weinhold }
328d6b205f3SIngo Weinhold 
329d6b205f3SIngo Weinhold // GetAppFlags
330d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
331d6b205f3SIngo Weinhold 
332d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
333d6b205f3SIngo Weinhold 		   flags of the file shall be written.
334d6b205f3SIngo Weinhold 	\return
335d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
336d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
337d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
338d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
339d6b205f3SIngo Weinhold 	  the wrong type.
340d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
341d6b205f3SIngo Weinhold 	- other error codes
342d6b205f3SIngo Weinhold */
343d6b205f3SIngo Weinhold status_t
344d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
345d6b205f3SIngo Weinhold {
34698da112cSIngo Weinhold 	// check param and initialization
34798da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
34898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
34998da112cSIngo Weinhold 		error = B_NO_INIT;
35098da112cSIngo Weinhold 	// read the data
35198da112cSIngo Weinhold 	size_t read = 0;
35298da112cSIngo Weinhold 	if (error == B_OK) {
35398da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
35498da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
35598da112cSIngo Weinhold 						  read);
35698da112cSIngo Weinhold 	}
35798da112cSIngo Weinhold 	// check the read data
35898da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
35998da112cSIngo Weinhold 		error = B_ERROR;
36098da112cSIngo Weinhold 	return error;
361d6b205f3SIngo Weinhold }
362d6b205f3SIngo Weinhold 
363d6b205f3SIngo Weinhold // SetAppFlags
364d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
365d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
366d6b205f3SIngo Weinhold 	\return
367d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
368d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
369d6b205f3SIngo Weinhold 	- other error codes
370d6b205f3SIngo Weinhold */
371d6b205f3SIngo Weinhold status_t
372d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
373d6b205f3SIngo Weinhold {
37498da112cSIngo Weinhold 	// check initialization
37598da112cSIngo Weinhold 	status_t error = B_OK;
37698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
37798da112cSIngo Weinhold 		error = B_NO_INIT;
37898da112cSIngo Weinhold 	if (error == B_OK) {
37998da112cSIngo Weinhold 		// write the data
38098da112cSIngo Weinhold 		if (error == B_OK) {
38198da112cSIngo Weinhold 			error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
38298da112cSIngo Weinhold 							   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
38398da112cSIngo Weinhold 		}
38498da112cSIngo Weinhold 	}
38598da112cSIngo Weinhold 	return error;
386d6b205f3SIngo Weinhold }
387d6b205f3SIngo Weinhold 
388d6b205f3SIngo Weinhold // GetSupportedTypes
389d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
390d6b205f3SIngo Weinhold 
391d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
392d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
393d6b205f3SIngo Weinhold 
394d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
395d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
396d6b205f3SIngo Weinhold 	\return
397d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
398d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
399d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
400d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
401d6b205f3SIngo Weinhold 	  have the wrong type.
402d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
403d6b205f3SIngo Weinhold 	- other error codes
404d6b205f3SIngo Weinhold */
405d6b205f3SIngo Weinhold status_t
406d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
407d6b205f3SIngo Weinhold {
40898da112cSIngo Weinhold 	// check param and initialization
40998da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
41098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
41198da112cSIngo Weinhold 		error = B_NO_INIT;
41298da112cSIngo Weinhold 	// read the data
41398da112cSIngo Weinhold 	size_t read = 0;
41498da112cSIngo Weinhold 	void *buffer = NULL;
41598da112cSIngo Weinhold 	if (error == B_OK) {
41698da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
41798da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
41898da112cSIngo Weinhold 	}
41998da112cSIngo Weinhold 	// unflatten the buffer
42098da112cSIngo Weinhold 	if (error == B_OK)
42198da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
42298da112cSIngo Weinhold 	// clean up
42398da112cSIngo Weinhold 	if (buffer)
42498da112cSIngo Weinhold 		free(buffer);
42598da112cSIngo Weinhold 	return error;
426d6b205f3SIngo Weinhold }
427d6b205f3SIngo Weinhold 
428d6b205f3SIngo Weinhold // SetSupportedTypes
429d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
430d6b205f3SIngo Weinhold 
431d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
432d6b205f3SIngo Weinhold 
433d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
434d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
435d6b205f3SIngo Weinhold 
43683a812a1SIngo Weinhold 	The method informs the registrar about this news.
43783a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
43883a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
43983a812a1SIngo Weinhold 	application file needs to have a signature set.
44083a812a1SIngo Weinhold 
44183a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
44283a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
44383a812a1SIngo Weinhold 	lists of supporting applications.
44483a812a1SIngo Weinhold 
445d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
446d6b205f3SIngo Weinhold 		   May be \c NULL.
44783a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
44883a812a1SIngo Weinhold 		   types, \c false otherwise.
449d6b205f3SIngo Weinhold 	\return
450d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
451d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
452d6b205f3SIngo Weinhold 	- other error codes
453d6b205f3SIngo Weinhold */
454d6b205f3SIngo Weinhold status_t
455d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
456d6b205f3SIngo Weinhold {
45798da112cSIngo Weinhold 	// check initialization
45898da112cSIngo Weinhold 	status_t error = B_OK;
45998da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
46098da112cSIngo Weinhold 		error = B_NO_INIT;
46198da112cSIngo Weinhold 	BMimeType mimeType;
46298da112cSIngo Weinhold 	if (error == B_OK)
46398da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
4647f20062dSJérôme Duval 	if (error == B_OK || error == B_ENTRY_NOT_FOUND) {
4657f20062dSJérôme Duval 		error = B_OK;
46698da112cSIngo Weinhold 		if (types) {
46717819be3SIngo Weinhold 			// check param -- supported types must be valid
46817819be3SIngo Weinhold 			const char *type;
46917819be3SIngo Weinhold 			for (int32 i = 0;
47017819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
47117819be3SIngo Weinhold 				 i++) {
47217819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
47317819be3SIngo Weinhold 					error = B_BAD_VALUE;
47417819be3SIngo Weinhold 			}
47517819be3SIngo Weinhold 			// get flattened size
47617819be3SIngo Weinhold 			ssize_t size = 0;
47717819be3SIngo Weinhold 			if (error == B_OK) {
47817819be3SIngo Weinhold 				size = types->FlattenedSize();
47998da112cSIngo Weinhold 				if (size < 0)
48098da112cSIngo Weinhold 					error = size;
48117819be3SIngo Weinhold 			}
48298da112cSIngo Weinhold 			// allocate a buffer for the flattened data
48398da112cSIngo Weinhold 			char *buffer = NULL;
48498da112cSIngo Weinhold 			if (error == B_OK) {
48598da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
48698da112cSIngo Weinhold 				if (!buffer)
48798da112cSIngo Weinhold 					error = B_NO_MEMORY;
48898da112cSIngo Weinhold 			}
48998da112cSIngo Weinhold 			// flatten the message
49098da112cSIngo Weinhold 			if (error == B_OK)
49198da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
49298da112cSIngo Weinhold 			// write the data
49398da112cSIngo Weinhold 			if (error == B_OK) {
49498da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
49598da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
49698da112cSIngo Weinhold 								   buffer, size);
49798da112cSIngo Weinhold 			}
49898da112cSIngo Weinhold 			// clean up
49998da112cSIngo Weinhold 			if (buffer)
50098da112cSIngo Weinhold 				delete[] buffer;
50198da112cSIngo Weinhold 		} else
50298da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
50398da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
50417819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
50517819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
50698da112cSIngo Weinhold 	}
50798da112cSIngo Weinhold 	return error;
508d6b205f3SIngo Weinhold }
509d6b205f3SIngo Weinhold 
510d6b205f3SIngo Weinhold // SetSupportedTypes
511d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
512d6b205f3SIngo Weinhold 
51398da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
51483a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
515d6b205f3SIngo Weinhold 
516d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
517d6b205f3SIngo Weinhold 		   May be \c NULL.
518d6b205f3SIngo Weinhold 	\return
519d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
520d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
521d6b205f3SIngo Weinhold 	- other error codes
522d6b205f3SIngo Weinhold */
523d6b205f3SIngo Weinhold status_t
524d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
525d6b205f3SIngo Weinhold {
52698da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
527d6b205f3SIngo Weinhold }
528d6b205f3SIngo Weinhold 
529d6b205f3SIngo Weinhold // IsSupportedType
530d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
531d6b205f3SIngo Weinhold 
532d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
533d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
534d6b205f3SIngo Weinhold 
535d6b205f3SIngo Weinhold 	\param type The MIME type in question.
536d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
537d6b205f3SIngo Weinhold 			the application, \c false otherwise.
538d6b205f3SIngo Weinhold */
539d6b205f3SIngo Weinhold bool
540d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
541d6b205f3SIngo Weinhold {
54298da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
54398da112cSIngo Weinhold 	// get the supported types
54498da112cSIngo Weinhold 	BMessage types;
54598da112cSIngo Weinhold 	if (error == B_OK)
54698da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
54798da112cSIngo Weinhold 	// turn type into a BMimeType
54898da112cSIngo Weinhold 	BMimeType mimeType;
54998da112cSIngo Weinhold 	if (error == B_OK)
55098da112cSIngo Weinhold 		error = mimeType.SetTo(type);
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 = !strcmp(supportedType, "application/octet-stream")
55998da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
56098da112cSIngo Weinhold 		}
56198da112cSIngo Weinhold 	}
56298da112cSIngo Weinhold 	return found;
563d6b205f3SIngo Weinhold }
564d6b205f3SIngo Weinhold 
565d6b205f3SIngo Weinhold // Supports
566d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
567d6b205f3SIngo Weinhold 		   explicitly.
568d6b205f3SIngo Weinhold 
569d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
570d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
571d6b205f3SIngo Weinhold 	"application/octet-stream".
572d6b205f3SIngo Weinhold 
573d6b205f3SIngo Weinhold 	\param type The MIME type in question.
574d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
575d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
576d6b205f3SIngo Weinhold */
577d6b205f3SIngo Weinhold bool
578d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
579d6b205f3SIngo Weinhold {
58098da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
58198da112cSIngo Weinhold 	// get the supported types
58298da112cSIngo Weinhold 	BMessage types;
58398da112cSIngo Weinhold 	if (error == B_OK)
58498da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
58598da112cSIngo Weinhold 	// iterate through the supported types
58698da112cSIngo Weinhold 	bool found = false;
58798da112cSIngo Weinhold 	if (error == B_OK) {
58898da112cSIngo Weinhold 		const char *supportedType;
58998da112cSIngo Weinhold 		for (int32 i = 0;
59098da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
59198da112cSIngo Weinhold 			 i++) {
59298da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
59398da112cSIngo Weinhold 		}
59498da112cSIngo Weinhold 	}
59598da112cSIngo Weinhold 	return found;
596d6b205f3SIngo Weinhold }
597d6b205f3SIngo Weinhold 
598d6b205f3SIngo Weinhold // GetIcon
599d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
600d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
601d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
602d6b205f3SIngo Weinhold 		   large icon).
603d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
604d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
605d6b205f3SIngo Weinhold 	\return
606d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
607d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
608d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
609d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
610d6b205f3SIngo Weinhold 	- other error codes
611d6b205f3SIngo Weinhold */
612d6b205f3SIngo Weinhold status_t
613d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
614d6b205f3SIngo Weinhold {
61598da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
616d6b205f3SIngo Weinhold }
617d6b205f3SIngo Weinhold 
618d6b205f3SIngo Weinhold // SetIcon
619d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
620d6b205f3SIngo Weinhold 
621d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
622d6b205f3SIngo Weinhold 
623d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
624d6b205f3SIngo Weinhold 		   May be \c NULL.
625d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
626d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
627d6b205f3SIngo Weinhold 	\return
628d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
629d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
630d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
631d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
632d6b205f3SIngo Weinhold 	- other error codes
633d6b205f3SIngo Weinhold */
634d6b205f3SIngo Weinhold status_t
635d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
636d6b205f3SIngo Weinhold {
63798da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
638d6b205f3SIngo Weinhold }
639d6b205f3SIngo Weinhold 
640d6b205f3SIngo Weinhold // GetVersionInfo
641d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
642d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
643d6b205f3SIngo Weinhold 		   the version info should be written.
644d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
645d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
646d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
647d6b205f3SIngo Weinhold 		   belongs to.
648d6b205f3SIngo Weinhold 	\return
649d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
650d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
651d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
652d6b205f3SIngo Weinhold 	- other error codes
653d6b205f3SIngo Weinhold */
654d6b205f3SIngo Weinhold status_t
655d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
656d6b205f3SIngo Weinhold {
65798da112cSIngo Weinhold 	// check params and initialization
658b1970bb8SIngo Weinhold 	if (!info)
659b1970bb8SIngo Weinhold 		return B_BAD_VALUE;
660b1970bb8SIngo Weinhold 
66198da112cSIngo Weinhold 	int32 index = 0;
66298da112cSIngo Weinhold 	switch (kind) {
66398da112cSIngo Weinhold 		case B_APP_VERSION_KIND:
66498da112cSIngo Weinhold 			index = 0;
66598da112cSIngo Weinhold 			break;
66698da112cSIngo Weinhold 		case B_SYSTEM_VERSION_KIND:
66798da112cSIngo Weinhold 			index = 1;
66898da112cSIngo Weinhold 			break;
66998da112cSIngo Weinhold 		default:
670b1970bb8SIngo Weinhold 			return B_BAD_VALUE;
67198da112cSIngo Weinhold 	}
672b1970bb8SIngo Weinhold 
673b1970bb8SIngo Weinhold 	if (InitCheck() != B_OK)
674b1970bb8SIngo Weinhold 		return B_NO_INIT;
675b1970bb8SIngo Weinhold 
67698da112cSIngo Weinhold 	// read the data
67798da112cSIngo Weinhold 	size_t read = 0;
67898da112cSIngo Weinhold 	version_info infos[2];
679b1970bb8SIngo Weinhold 	status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
680b1970bb8SIngo Weinhold 		B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read);
681b1970bb8SIngo Weinhold 	if (error != B_OK)
68298da112cSIngo Weinhold 		return error;
683b1970bb8SIngo Weinhold 
684b1970bb8SIngo Weinhold 	// check the read data
685b1970bb8SIngo Weinhold 	if (read == sizeof(version_info)) {
686b1970bb8SIngo Weinhold 		// only the app version info is there -- return a cleared system info
687b1970bb8SIngo Weinhold 		if (index == 0)
688b1970bb8SIngo Weinhold 			*info = infos[index];
689b1970bb8SIngo Weinhold 		else if (index == 1)
690b1970bb8SIngo Weinhold 			memset(info, 0, sizeof(version_info));
691b1970bb8SIngo Weinhold 	} else if (read == 2 * sizeof(version_info)) {
692b1970bb8SIngo Weinhold 		*info = infos[index];
693b1970bb8SIngo Weinhold 	} else
694b1970bb8SIngo Weinhold 		return B_ERROR;
695b1970bb8SIngo Weinhold 
696b1970bb8SIngo Weinhold 	// return result
697b1970bb8SIngo Weinhold 	return B_OK;
698d6b205f3SIngo Weinhold }
699d6b205f3SIngo Weinhold 
700d6b205f3SIngo Weinhold // SetVersionInfo
701d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
702d6b205f3SIngo Weinhold 
703d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
704d6b205f3SIngo Weinhold 
705d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
706d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
707d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
708d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
709d6b205f3SIngo Weinhold 		   belongs to.
710d6b205f3SIngo Weinhold 	\return
711d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
712d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
713d6b205f3SIngo Weinhold 	- other error codes
714d6b205f3SIngo Weinhold */
715d6b205f3SIngo Weinhold status_t
716d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
717d6b205f3SIngo Weinhold {
71898da112cSIngo Weinhold 	// check initialization
71998da112cSIngo Weinhold 	status_t error = B_OK;
72098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
72198da112cSIngo Weinhold 		error = B_NO_INIT;
72298da112cSIngo Weinhold 	if (error == B_OK) {
72398da112cSIngo Weinhold 		if (info) {
72498da112cSIngo Weinhold 			// check param
72598da112cSIngo Weinhold 			int32 index = 0;
72698da112cSIngo Weinhold 			if (error == B_OK) {
72798da112cSIngo Weinhold 				switch (kind) {
72898da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
72998da112cSIngo Weinhold 						index = 0;
73098da112cSIngo Weinhold 						break;
73198da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
73298da112cSIngo Weinhold 						index = 1;
73398da112cSIngo Weinhold 						break;
73498da112cSIngo Weinhold 					default:
73598da112cSIngo Weinhold 						error = B_BAD_VALUE;
73698da112cSIngo Weinhold 						break;
73798da112cSIngo Weinhold 				}
73898da112cSIngo Weinhold 			}
73998da112cSIngo Weinhold 			// read both infos
74098da112cSIngo Weinhold 			version_info infos[2];
74198da112cSIngo Weinhold 			if (error == B_OK) {
74298da112cSIngo Weinhold 				size_t read;
743b1970bb8SIngo Weinhold 				if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
744b1970bb8SIngo Weinhold 						B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info),
745b1970bb8SIngo Weinhold 						read) == B_OK) {
746b1970bb8SIngo Weinhold 					// clear the part that hasn't been read
747b1970bb8SIngo Weinhold 					if (read < sizeof(infos))
748b1970bb8SIngo Weinhold 						memset((char*)infos + read, 0, sizeof(infos) - read);
749b1970bb8SIngo Weinhold 				} else {
750b1970bb8SIngo Weinhold 					// failed to read -- clear
751b1970bb8SIngo Weinhold 					memset(infos, 0, sizeof(infos));
752b1970bb8SIngo Weinhold 				}
75398da112cSIngo Weinhold 			}
75498da112cSIngo Weinhold 			infos[index] = *info;
75598da112cSIngo Weinhold 			// write the data
75698da112cSIngo Weinhold 			if (error == B_OK) {
75798da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
75898da112cSIngo Weinhold 								   kVersionInfoResourceID,
75998da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
76098da112cSIngo Weinhold 								   2 * sizeof(version_info));
76198da112cSIngo Weinhold 			}
76298da112cSIngo Weinhold 		} else
76398da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
76498da112cSIngo Weinhold 	}
76598da112cSIngo Weinhold 	return error;
766d6b205f3SIngo Weinhold }
767d6b205f3SIngo Weinhold 
768d6b205f3SIngo Weinhold // GetIconForType
769d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
77098da112cSIngo Weinhold 
77198da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
77298da112cSIngo Weinhold 
77398da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
774d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
775d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
776d6b205f3SIngo Weinhold 		   large icon).
777d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
778d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
779d6b205f3SIngo Weinhold 	\return
780d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
781d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
78298da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
783d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
784d6b205f3SIngo Weinhold 		 not match.
785d6b205f3SIngo Weinhold 	- other error codes
786d6b205f3SIngo Weinhold */
787d6b205f3SIngo Weinhold status_t
788d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
789d6b205f3SIngo Weinhold 							 icon_size which) const
790d6b205f3SIngo Weinhold {
791*9ecf9d1cSIngo Weinhold 	if (InitCheck() != B_OK)
792*9ecf9d1cSIngo Weinhold 		return B_NO_INIT;
793*9ecf9d1cSIngo Weinhold 
794*9ecf9d1cSIngo Weinhold 	if (!icon || icon->InitCheck() != B_OK)
795*9ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
796*9ecf9d1cSIngo Weinhold 
797*9ecf9d1cSIngo Weinhold 	// try vector icon first
798*9ecf9d1cSIngo Weinhold 	BString vectorAttributeName(kIconAttribute);
799*9ecf9d1cSIngo Weinhold 
800*9ecf9d1cSIngo Weinhold 	// check type param
801*9ecf9d1cSIngo Weinhold 	if (type) {
802*9ecf9d1cSIngo Weinhold 		if (BMimeType::IsValid(type))
803*9ecf9d1cSIngo Weinhold 			vectorAttributeName += type;
804*9ecf9d1cSIngo Weinhold 		else
805*9ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
806*9ecf9d1cSIngo Weinhold 	} else {
807*9ecf9d1cSIngo Weinhold 		vectorAttributeName += kIconType;
808*9ecf9d1cSIngo Weinhold 	}
809*9ecf9d1cSIngo Weinhold 	const char* attribute = vectorAttributeName.String();
810*9ecf9d1cSIngo Weinhold 
811*9ecf9d1cSIngo Weinhold 	size_t bytesRead;
812*9ecf9d1cSIngo Weinhold 	void* allocatedBuffer;
813*9ecf9d1cSIngo Weinhold 	status_t error = _ReadData(attribute, -1, B_RAW_TYPE, NULL, 0,
814*9ecf9d1cSIngo Weinhold 							   bytesRead, &allocatedBuffer);
815*9ecf9d1cSIngo Weinhold 	if (error == B_OK) {
816*9ecf9d1cSIngo Weinhold 		return BIconUtils::GetVectorIcon((uint8*)allocatedBuffer,
817*9ecf9d1cSIngo Weinhold 										 bytesRead, icon);
818*9ecf9d1cSIngo Weinhold 	}
819*9ecf9d1cSIngo Weinhold 
820*9ecf9d1cSIngo Weinhold 	// no vector icon if we got this far
821*9ecf9d1cSIngo Weinhold 
822*9ecf9d1cSIngo Weinhold 	error = B_OK;
82398da112cSIngo Weinhold 	// set some icon size related variables
82498da112cSIngo Weinhold 	BString attributeString;
82598da112cSIngo Weinhold 	BRect bounds;
826a04efc92SIngo Weinhold 	uint32 attrType = 0;
827a04efc92SIngo Weinhold 	size_t attrSize = 0;
82898da112cSIngo Weinhold 	switch (which) {
82998da112cSIngo Weinhold 		case B_MINI_ICON:
83098da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
83198da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
83298da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
83398da112cSIngo Weinhold 			attrSize = 16 * 16;
83498da112cSIngo Weinhold 			break;
83598da112cSIngo Weinhold 		case B_LARGE_ICON:
83698da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
83798da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
83898da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
83998da112cSIngo Weinhold 			attrSize = 32 * 32;
84098da112cSIngo Weinhold 			break;
84198da112cSIngo Weinhold 		default:
842*9ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
84398da112cSIngo Weinhold 	}
84498da112cSIngo Weinhold 	// check type param
84598da112cSIngo Weinhold 	if (type) {
84617819be3SIngo Weinhold 		if (BMimeType::IsValid(type))
84717819be3SIngo Weinhold 			attributeString += type;
84817819be3SIngo Weinhold 		else
849*9ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
85098da112cSIngo Weinhold 	} else
85117819be3SIngo Weinhold 		attributeString += kStandardIconType;
852*9ecf9d1cSIngo Weinhold 
853*9ecf9d1cSIngo Weinhold 	attribute = attributeString.String();
85417819be3SIngo Weinhold 
85598da112cSIngo Weinhold 	// check parameter and initialization
856*9ecf9d1cSIngo Weinhold 	if (icon->Bounds() != bounds)
857*9ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
858*9ecf9d1cSIngo Weinhold 
85998da112cSIngo Weinhold 	// read the data
86098da112cSIngo Weinhold 	if (error == B_OK) {
86198da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
86298da112cSIngo Weinhold 		char *buffer = NULL;
86398da112cSIngo Weinhold 		size_t read;
86498da112cSIngo Weinhold 		if (otherColorSpace) {
86598da112cSIngo Weinhold 			// other color space than stored in attribute
86698da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
86798da112cSIngo Weinhold 			if (!buffer)
86898da112cSIngo Weinhold 				error = B_NO_MEMORY;
86998da112cSIngo Weinhold 			if (error == B_OK) {
87098da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
87198da112cSIngo Weinhold 								  read);
87298da112cSIngo Weinhold 			}
87398da112cSIngo Weinhold 		} else {
87498da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
87598da112cSIngo Weinhold 							  read);
87698da112cSIngo Weinhold 		}
87798da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
87898da112cSIngo Weinhold 			error = B_ERROR;
87998da112cSIngo Weinhold 		if (otherColorSpace) {
88098da112cSIngo Weinhold 			// other color space than stored in attribute
88176ba3434SIngo Weinhold 			if (error == B_OK) {
88276ba3434SIngo Weinhold 				error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
88376ba3434SIngo Weinhold 										 0, B_CMAP8);
88476ba3434SIngo Weinhold 			}
88598da112cSIngo Weinhold 			delete[] buffer;
88698da112cSIngo Weinhold 		}
88798da112cSIngo Weinhold 	}
88898da112cSIngo Weinhold 	return error;
889d6b205f3SIngo Weinhold }
890d6b205f3SIngo Weinhold 
891d6b205f3SIngo Weinhold // SetIconForType
892d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
893d6b205f3SIngo Weinhold 
89498da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
895d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
896d6b205f3SIngo Weinhold 
89798da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
89898da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
89998da112cSIngo Weinhold 	before.
90098da112cSIngo Weinhold 
90198da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
902d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
903d6b205f3SIngo Weinhold 		   May be \c NULL.
904d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
905d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
906d6b205f3SIngo Weinhold 	\return
907d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
908d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
909d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
910d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
911d6b205f3SIngo Weinhold 	- other error codes
912d6b205f3SIngo Weinhold */
913d6b205f3SIngo Weinhold status_t
914d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
915d6b205f3SIngo Weinhold 							 icon_size which)
916d6b205f3SIngo Weinhold {
91798da112cSIngo Weinhold 	status_t error = B_OK;
91898da112cSIngo Weinhold 	// set some icon size related variables
91998da112cSIngo Weinhold 	BString attributeString;
92098da112cSIngo Weinhold 	BRect bounds;
921a04efc92SIngo Weinhold 	uint32 attrType = 0;
922a04efc92SIngo Weinhold 	size_t attrSize = 0;
923a04efc92SIngo Weinhold 	int32 resourceID = 0;
92498da112cSIngo Weinhold 	switch (which) {
92598da112cSIngo Weinhold 		case B_MINI_ICON:
92698da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
92798da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
92898da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
92998da112cSIngo Weinhold 			attrSize = 16 * 16;
93098da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
93198da112cSIngo Weinhold 							   : kMiniIconResourceID);
93298da112cSIngo Weinhold 			break;
93398da112cSIngo Weinhold 		case B_LARGE_ICON:
93498da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
93598da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
93698da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
93798da112cSIngo Weinhold 			attrSize = 32 * 32;
93898da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
93998da112cSIngo Weinhold 							   : kLargeIconResourceID);
94098da112cSIngo Weinhold 			break;
94198da112cSIngo Weinhold 		default:
94298da112cSIngo Weinhold 			error = B_BAD_VALUE;
94398da112cSIngo Weinhold 			break;
94498da112cSIngo Weinhold 	}
94598da112cSIngo Weinhold 	// check type param
94698da112cSIngo Weinhold 	if (error == B_OK) {
94798da112cSIngo Weinhold 		if (type) {
94817819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
94998da112cSIngo Weinhold 				attributeString += type;
95017819be3SIngo Weinhold 			else
95117819be3SIngo Weinhold 				error = B_BAD_VALUE;
95298da112cSIngo Weinhold 		} else
95398da112cSIngo Weinhold 			attributeString += kStandardIconType;
95498da112cSIngo Weinhold 	}
95598da112cSIngo Weinhold 	const char *attribute = attributeString.String();
95698da112cSIngo Weinhold 	// check parameter and initialization
95798da112cSIngo Weinhold 	if (error == B_OK && icon
95898da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
95998da112cSIngo Weinhold 		error = B_BAD_VALUE;
96098da112cSIngo Weinhold 	}
96198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
96298da112cSIngo Weinhold 		error = B_NO_INIT;
96398da112cSIngo Weinhold 	// write/remove the attribute
96498da112cSIngo Weinhold 	if (error == B_OK) {
96598da112cSIngo Weinhold 		if (icon) {
96698da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
96798da112cSIngo Weinhold 			if (otherColorSpace) {
968290bc091SIngo Weinhold 				BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8);
96998da112cSIngo Weinhold 				error = bitmap.InitCheck();
97076ba3434SIngo Weinhold 				if (error == B_OK)
97176ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
97298da112cSIngo Weinhold 				if (error == B_OK) {
97398da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
97498da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
97598da112cSIngo Weinhold 				}
97698da112cSIngo Weinhold 			} else {
97798da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
97898da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
97998da112cSIngo Weinhold 			}
98098da112cSIngo Weinhold 		} else	// no icon given => remove
98198da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
98298da112cSIngo Weinhold 	}
98398da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
98498da112cSIngo Weinhold 	BMimeType mimeType;
98598da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
98698da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
98798da112cSIngo Weinhold 			error = mimeType.Install();
98898da112cSIngo Weinhold 		if (error == B_OK)
98998da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
99098da112cSIngo Weinhold 	}
99198da112cSIngo Weinhold 	return error;
992d6b205f3SIngo Weinhold }
993d6b205f3SIngo Weinhold 
994d6b205f3SIngo Weinhold // SetInfoLocation
995d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
996d6b205f3SIngo Weinhold 
997d6b205f3SIngo Weinhold 	The options for \a location are:
998d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
999d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
1000d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
1001d6b205f3SIngo Weinhold 
1002d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
1003d6b205f3SIngo Weinhold */
1004d6b205f3SIngo Weinhold void
1005d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
1006d6b205f3SIngo Weinhold {
100798da112cSIngo Weinhold 	fWhere = location;
1008d6b205f3SIngo Weinhold }
1009d6b205f3SIngo Weinhold 
1010d6b205f3SIngo Weinhold // IsUsingAttributes
1011d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
1012d6b205f3SIngo Weinhold 		   file's attributes.
1013d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
1014d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
1015d6b205f3SIngo Weinhold */
1016d6b205f3SIngo Weinhold bool
1017d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
1018d6b205f3SIngo Weinhold {
101998da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
1020d6b205f3SIngo Weinhold }
1021d6b205f3SIngo Weinhold 
1022d6b205f3SIngo Weinhold // IsUsingResources
1023d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
1024d6b205f3SIngo Weinhold 		   file's resources.
1025d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
1026d6b205f3SIngo Weinhold 			resources, \c false otherwise.
1027d6b205f3SIngo Weinhold */
1028d6b205f3SIngo Weinhold bool
1029d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
1030d6b205f3SIngo Weinhold {
103198da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
1032d6b205f3SIngo Weinhold }
1033d6b205f3SIngo Weinhold 
1034d6b205f3SIngo Weinhold // FBC
1035d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
1036d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
1037d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
1038d6b205f3SIngo Weinhold 
1039d6b205f3SIngo Weinhold // =
1040d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
1041d6b205f3SIngo Weinhold */
1042d6b205f3SIngo Weinhold BAppFileInfo &
1043d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
1044d6b205f3SIngo Weinhold {
1045d6b205f3SIngo Weinhold 	return *this;
1046d6b205f3SIngo Weinhold }
1047d6b205f3SIngo Weinhold 
1048d6b205f3SIngo Weinhold // copy constructor
1049d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1050d6b205f3SIngo Weinhold */
1051d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
1052d6b205f3SIngo Weinhold {
1053d6b205f3SIngo Weinhold }
1054d6b205f3SIngo Weinhold 
105598da112cSIngo Weinhold // GetMetaMime
105698da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
105798da112cSIngo Weinhold 
105898da112cSIngo Weinhold 	The parameter \a meta is not checked.
105998da112cSIngo Weinhold 
106098da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
106198da112cSIngo Weinhold 		   initialized to the file's signature.
106298da112cSIngo Weinhold 	\return
106398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
106498da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
106598da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
106698da112cSIngo Weinhold (	  not installed in the MIME database.)
106798da112cSIngo Weinhold 	  no valid MIME string.
106898da112cSIngo Weinhold 	- other error codes
106998da112cSIngo Weinhold */
107098da112cSIngo Weinhold status_t
107198da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
107298da112cSIngo Weinhold {
107398da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
107498da112cSIngo Weinhold 	status_t error = GetSignature(signature);
107598da112cSIngo Weinhold 	if (error == B_OK)
107698da112cSIngo Weinhold 		error = meta->SetTo(signature);
10777f20062dSJérôme Duval 	else if (error == B_BAD_VALUE)
10787f20062dSJérôme Duval 		error = B_ENTRY_NOT_FOUND;
107998da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
108098da112cSIngo Weinhold 		error = B_BAD_VALUE;
108198da112cSIngo Weinhold 	return error;
108298da112cSIngo Weinhold }
108398da112cSIngo Weinhold 
108498da112cSIngo Weinhold // _ReadData
108598da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
108698da112cSIngo Weinhold 
108798da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
108898da112cSIngo Weinhold 
108998da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
109098da112cSIngo Weinhold 
109198da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
109298da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
109398da112cSIngo Weinhold 		   < 0.
109498da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
109598da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
109698da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
109798da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
109898da112cSIngo Weinhold 		   actually read.
109998da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
110098da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
110198da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
110298da112cSIngo Weinhold 	\return
110398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
110498da112cSIngo Weinhold 	- error code
110598da112cSIngo Weinhold */
110698da112cSIngo Weinhold status_t
110798da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
110898da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
110998da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
111098da112cSIngo Weinhold {
111198da112cSIngo Weinhold 	status_t error = B_OK;
1112338b8dc3SIngo Weinhold 
111398da112cSIngo Weinhold 	if (allocatedBuffer)
111498da112cSIngo Weinhold 		buffer = NULL;
1115338b8dc3SIngo Weinhold 
1116338b8dc3SIngo Weinhold 	bool foundData = false;
1117338b8dc3SIngo Weinhold 
111898da112cSIngo Weinhold 	if (IsUsingAttributes()) {
111998da112cSIngo Weinhold 		// get an attribute info
112098da112cSIngo Weinhold 		attr_info info;
112198da112cSIngo Weinhold 		if (error == B_OK)
112298da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1123338b8dc3SIngo Weinhold 
112498da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
112598da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
112698da112cSIngo Weinhold 			error = B_BAD_VALUE;
1127b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
112898da112cSIngo Weinhold 			buffer = malloc(info.size);
112998da112cSIngo Weinhold 			if (!buffer)
113098da112cSIngo Weinhold 				error = B_NO_MEMORY;
113198da112cSIngo Weinhold 			bufferSize = info.size;
113298da112cSIngo Weinhold 		}
113398da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
113498da112cSIngo Weinhold 			error = B_BAD_VALUE;
1135338b8dc3SIngo Weinhold 
113698da112cSIngo Weinhold 		// read the data
113798da112cSIngo Weinhold 		if (error == B_OK) {
113898da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
113998da112cSIngo Weinhold 			if (read < 0)
114098da112cSIngo Weinhold 				error = read;
114198da112cSIngo Weinhold 			else if (read != info.size)
114298da112cSIngo Weinhold 				error = B_ERROR;
114398da112cSIngo Weinhold 			else
114498da112cSIngo Weinhold 				bytesRead = read;
114598da112cSIngo Weinhold 		}
1146338b8dc3SIngo Weinhold 
1147338b8dc3SIngo Weinhold 		foundData = (error == B_OK);
1148b4598d95SIngo Weinhold 
1149b4598d95SIngo Weinhold 		// free the allocated buffer on error
1150b4598d95SIngo Weinhold 		if (!foundData && allocatedBuffer && buffer) {
1151b4598d95SIngo Weinhold 			free(buffer);
1152b4598d95SIngo Weinhold 			buffer = NULL;
1153b4598d95SIngo Weinhold 		}
1154338b8dc3SIngo Weinhold 	}
1155338b8dc3SIngo Weinhold 
1156338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
115798da112cSIngo Weinhold 		// get a resource info
1158338b8dc3SIngo Weinhold 		error = B_OK;
115998da112cSIngo Weinhold 		int32 idFound;
116098da112cSIngo Weinhold 		size_t sizeFound;
116198da112cSIngo Weinhold 		if (error == B_OK) {
116298da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
116398da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
116498da112cSIngo Weinhold 		}
1165338b8dc3SIngo Weinhold 
116698da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
116798da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
116898da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1169b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
117098da112cSIngo Weinhold 			buffer = malloc(sizeFound);
117198da112cSIngo Weinhold 			if (!buffer)
117298da112cSIngo Weinhold 				error = B_NO_MEMORY;
117398da112cSIngo Weinhold 			bufferSize = sizeFound;
117498da112cSIngo Weinhold 		}
117598da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
117698da112cSIngo Weinhold 			error = B_BAD_VALUE;
1177338b8dc3SIngo Weinhold 
117898da112cSIngo Weinhold 		// load resource
117998da112cSIngo Weinhold 		const void *resourceData = NULL;
118098da112cSIngo Weinhold 		if (error == B_OK) {
118198da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
118298da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
118398da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
118498da112cSIngo Weinhold 			else
118598da112cSIngo Weinhold 				error = B_ERROR;
118698da112cSIngo Weinhold 		}
1187773be699SAxel Dörfler 	} else if (!foundData)
118898da112cSIngo Weinhold 		error = B_BAD_VALUE;
1189338b8dc3SIngo Weinhold 
119098da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
119198da112cSIngo Weinhold 	if (allocatedBuffer) {
119298da112cSIngo Weinhold 		if (error == B_OK)
119398da112cSIngo Weinhold 			*allocatedBuffer = buffer;
119498da112cSIngo Weinhold 		else
119598da112cSIngo Weinhold 			free(buffer);
119698da112cSIngo Weinhold 	}
1197338b8dc3SIngo Weinhold 
119898da112cSIngo Weinhold 	return error;
119998da112cSIngo Weinhold }
120098da112cSIngo Weinhold 
120198da112cSIngo Weinhold // _WriteData
120298da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
120398da112cSIngo Weinhold 
120498da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
120598da112cSIngo Weinhold 
120698da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
120798da112cSIngo Weinhold 
120898da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
120998da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
121098da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
121198da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
121298da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
121398da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
121498da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
121598da112cSIngo Weinhold 		   If \c false, \a id is used.
121698da112cSIngo Weinhold 	If \a id is already in use and .
121798da112cSIngo Weinhold 	\return
121898da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
121998da112cSIngo Weinhold 	- error code
122098da112cSIngo Weinhold */
122198da112cSIngo Weinhold status_t
122298da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
122398da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
122498da112cSIngo Weinhold {
122598da112cSIngo Weinhold 	status_t error = B_OK;
122698da112cSIngo Weinhold 	// write to attribute
122798da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
122898da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
122998da112cSIngo Weinhold 		if (written < 0)
123098da112cSIngo Weinhold 			error = written;
123198da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
123298da112cSIngo Weinhold 			error = B_ERROR;
123398da112cSIngo Weinhold 	}
123498da112cSIngo Weinhold 	// write to resource
123598da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
123698da112cSIngo Weinhold 		if (findID) {
123798da112cSIngo Weinhold 			// get the resource info
123898da112cSIngo Weinhold 			int32 idFound;
123998da112cSIngo Weinhold 			size_t sizeFound;
124098da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
124198da112cSIngo Weinhold 				id = idFound;
124298da112cSIngo Weinhold 			else {
124398da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
124498da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
124598da112cSIngo Weinhold 					id++;
124698da112cSIngo Weinhold 			}
124798da112cSIngo Weinhold 		}
124898da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
124998da112cSIngo Weinhold 	}
125098da112cSIngo Weinhold 	return error;
125198da112cSIngo Weinhold }
125298da112cSIngo Weinhold 
125398da112cSIngo Weinhold // _RemoveData
125498da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
125598da112cSIngo Weinhold 
125698da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
125798da112cSIngo Weinhold 
125898da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
125998da112cSIngo Weinhold 
126098da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
126198da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
126298da112cSIngo Weinhold 	\return
126398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
126498da112cSIngo Weinhold 	- error code
126598da112cSIngo Weinhold */
126698da112cSIngo Weinhold status_t
126798da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
126898da112cSIngo Weinhold {
126998da112cSIngo Weinhold 	status_t error = B_OK;
127098da112cSIngo Weinhold 	// remove the attribute
127198da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
127298da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
127398da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
127498da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
127598da112cSIngo Weinhold 			error = B_OK;
127698da112cSIngo Weinhold 	}
127798da112cSIngo Weinhold 	// remove the resource
127898da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
127998da112cSIngo Weinhold 		// get a resource info
128098da112cSIngo Weinhold 		int32 idFound;
128198da112cSIngo Weinhold 		size_t sizeFound;
128298da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
128398da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
128498da112cSIngo Weinhold 	}
128598da112cSIngo Weinhold 	return error;
128698da112cSIngo Weinhold }
128798da112cSIngo Weinhold 
1288