xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 9be774b553296a712704078314f2291ae5fc352c)
131dc79a1SAxel Dörfler /*
2d0c290bfSAxel Dörfler  * Copyright 2002-2007, 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>
1218cd67c7SMichael Lotz #include <stdlib.h>
1398da112cSIngo Weinhold #include <string>
1498da112cSIngo Weinhold 
15d6b205f3SIngo Weinhold #include <AppFileInfo.h>
1698da112cSIngo Weinhold #include <Bitmap.h>
1798da112cSIngo Weinhold #include <File.h>
1898da112cSIngo Weinhold #include <fs_attr.h>
199ecf9d1cSIngo Weinhold #include <IconUtils.h>
2098da112cSIngo Weinhold #include <MimeType.h>
2198da112cSIngo Weinhold #include <RegistrarDefs.h>
2298da112cSIngo Weinhold #include <Resources.h>
2398da112cSIngo Weinhold #include <Roster.h>
2498da112cSIngo Weinhold #include <String.h>
2598da112cSIngo Weinhold 
2650f17542Shaydentech using namespace std;
2750f17542Shaydentech 
2898da112cSIngo Weinhold // attributes
2998da112cSIngo Weinhold static const char* kTypeAttribute				= "BEOS:TYPE";
3098da112cSIngo Weinhold static const char* kSignatureAttribute			= "BEOS:APP_SIG";
3198da112cSIngo Weinhold static const char* kAppFlagsAttribute			= "BEOS:APP_FLAGS";
3298da112cSIngo Weinhold static const char* kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
3398da112cSIngo Weinhold static const char* kVersionInfoAttribute		= "BEOS:APP_VERSION";
3498da112cSIngo Weinhold static const char* kMiniIconAttribute			= "BEOS:M:";
3598da112cSIngo Weinhold static const char* kLargeIconAttribute			= "BEOS:L:";
369ecf9d1cSIngo Weinhold static const char* kIconAttribute				= "BEOS:";
3798da112cSIngo Weinhold static const char* kStandardIconType			= "STD_ICON";
389ecf9d1cSIngo Weinhold static const char* kIconType					= "ICON";
3982e7ef67SJonas Sundström static const char* kCatalogEntryAttribute		= "SYS:NAME";
4098da112cSIngo Weinhold 
4198da112cSIngo Weinhold // resource IDs
4298da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
4398da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
4498da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
4598da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
4698da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
4798da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
487fb6186fSStephan Aßmus static const int32 kIconResourceID				= 101;
4998da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
5098da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
5198da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
527fb6186fSStephan Aßmus static const int32 kIconForTypeResourceID		= 0;
5382e7ef67SJonas Sundström static const int32 kCatalogEntryResourceID		= 1;
5498da112cSIngo Weinhold 
5598da112cSIngo Weinhold // type codes
5698da112cSIngo Weinhold enum {
5798da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
5898da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
5998da112cSIngo Weinhold };
6098da112cSIngo Weinhold 
6188706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
6288706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
6388706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
6488706bbeSAxel Dörfler // Tracker when compiled for Haiku)
6588706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
6688706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
6788706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
6888706bbeSAxel Dörfler 
6978b31a7cSIngo Weinhold // debugging
7078b31a7cSIngo Weinhold //#define DBG(x) x
7178b31a7cSIngo Weinhold #define DBG(x)
7278b31a7cSIngo Weinhold #define OUT	printf
73d6b205f3SIngo Weinhold 
74d6b205f3SIngo Weinhold // constructor
75d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
76d6b205f3SIngo Weinhold */
77d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
78e1b526b9SJonas Sundström 	:
79e1b526b9SJonas Sundström 	fResources(NULL),
80d6b205f3SIngo Weinhold 	fWhere(B_USE_BOTH_LOCATIONS)
81d6b205f3SIngo Weinhold {
82d6b205f3SIngo Weinhold }
83d6b205f3SIngo Weinhold 
84e1b526b9SJonas Sundström 
85d6b205f3SIngo Weinhold // constructor
86d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
87d6b205f3SIngo Weinhold 		   file.
88d6b205f3SIngo Weinhold 
89d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
90d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
91d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
92d6b205f3SIngo Weinhold 
93d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
94d6b205f3SIngo Weinhold */
95d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile* file)
96e1b526b9SJonas Sundström 	:
97e1b526b9SJonas Sundström 	fResources(NULL),
98d6b205f3SIngo Weinhold 	fWhere(B_USE_BOTH_LOCATIONS)
99d6b205f3SIngo Weinhold {
10098da112cSIngo Weinhold 	SetTo(file);
101d6b205f3SIngo Weinhold }
102d6b205f3SIngo Weinhold 
103e1b526b9SJonas Sundström 
104d6b205f3SIngo Weinhold // destructor
105d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
106d6b205f3SIngo Weinhold 
107d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
108d6b205f3SIngo Weinhold */
109d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
110d6b205f3SIngo Weinhold {
11198da112cSIngo Weinhold 	delete fResources;
112d6b205f3SIngo Weinhold }
113d6b205f3SIngo Weinhold 
114e1b526b9SJonas Sundström 
115d6b205f3SIngo Weinhold // SetTo
116d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
117d6b205f3SIngo Weinhold 
118d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
119d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
120d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
121d6b205f3SIngo Weinhold 
122d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
123d6b205f3SIngo Weinhold 
124d6b205f3SIngo Weinhold 	\return
125d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
126d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
127d6b205f3SIngo Weinhold */
128d6b205f3SIngo Weinhold status_t
129d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
130d6b205f3SIngo Weinhold {
13198da112cSIngo Weinhold 	// unset the old file
13298da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
13398da112cSIngo Weinhold 	if (fResources) {
13498da112cSIngo Weinhold 		delete fResources;
13598da112cSIngo Weinhold 		fResources = NULL;
13698da112cSIngo Weinhold 	}
137c2a2369dSAxel Dörfler 
13898da112cSIngo Weinhold 	// check param
13998da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
140c2a2369dSAxel Dörfler 
141c2a2369dSAxel Dörfler 	info_location where = B_USE_BOTH_LOCATIONS;
142c2a2369dSAxel Dörfler 
14398da112cSIngo Weinhold 	// create resources
14498da112cSIngo Weinhold 	if (error == B_OK) {
14598da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
146c2a2369dSAxel Dörfler 		if (fResources) {
14798da112cSIngo Weinhold 			error = fResources->SetTo(file);
148c2a2369dSAxel Dörfler 			if (error != B_OK) {
149c2a2369dSAxel Dörfler 				// no resources - this is no critical error, we'll just use
150c2a2369dSAxel Dörfler 				// attributes only, then
151c2a2369dSAxel Dörfler 				where = B_USE_ATTRIBUTES;
152c2a2369dSAxel Dörfler 				error = B_OK;
153c2a2369dSAxel Dörfler 			}
154c2a2369dSAxel Dörfler 		} else
15598da112cSIngo Weinhold 			error = B_NO_MEMORY;
15698da112cSIngo Weinhold 	}
157c2a2369dSAxel Dörfler 
15898da112cSIngo Weinhold 	// set node info
15998da112cSIngo Weinhold 	if (error == B_OK)
16098da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
161c2a2369dSAxel Dörfler 
162c2a2369dSAxel Dörfler 	if (error != B_OK || (where & B_USE_RESOURCES) == 0) {
16398da112cSIngo Weinhold 		delete fResources;
16498da112cSIngo Weinhold 		fResources = NULL;
16598da112cSIngo Weinhold 	}
166c2a2369dSAxel Dörfler 
167c2a2369dSAxel Dörfler 	// clean up on error
168c2a2369dSAxel Dörfler 	if (error != B_OK) {
16998da112cSIngo Weinhold 		if (InitCheck() == B_OK)
17098da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
17198da112cSIngo Weinhold 	}
172c2a2369dSAxel Dörfler 
17398da112cSIngo Weinhold 	// set data location
17498da112cSIngo Weinhold 	if (error == B_OK)
175c2a2369dSAxel Dörfler 		SetInfoLocation(where);
176c2a2369dSAxel Dörfler 
17798da112cSIngo Weinhold 	// set error
17898da112cSIngo Weinhold 	fCStatus = error;
17998da112cSIngo Weinhold 	return error;
180d6b205f3SIngo Weinhold }
181d6b205f3SIngo Weinhold 
182e1b526b9SJonas Sundström 
183d6b205f3SIngo Weinhold // GetType
184d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
185d6b205f3SIngo Weinhold 
186d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
187d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
188d6b205f3SIngo Weinhold 		   file shall be written.
189d6b205f3SIngo Weinhold 	\return
190d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
191d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
192d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
193d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
194d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
195d6b205f3SIngo Weinhold 	  the wrong type.
196d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
197d6b205f3SIngo Weinhold 	- other error codes
198d6b205f3SIngo Weinhold */
199d6b205f3SIngo Weinhold status_t
200d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
201d6b205f3SIngo Weinhold {
20298da112cSIngo Weinhold 	// check param and initialization
20398da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
20498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
20598da112cSIngo Weinhold 		error = B_NO_INIT;
20698da112cSIngo Weinhold 	// read the data
20798da112cSIngo Weinhold 	size_t read = 0;
20898da112cSIngo Weinhold 	if (error == B_OK) {
20998da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
21098da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
21198da112cSIngo Weinhold 	}
21298da112cSIngo Weinhold 	// check the read data -- null terminate the string
21398da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
21498da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
21598da112cSIngo Weinhold 			error = B_ERROR;
21698da112cSIngo Weinhold 		else
21798da112cSIngo Weinhold 			type[read] = '\0';
21898da112cSIngo Weinhold 	}
21998da112cSIngo Weinhold 	return error;
220d6b205f3SIngo Weinhold }
221d6b205f3SIngo Weinhold 
222e1b526b9SJonas Sundström 
223d6b205f3SIngo Weinhold // SetType
224d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
225d6b205f3SIngo Weinhold 
226d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
227d6b205f3SIngo Weinhold 
228d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
229d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
230d6b205f3SIngo Weinhold 		   May be \c NULL.
231d6b205f3SIngo Weinhold 	\return
232d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
233d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
234d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
235d6b205f3SIngo Weinhold 	- other error codes
236d6b205f3SIngo Weinhold */
237d6b205f3SIngo Weinhold status_t
238d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char* type)
239d6b205f3SIngo Weinhold {
24098da112cSIngo Weinhold 	// check initialization
24198da112cSIngo Weinhold 	status_t error = B_OK;
24298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
24398da112cSIngo Weinhold 		error = B_NO_INIT;
24498da112cSIngo Weinhold 	if (error == B_OK) {
24598da112cSIngo Weinhold 		if (type) {
24698da112cSIngo Weinhold 			// check param
24798da112cSIngo Weinhold 			size_t typeLen = strlen(type);
24898da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
24998da112cSIngo Weinhold 				error = B_BAD_VALUE;
25098da112cSIngo Weinhold 			// write the data
25198da112cSIngo Weinhold 			if (error == B_OK) {
25298da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
25398da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
25498da112cSIngo Weinhold 			}
25598da112cSIngo Weinhold 		} else
25698da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
25798da112cSIngo Weinhold 	}
25898da112cSIngo Weinhold 	return error;
259d6b205f3SIngo Weinhold }
260d6b205f3SIngo Weinhold 
261e1b526b9SJonas Sundström 
262d6b205f3SIngo Weinhold // GetSignature
263d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
264d6b205f3SIngo Weinhold 
265d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
266d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
267d6b205f3SIngo Weinhold 		   signature of the file shall be written.
268d6b205f3SIngo Weinhold 	\return
269d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
270d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
271d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
272d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
273d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
274d6b205f3SIngo Weinhold 	  the wrong type.
275d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
276d6b205f3SIngo Weinhold 	- other error codes
277d6b205f3SIngo Weinhold */
278d6b205f3SIngo Weinhold status_t
279d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char* signature) const
280d6b205f3SIngo Weinhold {
28198da112cSIngo Weinhold 	// check param and initialization
28298da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
28398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
28498da112cSIngo Weinhold 		error = B_NO_INIT;
28598da112cSIngo Weinhold 	// read the data
28698da112cSIngo Weinhold 	size_t read = 0;
28798da112cSIngo Weinhold 	if (error == B_OK) {
28898da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
289e1b526b9SJonas Sundström 						  B_MIME_STRING_TYPE, signature,
290e1b526b9SJonas Sundström 						  B_MIME_TYPE_LENGTH, read);
29198da112cSIngo Weinhold 	}
29298da112cSIngo Weinhold 	// check the read data -- null terminate the string
29398da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
29498da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
29598da112cSIngo Weinhold 			error = B_ERROR;
29698da112cSIngo Weinhold 		else
29798da112cSIngo Weinhold 			signature[read] = '\0';
29898da112cSIngo Weinhold 	}
29998da112cSIngo Weinhold 	return error;
300d6b205f3SIngo Weinhold }
301d6b205f3SIngo Weinhold 
302e1b526b9SJonas Sundström 
303d6b205f3SIngo Weinhold // SetSignature
304d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
305d6b205f3SIngo Weinhold 
306d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
307d6b205f3SIngo Weinhold 
308d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
309d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
310d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
311d6b205f3SIngo Weinhold 	\return
312d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
313d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
314d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
315d6b205f3SIngo Weinhold 	- other error codes
316d6b205f3SIngo Weinhold */
317d6b205f3SIngo Weinhold status_t
318d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char* signature)
319d6b205f3SIngo Weinhold {
32098da112cSIngo Weinhold 	// check initialization
32198da112cSIngo Weinhold 	status_t error = B_OK;
32298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
32398da112cSIngo Weinhold 		error = B_NO_INIT;
32498da112cSIngo Weinhold 	if (error == B_OK) {
32598da112cSIngo Weinhold 		if (signature) {
32698da112cSIngo Weinhold 			// check param
32798da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
32898da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
32998da112cSIngo Weinhold 				error = B_BAD_VALUE;
33098da112cSIngo Weinhold 			// write the data
33198da112cSIngo Weinhold 			if (error == B_OK) {
33298da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
33398da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
33498da112cSIngo Weinhold 								   signatureLen + 1);
33598da112cSIngo Weinhold 			}
33698da112cSIngo Weinhold 		} else
33798da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
33898da112cSIngo Weinhold 	}
33998da112cSIngo Weinhold 	return error;
340d6b205f3SIngo Weinhold }
341d6b205f3SIngo Weinhold 
34282e7ef67SJonas Sundström 
34382e7ef67SJonas Sundström // GetCatalogEntry
34482e7ef67SJonas Sundström /*!	\brief Gets the file's catalog entry. (localization)
34582e7ef67SJonas Sundström 
34682e7ef67SJonas Sundström 	\param catalogEntry A pointer to a pre-allocated character buffer of size
34782e7ef67SJonas Sundström 		   \c B_MIME_TYPE_LENGTH * 3 or larger into which the catalog entry
34882e7ef67SJonas Sundström 		   of the file shall be written.
34982e7ef67SJonas Sundström 	\return
35082e7ef67SJonas Sundström 	- \c B_OK: Everything went fine.
35182e7ef67SJonas Sundström 	- \c B_NO_INIT: The object is not properly initialized.
35282e7ef67SJonas Sundström 	- \c B_BAD_VALUE: \c NULL \a catalogEntry or the entry stored in the
35382e7ef67SJonas Sundström 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH * 3.
35482e7ef67SJonas Sundström 	- \c B_BAD_TYPE: The attribute/resources the entry is stored in have
35582e7ef67SJonas Sundström 	  the wrong type.
35682e7ef67SJonas Sundström 	- \c B_ENTRY_NOT_FOUND: No catalog entry is set on the file.
35782e7ef67SJonas Sundström 	- other error codes
35882e7ef67SJonas Sundström */
35982e7ef67SJonas Sundström status_t
36082e7ef67SJonas Sundström BAppFileInfo::GetCatalogEntry(char *catalogEntry) const
36182e7ef67SJonas Sundström {
36282e7ef67SJonas Sundström 	if (catalogEntry == NULL)
36382e7ef67SJonas Sundström 		return B_BAD_VALUE;
36482e7ef67SJonas Sundström 
36582e7ef67SJonas Sundström 	if (InitCheck() != B_OK)
36682e7ef67SJonas Sundström 		return B_NO_INIT;
36782e7ef67SJonas Sundström 
36882e7ef67SJonas Sundström 	size_t read = 0;
36982e7ef67SJonas Sundström 	status_t error = _ReadData(kCatalogEntryAttribute, kCatalogEntryResourceID,
37082e7ef67SJonas Sundström 		B_STRING_TYPE, catalogEntry, B_MIME_TYPE_LENGTH * 3, read);
37182e7ef67SJonas Sundström 
37282e7ef67SJonas Sundström 	if (error != B_OK)
37382e7ef67SJonas Sundström 		return error;
37482e7ef67SJonas Sundström 
37582e7ef67SJonas Sundström 	if (read >= B_MIME_TYPE_LENGTH * 3)
37682e7ef67SJonas Sundström 		return B_ERROR;
37782e7ef67SJonas Sundström 
37882e7ef67SJonas Sundström 	catalogEntry[read] = '\0';
37982e7ef67SJonas Sundström 
38082e7ef67SJonas Sundström 	return B_OK;
38182e7ef67SJonas Sundström }
38282e7ef67SJonas Sundström 
38382e7ef67SJonas Sundström 
38482e7ef67SJonas Sundström // SetCatalogEntry
38582e7ef67SJonas Sundström /*!	\brief Sets the file's catalog entry. (localization)
38682e7ef67SJonas Sundström 
38782e7ef67SJonas Sundström 	If \a catalogEntry is \c NULL the file's catalog entry is unset.
38882e7ef67SJonas Sundström 
38982e7ef67SJonas Sundström 	\param catalogEntry The catalog entry to be assigned to the file.
39082e7ef67SJonas Sundström 		Of the form "x-vnd.Haiku-app:context:name".
39182e7ef67SJonas Sundström 		Must not be longer than \c B_MIME_TYPE_LENGTH * 3
39282e7ef67SJonas Sundström 		(including the terminating null). May be \c NULL.
39382e7ef67SJonas Sundström 	\return
39482e7ef67SJonas Sundström 	- \c B_OK: Everything went fine.
39582e7ef67SJonas Sundström 	- \c B_NO_INIT: The object is not properly initialized.
39682e7ef67SJonas Sundström 	- \c B_BAD_VALUE: \a catalogEntry is longer than \c B_MIME_TYPE_LENGTH * 3.
39782e7ef67SJonas Sundström 	- other error codes
39882e7ef67SJonas Sundström */
39982e7ef67SJonas Sundström status_t
40082e7ef67SJonas Sundström BAppFileInfo::SetCatalogEntry(const char* catalogEntry)
40182e7ef67SJonas Sundström {
40282e7ef67SJonas Sundström 	if (InitCheck() != B_OK)
40382e7ef67SJonas Sundström 		return B_NO_INIT;
40482e7ef67SJonas Sundström 
40582e7ef67SJonas Sundström 	if (catalogEntry == NULL)
40682e7ef67SJonas Sundström 		return _RemoveData(kCatalogEntryAttribute, B_STRING_TYPE);
40782e7ef67SJonas Sundström 
40882e7ef67SJonas Sundström 	size_t nameLength = strlen(catalogEntry);
40982e7ef67SJonas Sundström 	if (nameLength > B_MIME_TYPE_LENGTH * 3)
41082e7ef67SJonas Sundström 		return B_BAD_VALUE;
41182e7ef67SJonas Sundström 
41282e7ef67SJonas Sundström 	return _WriteData(kCatalogEntryAttribute, kCatalogEntryResourceID,
41382e7ef67SJonas Sundström 		B_STRING_TYPE, catalogEntry, nameLength + 1);
41482e7ef67SJonas Sundström }
41582e7ef67SJonas Sundström 
41682e7ef67SJonas Sundström 
417d6b205f3SIngo Weinhold // GetAppFlags
418d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
419d6b205f3SIngo Weinhold 
420d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
421d6b205f3SIngo Weinhold 		   flags of the file shall be written.
422d6b205f3SIngo Weinhold 	\return
423d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
424d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
425d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
426d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
427d6b205f3SIngo Weinhold 	  the wrong type.
428d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
429d6b205f3SIngo Weinhold 	- other error codes
430d6b205f3SIngo Weinhold */
431d6b205f3SIngo Weinhold status_t
432d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32* flags) const
433d6b205f3SIngo Weinhold {
43498da112cSIngo Weinhold 	// check param and initialization
43598da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
43698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
43798da112cSIngo Weinhold 		error = B_NO_INIT;
43898da112cSIngo Weinhold 	// read the data
43998da112cSIngo Weinhold 	size_t read = 0;
44098da112cSIngo Weinhold 	if (error == B_OK) {
44198da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
44298da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
44398da112cSIngo Weinhold 						  read);
44498da112cSIngo Weinhold 	}
44598da112cSIngo Weinhold 	// check the read data
44698da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
44798da112cSIngo Weinhold 		error = B_ERROR;
44898da112cSIngo Weinhold 	return error;
449d6b205f3SIngo Weinhold }
450d6b205f3SIngo Weinhold 
451e1b526b9SJonas Sundström 
452d6b205f3SIngo Weinhold // SetAppFlags
453d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
454d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
455d6b205f3SIngo Weinhold 	\return
456d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
457d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
458d6b205f3SIngo Weinhold 	- other error codes
459d6b205f3SIngo Weinhold */
460d6b205f3SIngo Weinhold status_t
461d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
462d6b205f3SIngo Weinhold {
46398da112cSIngo Weinhold 	// check initialization
46498da112cSIngo Weinhold 	status_t error = B_OK;
46598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
46698da112cSIngo Weinhold 		error = B_NO_INIT;
46798da112cSIngo Weinhold 	if (error == B_OK) {
46898da112cSIngo Weinhold 		// write the data
46998da112cSIngo Weinhold 		error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
47098da112cSIngo Weinhold 						   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
47198da112cSIngo Weinhold 	}
47222920adfSStephan Aßmus 	return error;
47322920adfSStephan Aßmus }
47422920adfSStephan Aßmus 
475e1b526b9SJonas Sundström 
47622920adfSStephan Aßmus // RemoveAppFlags
47722920adfSStephan Aßmus /*!	\brief Removes the file's application flags.
47822920adfSStephan Aßmus 	\return
47922920adfSStephan Aßmus 	- \c B_OK: Everything went fine.
48022920adfSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
48122920adfSStephan Aßmus 	- other error codes
48222920adfSStephan Aßmus */
48322920adfSStephan Aßmus status_t
48422920adfSStephan Aßmus BAppFileInfo::RemoveAppFlags()
48522920adfSStephan Aßmus {
48622920adfSStephan Aßmus 	// check initialization
48722920adfSStephan Aßmus 	status_t error = B_OK;
48822920adfSStephan Aßmus 	if (error == B_OK && InitCheck() != B_OK)
48922920adfSStephan Aßmus 		error = B_NO_INIT;
49022920adfSStephan Aßmus 	if (error == B_OK) {
49122920adfSStephan Aßmus 		// remove the data
49222920adfSStephan Aßmus 		error = _RemoveData(kAppFlagsAttribute, B_APP_FLAGS_TYPE);
49398da112cSIngo Weinhold 	}
49498da112cSIngo Weinhold 	return error;
495d6b205f3SIngo Weinhold }
496d6b205f3SIngo Weinhold 
497e1b526b9SJonas Sundström 
498d6b205f3SIngo Weinhold // GetSupportedTypes
499d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
500d6b205f3SIngo Weinhold 
501d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
502d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
503d6b205f3SIngo Weinhold 
504d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
505d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
506d6b205f3SIngo Weinhold 	\return
507d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
508d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
509d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
510d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
511d6b205f3SIngo Weinhold 	  have the wrong type.
512d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
513d6b205f3SIngo Weinhold 	- other error codes
514d6b205f3SIngo Weinhold */
515d6b205f3SIngo Weinhold status_t
516d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage* types) const
517d6b205f3SIngo Weinhold {
51898da112cSIngo Weinhold 	// check param and initialization
51998da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
52098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
52198da112cSIngo Weinhold 		error = B_NO_INIT;
52298da112cSIngo Weinhold 	// read the data
52398da112cSIngo Weinhold 	size_t read = 0;
52498da112cSIngo Weinhold 	void *buffer = NULL;
52598da112cSIngo Weinhold 	if (error == B_OK) {
52698da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
52798da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
52898da112cSIngo Weinhold 	}
52998da112cSIngo Weinhold 	// unflatten the buffer
53098da112cSIngo Weinhold 	if (error == B_OK)
53198da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
53298da112cSIngo Weinhold 	// clean up
53398da112cSIngo Weinhold 	free(buffer);
53498da112cSIngo Weinhold 	return error;
535d6b205f3SIngo Weinhold }
536d6b205f3SIngo Weinhold 
537e1b526b9SJonas Sundström 
538d6b205f3SIngo Weinhold // SetSupportedTypes
539d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
540d6b205f3SIngo Weinhold 
541d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
542d6b205f3SIngo Weinhold 
543d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
544d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
545d6b205f3SIngo Weinhold 
54683a812a1SIngo Weinhold 	The method informs the registrar about this news.
54783a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
54883a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
54983a812a1SIngo Weinhold 	application file needs to have a signature set.
55083a812a1SIngo Weinhold 
55183a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
55283a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
55383a812a1SIngo Weinhold 	lists of supporting applications.
55483a812a1SIngo Weinhold 
555d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
556d6b205f3SIngo Weinhold 		   May be \c NULL.
55783a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
55883a812a1SIngo Weinhold 		   types, \c false otherwise.
559d6b205f3SIngo Weinhold 	\return
560d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
561d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
562d6b205f3SIngo Weinhold 	- other error codes
563d6b205f3SIngo Weinhold */
564d6b205f3SIngo Weinhold status_t
565d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool syncAll)
566d6b205f3SIngo Weinhold {
56798da112cSIngo Weinhold 	// check initialization
56898da112cSIngo Weinhold 	status_t error = B_OK;
56998da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
57098da112cSIngo Weinhold 		error = B_NO_INIT;
57198da112cSIngo Weinhold 	BMimeType mimeType;
57298da112cSIngo Weinhold 	if (error == B_OK)
57398da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
5747f20062dSJérôme Duval 	if (error == B_OK || error == B_ENTRY_NOT_FOUND) {
5757f20062dSJérôme Duval 		error = B_OK;
57698da112cSIngo Weinhold 		if (types) {
57717819be3SIngo Weinhold 			// check param -- supported types must be valid
57817819be3SIngo Weinhold 			const char* type;
57917819be3SIngo Weinhold 			for (int32 i = 0;
58017819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
58117819be3SIngo Weinhold 				 i++) {
58217819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
58317819be3SIngo Weinhold 					error = B_BAD_VALUE;
58417819be3SIngo Weinhold 			}
58517819be3SIngo Weinhold 			// get flattened size
58617819be3SIngo Weinhold 			ssize_t size = 0;
58717819be3SIngo Weinhold 			if (error == B_OK) {
58817819be3SIngo Weinhold 				size = types->FlattenedSize();
58998da112cSIngo Weinhold 				if (size < 0)
59098da112cSIngo Weinhold 					error = size;
59117819be3SIngo Weinhold 			}
59298da112cSIngo Weinhold 			// allocate a buffer for the flattened data
59398da112cSIngo Weinhold 			char* buffer = NULL;
59498da112cSIngo Weinhold 			if (error == B_OK) {
59598da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
59698da112cSIngo Weinhold 				if (!buffer)
59798da112cSIngo Weinhold 					error = B_NO_MEMORY;
59898da112cSIngo Weinhold 			}
59998da112cSIngo Weinhold 			// flatten the message
60098da112cSIngo Weinhold 			if (error == B_OK)
60198da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
60298da112cSIngo Weinhold 			// write the data
60398da112cSIngo Weinhold 			if (error == B_OK) {
60498da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
60598da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
60698da112cSIngo Weinhold 								   buffer, size);
60798da112cSIngo Weinhold 			}
60898da112cSIngo Weinhold 			// clean up
60998da112cSIngo Weinhold 			delete[] buffer;
61098da112cSIngo Weinhold 		} else
61198da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
61298da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
61317819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
61417819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
61598da112cSIngo Weinhold 	}
61698da112cSIngo Weinhold 	return error;
617d6b205f3SIngo Weinhold }
618d6b205f3SIngo Weinhold 
619e1b526b9SJonas Sundström 
620d6b205f3SIngo Weinhold // SetSupportedTypes
621d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
622d6b205f3SIngo Weinhold 
62398da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
62483a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
625d6b205f3SIngo Weinhold 
626d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
627d6b205f3SIngo Weinhold 		   May be \c NULL.
628d6b205f3SIngo Weinhold 	\return
629d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
630d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
631d6b205f3SIngo Weinhold 	- other error codes
632d6b205f3SIngo Weinhold */
633d6b205f3SIngo Weinhold status_t
634d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types)
635d6b205f3SIngo Weinhold {
63698da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
637d6b205f3SIngo Weinhold }
638d6b205f3SIngo Weinhold 
639e1b526b9SJonas Sundström 
640d6b205f3SIngo Weinhold // IsSupportedType
641d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
642d6b205f3SIngo Weinhold 
643d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
644d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
645d6b205f3SIngo Weinhold 
646d6b205f3SIngo Weinhold 	\param type The MIME type in question.
647d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
648d6b205f3SIngo Weinhold 			the application, \c false otherwise.
649d6b205f3SIngo Weinhold */
650d6b205f3SIngo Weinhold bool
651d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char* type) const
652d6b205f3SIngo Weinhold {
65398da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
65498da112cSIngo Weinhold 	// get the supported types
65598da112cSIngo Weinhold 	BMessage types;
65698da112cSIngo Weinhold 	if (error == B_OK)
65798da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
65898da112cSIngo Weinhold 	// turn type into a BMimeType
65998da112cSIngo Weinhold 	BMimeType mimeType;
66098da112cSIngo Weinhold 	if (error == B_OK)
66198da112cSIngo Weinhold 		error = mimeType.SetTo(type);
66298da112cSIngo Weinhold 	// iterate through the supported types
66398da112cSIngo Weinhold 	bool found = false;
66498da112cSIngo Weinhold 	if (error == B_OK) {
66598da112cSIngo Weinhold 		const char* supportedType;
66698da112cSIngo Weinhold 		for (int32 i = 0;
66798da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
66898da112cSIngo Weinhold 			 i++) {
66998da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
67098da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
67198da112cSIngo Weinhold 		}
67298da112cSIngo Weinhold 	}
67398da112cSIngo Weinhold 	return found;
674d6b205f3SIngo Weinhold }
675d6b205f3SIngo Weinhold 
676e1b526b9SJonas Sundström 
677d6b205f3SIngo Weinhold // Supports
678d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
679d6b205f3SIngo Weinhold 		   explicitly.
680d6b205f3SIngo Weinhold 
681d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
682d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
683d6b205f3SIngo Weinhold 	"application/octet-stream".
684d6b205f3SIngo Weinhold 
685d6b205f3SIngo Weinhold 	\param type The MIME type in question.
686d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
687d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
688d6b205f3SIngo Weinhold */
689d6b205f3SIngo Weinhold bool
690d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType* type) const
691d6b205f3SIngo Weinhold {
69298da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
69398da112cSIngo Weinhold 	// get the supported types
69498da112cSIngo Weinhold 	BMessage types;
69598da112cSIngo Weinhold 	if (error == B_OK)
69698da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
69798da112cSIngo Weinhold 	// iterate through the supported types
69898da112cSIngo Weinhold 	bool found = false;
69998da112cSIngo Weinhold 	if (error == B_OK) {
70098da112cSIngo Weinhold 		const char* supportedType;
70198da112cSIngo Weinhold 		for (int32 i = 0;
70298da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
70398da112cSIngo Weinhold 			 i++) {
70498da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
70598da112cSIngo Weinhold 		}
70698da112cSIngo Weinhold 	}
70798da112cSIngo Weinhold 	return found;
708d6b205f3SIngo Weinhold }
709d6b205f3SIngo Weinhold 
710e1b526b9SJonas Sundström 
711d6b205f3SIngo Weinhold // GetIcon
712d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
713d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
714d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
715d6b205f3SIngo Weinhold 		   large icon).
716d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
717d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
718d6b205f3SIngo Weinhold 	\return
719d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
720d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
721d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
722d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
723d6b205f3SIngo Weinhold 	- other error codes
724d6b205f3SIngo Weinhold */
725d6b205f3SIngo Weinhold status_t
726d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap* icon, icon_size which) const
727d6b205f3SIngo Weinhold {
72898da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
729d6b205f3SIngo Weinhold }
730d6b205f3SIngo Weinhold 
731e1b526b9SJonas Sundström 
7327fb6186fSStephan Aßmus // GetIcon
7337fb6186fSStephan Aßmus /*!	\brief Gets the file's icon.
7347fb6186fSStephan Aßmus 	\param data The pointer in which the flat icon data will be returned.
7357fb6186fSStephan Aßmus 	\param size The pointer in which the size of the data found will be returned.
7367fb6186fSStephan Aßmus 	\return
7377fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
7387fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
7397fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: \c NULL \a data or \c NULL size.
7407fb6186fSStephan Aßmus 	- other error codes
7417fb6186fSStephan Aßmus */
7427fb6186fSStephan Aßmus status_t
7437fb6186fSStephan Aßmus BAppFileInfo::GetIcon(uint8** data, size_t* size) const
7447fb6186fSStephan Aßmus {
7457fb6186fSStephan Aßmus 	return GetIconForType(NULL, data, size);
7467fb6186fSStephan Aßmus }
7477fb6186fSStephan Aßmus 
748e1b526b9SJonas Sundström 
749d6b205f3SIngo Weinhold // SetIcon
750d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
751d6b205f3SIngo Weinhold 
752d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
753d6b205f3SIngo Weinhold 
754d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
755d6b205f3SIngo Weinhold 		   May be \c NULL.
756d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
757d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
758d6b205f3SIngo Weinhold 	\return
759d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
760d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
761d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
762d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
763d6b205f3SIngo Weinhold 	- other error codes
764d6b205f3SIngo Weinhold */
765d6b205f3SIngo Weinhold status_t
766d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which)
767d6b205f3SIngo Weinhold {
76898da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
769d6b205f3SIngo Weinhold }
770d6b205f3SIngo Weinhold 
771e1b526b9SJonas Sundström 
7727fb6186fSStephan Aßmus // SetIcon
7737fb6186fSStephan Aßmus /*!	\brief Sets the file's icon.
7747fb6186fSStephan Aßmus 
7757fb6186fSStephan Aßmus 	If \a icon is \c NULL the file's icon is unset.
7767fb6186fSStephan Aßmus 
7777fb6186fSStephan Aßmus 	\param data A pointer to the data buffer containing the vector icon
7787fb6186fSStephan Aßmus 		   to be set. May be \c NULL.
7797fb6186fSStephan Aßmus 	\param size Specifies the size of buffer pointed to by \a data.
7807fb6186fSStephan Aßmus 	\return
7817fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
7827fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
7837fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: \c NULL data.
7847fb6186fSStephan Aßmus 	- other error codes
7857fb6186fSStephan Aßmus */
7867fb6186fSStephan Aßmus status_t
7877fb6186fSStephan Aßmus BAppFileInfo::SetIcon(const uint8* data, size_t size)
7887fb6186fSStephan Aßmus {
7897fb6186fSStephan Aßmus 	return SetIconForType(NULL, data, size);
7907fb6186fSStephan Aßmus }
7917fb6186fSStephan Aßmus 
792e1b526b9SJonas Sundström 
793d6b205f3SIngo Weinhold // GetVersionInfo
794d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
795d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
796d6b205f3SIngo Weinhold 		   the version info should be written.
797d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
798d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
799d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
800d6b205f3SIngo Weinhold 		   belongs to.
801d6b205f3SIngo Weinhold 	\return
802d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
803d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
804d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
805d6b205f3SIngo Weinhold 	- other error codes
806d6b205f3SIngo Weinhold */
807d6b205f3SIngo Weinhold status_t
808d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info* info, version_kind kind) const
809d6b205f3SIngo Weinhold {
81098da112cSIngo Weinhold 	// check params and initialization
811b1970bb8SIngo Weinhold 	if (!info)
812b1970bb8SIngo Weinhold 		return B_BAD_VALUE;
813b1970bb8SIngo Weinhold 
81498da112cSIngo Weinhold 	int32 index = 0;
81598da112cSIngo Weinhold 	switch (kind) {
81698da112cSIngo Weinhold 		case B_APP_VERSION_KIND:
81798da112cSIngo Weinhold 			index = 0;
81898da112cSIngo Weinhold 			break;
81998da112cSIngo Weinhold 		case B_SYSTEM_VERSION_KIND:
82098da112cSIngo Weinhold 			index = 1;
82198da112cSIngo Weinhold 			break;
82298da112cSIngo Weinhold 		default:
823b1970bb8SIngo Weinhold 			return B_BAD_VALUE;
82498da112cSIngo Weinhold 	}
825b1970bb8SIngo Weinhold 
826b1970bb8SIngo Weinhold 	if (InitCheck() != B_OK)
827b1970bb8SIngo Weinhold 		return B_NO_INIT;
828b1970bb8SIngo Weinhold 
82998da112cSIngo Weinhold 	// read the data
83098da112cSIngo Weinhold 	size_t read = 0;
83198da112cSIngo Weinhold 	version_info infos[2];
832b1970bb8SIngo Weinhold 	status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
833b1970bb8SIngo Weinhold 		B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read);
834b1970bb8SIngo Weinhold 	if (error != B_OK)
83598da112cSIngo Weinhold 		return error;
836b1970bb8SIngo Weinhold 
837b1970bb8SIngo Weinhold 	// check the read data
838b1970bb8SIngo Weinhold 	if (read == sizeof(version_info)) {
839b1970bb8SIngo Weinhold 		// only the app version info is there -- return a cleared system info
840b1970bb8SIngo Weinhold 		if (index == 0)
841b1970bb8SIngo Weinhold 			*info = infos[index];
842b1970bb8SIngo Weinhold 		else if (index == 1)
843b1970bb8SIngo Weinhold 			memset(info, 0, sizeof(version_info));
844b1970bb8SIngo Weinhold 	} else if (read == 2 * sizeof(version_info)) {
845b1970bb8SIngo Weinhold 		*info = infos[index];
846b1970bb8SIngo Weinhold 	} else
847b1970bb8SIngo Weinhold 		return B_ERROR;
848b1970bb8SIngo Weinhold 
849b1970bb8SIngo Weinhold 	// return result
850b1970bb8SIngo Weinhold 	return B_OK;
851d6b205f3SIngo Weinhold }
852d6b205f3SIngo Weinhold 
853e1b526b9SJonas Sundström 
854d6b205f3SIngo Weinhold // SetVersionInfo
855d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
856d6b205f3SIngo Weinhold 
857d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
858d6b205f3SIngo Weinhold 
859d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
860d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
861d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
862d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
863d6b205f3SIngo Weinhold 		   belongs to.
864d6b205f3SIngo Weinhold 	\return
865d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
866d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
867d6b205f3SIngo Weinhold 	- other error codes
868d6b205f3SIngo Weinhold */
869d6b205f3SIngo Weinhold status_t
870d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info* info, version_kind kind)
871d6b205f3SIngo Weinhold {
87298da112cSIngo Weinhold 	// check initialization
87398da112cSIngo Weinhold 	status_t error = B_OK;
87498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
87598da112cSIngo Weinhold 		error = B_NO_INIT;
87698da112cSIngo Weinhold 	if (error == B_OK) {
87798da112cSIngo Weinhold 		if (info) {
87898da112cSIngo Weinhold 			// check param
87998da112cSIngo Weinhold 			int32 index = 0;
88098da112cSIngo Weinhold 			if (error == B_OK) {
88198da112cSIngo Weinhold 				switch (kind) {
88298da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
88398da112cSIngo Weinhold 						index = 0;
88498da112cSIngo Weinhold 						break;
88598da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
88698da112cSIngo Weinhold 						index = 1;
88798da112cSIngo Weinhold 						break;
88898da112cSIngo Weinhold 					default:
88998da112cSIngo Weinhold 						error = B_BAD_VALUE;
89098da112cSIngo Weinhold 						break;
89198da112cSIngo Weinhold 				}
89298da112cSIngo Weinhold 			}
89398da112cSIngo Weinhold 			// read both infos
89498da112cSIngo Weinhold 			version_info infos[2];
89598da112cSIngo Weinhold 			if (error == B_OK) {
89698da112cSIngo Weinhold 				size_t read;
897b1970bb8SIngo Weinhold 				if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
898b1970bb8SIngo Weinhold 						B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info),
899b1970bb8SIngo Weinhold 						read) == B_OK) {
900b1970bb8SIngo Weinhold 					// clear the part that hasn't been read
901b1970bb8SIngo Weinhold 					if (read < sizeof(infos))
902b1970bb8SIngo Weinhold 						memset((char*)infos + read, 0, sizeof(infos) - read);
903b1970bb8SIngo Weinhold 				} else {
904b1970bb8SIngo Weinhold 					// failed to read -- clear
905b1970bb8SIngo Weinhold 					memset(infos, 0, sizeof(infos));
906b1970bb8SIngo Weinhold 				}
90798da112cSIngo Weinhold 			}
90898da112cSIngo Weinhold 			infos[index] = *info;
90998da112cSIngo Weinhold 			// write the data
91098da112cSIngo Weinhold 			if (error == B_OK) {
91198da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
91298da112cSIngo Weinhold 								   kVersionInfoResourceID,
91398da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
91498da112cSIngo Weinhold 								   2 * sizeof(version_info));
91598da112cSIngo Weinhold 			}
91698da112cSIngo Weinhold 		} else
91798da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
91898da112cSIngo Weinhold 	}
91998da112cSIngo Weinhold 	return error;
920d6b205f3SIngo Weinhold }
921d6b205f3SIngo Weinhold 
922e1b526b9SJonas Sundström 
923d6b205f3SIngo Weinhold // GetIconForType
924d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
92598da112cSIngo Weinhold 
92698da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
92798da112cSIngo Weinhold 
92898da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
929d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
930d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
931d6b205f3SIngo Weinhold 		   large icon).
932d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
933d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
934d6b205f3SIngo Weinhold 	\return
935d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
936d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
93798da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
938d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
939d6b205f3SIngo Weinhold 		 not match.
940d6b205f3SIngo Weinhold 	- other error codes
941d6b205f3SIngo Weinhold */
942d6b205f3SIngo Weinhold status_t
943d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char* type, BBitmap* icon,
9449f507806SStephan Aßmus 							 icon_size size) const
945d6b205f3SIngo Weinhold {
9469ecf9d1cSIngo Weinhold 	if (InitCheck() != B_OK)
9479ecf9d1cSIngo Weinhold 		return B_NO_INIT;
9489ecf9d1cSIngo Weinhold 
9499ecf9d1cSIngo Weinhold 	if (!icon || icon->InitCheck() != B_OK)
9509ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
9519ecf9d1cSIngo Weinhold 
9522a74c553SStephan Aßmus 	// TODO: for consistency with attribute based icon reading, we
9532a74c553SStephan Aßmus 	// could also prefer B_CMAP8 icons here if the provided bitmap
9542a74c553SStephan Aßmus 	// is in that format. Right now, an existing B_CMAP8 icon resource
9552a74c553SStephan Aßmus 	// would be ignored as soon as a vector icon is present. On the other
9562a74c553SStephan Aßmus 	// hand, maybe this still results in a more consistent user interface,
9572a74c553SStephan Aßmus 	// since Tracker/Deskbar would surely show the vector icon.
9582a74c553SStephan Aßmus 
9599ecf9d1cSIngo Weinhold 	// try vector icon first
9609ecf9d1cSIngo Weinhold 	BString vectorAttributeName(kIconAttribute);
9619ecf9d1cSIngo Weinhold 
9629ecf9d1cSIngo Weinhold 	// check type param
9639ecf9d1cSIngo Weinhold 	if (type) {
9649ecf9d1cSIngo Weinhold 		if (BMimeType::IsValid(type))
9659ecf9d1cSIngo Weinhold 			vectorAttributeName += type;
9669ecf9d1cSIngo Weinhold 		else
9679ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
9689ecf9d1cSIngo Weinhold 	} else {
9699ecf9d1cSIngo Weinhold 		vectorAttributeName += kIconType;
9709ecf9d1cSIngo Weinhold 	}
9719ecf9d1cSIngo Weinhold 	const char* attribute = vectorAttributeName.String();
9729ecf9d1cSIngo Weinhold 
9739ecf9d1cSIngo Weinhold 	size_t bytesRead;
9749ecf9d1cSIngo Weinhold 	void* allocatedBuffer;
975bae87c91SAxel Dörfler 	status_t error = _ReadData(attribute, -1, B_VECTOR_ICON_TYPE, NULL, 0,
9769ecf9d1cSIngo Weinhold 							   bytesRead, &allocatedBuffer);
9779ecf9d1cSIngo Weinhold 	if (error == B_OK) {
9787fb6186fSStephan Aßmus 		error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer,
9799ecf9d1cSIngo Weinhold 										  bytesRead, icon);
9807fb6186fSStephan Aßmus 		free(allocatedBuffer);
9817fb6186fSStephan Aßmus 		return error;
9829ecf9d1cSIngo Weinhold 	}
9839ecf9d1cSIngo Weinhold 
9849f507806SStephan Aßmus 	// no vector icon if we got this far,
9859f507806SStephan Aßmus 	// align size argument just in case
9869f507806SStephan Aßmus 	if (size < B_LARGE_ICON)
9879f507806SStephan Aßmus 		size = B_MINI_ICON;
9889f507806SStephan Aßmus 	else
9899f507806SStephan Aßmus 		size = B_LARGE_ICON;
9909ecf9d1cSIngo Weinhold 
9919ecf9d1cSIngo Weinhold 	error = B_OK;
99298da112cSIngo Weinhold 	// set some icon size related variables
99398da112cSIngo Weinhold 	BString attributeString;
99498da112cSIngo Weinhold 	BRect bounds;
995a04efc92SIngo Weinhold 	uint32 attrType = 0;
996a04efc92SIngo Weinhold 	size_t attrSize = 0;
9979f507806SStephan Aßmus 	switch (size) {
99898da112cSIngo Weinhold 		case B_MINI_ICON:
99998da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
100098da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
100198da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
100298da112cSIngo Weinhold 			attrSize = 16 * 16;
100398da112cSIngo Weinhold 			break;
100498da112cSIngo Weinhold 		case B_LARGE_ICON:
100598da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
100698da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
100798da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
100898da112cSIngo Weinhold 			attrSize = 32 * 32;
100998da112cSIngo Weinhold 			break;
101098da112cSIngo Weinhold 		default:
10119ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
101298da112cSIngo Weinhold 	}
101398da112cSIngo Weinhold 	// check type param
101498da112cSIngo Weinhold 	if (type) {
101517819be3SIngo Weinhold 		if (BMimeType::IsValid(type))
101617819be3SIngo Weinhold 			attributeString += type;
101717819be3SIngo Weinhold 		else
10189ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
101998da112cSIngo Weinhold 	} else
102017819be3SIngo Weinhold 		attributeString += kStandardIconType;
10219ecf9d1cSIngo Weinhold 
10229ecf9d1cSIngo Weinhold 	attribute = attributeString.String();
102317819be3SIngo Weinhold 
10249f507806SStephan Aßmus 	// check parameters
10259f507806SStephan Aßmus 	// currently, scaling B_CMAP8 icons is not supported
10269f507806SStephan Aßmus 	if (icon->ColorSpace() == B_CMAP8 && icon->Bounds() != bounds)
10279ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
10289ecf9d1cSIngo Weinhold 
102998da112cSIngo Weinhold 	// read the data
103098da112cSIngo Weinhold 	if (error == B_OK) {
10319f507806SStephan Aßmus 		bool tempBuffer = (icon->ColorSpace() != B_CMAP8
10329f507806SStephan Aßmus 						   || icon->Bounds() != bounds);
10339f507806SStephan Aßmus 		uint8* buffer = NULL;
103498da112cSIngo Weinhold 		size_t read;
10359f507806SStephan Aßmus 		if (tempBuffer) {
10369f507806SStephan Aßmus 			// other color space or bitmap size than stored in attribute
10379f507806SStephan Aßmus 			buffer = new(nothrow) uint8[attrSize];
10389f507806SStephan Aßmus 			if (!buffer) {
103998da112cSIngo Weinhold 				error = B_NO_MEMORY;
10409f507806SStephan Aßmus 			} else {
104198da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
104298da112cSIngo Weinhold 								  read);
104398da112cSIngo Weinhold 			}
104498da112cSIngo Weinhold 		} else {
104598da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
104698da112cSIngo Weinhold 							  read);
104798da112cSIngo Weinhold 		}
104898da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
104998da112cSIngo Weinhold 			error = B_ERROR;
10509f507806SStephan Aßmus 		if (tempBuffer) {
105198da112cSIngo Weinhold 			// other color space than stored in attribute
105276ba3434SIngo Weinhold 			if (error == B_OK) {
10539f507806SStephan Aßmus 				error = BIconUtils::ConvertFromCMAP8(buffer,
10549f507806SStephan Aßmus 													 (uint32)size,
10559f507806SStephan Aßmus 													 (uint32)size,
10569f507806SStephan Aßmus 													 (uint32)size,
10579f507806SStephan Aßmus 													 icon);
105876ba3434SIngo Weinhold 			}
105998da112cSIngo Weinhold 			delete[] buffer;
106098da112cSIngo Weinhold 		}
106198da112cSIngo Weinhold 	}
106298da112cSIngo Weinhold 	return error;
1063d6b205f3SIngo Weinhold }
1064d6b205f3SIngo Weinhold 
1065e1b526b9SJonas Sundström 
10667fb6186fSStephan Aßmus // GetIconForType
10677fb6186fSStephan Aßmus /*!	\brief Gets the icon the application provides for a given MIME type.
10687fb6186fSStephan Aßmus 
10697fb6186fSStephan Aßmus 	If \a type is \c NULL, the application's icon is retrieved.
10707fb6186fSStephan Aßmus 
10717fb6186fSStephan Aßmus 	\param type The MIME type in question. May be \c NULL.
10727fb6186fSStephan Aßmus 	\param data A pointer in which the icon data will be returned. When you
10737fb6186fSStephan Aßmus 	are done with the data, you should use free() to deallocate it.
10747fb6186fSStephan Aßmus 	\param size A pointer in which the size of the retrieved data is returned.
10757fb6186fSStephan Aßmus 	\return
10767fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
10777fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
10787fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: \c NULL \a data and/or \a size. Or the supplied
10797fb6186fSStephan Aßmus 	\a type is not a valid MIME type.
10807fb6186fSStephan Aßmus 	- other error codes
10817fb6186fSStephan Aßmus */
10827fb6186fSStephan Aßmus status_t
10837fb6186fSStephan Aßmus BAppFileInfo::GetIconForType(const char* type, uint8** data,
10847fb6186fSStephan Aßmus 							 size_t* size) const
10857fb6186fSStephan Aßmus {
10867fb6186fSStephan Aßmus 	if (InitCheck() != B_OK)
10877fb6186fSStephan Aßmus 		return B_NO_INIT;
10887fb6186fSStephan Aßmus 
10897fb6186fSStephan Aßmus 	if (!data || !size)
10907fb6186fSStephan Aßmus 		return B_BAD_VALUE;
10917fb6186fSStephan Aßmus 
10927fb6186fSStephan Aßmus 	// get vector icon
10937fb6186fSStephan Aßmus 	BString attributeName(kIconAttribute);
10947fb6186fSStephan Aßmus 
10957fb6186fSStephan Aßmus 	// check type param
10967fb6186fSStephan Aßmus 	if (type) {
10977fb6186fSStephan Aßmus 		if (BMimeType::IsValid(type))
10987fb6186fSStephan Aßmus 			attributeName += type;
10997fb6186fSStephan Aßmus 		else
11007fb6186fSStephan Aßmus 			return B_BAD_VALUE;
11017fb6186fSStephan Aßmus 	} else {
11027fb6186fSStephan Aßmus 		attributeName += kIconType;
11037fb6186fSStephan Aßmus 	}
11047fb6186fSStephan Aßmus 
11057fb6186fSStephan Aßmus 	void* allocatedBuffer = NULL;
11067fb6186fSStephan Aßmus 	status_t ret = _ReadData(attributeName.String(), -1,
1107bae87c91SAxel Dörfler 							 B_VECTOR_ICON_TYPE, NULL, 0, *size, &allocatedBuffer);
11087fb6186fSStephan Aßmus 
11097fb6186fSStephan Aßmus 	if (ret < B_OK)
11107fb6186fSStephan Aßmus 		return ret;
11117fb6186fSStephan Aßmus 
11127fb6186fSStephan Aßmus 	*data = (uint8*)allocatedBuffer;
11137fb6186fSStephan Aßmus 	return B_OK;
11147fb6186fSStephan Aßmus }
11157fb6186fSStephan Aßmus 
1116e1b526b9SJonas Sundström 
1117d6b205f3SIngo Weinhold // SetIconForType
1118d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
1119d6b205f3SIngo Weinhold 
112098da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
1121d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
1122d6b205f3SIngo Weinhold 
112398da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
112498da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
112598da112cSIngo Weinhold 	before.
112698da112cSIngo Weinhold 
112798da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
1128d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
1129d6b205f3SIngo Weinhold 		   May be \c NULL.
1130d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
1131d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
1132d6b205f3SIngo Weinhold 	\return
1133d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
1134d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
11357fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: Either the icon size \a which is unkown, bitmap dimensions (\a icon)
11367fb6186fSStephan Aßmus 		 and icon size (\a which) do not match, or the provided \a type is
11377fb6186fSStephan Aßmus 		 not a valid MIME type.
1138d6b205f3SIngo Weinhold 	- other error codes
1139d6b205f3SIngo Weinhold */
1140d6b205f3SIngo Weinhold status_t
1141d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const BBitmap* icon,
1142d6b205f3SIngo Weinhold 							 icon_size which)
1143d6b205f3SIngo Weinhold {
114498da112cSIngo Weinhold 	status_t error = B_OK;
114598da112cSIngo Weinhold 	// set some icon size related variables
114698da112cSIngo Weinhold 	BString attributeString;
114798da112cSIngo Weinhold 	BRect bounds;
1148a04efc92SIngo Weinhold 	uint32 attrType = 0;
1149a04efc92SIngo Weinhold 	size_t attrSize = 0;
1150a04efc92SIngo Weinhold 	int32 resourceID = 0;
115198da112cSIngo Weinhold 	switch (which) {
115298da112cSIngo Weinhold 		case B_MINI_ICON:
115398da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
115498da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
115598da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
115698da112cSIngo Weinhold 			attrSize = 16 * 16;
115798da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
115898da112cSIngo Weinhold 							   : kMiniIconResourceID);
115998da112cSIngo Weinhold 			break;
116098da112cSIngo Weinhold 		case B_LARGE_ICON:
116198da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
116298da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
116398da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
116498da112cSIngo Weinhold 			attrSize = 32 * 32;
116598da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
116698da112cSIngo Weinhold 							   : kLargeIconResourceID);
116798da112cSIngo Weinhold 			break;
116898da112cSIngo Weinhold 		default:
116998da112cSIngo Weinhold 			error = B_BAD_VALUE;
117098da112cSIngo Weinhold 			break;
117198da112cSIngo Weinhold 	}
117298da112cSIngo Weinhold 	// check type param
117398da112cSIngo Weinhold 	if (error == B_OK) {
117498da112cSIngo Weinhold 		if (type) {
117517819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
117698da112cSIngo Weinhold 				attributeString += type;
117717819be3SIngo Weinhold 			else
117817819be3SIngo Weinhold 				error = B_BAD_VALUE;
117998da112cSIngo Weinhold 		} else
118098da112cSIngo Weinhold 			attributeString += kStandardIconType;
118198da112cSIngo Weinhold 	}
118298da112cSIngo Weinhold 	const char* attribute = attributeString.String();
118398da112cSIngo Weinhold 	// check parameter and initialization
118498da112cSIngo Weinhold 	if (error == B_OK && icon
118598da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
118698da112cSIngo Weinhold 		error = B_BAD_VALUE;
118798da112cSIngo Weinhold 	}
118898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
118998da112cSIngo Weinhold 		error = B_NO_INIT;
119098da112cSIngo Weinhold 	// write/remove the attribute
119198da112cSIngo Weinhold 	if (error == B_OK) {
119298da112cSIngo Weinhold 		if (icon) {
119398da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
119498da112cSIngo Weinhold 			if (otherColorSpace) {
1195290bc091SIngo Weinhold 				BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8);
119698da112cSIngo Weinhold 				error = bitmap.InitCheck();
119776ba3434SIngo Weinhold 				if (error == B_OK)
119876ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
119998da112cSIngo Weinhold 				if (error == B_OK) {
120098da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
120198da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
120298da112cSIngo Weinhold 				}
120398da112cSIngo Weinhold 			} else {
120498da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
120598da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
120698da112cSIngo Weinhold 			}
120798da112cSIngo Weinhold 		} else	// no icon given => remove
120898da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
120998da112cSIngo Weinhold 	}
121098da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
121198da112cSIngo Weinhold 	BMimeType mimeType;
121298da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
121398da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
121498da112cSIngo Weinhold 			error = mimeType.Install();
121598da112cSIngo Weinhold 		if (error == B_OK)
121698da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
121798da112cSIngo Weinhold 	}
121898da112cSIngo Weinhold 	return error;
1219d6b205f3SIngo Weinhold }
1220d6b205f3SIngo Weinhold 
1221e1b526b9SJonas Sundström 
12227fb6186fSStephan Aßmus // SetIconForType
12237fb6186fSStephan Aßmus /*!	\brief Sets the icon the application provides for a given MIME type.
12247fb6186fSStephan Aßmus 
12257fb6186fSStephan Aßmus 	If \a type is \c NULL, the application's icon is set.
12267fb6186fSStephan Aßmus 	If \a data is \c NULL the icon is unset.
12277fb6186fSStephan Aßmus 
12287fb6186fSStephan Aßmus 	If the file has a signature, then the icon is also set on the MIME type.
12297fb6186fSStephan Aßmus 	If the type for the signature has not been installed yet, it is installed
12307fb6186fSStephan Aßmus 	before.
12317fb6186fSStephan Aßmus 
12327fb6186fSStephan Aßmus 	\param type The MIME type in question. May be \c NULL.
12337fb6186fSStephan Aßmus 	\param data A pointer to the data containing the icon to be set.
12347fb6186fSStephan Aßmus 		   May be \c NULL.
12357fb6186fSStephan Aßmus 	\param size Specifies the size of buffer provided in \a data.
12367fb6186fSStephan Aßmus 	\return
12377fb6186fSStephan Aßmus 	- \c B_OK: Everything went fine.
12387fb6186fSStephan Aßmus 	- \c B_NO_INIT: The object is not properly initialized.
12397fb6186fSStephan Aßmus 	- \c B_BAD_VALUE: The provided \a type is not a valid MIME type.
12407fb6186fSStephan Aßmus 	- other error codes
12417fb6186fSStephan Aßmus */
12427fb6186fSStephan Aßmus status_t
12437fb6186fSStephan Aßmus BAppFileInfo::SetIconForType(const char* type, const uint8* data,
12447fb6186fSStephan Aßmus 							 size_t size)
12457fb6186fSStephan Aßmus {
12467fb6186fSStephan Aßmus 	if (InitCheck() != B_OK)
12477fb6186fSStephan Aßmus 		return B_NO_INIT;
12487fb6186fSStephan Aßmus 
12497fb6186fSStephan Aßmus 	// set some icon related variables
12507fb6186fSStephan Aßmus 	BString attributeString = kIconAttribute;
12517fb6186fSStephan Aßmus 	int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID;
1252bae87c91SAxel Dörfler 	uint32 attrType = B_VECTOR_ICON_TYPE;
12537fb6186fSStephan Aßmus 
12547fb6186fSStephan Aßmus 	// check type param
12557fb6186fSStephan Aßmus 	if (type) {
12567fb6186fSStephan Aßmus 		if (BMimeType::IsValid(type))
12577fb6186fSStephan Aßmus 			attributeString += type;
12587fb6186fSStephan Aßmus 		else
12597fb6186fSStephan Aßmus 			return B_BAD_VALUE;
12607fb6186fSStephan Aßmus 	} else
12617fb6186fSStephan Aßmus 		attributeString += kIconType;
12627fb6186fSStephan Aßmus 
12637fb6186fSStephan Aßmus 	const char* attribute = attributeString.String();
12647fb6186fSStephan Aßmus 
12657fb6186fSStephan Aßmus 	status_t error;
12667fb6186fSStephan Aßmus 	// write/remove the attribute
12677fb6186fSStephan Aßmus 	if (data)
12687fb6186fSStephan Aßmus 		error = _WriteData(attribute, resourceID, attrType, data, size, true);
12697fb6186fSStephan Aßmus 	else	// no icon given => remove
12707fb6186fSStephan Aßmus 		error = _RemoveData(attribute, attrType);
12717fb6186fSStephan Aßmus 
12727fb6186fSStephan Aßmus 	// set the attribute on the MIME type, if the file has a signature
12737fb6186fSStephan Aßmus 	BMimeType mimeType;
12747fb6186fSStephan Aßmus 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
12757fb6186fSStephan Aßmus 		if (!mimeType.IsInstalled())
12767fb6186fSStephan Aßmus 			error = mimeType.Install();
12777fb6186fSStephan Aßmus 		if (error == B_OK)
12787fb6186fSStephan Aßmus 			error = mimeType.SetIconForType(type, data, size);
12797fb6186fSStephan Aßmus 	}
12807fb6186fSStephan Aßmus 	return error;
12817fb6186fSStephan Aßmus }
12827fb6186fSStephan Aßmus 
1283e1b526b9SJonas Sundström 
1284d6b205f3SIngo Weinhold // SetInfoLocation
1285d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
1286d6b205f3SIngo Weinhold 
1287d6b205f3SIngo Weinhold 	The options for \a location are:
1288d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
1289d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
1290d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
1291d6b205f3SIngo Weinhold 
1292d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
1293d6b205f3SIngo Weinhold */
1294d6b205f3SIngo Weinhold void
1295d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
1296d6b205f3SIngo Weinhold {
1297d0c290bfSAxel Dörfler 	// if the resources failed to initialize, we must not use them
1298d0c290bfSAxel Dörfler 	if (fResources == NULL)
1299d0c290bfSAxel Dörfler 		location = info_location(location & ~B_USE_RESOURCES);
1300d0c290bfSAxel Dörfler 
130198da112cSIngo Weinhold 	fWhere = location;
1302d6b205f3SIngo Weinhold }
1303d6b205f3SIngo Weinhold 
1304d6b205f3SIngo Weinhold // IsUsingAttributes
1305d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
1306d6b205f3SIngo Weinhold 		   file's attributes.
1307d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
1308d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
1309d6b205f3SIngo Weinhold */
1310d6b205f3SIngo Weinhold bool
1311d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
1312d6b205f3SIngo Weinhold {
1313d0c290bfSAxel Dörfler 	return (fWhere & B_USE_ATTRIBUTES) != 0;
1314d6b205f3SIngo Weinhold }
1315d6b205f3SIngo Weinhold 
1316e1b526b9SJonas Sundström 
1317d6b205f3SIngo Weinhold // IsUsingResources
1318d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
1319d6b205f3SIngo Weinhold 		   file's resources.
1320d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
1321d6b205f3SIngo Weinhold 			resources, \c false otherwise.
1322d6b205f3SIngo Weinhold */
1323d6b205f3SIngo Weinhold bool
1324d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
1325d6b205f3SIngo Weinhold {
1326d0c290bfSAxel Dörfler 	return (fWhere & B_USE_RESOURCES) != 0;
1327d6b205f3SIngo Weinhold }
1328d6b205f3SIngo Weinhold 
1329e1b526b9SJonas Sundström 
1330d6b205f3SIngo Weinhold // FBC
1331d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
1332d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
1333d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
1334d6b205f3SIngo Weinhold 
1335e1b526b9SJonas Sundström 
1336d6b205f3SIngo Weinhold // =
1337d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
1338d6b205f3SIngo Weinhold */
1339d6b205f3SIngo Weinhold BAppFileInfo &
1340d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
1341d6b205f3SIngo Weinhold {
1342d6b205f3SIngo Weinhold 	return *this;
1343d6b205f3SIngo Weinhold }
1344d6b205f3SIngo Weinhold 
1345e1b526b9SJonas Sundström 
1346d6b205f3SIngo Weinhold // copy constructor
1347d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1348d6b205f3SIngo Weinhold */
1349d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
1350d6b205f3SIngo Weinhold {
1351d6b205f3SIngo Weinhold }
1352d6b205f3SIngo Weinhold 
1353e1b526b9SJonas Sundström 
135498da112cSIngo Weinhold // GetMetaMime
135598da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
135698da112cSIngo Weinhold 
135798da112cSIngo Weinhold 	The parameter \a meta is not checked.
135898da112cSIngo Weinhold 
135998da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
136098da112cSIngo Weinhold 		   initialized to the file's signature.
136198da112cSIngo Weinhold 	\return
136298da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
136398da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
136498da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
136598da112cSIngo Weinhold (	  not installed in the MIME database.)
136698da112cSIngo Weinhold 	  no valid MIME string.
136798da112cSIngo Weinhold 	- other error codes
136898da112cSIngo Weinhold */
136998da112cSIngo Weinhold status_t
137098da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType* meta) const
137198da112cSIngo Weinhold {
137298da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
137398da112cSIngo Weinhold 	status_t error = GetSignature(signature);
137498da112cSIngo Weinhold 	if (error == B_OK)
137598da112cSIngo Weinhold 		error = meta->SetTo(signature);
13767f20062dSJérôme Duval 	else if (error == B_BAD_VALUE)
13777f20062dSJérôme Duval 		error = B_ENTRY_NOT_FOUND;
137898da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
137998da112cSIngo Weinhold 		error = B_BAD_VALUE;
138098da112cSIngo Weinhold 	return error;
138198da112cSIngo Weinhold }
138298da112cSIngo Weinhold 
1383e1b526b9SJonas Sundström 
138498da112cSIngo Weinhold // _ReadData
138598da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
138698da112cSIngo Weinhold 
138798da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
138898da112cSIngo Weinhold 
138998da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
139098da112cSIngo Weinhold 
139198da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
139298da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
139398da112cSIngo Weinhold 		   < 0.
139498da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
139598da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
139698da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
139798da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
139898da112cSIngo Weinhold 		   actually read.
139998da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
140098da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
140198da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
140298da112cSIngo Weinhold 	\return
140398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
140498da112cSIngo Weinhold 	- error code
140598da112cSIngo Weinhold */
140698da112cSIngo Weinhold status_t
140798da112cSIngo Weinhold BAppFileInfo::_ReadData(const char* name, int32 id, type_code type,
140898da112cSIngo Weinhold 						void* buffer, size_t bufferSize,
140998da112cSIngo Weinhold 						size_t &bytesRead, void** allocatedBuffer) const
141098da112cSIngo Weinhold {
141198da112cSIngo Weinhold 	status_t error = B_OK;
1412338b8dc3SIngo Weinhold 
141398da112cSIngo Weinhold 	if (allocatedBuffer)
141498da112cSIngo Weinhold 		buffer = NULL;
1415338b8dc3SIngo Weinhold 
1416338b8dc3SIngo Weinhold 	bool foundData = false;
1417338b8dc3SIngo Weinhold 
141898da112cSIngo Weinhold 	if (IsUsingAttributes()) {
141998da112cSIngo Weinhold 		// get an attribute info
142098da112cSIngo Weinhold 		attr_info info;
142198da112cSIngo Weinhold 		if (error == B_OK)
142298da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1423338b8dc3SIngo Weinhold 
142498da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
142598da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
142698da112cSIngo Weinhold 			error = B_BAD_VALUE;
1427b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
142898da112cSIngo Weinhold 			buffer = malloc(info.size);
142998da112cSIngo Weinhold 			if (!buffer)
143098da112cSIngo Weinhold 				error = B_NO_MEMORY;
143198da112cSIngo Weinhold 			bufferSize = info.size;
143298da112cSIngo Weinhold 		}
1433*9be774b5SAlex Smith 		if (error == B_OK && (off_t)bufferSize < info.size)
143498da112cSIngo Weinhold 			error = B_BAD_VALUE;
1435338b8dc3SIngo Weinhold 
143698da112cSIngo Weinhold 		// read the data
143798da112cSIngo Weinhold 		if (error == B_OK) {
143898da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
143998da112cSIngo Weinhold 			if (read < 0)
144098da112cSIngo Weinhold 				error = read;
144198da112cSIngo Weinhold 			else if (read != info.size)
144298da112cSIngo Weinhold 				error = B_ERROR;
144398da112cSIngo Weinhold 			else
144498da112cSIngo Weinhold 				bytesRead = read;
144598da112cSIngo Weinhold 		}
1446338b8dc3SIngo Weinhold 
1447338b8dc3SIngo Weinhold 		foundData = (error == B_OK);
1448b4598d95SIngo Weinhold 
1449b4598d95SIngo Weinhold 		// free the allocated buffer on error
1450b4598d95SIngo Weinhold 		if (!foundData && allocatedBuffer && buffer) {
1451b4598d95SIngo Weinhold 			free(buffer);
1452b4598d95SIngo Weinhold 			buffer = NULL;
1453b4598d95SIngo Weinhold 		}
1454338b8dc3SIngo Weinhold 	}
1455338b8dc3SIngo Weinhold 
1456338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
145798da112cSIngo Weinhold 		// get a resource info
1458338b8dc3SIngo Weinhold 		error = B_OK;
145998da112cSIngo Weinhold 		int32 idFound;
146098da112cSIngo Weinhold 		size_t sizeFound;
146198da112cSIngo Weinhold 		if (error == B_OK) {
146298da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
146398da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
146498da112cSIngo Weinhold 		}
1465338b8dc3SIngo Weinhold 
146698da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
146798da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
146898da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1469b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
147098da112cSIngo Weinhold 			buffer = malloc(sizeFound);
147198da112cSIngo Weinhold 			if (!buffer)
147298da112cSIngo Weinhold 				error = B_NO_MEMORY;
147398da112cSIngo Weinhold 			bufferSize = sizeFound;
147498da112cSIngo Weinhold 		}
147598da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
147698da112cSIngo Weinhold 			error = B_BAD_VALUE;
1477338b8dc3SIngo Weinhold 
147898da112cSIngo Weinhold 		// load resource
147998da112cSIngo Weinhold 		const void* resourceData = NULL;
148098da112cSIngo Weinhold 		if (error == B_OK) {
148198da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
148298da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
148398da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
148498da112cSIngo Weinhold 			else
148598da112cSIngo Weinhold 				error = B_ERROR;
148698da112cSIngo Weinhold 		}
1487773be699SAxel Dörfler 	} else if (!foundData)
148898da112cSIngo Weinhold 		error = B_BAD_VALUE;
1489338b8dc3SIngo Weinhold 
149098da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
149198da112cSIngo Weinhold 	if (allocatedBuffer) {
149298da112cSIngo Weinhold 		if (error == B_OK)
149398da112cSIngo Weinhold 			*allocatedBuffer = buffer;
149498da112cSIngo Weinhold 		else
149598da112cSIngo Weinhold 			free(buffer);
149698da112cSIngo Weinhold 	}
1497338b8dc3SIngo Weinhold 
149898da112cSIngo Weinhold 	return error;
149998da112cSIngo Weinhold }
150098da112cSIngo Weinhold 
1501e1b526b9SJonas Sundström 
150298da112cSIngo Weinhold // _WriteData
150398da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
150498da112cSIngo Weinhold 
150598da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
150698da112cSIngo Weinhold 
150798da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
150898da112cSIngo Weinhold 
150998da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
151098da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
151198da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
151298da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
151398da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
151498da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
151598da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
151698da112cSIngo Weinhold 		   If \c false, \a id is used.
151798da112cSIngo Weinhold 	If \a id is already in use and .
151898da112cSIngo Weinhold 	\return
151998da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
152098da112cSIngo Weinhold 	- error code
152198da112cSIngo Weinhold */
152298da112cSIngo Weinhold status_t
152398da112cSIngo Weinhold BAppFileInfo::_WriteData(const char* name, int32 id, type_code type,
152498da112cSIngo Weinhold 						 const void* buffer, size_t bufferSize, bool findID)
152598da112cSIngo Weinhold {
1526d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1527d0c290bfSAxel Dörfler 		return B_NO_INIT;
1528d0c290bfSAxel Dörfler 
152998da112cSIngo Weinhold 	status_t error = B_OK;
1530d0c290bfSAxel Dörfler 
153198da112cSIngo Weinhold 	// write to attribute
1532d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
153398da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
153498da112cSIngo Weinhold 		if (written < 0)
153598da112cSIngo Weinhold 			error = written;
153698da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
153798da112cSIngo Weinhold 			error = B_ERROR;
153898da112cSIngo Weinhold 	}
153998da112cSIngo Weinhold 	// write to resource
154098da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
154198da112cSIngo Weinhold 		if (findID) {
154298da112cSIngo Weinhold 			// get the resource info
154398da112cSIngo Weinhold 			int32 idFound;
154498da112cSIngo Weinhold 			size_t sizeFound;
154598da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
154698da112cSIngo Weinhold 				id = idFound;
154798da112cSIngo Weinhold 			else {
154898da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
154998da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
155098da112cSIngo Weinhold 					id++;
155198da112cSIngo Weinhold 			}
155298da112cSIngo Weinhold 		}
155398da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
155498da112cSIngo Weinhold 	}
155598da112cSIngo Weinhold 	return error;
155698da112cSIngo Weinhold }
155798da112cSIngo Weinhold 
155898da112cSIngo Weinhold // _RemoveData
155998da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
156098da112cSIngo Weinhold 
156198da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
156298da112cSIngo Weinhold 
156398da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
156498da112cSIngo Weinhold 
156598da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
156698da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
156798da112cSIngo Weinhold 	\return
156898da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
156998da112cSIngo Weinhold 	- error code
157098da112cSIngo Weinhold */
157198da112cSIngo Weinhold status_t
157298da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char* name, type_code type)
157398da112cSIngo Weinhold {
1574d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1575d0c290bfSAxel Dörfler 		return B_NO_INIT;
1576d0c290bfSAxel Dörfler 
157798da112cSIngo Weinhold 	status_t error = B_OK;
1578d0c290bfSAxel Dörfler 
157998da112cSIngo Weinhold 	// remove the attribute
1580d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
158198da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
158298da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
158398da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
158498da112cSIngo Weinhold 			error = B_OK;
158598da112cSIngo Weinhold 	}
158698da112cSIngo Weinhold 	// remove the resource
158798da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
158898da112cSIngo Weinhold 		// get a resource info
158998da112cSIngo Weinhold 		int32 idFound;
159098da112cSIngo Weinhold 		size_t sizeFound;
159198da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
159298da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
159398da112cSIngo Weinhold 	}
159498da112cSIngo Weinhold 	return error;
159598da112cSIngo Weinhold }
159698da112cSIngo Weinhold 
1597