xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision c2a2369d4947373f08ef45a3c97d974d6379f1c7)
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>
1898da112cSIngo Weinhold #include <MimeType.h>
1998da112cSIngo Weinhold #include <RegistrarDefs.h>
2098da112cSIngo Weinhold #include <Resources.h>
2198da112cSIngo Weinhold #include <Roster.h>
2298da112cSIngo Weinhold #include <String.h>
2398da112cSIngo Weinhold 
2450f17542Shaydentech using namespace std;
2550f17542Shaydentech 
2698da112cSIngo Weinhold // attributes
2798da112cSIngo Weinhold static const char *kTypeAttribute				= "BEOS:TYPE";
2898da112cSIngo Weinhold static const char *kSignatureAttribute			= "BEOS:APP_SIG";
2998da112cSIngo Weinhold static const char *kAppFlagsAttribute			= "BEOS:APP_FLAGS";
3098da112cSIngo Weinhold static const char *kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
3198da112cSIngo Weinhold static const char *kVersionInfoAttribute		= "BEOS:APP_VERSION";
3298da112cSIngo Weinhold static const char *kMiniIconAttribute			= "BEOS:M:";
3398da112cSIngo Weinhold static const char *kLargeIconAttribute			= "BEOS:L:";
3498da112cSIngo Weinhold static const char *kStandardIconType			= "STD_ICON";
3598da112cSIngo Weinhold 
3698da112cSIngo Weinhold // resource IDs
3798da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
3898da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
3998da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
4098da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
4198da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
4298da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
4398da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
4498da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
4598da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
4698da112cSIngo Weinhold 
4798da112cSIngo Weinhold // type codes
4898da112cSIngo Weinhold enum {
4998da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
5098da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
5198da112cSIngo Weinhold };
5298da112cSIngo Weinhold 
5388706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
5488706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
5588706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
5688706bbeSAxel Dörfler // Tracker when compiled for Haiku)
5788706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
5888706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
5988706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
6088706bbeSAxel Dörfler 
6178b31a7cSIngo Weinhold // debugging
6278b31a7cSIngo Weinhold //#define DBG(x) x
6378b31a7cSIngo Weinhold #define DBG(x)
6478b31a7cSIngo Weinhold #define OUT	printf
65d6b205f3SIngo Weinhold 
66d6b205f3SIngo Weinhold // constructor
67d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
68d6b205f3SIngo Weinhold */
69d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
70d6b205f3SIngo Weinhold 			: fResources(NULL),
71d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
72d6b205f3SIngo Weinhold {
73d6b205f3SIngo Weinhold }
74d6b205f3SIngo Weinhold 
75d6b205f3SIngo Weinhold // constructor
76d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
77d6b205f3SIngo Weinhold 		   file.
78d6b205f3SIngo Weinhold 
79d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
80d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
81d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
82d6b205f3SIngo Weinhold 
83d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
84d6b205f3SIngo Weinhold */
85d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
86d6b205f3SIngo Weinhold 			: fResources(NULL),
87d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
88d6b205f3SIngo Weinhold {
8998da112cSIngo Weinhold 	SetTo(file);
90d6b205f3SIngo Weinhold }
91d6b205f3SIngo Weinhold 
92d6b205f3SIngo Weinhold // destructor
93d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
94d6b205f3SIngo Weinhold 
95d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
96d6b205f3SIngo Weinhold */
97d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
98d6b205f3SIngo Weinhold {
9998da112cSIngo Weinhold 	if (fResources)
10098da112cSIngo Weinhold 		delete fResources;
101d6b205f3SIngo Weinhold }
102d6b205f3SIngo Weinhold 
103d6b205f3SIngo Weinhold // SetTo
104d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
105d6b205f3SIngo Weinhold 
106d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
107d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
108d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
109d6b205f3SIngo Weinhold 
110d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
111d6b205f3SIngo Weinhold 
112d6b205f3SIngo Weinhold 	\return
113d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
114d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
115d6b205f3SIngo Weinhold */
116d6b205f3SIngo Weinhold status_t
117d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
118d6b205f3SIngo Weinhold {
11998da112cSIngo Weinhold 	// unset the old file
12098da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
12198da112cSIngo Weinhold 	if (fResources) {
12298da112cSIngo Weinhold 		delete fResources;
12398da112cSIngo Weinhold 		fResources = NULL;
12498da112cSIngo Weinhold 	}
125*c2a2369dSAxel Dörfler 
12698da112cSIngo Weinhold 	// check param
12798da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
128*c2a2369dSAxel Dörfler 
129*c2a2369dSAxel Dörfler 	info_location where = B_USE_BOTH_LOCATIONS;
130*c2a2369dSAxel Dörfler 
13198da112cSIngo Weinhold 	// create resources
13298da112cSIngo Weinhold 	if (error == B_OK) {
13398da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
134*c2a2369dSAxel Dörfler 		if (fResources) {
13598da112cSIngo Weinhold 			error = fResources->SetTo(file);
136*c2a2369dSAxel Dörfler 			if (error != B_OK) {
137*c2a2369dSAxel Dörfler 				// no resources - this is no critical error, we'll just use
138*c2a2369dSAxel Dörfler 				// attributes only, then
139*c2a2369dSAxel Dörfler 				where = B_USE_ATTRIBUTES;
140*c2a2369dSAxel Dörfler 				error = B_OK;
141*c2a2369dSAxel Dörfler 			}
142*c2a2369dSAxel Dörfler 		} else
14398da112cSIngo Weinhold 			error = B_NO_MEMORY;
14498da112cSIngo Weinhold 	}
145*c2a2369dSAxel Dörfler 
14698da112cSIngo Weinhold 	// set node info
14798da112cSIngo Weinhold 	if (error == B_OK)
14898da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
149*c2a2369dSAxel Dörfler 
150*c2a2369dSAxel Dörfler 	if (error != B_OK || (where & B_USE_RESOURCES) == 0) {
15198da112cSIngo Weinhold 		delete fResources;
15298da112cSIngo Weinhold 		fResources = NULL;
15398da112cSIngo Weinhold 	}
154*c2a2369dSAxel Dörfler 
155*c2a2369dSAxel Dörfler 	// clean up on error
156*c2a2369dSAxel Dörfler 	if (error != B_OK) {
15798da112cSIngo Weinhold 		if (InitCheck() == B_OK)
15898da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
15998da112cSIngo Weinhold 	}
160*c2a2369dSAxel Dörfler 
16198da112cSIngo Weinhold 	// set data location
16298da112cSIngo Weinhold 	if (error == B_OK)
163*c2a2369dSAxel Dörfler 		SetInfoLocation(where);
164*c2a2369dSAxel Dörfler 
16598da112cSIngo Weinhold 	// set error
16698da112cSIngo Weinhold 	fCStatus = error;
16798da112cSIngo Weinhold 	return error;
168d6b205f3SIngo Weinhold }
169d6b205f3SIngo Weinhold 
170d6b205f3SIngo Weinhold // GetType
171d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
172d6b205f3SIngo Weinhold 
173d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
174d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
175d6b205f3SIngo Weinhold 		   file shall be written.
176d6b205f3SIngo Weinhold 	\return
177d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
178d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
179d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
180d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
181d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
182d6b205f3SIngo Weinhold 	  the wrong type.
183d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
184d6b205f3SIngo Weinhold 	- other error codes
185d6b205f3SIngo Weinhold */
186d6b205f3SIngo Weinhold status_t
187d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
188d6b205f3SIngo Weinhold {
18998da112cSIngo Weinhold 	// check param and initialization
19098da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
19198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
19298da112cSIngo Weinhold 		error = B_NO_INIT;
19398da112cSIngo Weinhold 	// read the data
19498da112cSIngo Weinhold 	size_t read = 0;
19598da112cSIngo Weinhold 	if (error == B_OK) {
19698da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
19798da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
19898da112cSIngo Weinhold 	}
19998da112cSIngo Weinhold 	// check the read data -- null terminate the string
20098da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
20198da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
20298da112cSIngo Weinhold 			error = B_ERROR;
20398da112cSIngo Weinhold 		else
20498da112cSIngo Weinhold 			type[read] = '\0';
20598da112cSIngo Weinhold 	}
20698da112cSIngo Weinhold 	return error;
207d6b205f3SIngo Weinhold }
208d6b205f3SIngo Weinhold 
209d6b205f3SIngo Weinhold // SetType
210d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
211d6b205f3SIngo Weinhold 
212d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
213d6b205f3SIngo Weinhold 
214d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
215d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
216d6b205f3SIngo Weinhold 		   May be \c NULL.
217d6b205f3SIngo Weinhold 	\return
218d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
219d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
220d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
221d6b205f3SIngo Weinhold 	- other error codes
222d6b205f3SIngo Weinhold */
223d6b205f3SIngo Weinhold status_t
224d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
225d6b205f3SIngo Weinhold {
22698da112cSIngo Weinhold 	// check initialization
22798da112cSIngo Weinhold 	status_t error = B_OK;
22898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
22998da112cSIngo Weinhold 		error = B_NO_INIT;
23098da112cSIngo Weinhold 	if (error == B_OK) {
23198da112cSIngo Weinhold 		if (type) {
23298da112cSIngo Weinhold 			// check param
23398da112cSIngo Weinhold 			size_t typeLen = strlen(type);
23498da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
23598da112cSIngo Weinhold 				error = B_BAD_VALUE;
23698da112cSIngo Weinhold 			// write the data
23798da112cSIngo Weinhold 			if (error == B_OK) {
23898da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
23998da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
24098da112cSIngo Weinhold 			}
24198da112cSIngo Weinhold 		} else
24298da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
24398da112cSIngo Weinhold 	}
24498da112cSIngo Weinhold 	return error;
245d6b205f3SIngo Weinhold }
246d6b205f3SIngo Weinhold 
247d6b205f3SIngo Weinhold // GetSignature
248d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
249d6b205f3SIngo Weinhold 
250d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
251d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
252d6b205f3SIngo Weinhold 		   signature of the file shall be written.
253d6b205f3SIngo Weinhold 	\return
254d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
255d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
256d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
257d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
258d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
259d6b205f3SIngo Weinhold 	  the wrong type.
260d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
261d6b205f3SIngo Weinhold 	- other error codes
262d6b205f3SIngo Weinhold */
263d6b205f3SIngo Weinhold status_t
264d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
265d6b205f3SIngo Weinhold {
26698da112cSIngo Weinhold 	// check param and initialization
26798da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
26898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
26998da112cSIngo Weinhold 		error = B_NO_INIT;
27098da112cSIngo Weinhold 	// read the data
27198da112cSIngo Weinhold 	size_t read = 0;
27298da112cSIngo Weinhold 	if (error == B_OK) {
27398da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
27498da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
27598da112cSIngo Weinhold 						  read);
27698da112cSIngo Weinhold 	}
27798da112cSIngo Weinhold 	// check the read data -- null terminate the string
27898da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
27998da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
28098da112cSIngo Weinhold 			error = B_ERROR;
28198da112cSIngo Weinhold 		else
28298da112cSIngo Weinhold 			signature[read] = '\0';
28398da112cSIngo Weinhold 	}
28498da112cSIngo Weinhold 	return error;
285d6b205f3SIngo Weinhold }
286d6b205f3SIngo Weinhold 
287d6b205f3SIngo Weinhold // SetSignature
288d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
289d6b205f3SIngo Weinhold 
290d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
291d6b205f3SIngo Weinhold 
292d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
293d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
294d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
295d6b205f3SIngo Weinhold 	\return
296d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
297d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
298d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
299d6b205f3SIngo Weinhold 	- other error codes
300d6b205f3SIngo Weinhold */
301d6b205f3SIngo Weinhold status_t
302d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
303d6b205f3SIngo Weinhold {
30498da112cSIngo Weinhold 	// check initialization
30598da112cSIngo Weinhold 	status_t error = B_OK;
30698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
30798da112cSIngo Weinhold 		error = B_NO_INIT;
30898da112cSIngo Weinhold 	if (error == B_OK) {
30998da112cSIngo Weinhold 		if (signature) {
31098da112cSIngo Weinhold 			// check param
31198da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
31298da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
31398da112cSIngo Weinhold 				error = B_BAD_VALUE;
31498da112cSIngo Weinhold 			// write the data
31598da112cSIngo Weinhold 			if (error == B_OK) {
31698da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
31798da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
31898da112cSIngo Weinhold 								   signatureLen + 1);
31998da112cSIngo Weinhold 			}
32098da112cSIngo Weinhold 		} else
32198da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
32298da112cSIngo Weinhold 	}
32398da112cSIngo Weinhold 	return error;
324d6b205f3SIngo Weinhold }
325d6b205f3SIngo Weinhold 
326d6b205f3SIngo Weinhold // GetAppFlags
327d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
328d6b205f3SIngo Weinhold 
329d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
330d6b205f3SIngo Weinhold 		   flags of the file shall be written.
331d6b205f3SIngo Weinhold 	\return
332d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
333d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
334d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
335d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
336d6b205f3SIngo Weinhold 	  the wrong type.
337d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
338d6b205f3SIngo Weinhold 	- other error codes
339d6b205f3SIngo Weinhold */
340d6b205f3SIngo Weinhold status_t
341d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
342d6b205f3SIngo Weinhold {
34398da112cSIngo Weinhold 	// check param and initialization
34498da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
34598da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
34698da112cSIngo Weinhold 		error = B_NO_INIT;
34798da112cSIngo Weinhold 	// read the data
34898da112cSIngo Weinhold 	size_t read = 0;
34998da112cSIngo Weinhold 	if (error == B_OK) {
35098da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
35198da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
35298da112cSIngo Weinhold 						  read);
35398da112cSIngo Weinhold 	}
35498da112cSIngo Weinhold 	// check the read data
35598da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
35698da112cSIngo Weinhold 		error = B_ERROR;
35798da112cSIngo Weinhold 	return error;
358d6b205f3SIngo Weinhold }
359d6b205f3SIngo Weinhold 
360d6b205f3SIngo Weinhold // SetAppFlags
361d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
362d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
363d6b205f3SIngo Weinhold 	\return
364d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
365d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
366d6b205f3SIngo Weinhold 	- other error codes
367d6b205f3SIngo Weinhold */
368d6b205f3SIngo Weinhold status_t
369d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
370d6b205f3SIngo Weinhold {
37198da112cSIngo Weinhold 	// check initialization
37298da112cSIngo Weinhold 	status_t error = B_OK;
37398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
37498da112cSIngo Weinhold 		error = B_NO_INIT;
37598da112cSIngo Weinhold 	if (error == B_OK) {
37698da112cSIngo Weinhold 		// write the data
37798da112cSIngo Weinhold 		if (error == B_OK) {
37898da112cSIngo Weinhold 			error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
37998da112cSIngo Weinhold 							   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
38098da112cSIngo Weinhold 		}
38198da112cSIngo Weinhold 	}
38298da112cSIngo Weinhold 	return error;
383d6b205f3SIngo Weinhold }
384d6b205f3SIngo Weinhold 
385d6b205f3SIngo Weinhold // GetSupportedTypes
386d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
387d6b205f3SIngo Weinhold 
388d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
389d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
390d6b205f3SIngo Weinhold 
391d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
392d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
393d6b205f3SIngo Weinhold 	\return
394d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
395d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
396d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
397d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
398d6b205f3SIngo Weinhold 	  have the wrong type.
399d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
400d6b205f3SIngo Weinhold 	- other error codes
401d6b205f3SIngo Weinhold */
402d6b205f3SIngo Weinhold status_t
403d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
404d6b205f3SIngo Weinhold {
40598da112cSIngo Weinhold 	// check param and initialization
40698da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
40798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
40898da112cSIngo Weinhold 		error = B_NO_INIT;
40998da112cSIngo Weinhold 	// read the data
41098da112cSIngo Weinhold 	size_t read = 0;
41198da112cSIngo Weinhold 	void *buffer = NULL;
41298da112cSIngo Weinhold 	if (error == B_OK) {
41398da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
41498da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
41598da112cSIngo Weinhold 	}
41698da112cSIngo Weinhold 	// unflatten the buffer
41798da112cSIngo Weinhold 	if (error == B_OK)
41898da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
41998da112cSIngo Weinhold 	// clean up
42098da112cSIngo Weinhold 	if (buffer)
42198da112cSIngo Weinhold 		free(buffer);
42298da112cSIngo Weinhold 	return error;
423d6b205f3SIngo Weinhold }
424d6b205f3SIngo Weinhold 
425d6b205f3SIngo Weinhold // SetSupportedTypes
426d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
427d6b205f3SIngo Weinhold 
428d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
429d6b205f3SIngo Weinhold 
430d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
431d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
432d6b205f3SIngo Weinhold 
43383a812a1SIngo Weinhold 	The method informs the registrar about this news.
43483a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
43583a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
43683a812a1SIngo Weinhold 	application file needs to have a signature set.
43783a812a1SIngo Weinhold 
43883a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
43983a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
44083a812a1SIngo Weinhold 	lists of supporting applications.
44183a812a1SIngo Weinhold 
442d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
443d6b205f3SIngo Weinhold 		   May be \c NULL.
44483a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
44583a812a1SIngo Weinhold 		   types, \c false otherwise.
446d6b205f3SIngo Weinhold 	\return
447d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
448d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
449d6b205f3SIngo Weinhold 	- other error codes
450d6b205f3SIngo Weinhold */
451d6b205f3SIngo Weinhold status_t
452d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
453d6b205f3SIngo Weinhold {
45498da112cSIngo Weinhold 	// check initialization
45598da112cSIngo Weinhold 	status_t error = B_OK;
45698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
45798da112cSIngo Weinhold 		error = B_NO_INIT;
45898da112cSIngo Weinhold 	BMimeType mimeType;
45998da112cSIngo Weinhold 	if (error == B_OK)
46098da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
46198da112cSIngo Weinhold 	if (error == B_OK) {
46298da112cSIngo Weinhold 		if (types) {
46317819be3SIngo Weinhold 			// check param -- supported types must be valid
46417819be3SIngo Weinhold 			const char *type;
46517819be3SIngo Weinhold 			for (int32 i = 0;
46617819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
46717819be3SIngo Weinhold 				 i++) {
46817819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
46917819be3SIngo Weinhold 					error = B_BAD_VALUE;
47017819be3SIngo Weinhold 			}
47117819be3SIngo Weinhold 			// get flattened size
47217819be3SIngo Weinhold 			ssize_t size = 0;
47317819be3SIngo Weinhold 			if (error == B_OK) {
47417819be3SIngo Weinhold 				size = types->FlattenedSize();
47598da112cSIngo Weinhold 				if (size < 0)
47698da112cSIngo Weinhold 					error = size;
47717819be3SIngo Weinhold 			}
47898da112cSIngo Weinhold 			// allocate a buffer for the flattened data
47998da112cSIngo Weinhold 			char *buffer = NULL;
48098da112cSIngo Weinhold 			if (error == B_OK) {
48198da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
48298da112cSIngo Weinhold 				if (!buffer)
48398da112cSIngo Weinhold 					error = B_NO_MEMORY;
48498da112cSIngo Weinhold 			}
48598da112cSIngo Weinhold 			// flatten the message
48698da112cSIngo Weinhold 			if (error == B_OK)
48798da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
48898da112cSIngo Weinhold 			// write the data
48998da112cSIngo Weinhold 			if (error == B_OK) {
49098da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
49198da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
49298da112cSIngo Weinhold 								   buffer, size);
49398da112cSIngo Weinhold 			}
49498da112cSIngo Weinhold 			// clean up
49598da112cSIngo Weinhold 			if (buffer)
49698da112cSIngo Weinhold 				delete[] buffer;
49798da112cSIngo Weinhold 		} else
49898da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
49998da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
50017819be3SIngo Weinhold 		if (error == B_OK && mimeType.IsInstalled())
50117819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
50298da112cSIngo Weinhold 	}
50398da112cSIngo Weinhold 	return error;
504d6b205f3SIngo Weinhold }
505d6b205f3SIngo Weinhold 
506d6b205f3SIngo Weinhold // SetSupportedTypes
507d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
508d6b205f3SIngo Weinhold 
50998da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
51083a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
511d6b205f3SIngo Weinhold 
512d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
513d6b205f3SIngo Weinhold 		   May be \c NULL.
514d6b205f3SIngo Weinhold 	\return
515d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
516d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
517d6b205f3SIngo Weinhold 	- other error codes
518d6b205f3SIngo Weinhold */
519d6b205f3SIngo Weinhold status_t
520d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
521d6b205f3SIngo Weinhold {
52298da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
523d6b205f3SIngo Weinhold }
524d6b205f3SIngo Weinhold 
525d6b205f3SIngo Weinhold // IsSupportedType
526d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
527d6b205f3SIngo Weinhold 
528d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
529d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
530d6b205f3SIngo Weinhold 
531d6b205f3SIngo Weinhold 	\param type The MIME type in question.
532d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
533d6b205f3SIngo Weinhold 			the application, \c false otherwise.
534d6b205f3SIngo Weinhold */
535d6b205f3SIngo Weinhold bool
536d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
537d6b205f3SIngo Weinhold {
53898da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
53998da112cSIngo Weinhold 	// get the supported types
54098da112cSIngo Weinhold 	BMessage types;
54198da112cSIngo Weinhold 	if (error == B_OK)
54298da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
54398da112cSIngo Weinhold 	// turn type into a BMimeType
54498da112cSIngo Weinhold 	BMimeType mimeType;
54598da112cSIngo Weinhold 	if (error == B_OK)
54698da112cSIngo Weinhold 		error = mimeType.SetTo(type);
54798da112cSIngo Weinhold 	// iterate through the supported types
54898da112cSIngo Weinhold 	bool found = false;
54998da112cSIngo Weinhold 	if (error == B_OK) {
55098da112cSIngo Weinhold 		const char *supportedType;
55198da112cSIngo Weinhold 		for (int32 i = 0;
55298da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
55398da112cSIngo Weinhold 			 i++) {
55498da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
55598da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
55698da112cSIngo Weinhold 		}
55798da112cSIngo Weinhold 	}
55898da112cSIngo Weinhold 	return found;
559d6b205f3SIngo Weinhold }
560d6b205f3SIngo Weinhold 
561d6b205f3SIngo Weinhold // Supports
562d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
563d6b205f3SIngo Weinhold 		   explicitly.
564d6b205f3SIngo Weinhold 
565d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
566d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
567d6b205f3SIngo Weinhold 	"application/octet-stream".
568d6b205f3SIngo Weinhold 
569d6b205f3SIngo Weinhold 	\param type The MIME type in question.
570d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
571d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
572d6b205f3SIngo Weinhold */
573d6b205f3SIngo Weinhold bool
574d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
575d6b205f3SIngo Weinhold {
57698da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
57798da112cSIngo Weinhold 	// get the supported types
57898da112cSIngo Weinhold 	BMessage types;
57998da112cSIngo Weinhold 	if (error == B_OK)
58098da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
58198da112cSIngo Weinhold 	// iterate through the supported types
58298da112cSIngo Weinhold 	bool found = false;
58398da112cSIngo Weinhold 	if (error == B_OK) {
58498da112cSIngo Weinhold 		const char *supportedType;
58598da112cSIngo Weinhold 		for (int32 i = 0;
58698da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
58798da112cSIngo Weinhold 			 i++) {
58898da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
58998da112cSIngo Weinhold 		}
59098da112cSIngo Weinhold 	}
59198da112cSIngo Weinhold 	return found;
592d6b205f3SIngo Weinhold }
593d6b205f3SIngo Weinhold 
594d6b205f3SIngo Weinhold // GetIcon
595d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
596d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
597d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
598d6b205f3SIngo Weinhold 		   large icon).
599d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
600d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
601d6b205f3SIngo Weinhold 	\return
602d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
603d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
604d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
605d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
606d6b205f3SIngo Weinhold 	- other error codes
607d6b205f3SIngo Weinhold */
608d6b205f3SIngo Weinhold status_t
609d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
610d6b205f3SIngo Weinhold {
61198da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
612d6b205f3SIngo Weinhold }
613d6b205f3SIngo Weinhold 
614d6b205f3SIngo Weinhold // SetIcon
615d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
616d6b205f3SIngo Weinhold 
617d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
618d6b205f3SIngo Weinhold 
619d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
620d6b205f3SIngo Weinhold 		   May be \c NULL.
621d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
622d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
623d6b205f3SIngo Weinhold 	\return
624d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
625d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
626d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
627d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
628d6b205f3SIngo Weinhold 	- other error codes
629d6b205f3SIngo Weinhold */
630d6b205f3SIngo Weinhold status_t
631d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
632d6b205f3SIngo Weinhold {
63398da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
634d6b205f3SIngo Weinhold }
635d6b205f3SIngo Weinhold 
636d6b205f3SIngo Weinhold // GetVersionInfo
637d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
638d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
639d6b205f3SIngo Weinhold 		   the version info should be written.
640d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
641d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
642d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
643d6b205f3SIngo Weinhold 		   belongs to.
644d6b205f3SIngo Weinhold 	\return
645d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
646d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
647d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
648d6b205f3SIngo Weinhold 	- other error codes
649d6b205f3SIngo Weinhold */
650d6b205f3SIngo Weinhold status_t
651d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
652d6b205f3SIngo Weinhold {
65398da112cSIngo Weinhold 	// check params and initialization
654b1970bb8SIngo Weinhold 	if (!info)
655b1970bb8SIngo Weinhold 		return B_BAD_VALUE;
656b1970bb8SIngo Weinhold 
65798da112cSIngo Weinhold 	int32 index = 0;
65898da112cSIngo Weinhold 	switch (kind) {
65998da112cSIngo Weinhold 		case B_APP_VERSION_KIND:
66098da112cSIngo Weinhold 			index = 0;
66198da112cSIngo Weinhold 			break;
66298da112cSIngo Weinhold 		case B_SYSTEM_VERSION_KIND:
66398da112cSIngo Weinhold 			index = 1;
66498da112cSIngo Weinhold 			break;
66598da112cSIngo Weinhold 		default:
666b1970bb8SIngo Weinhold 			return B_BAD_VALUE;
66798da112cSIngo Weinhold 	}
668b1970bb8SIngo Weinhold 
669b1970bb8SIngo Weinhold 	if (InitCheck() != B_OK)
670b1970bb8SIngo Weinhold 		return B_NO_INIT;
671b1970bb8SIngo Weinhold 
67298da112cSIngo Weinhold 	// read the data
67398da112cSIngo Weinhold 	size_t read = 0;
67498da112cSIngo Weinhold 	version_info infos[2];
675b1970bb8SIngo Weinhold 	status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
676b1970bb8SIngo Weinhold 		B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read);
677b1970bb8SIngo Weinhold 	if (error != B_OK)
67898da112cSIngo Weinhold 		return error;
679b1970bb8SIngo Weinhold 
680b1970bb8SIngo Weinhold 	// check the read data
681b1970bb8SIngo Weinhold 	if (read == sizeof(version_info)) {
682b1970bb8SIngo Weinhold 		// only the app version info is there -- return a cleared system info
683b1970bb8SIngo Weinhold 		if (index == 0)
684b1970bb8SIngo Weinhold 			*info = infos[index];
685b1970bb8SIngo Weinhold 		else if (index == 1)
686b1970bb8SIngo Weinhold 			memset(info, 0, sizeof(version_info));
687b1970bb8SIngo Weinhold 	} else if (read == 2 * sizeof(version_info)) {
688b1970bb8SIngo Weinhold 		*info = infos[index];
689b1970bb8SIngo Weinhold 	} else
690b1970bb8SIngo Weinhold 		return B_ERROR;
691b1970bb8SIngo Weinhold 
692b1970bb8SIngo Weinhold 	// return result
693b1970bb8SIngo Weinhold 	return B_OK;
694d6b205f3SIngo Weinhold }
695d6b205f3SIngo Weinhold 
696d6b205f3SIngo Weinhold // SetVersionInfo
697d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
698d6b205f3SIngo Weinhold 
699d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
700d6b205f3SIngo Weinhold 
701d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
702d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
703d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
704d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
705d6b205f3SIngo Weinhold 		   belongs to.
706d6b205f3SIngo Weinhold 	\return
707d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
708d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
709d6b205f3SIngo Weinhold 	- other error codes
710d6b205f3SIngo Weinhold */
711d6b205f3SIngo Weinhold status_t
712d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
713d6b205f3SIngo Weinhold {
71498da112cSIngo Weinhold 	// check initialization
71598da112cSIngo Weinhold 	status_t error = B_OK;
71698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
71798da112cSIngo Weinhold 		error = B_NO_INIT;
71898da112cSIngo Weinhold 	if (error == B_OK) {
71998da112cSIngo Weinhold 		if (info) {
72098da112cSIngo Weinhold 			// check param
72198da112cSIngo Weinhold 			int32 index = 0;
72298da112cSIngo Weinhold 			if (error == B_OK) {
72398da112cSIngo Weinhold 				switch (kind) {
72498da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
72598da112cSIngo Weinhold 						index = 0;
72698da112cSIngo Weinhold 						break;
72798da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
72898da112cSIngo Weinhold 						index = 1;
72998da112cSIngo Weinhold 						break;
73098da112cSIngo Weinhold 					default:
73198da112cSIngo Weinhold 						error = B_BAD_VALUE;
73298da112cSIngo Weinhold 						break;
73398da112cSIngo Weinhold 				}
73498da112cSIngo Weinhold 			}
73598da112cSIngo Weinhold 			// read both infos
73698da112cSIngo Weinhold 			version_info infos[2];
73798da112cSIngo Weinhold 			if (error == B_OK) {
73898da112cSIngo Weinhold 				size_t read;
739b1970bb8SIngo Weinhold 				if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
740b1970bb8SIngo Weinhold 						B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info),
741b1970bb8SIngo Weinhold 						read) == B_OK) {
742b1970bb8SIngo Weinhold 					// clear the part that hasn't been read
743b1970bb8SIngo Weinhold 					if (read < sizeof(infos))
744b1970bb8SIngo Weinhold 						memset((char*)infos + read, 0, sizeof(infos) - read);
745b1970bb8SIngo Weinhold 				} else {
746b1970bb8SIngo Weinhold 					// failed to read -- clear
747b1970bb8SIngo Weinhold 					memset(infos, 0, sizeof(infos));
748b1970bb8SIngo Weinhold 				}
74998da112cSIngo Weinhold 			}
75098da112cSIngo Weinhold 			infos[index] = *info;
75198da112cSIngo Weinhold 			// write the data
75298da112cSIngo Weinhold 			if (error == B_OK) {
75398da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
75498da112cSIngo Weinhold 								   kVersionInfoResourceID,
75598da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
75698da112cSIngo Weinhold 								   2 * sizeof(version_info));
75798da112cSIngo Weinhold 			}
75898da112cSIngo Weinhold 		} else
75998da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
76098da112cSIngo Weinhold 	}
76198da112cSIngo Weinhold 	return error;
762d6b205f3SIngo Weinhold }
763d6b205f3SIngo Weinhold 
764d6b205f3SIngo Weinhold // GetIconForType
765d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
76698da112cSIngo Weinhold 
76798da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
76898da112cSIngo Weinhold 
76998da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
770d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
771d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
772d6b205f3SIngo Weinhold 		   large icon).
773d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
774d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
775d6b205f3SIngo Weinhold 	\return
776d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
777d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
77898da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
779d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
780d6b205f3SIngo Weinhold 		 not match.
781d6b205f3SIngo Weinhold 	- other error codes
782d6b205f3SIngo Weinhold */
783d6b205f3SIngo Weinhold status_t
784d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
785d6b205f3SIngo Weinhold 							 icon_size which) const
786d6b205f3SIngo Weinhold {
78798da112cSIngo Weinhold 	status_t error = B_OK;
78898da112cSIngo Weinhold 	// set some icon size related variables
78998da112cSIngo Weinhold 	BString attributeString;
79098da112cSIngo Weinhold 	BRect bounds;
791a04efc92SIngo Weinhold 	uint32 attrType = 0;
792a04efc92SIngo Weinhold 	size_t attrSize = 0;
79398da112cSIngo Weinhold 	switch (which) {
79498da112cSIngo Weinhold 		case B_MINI_ICON:
79598da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
79698da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
79798da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
79898da112cSIngo Weinhold 			attrSize = 16 * 16;
79998da112cSIngo Weinhold 			break;
80098da112cSIngo Weinhold 		case B_LARGE_ICON:
80198da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
80298da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
80398da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
80498da112cSIngo Weinhold 			attrSize = 32 * 32;
80598da112cSIngo Weinhold 			break;
80698da112cSIngo Weinhold 		default:
80798da112cSIngo Weinhold 			error = B_BAD_VALUE;
80898da112cSIngo Weinhold 			break;
80998da112cSIngo Weinhold 	}
81098da112cSIngo Weinhold 	// check type param
81198da112cSIngo Weinhold 	if (error == B_OK) {
81298da112cSIngo Weinhold 		if (type) {
81317819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
81417819be3SIngo Weinhold 				attributeString += type;
81517819be3SIngo Weinhold 			else
81698da112cSIngo Weinhold 				error = B_BAD_VALUE;
81798da112cSIngo Weinhold 		} else
81817819be3SIngo Weinhold 			attributeString += kStandardIconType;
81998da112cSIngo Weinhold 	}
82098da112cSIngo Weinhold 	const char *attribute = attributeString.String();
82117819be3SIngo Weinhold 
82298da112cSIngo Weinhold 	// check parameter and initialization
82398da112cSIngo Weinhold 	if (error == B_OK
82498da112cSIngo Weinhold 		&& (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
82598da112cSIngo Weinhold 		error = B_BAD_VALUE;
82698da112cSIngo Weinhold 	}
82798da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
82898da112cSIngo Weinhold 		error = B_NO_INIT;
82998da112cSIngo Weinhold 	// read the data
83098da112cSIngo Weinhold 	if (error == B_OK) {
83198da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
83298da112cSIngo Weinhold 		char *buffer = NULL;
83398da112cSIngo Weinhold 		size_t read;
83498da112cSIngo Weinhold 		if (otherColorSpace) {
83598da112cSIngo Weinhold 			// other color space than stored in attribute
83698da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
83798da112cSIngo Weinhold 			if (!buffer)
83898da112cSIngo Weinhold 				error = B_NO_MEMORY;
83998da112cSIngo Weinhold 			if (error == B_OK) {
84098da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
84198da112cSIngo Weinhold 								  read);
84298da112cSIngo Weinhold 			}
84398da112cSIngo Weinhold 		} else {
84498da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
84598da112cSIngo Weinhold 							  read);
84698da112cSIngo Weinhold 		}
84798da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
84898da112cSIngo Weinhold 			error = B_ERROR;
84998da112cSIngo Weinhold 		if (otherColorSpace) {
85098da112cSIngo Weinhold 			// other color space than stored in attribute
85176ba3434SIngo Weinhold 			if (error == B_OK) {
85276ba3434SIngo Weinhold 				error = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
85376ba3434SIngo Weinhold 										 0, B_CMAP8);
85476ba3434SIngo Weinhold 			}
85598da112cSIngo Weinhold 			delete[] buffer;
85698da112cSIngo Weinhold 		}
85798da112cSIngo Weinhold 	}
85898da112cSIngo Weinhold 	return error;
859d6b205f3SIngo Weinhold }
860d6b205f3SIngo Weinhold 
861d6b205f3SIngo Weinhold // SetIconForType
862d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
863d6b205f3SIngo Weinhold 
86498da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
865d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
866d6b205f3SIngo Weinhold 
86798da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
86898da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
86998da112cSIngo Weinhold 	before.
87098da112cSIngo Weinhold 
87198da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
872d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
873d6b205f3SIngo Weinhold 		   May be \c NULL.
874d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
875d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
876d6b205f3SIngo Weinhold 	\return
877d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
878d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
879d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
880d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
881d6b205f3SIngo Weinhold 	- other error codes
882d6b205f3SIngo Weinhold */
883d6b205f3SIngo Weinhold status_t
884d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
885d6b205f3SIngo Weinhold 							 icon_size which)
886d6b205f3SIngo Weinhold {
88798da112cSIngo Weinhold 	status_t error = B_OK;
88898da112cSIngo Weinhold 	// set some icon size related variables
88998da112cSIngo Weinhold 	BString attributeString;
89098da112cSIngo Weinhold 	BRect bounds;
891a04efc92SIngo Weinhold 	uint32 attrType = 0;
892a04efc92SIngo Weinhold 	size_t attrSize = 0;
893a04efc92SIngo Weinhold 	int32 resourceID = 0;
89498da112cSIngo Weinhold 	switch (which) {
89598da112cSIngo Weinhold 		case B_MINI_ICON:
89698da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
89798da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
89898da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
89998da112cSIngo Weinhold 			attrSize = 16 * 16;
90098da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
90198da112cSIngo Weinhold 							   : kMiniIconResourceID);
90298da112cSIngo Weinhold 			break;
90398da112cSIngo Weinhold 		case B_LARGE_ICON:
90498da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
90598da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
90698da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
90798da112cSIngo Weinhold 			attrSize = 32 * 32;
90898da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
90998da112cSIngo Weinhold 							   : kLargeIconResourceID);
91098da112cSIngo Weinhold 			break;
91198da112cSIngo Weinhold 		default:
91298da112cSIngo Weinhold 			error = B_BAD_VALUE;
91398da112cSIngo Weinhold 			break;
91498da112cSIngo Weinhold 	}
91598da112cSIngo Weinhold 	// check type param
91698da112cSIngo Weinhold 	if (error == B_OK) {
91798da112cSIngo Weinhold 		if (type) {
91817819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
91998da112cSIngo Weinhold 				attributeString += type;
92017819be3SIngo Weinhold 			else
92117819be3SIngo Weinhold 				error = B_BAD_VALUE;
92298da112cSIngo Weinhold 		} else
92398da112cSIngo Weinhold 			attributeString += kStandardIconType;
92498da112cSIngo Weinhold 	}
92598da112cSIngo Weinhold 	const char *attribute = attributeString.String();
92698da112cSIngo Weinhold 	// check parameter and initialization
92798da112cSIngo Weinhold 	if (error == B_OK && icon
92898da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
92998da112cSIngo Weinhold 		error = B_BAD_VALUE;
93098da112cSIngo Weinhold 	}
93198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
93298da112cSIngo Weinhold 		error = B_NO_INIT;
93398da112cSIngo Weinhold 	// write/remove the attribute
93498da112cSIngo Weinhold 	if (error == B_OK) {
93598da112cSIngo Weinhold 		if (icon) {
93698da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
93798da112cSIngo Weinhold 			if (otherColorSpace) {
938290bc091SIngo Weinhold 				BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8);
93998da112cSIngo Weinhold 				error = bitmap.InitCheck();
94076ba3434SIngo Weinhold 				if (error == B_OK)
94176ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
94298da112cSIngo Weinhold 				if (error == B_OK) {
94398da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
94498da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
94598da112cSIngo Weinhold 				}
94698da112cSIngo Weinhold 			} else {
94798da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
94898da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
94998da112cSIngo Weinhold 			}
95098da112cSIngo Weinhold 		} else	// no icon given => remove
95198da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
95298da112cSIngo Weinhold 	}
95398da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
95498da112cSIngo Weinhold 	BMimeType mimeType;
95598da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
95698da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
95798da112cSIngo Weinhold 			error = mimeType.Install();
95898da112cSIngo Weinhold 		if (error == B_OK)
95998da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
96098da112cSIngo Weinhold 	}
96198da112cSIngo Weinhold 	return error;
962d6b205f3SIngo Weinhold }
963d6b205f3SIngo Weinhold 
964d6b205f3SIngo Weinhold // SetInfoLocation
965d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
966d6b205f3SIngo Weinhold 
967d6b205f3SIngo Weinhold 	The options for \a location are:
968d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
969d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
970d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
971d6b205f3SIngo Weinhold 
972d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
973d6b205f3SIngo Weinhold */
974d6b205f3SIngo Weinhold void
975d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
976d6b205f3SIngo Weinhold {
97798da112cSIngo Weinhold 	fWhere = location;
978d6b205f3SIngo Weinhold }
979d6b205f3SIngo Weinhold 
980d6b205f3SIngo Weinhold // IsUsingAttributes
981d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
982d6b205f3SIngo Weinhold 		   file's attributes.
983d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
984d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
985d6b205f3SIngo Weinhold */
986d6b205f3SIngo Weinhold bool
987d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
988d6b205f3SIngo Weinhold {
98998da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
990d6b205f3SIngo Weinhold }
991d6b205f3SIngo Weinhold 
992d6b205f3SIngo Weinhold // IsUsingResources
993d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
994d6b205f3SIngo Weinhold 		   file's resources.
995d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
996d6b205f3SIngo Weinhold 			resources, \c false otherwise.
997d6b205f3SIngo Weinhold */
998d6b205f3SIngo Weinhold bool
999d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
1000d6b205f3SIngo Weinhold {
100198da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
1002d6b205f3SIngo Weinhold }
1003d6b205f3SIngo Weinhold 
1004d6b205f3SIngo Weinhold // FBC
1005d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
1006d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
1007d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
1008d6b205f3SIngo Weinhold 
1009d6b205f3SIngo Weinhold // =
1010d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
1011d6b205f3SIngo Weinhold */
1012d6b205f3SIngo Weinhold BAppFileInfo &
1013d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
1014d6b205f3SIngo Weinhold {
1015d6b205f3SIngo Weinhold 	return *this;
1016d6b205f3SIngo Weinhold }
1017d6b205f3SIngo Weinhold 
1018d6b205f3SIngo Weinhold // copy constructor
1019d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1020d6b205f3SIngo Weinhold */
1021d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
1022d6b205f3SIngo Weinhold {
1023d6b205f3SIngo Weinhold }
1024d6b205f3SIngo Weinhold 
102598da112cSIngo Weinhold // GetMetaMime
102698da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
102798da112cSIngo Weinhold 
102898da112cSIngo Weinhold 	The parameter \a meta is not checked.
102998da112cSIngo Weinhold 
103098da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
103198da112cSIngo Weinhold 		   initialized to the file's signature.
103298da112cSIngo Weinhold 	\return
103398da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
103498da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
103598da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
103698da112cSIngo Weinhold (	  not installed in the MIME database.)
103798da112cSIngo Weinhold 	  no valid MIME string.
103898da112cSIngo Weinhold 	- other error codes
103998da112cSIngo Weinhold */
104098da112cSIngo Weinhold status_t
104198da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
104298da112cSIngo Weinhold {
104398da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
104498da112cSIngo Weinhold 	status_t error = GetSignature(signature);
104598da112cSIngo Weinhold 	if (error == B_OK)
104698da112cSIngo Weinhold 		error = meta->SetTo(signature);
104798da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
104898da112cSIngo Weinhold 		error = B_BAD_VALUE;
104998da112cSIngo Weinhold 	return error;
105098da112cSIngo Weinhold }
105198da112cSIngo Weinhold 
105298da112cSIngo Weinhold // _ReadData
105398da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
105498da112cSIngo Weinhold 
105598da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
105698da112cSIngo Weinhold 
105798da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
105898da112cSIngo Weinhold 
105998da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
106098da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
106198da112cSIngo Weinhold 		   < 0.
106298da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
106398da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
106498da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
106598da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
106698da112cSIngo Weinhold 		   actually read.
106798da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
106898da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
106998da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
107098da112cSIngo Weinhold 	\return
107198da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
107298da112cSIngo Weinhold 	- error code
107398da112cSIngo Weinhold */
107498da112cSIngo Weinhold status_t
107598da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
107698da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
107798da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
107898da112cSIngo Weinhold {
107998da112cSIngo Weinhold 	status_t error = B_OK;
1080338b8dc3SIngo Weinhold 
108198da112cSIngo Weinhold 	if (allocatedBuffer)
108298da112cSIngo Weinhold 		buffer = NULL;
1083338b8dc3SIngo Weinhold 
1084338b8dc3SIngo Weinhold 	bool foundData = false;
1085338b8dc3SIngo Weinhold 
108698da112cSIngo Weinhold 	if (IsUsingAttributes()) {
108798da112cSIngo Weinhold 		// get an attribute info
108898da112cSIngo Weinhold 		attr_info info;
108998da112cSIngo Weinhold 		if (error == B_OK)
109098da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1091338b8dc3SIngo Weinhold 
109298da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
109398da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
109498da112cSIngo Weinhold 			error = B_BAD_VALUE;
1095b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
109698da112cSIngo Weinhold 			buffer = malloc(info.size);
109798da112cSIngo Weinhold 			if (!buffer)
109898da112cSIngo Weinhold 				error = B_NO_MEMORY;
109998da112cSIngo Weinhold 			bufferSize = info.size;
110098da112cSIngo Weinhold 		}
110198da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
110298da112cSIngo Weinhold 			error = B_BAD_VALUE;
1103338b8dc3SIngo Weinhold 
110498da112cSIngo Weinhold 		// read the data
110598da112cSIngo Weinhold 		if (error == B_OK) {
110698da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
110798da112cSIngo Weinhold 			if (read < 0)
110898da112cSIngo Weinhold 				error = read;
110998da112cSIngo Weinhold 			else if (read != info.size)
111098da112cSIngo Weinhold 				error = B_ERROR;
111198da112cSIngo Weinhold 			else
111298da112cSIngo Weinhold 				bytesRead = read;
111398da112cSIngo Weinhold 		}
1114338b8dc3SIngo Weinhold 
1115338b8dc3SIngo Weinhold 		foundData = (error == B_OK);
1116b4598d95SIngo Weinhold 
1117b4598d95SIngo Weinhold 		// free the allocated buffer on error
1118b4598d95SIngo Weinhold 		if (!foundData && allocatedBuffer && buffer) {
1119b4598d95SIngo Weinhold 			free(buffer);
1120b4598d95SIngo Weinhold 			buffer = NULL;
1121b4598d95SIngo Weinhold 		}
1122338b8dc3SIngo Weinhold 	}
1123338b8dc3SIngo Weinhold 
1124338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
112598da112cSIngo Weinhold 		// get a resource info
1126338b8dc3SIngo Weinhold 		error = B_OK;
112798da112cSIngo Weinhold 		int32 idFound;
112898da112cSIngo Weinhold 		size_t sizeFound;
112998da112cSIngo Weinhold 		if (error == B_OK) {
113098da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
113198da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
113298da112cSIngo Weinhold 		}
1133338b8dc3SIngo Weinhold 
113498da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
113598da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
113698da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1137b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
113898da112cSIngo Weinhold 			buffer = malloc(sizeFound);
113998da112cSIngo Weinhold 			if (!buffer)
114098da112cSIngo Weinhold 				error = B_NO_MEMORY;
114198da112cSIngo Weinhold 			bufferSize = sizeFound;
114298da112cSIngo Weinhold 		}
114398da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
114498da112cSIngo Weinhold 			error = B_BAD_VALUE;
1145338b8dc3SIngo Weinhold 
114698da112cSIngo Weinhold 		// load resource
114798da112cSIngo Weinhold 		const void *resourceData = NULL;
114898da112cSIngo Weinhold 		if (error == B_OK) {
114998da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
115098da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
115198da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
115298da112cSIngo Weinhold 			else
115398da112cSIngo Weinhold 				error = B_ERROR;
115498da112cSIngo Weinhold 		}
1155773be699SAxel Dörfler 	} else if (!foundData)
115698da112cSIngo Weinhold 		error = B_BAD_VALUE;
1157338b8dc3SIngo Weinhold 
115898da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
115998da112cSIngo Weinhold 	if (allocatedBuffer) {
116098da112cSIngo Weinhold 		if (error == B_OK)
116198da112cSIngo Weinhold 			*allocatedBuffer = buffer;
116298da112cSIngo Weinhold 		else
116398da112cSIngo Weinhold 			free(buffer);
116498da112cSIngo Weinhold 	}
1165338b8dc3SIngo Weinhold 
116698da112cSIngo Weinhold 	return error;
116798da112cSIngo Weinhold }
116898da112cSIngo Weinhold 
116998da112cSIngo Weinhold // _WriteData
117098da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
117198da112cSIngo Weinhold 
117298da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
117398da112cSIngo Weinhold 
117498da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
117598da112cSIngo Weinhold 
117698da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
117798da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
117898da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
117998da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
118098da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
118198da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
118298da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
118398da112cSIngo Weinhold 		   If \c false, \a id is used.
118498da112cSIngo Weinhold 	If \a id is already in use and .
118598da112cSIngo Weinhold 	\return
118698da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
118798da112cSIngo Weinhold 	- error code
118898da112cSIngo Weinhold */
118998da112cSIngo Weinhold status_t
119098da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
119198da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
119298da112cSIngo Weinhold {
119398da112cSIngo Weinhold 	status_t error = B_OK;
119498da112cSIngo Weinhold 	// write to attribute
119598da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
119698da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
119798da112cSIngo Weinhold 		if (written < 0)
119898da112cSIngo Weinhold 			error = written;
119998da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
120098da112cSIngo Weinhold 			error = B_ERROR;
120198da112cSIngo Weinhold 	}
120298da112cSIngo Weinhold 	// write to resource
120398da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
120498da112cSIngo Weinhold 		if (findID) {
120598da112cSIngo Weinhold 			// get the resource info
120698da112cSIngo Weinhold 			int32 idFound;
120798da112cSIngo Weinhold 			size_t sizeFound;
120898da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
120998da112cSIngo Weinhold 				id = idFound;
121098da112cSIngo Weinhold 			else {
121198da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
121298da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
121398da112cSIngo Weinhold 					id++;
121498da112cSIngo Weinhold 			}
121598da112cSIngo Weinhold 		}
121698da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
121798da112cSIngo Weinhold 	}
121898da112cSIngo Weinhold 	return error;
121998da112cSIngo Weinhold }
122098da112cSIngo Weinhold 
122198da112cSIngo Weinhold // _RemoveData
122298da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
122398da112cSIngo Weinhold 
122498da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
122598da112cSIngo Weinhold 
122698da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
122798da112cSIngo Weinhold 
122898da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
122998da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
123098da112cSIngo Weinhold 	\return
123198da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
123298da112cSIngo Weinhold 	- error code
123398da112cSIngo Weinhold */
123498da112cSIngo Weinhold status_t
123598da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
123698da112cSIngo Weinhold {
123798da112cSIngo Weinhold 	status_t error = B_OK;
123898da112cSIngo Weinhold 	// remove the attribute
123998da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
124098da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
124198da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
124298da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
124398da112cSIngo Weinhold 			error = B_OK;
124498da112cSIngo Weinhold 	}
124598da112cSIngo Weinhold 	// remove the resource
124698da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
124798da112cSIngo Weinhold 		// get a resource info
124898da112cSIngo Weinhold 		int32 idFound;
124998da112cSIngo Weinhold 		size_t sizeFound;
125098da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
125198da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
125298da112cSIngo Weinhold 	}
125398da112cSIngo Weinhold 	return error;
125498da112cSIngo Weinhold }
125598da112cSIngo Weinhold 
1256