xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision 98da112ccabc1bb25391a79e3effa70cd8747c15)
1d6b205f3SIngo Weinhold // BAppFileInfo.cpp
2d6b205f3SIngo Weinhold 
3*98da112cSIngo Weinhold #include <new>
4*98da112cSIngo Weinhold #include <set>
5*98da112cSIngo Weinhold #include <string>
6*98da112cSIngo Weinhold 
7d6b205f3SIngo Weinhold #include <AppFileInfo.h>
8*98da112cSIngo Weinhold #include <Bitmap.h>
9*98da112cSIngo Weinhold #include <File.h>
10*98da112cSIngo Weinhold #include <fs_attr.h>
11*98da112cSIngo Weinhold #include <MimeType.h>
12*98da112cSIngo Weinhold #include <RegistrarDefs.h>
13*98da112cSIngo Weinhold #include <Resources.h>
14*98da112cSIngo Weinhold #include <Roster.h>
15*98da112cSIngo Weinhold #include <String.h>
16*98da112cSIngo Weinhold 
17*98da112cSIngo Weinhold // attributes
18*98da112cSIngo Weinhold static const char *kTypeAttribute				= "BEOS:TYPE";
19*98da112cSIngo Weinhold static const char *kSignatureAttribute			= "BEOS:APP_SIG";
20*98da112cSIngo Weinhold static const char *kAppFlagsAttribute			= "BEOS:APP_FLAGS";
21*98da112cSIngo Weinhold static const char *kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
22*98da112cSIngo Weinhold static const char *kVersionInfoAttribute		= "BEOS:APP_VERSION";
23*98da112cSIngo Weinhold static const char *kMiniIconAttribute			= "BEOS:M:";
24*98da112cSIngo Weinhold static const char *kLargeIconAttribute			= "BEOS:L:";
25*98da112cSIngo Weinhold static const char *kStandardIconType			= "STD_ICON";
26*98da112cSIngo Weinhold 
27*98da112cSIngo Weinhold // resource IDs
28*98da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
29*98da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
30*98da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
31*98da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
32*98da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
33*98da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
34*98da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
35*98da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
36*98da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
37*98da112cSIngo Weinhold 
38*98da112cSIngo Weinhold // type codes
39*98da112cSIngo Weinhold enum {
40*98da112cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
41*98da112cSIngo Weinhold 	B_MINI_ICON_TYPE	= 'MICN',
42*98da112cSIngo Weinhold 	B_LARGE_ICON_TYPE	= 'ICON',
43*98da112cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
44*98da112cSIngo Weinhold };
45*98da112cSIngo Weinhold 
46d6b205f3SIngo Weinhold 
47d6b205f3SIngo Weinhold enum {
48d6b205f3SIngo Weinhold 	NOT_IMPLEMENTED	= B_ERROR,
49d6b205f3SIngo Weinhold };
50d6b205f3SIngo Weinhold 
51d6b205f3SIngo Weinhold // constructor
52d6b205f3SIngo Weinhold /*!	\brief Creates an uninitialized BAppFileInfo object.
53d6b205f3SIngo Weinhold */
54d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
55d6b205f3SIngo Weinhold 			: fResources(NULL),
56d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
57d6b205f3SIngo Weinhold {
58d6b205f3SIngo Weinhold }
59d6b205f3SIngo Weinhold 
60d6b205f3SIngo Weinhold // constructor
61d6b205f3SIngo Weinhold /*!	\brief Creates an BAppFileInfo object and initializes it to the supplied
62d6b205f3SIngo Weinhold 		   file.
63d6b205f3SIngo Weinhold 
64d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
65d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
66d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
67d6b205f3SIngo Weinhold 
68d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
69d6b205f3SIngo Weinhold */
70d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile *file)
71d6b205f3SIngo Weinhold 			: fResources(NULL),
72d6b205f3SIngo Weinhold 			  fWhere(B_USE_BOTH_LOCATIONS)
73d6b205f3SIngo Weinhold {
74*98da112cSIngo Weinhold 	SetTo(file);
75d6b205f3SIngo Weinhold }
76d6b205f3SIngo Weinhold 
77d6b205f3SIngo Weinhold // destructor
78d6b205f3SIngo Weinhold /*!	\brief Frees all resources associated with this object.
79d6b205f3SIngo Weinhold 
80d6b205f3SIngo Weinhold 	The BFile the object is set to is not deleted.
81d6b205f3SIngo Weinhold */
82d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
83d6b205f3SIngo Weinhold {
84*98da112cSIngo Weinhold 	if (fResources)
85*98da112cSIngo Weinhold 		delete fResources;
86d6b205f3SIngo Weinhold }
87d6b205f3SIngo Weinhold 
88d6b205f3SIngo Weinhold // SetTo
89d6b205f3SIngo Weinhold /*!	\brief Initializes the BAppFileInfo to the supplied file.
90d6b205f3SIngo Weinhold 
91d6b205f3SIngo Weinhold 	The caller retains ownership of the supplied BFile object. It must not
92d6b205f3SIngo Weinhold 	be deleted during the life time of the BAppFileInfo. It is not deleted
93d6b205f3SIngo Weinhold 	when the BAppFileInfo is destroyed.
94d6b205f3SIngo Weinhold 
95d6b205f3SIngo Weinhold 	\param file The file the object shall be initialized to.
96d6b205f3SIngo Weinhold 
97d6b205f3SIngo Weinhold 	\return
98d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
99d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a file or \a file is not properly initialized.
100d6b205f3SIngo Weinhold */
101d6b205f3SIngo Weinhold status_t
102d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile *file)
103d6b205f3SIngo Weinhold {
104*98da112cSIngo Weinhold 	// unset the old file
105*98da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
106*98da112cSIngo Weinhold 	if (fResources) {
107*98da112cSIngo Weinhold 		delete fResources;
108*98da112cSIngo Weinhold 		fResources = NULL;
109*98da112cSIngo Weinhold 	}
110*98da112cSIngo Weinhold 	// check param
111*98da112cSIngo Weinhold 	status_t error = (file && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
112*98da112cSIngo Weinhold 	// create resources
113*98da112cSIngo Weinhold 	if (error == B_OK) {
114*98da112cSIngo Weinhold 		fResources = new(nothrow) BResources();
115*98da112cSIngo Weinhold 		if (fResources)
116*98da112cSIngo Weinhold 			error = fResources->SetTo(file);
117*98da112cSIngo Weinhold 		else
118*98da112cSIngo Weinhold 			error = B_NO_MEMORY;
119*98da112cSIngo Weinhold 	}
120*98da112cSIngo Weinhold 	// set node info
121*98da112cSIngo Weinhold 	if (error == B_OK)
122*98da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
123*98da112cSIngo Weinhold 	// clean up on error
124*98da112cSIngo Weinhold 	if (error != B_OK) {
125*98da112cSIngo Weinhold 		if (fResources) {
126*98da112cSIngo Weinhold 			delete fResources;
127*98da112cSIngo Weinhold 			fResources = NULL;
128*98da112cSIngo Weinhold 		}
129*98da112cSIngo Weinhold 		if (InitCheck() == B_OK)
130*98da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
131*98da112cSIngo Weinhold 	}
132*98da112cSIngo Weinhold 	// set data location
133*98da112cSIngo Weinhold 	if (error == B_OK)
134*98da112cSIngo Weinhold 		SetInfoLocation(B_USE_BOTH_LOCATIONS);
135*98da112cSIngo Weinhold 	// set error
136*98da112cSIngo Weinhold 	fCStatus = error;
137*98da112cSIngo Weinhold 	return error;
138d6b205f3SIngo Weinhold }
139d6b205f3SIngo Weinhold 
140d6b205f3SIngo Weinhold // GetType
141d6b205f3SIngo Weinhold /*!	\brief Gets the file's MIME type.
142d6b205f3SIngo Weinhold 
143d6b205f3SIngo Weinhold 	\param type A pointer to a pre-allocated character buffer of size
144d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the MIME type of the
145d6b205f3SIngo Weinhold 		   file shall be written.
146d6b205f3SIngo Weinhold 	\return
147d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
148d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
149d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a type or the type string stored in the
150d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
151d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the type string is stored in have
152d6b205f3SIngo Weinhold 	  the wrong type.
153d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No type is set on the file.
154d6b205f3SIngo Weinhold 	- other error codes
155d6b205f3SIngo Weinhold */
156d6b205f3SIngo Weinhold status_t
157d6b205f3SIngo Weinhold BAppFileInfo::GetType(char *type) const
158d6b205f3SIngo Weinhold {
159*98da112cSIngo Weinhold 	// check param and initialization
160*98da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
161*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
162*98da112cSIngo Weinhold 		error = B_NO_INIT;
163*98da112cSIngo Weinhold 	// read the data
164*98da112cSIngo Weinhold 	size_t read = 0;
165*98da112cSIngo Weinhold 	if (error == B_OK) {
166*98da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
167*98da112cSIngo Weinhold 						  type, B_MIME_TYPE_LENGTH, read);
168*98da112cSIngo Weinhold 	}
169*98da112cSIngo Weinhold 	// check the read data -- null terminate the string
170*98da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
171*98da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
172*98da112cSIngo Weinhold 			error = B_ERROR;
173*98da112cSIngo Weinhold 		else
174*98da112cSIngo Weinhold 			type[read] = '\0';
175*98da112cSIngo Weinhold 	}
176*98da112cSIngo Weinhold 	return error;
177d6b205f3SIngo Weinhold }
178d6b205f3SIngo Weinhold 
179d6b205f3SIngo Weinhold // SetType
180d6b205f3SIngo Weinhold /*!	\brief Sets the file's MIME type.
181d6b205f3SIngo Weinhold 
182d6b205f3SIngo Weinhold 	If \a type is \c NULL the file's MIME type is unset.
183d6b205f3SIngo Weinhold 
184d6b205f3SIngo Weinhold 	\param type The MIME type to be assigned to the file. Must not be longer
185d6b205f3SIngo Weinhold 		   than \c B_MIME_TYPE_LENGTH (including the terminating null).
186d6b205f3SIngo Weinhold 		   May be \c NULL.
187d6b205f3SIngo Weinhold 	\return
188d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
189d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
190d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a type is longer than \c B_MIME_TYPE_LENGTH.
191d6b205f3SIngo Weinhold 	- other error codes
192d6b205f3SIngo Weinhold */
193d6b205f3SIngo Weinhold status_t
194d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char *type)
195d6b205f3SIngo Weinhold {
196*98da112cSIngo Weinhold 	// check initialization
197*98da112cSIngo Weinhold 	status_t error = B_OK;
198*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
199*98da112cSIngo Weinhold 		error = B_NO_INIT;
200*98da112cSIngo Weinhold 	if (error == B_OK) {
201*98da112cSIngo Weinhold 		if (type) {
202*98da112cSIngo Weinhold 			// check param
203*98da112cSIngo Weinhold 			size_t typeLen = strlen(type);
204*98da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
205*98da112cSIngo Weinhold 				error = B_BAD_VALUE;
206*98da112cSIngo Weinhold 			// write the data
207*98da112cSIngo Weinhold 			if (error == B_OK) {
208*98da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
209*98da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, type, typeLen + 1);
210*98da112cSIngo Weinhold 			}
211*98da112cSIngo Weinhold 		} else
212*98da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
213*98da112cSIngo Weinhold 	}
214*98da112cSIngo Weinhold 	return error;
215d6b205f3SIngo Weinhold }
216d6b205f3SIngo Weinhold 
217d6b205f3SIngo Weinhold // GetSignature
218d6b205f3SIngo Weinhold /*!	\brief Gets the file's application signature.
219d6b205f3SIngo Weinhold 
220d6b205f3SIngo Weinhold 	\param signature A pointer to a pre-allocated character buffer of size
221d6b205f3SIngo Weinhold 		   \c B_MIME_TYPE_LENGTH or larger into which the application
222d6b205f3SIngo Weinhold 		   signature of the file shall be written.
223d6b205f3SIngo Weinhold 	\return
224d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
225d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
226d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a signature or the signature stored in the
227d6b205f3SIngo Weinhold 	  attribute/resources is longer than \c B_MIME_TYPE_LENGTH.
228d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the signature is stored in have
229d6b205f3SIngo Weinhold 	  the wrong type.
230d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No signature is set on the file.
231d6b205f3SIngo Weinhold 	- other error codes
232d6b205f3SIngo Weinhold */
233d6b205f3SIngo Weinhold status_t
234d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char *signature) const
235d6b205f3SIngo Weinhold {
236*98da112cSIngo Weinhold 	// check param and initialization
237*98da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
238*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
239*98da112cSIngo Weinhold 		error = B_NO_INIT;
240*98da112cSIngo Weinhold 	// read the data
241*98da112cSIngo Weinhold 	size_t read = 0;
242*98da112cSIngo Weinhold 	if (error == B_OK) {
243*98da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
244*98da112cSIngo Weinhold 						  B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH,
245*98da112cSIngo Weinhold 						  read);
246*98da112cSIngo Weinhold 	}
247*98da112cSIngo Weinhold 	// check the read data -- null terminate the string
248*98da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
249*98da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
250*98da112cSIngo Weinhold 			error = B_ERROR;
251*98da112cSIngo Weinhold 		else
252*98da112cSIngo Weinhold 			signature[read] = '\0';
253*98da112cSIngo Weinhold 	}
254*98da112cSIngo Weinhold 	return error;
255d6b205f3SIngo Weinhold }
256d6b205f3SIngo Weinhold 
257d6b205f3SIngo Weinhold // SetSignature
258d6b205f3SIngo Weinhold /*!	\brief Sets the file's application signature.
259d6b205f3SIngo Weinhold 
260d6b205f3SIngo Weinhold 	If \a signature is \c NULL the file's application signature is unset.
261d6b205f3SIngo Weinhold 
262d6b205f3SIngo Weinhold 	\param signature The application signature to be assigned to the file.
263d6b205f3SIngo Weinhold 		   Must not be longer than \c B_MIME_TYPE_LENGTH (including the
264d6b205f3SIngo Weinhold 		   terminating null). May be \c NULL.
265d6b205f3SIngo Weinhold 	\return
266d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
267d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
268d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \a signature is longer than \c B_MIME_TYPE_LENGTH.
269d6b205f3SIngo Weinhold 	- other error codes
270d6b205f3SIngo Weinhold */
271d6b205f3SIngo Weinhold status_t
272d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char *signature)
273d6b205f3SIngo Weinhold {
274*98da112cSIngo Weinhold 	// check initialization
275*98da112cSIngo Weinhold 	status_t error = B_OK;
276*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
277*98da112cSIngo Weinhold 		error = B_NO_INIT;
278*98da112cSIngo Weinhold 	if (error == B_OK) {
279*98da112cSIngo Weinhold 		if (signature) {
280*98da112cSIngo Weinhold 			// check param
281*98da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
282*98da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
283*98da112cSIngo Weinhold 				error = B_BAD_VALUE;
284*98da112cSIngo Weinhold 			// write the data
285*98da112cSIngo Weinhold 			if (error == B_OK) {
286*98da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
287*98da112cSIngo Weinhold 								   B_MIME_STRING_TYPE, signature,
288*98da112cSIngo Weinhold 								   signatureLen + 1);
289*98da112cSIngo Weinhold 			}
290*98da112cSIngo Weinhold 		} else
291*98da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
292*98da112cSIngo Weinhold 	}
293*98da112cSIngo Weinhold 	return error;
294d6b205f3SIngo Weinhold }
295d6b205f3SIngo Weinhold 
296d6b205f3SIngo Weinhold // GetAppFlags
297d6b205f3SIngo Weinhold /*!	\brief Gets the file's application flags.
298d6b205f3SIngo Weinhold 
299d6b205f3SIngo Weinhold 	\param flags A pointer to a pre-allocated uint32 into which the application
300d6b205f3SIngo Weinhold 		   flags of the file shall be written.
301d6b205f3SIngo Weinhold 	\return
302d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
303d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
304d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a flags.
305d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the flags are stored in have
306d6b205f3SIngo Weinhold 	  the wrong type.
307d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No application flags are set on the file.
308d6b205f3SIngo Weinhold 	- other error codes
309d6b205f3SIngo Weinhold */
310d6b205f3SIngo Weinhold status_t
311d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32 *flags) const
312d6b205f3SIngo Weinhold {
313*98da112cSIngo Weinhold 	// check param and initialization
314*98da112cSIngo Weinhold 	status_t error = (flags ? B_OK : B_BAD_VALUE);
315*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
316*98da112cSIngo Weinhold 		error = B_NO_INIT;
317*98da112cSIngo Weinhold 	// read the data
318*98da112cSIngo Weinhold 	size_t read = 0;
319*98da112cSIngo Weinhold 	if (error == B_OK) {
320*98da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
321*98da112cSIngo Weinhold 						  B_APP_FLAGS_TYPE, flags, sizeof(uint32),
322*98da112cSIngo Weinhold 						  read);
323*98da112cSIngo Weinhold 	}
324*98da112cSIngo Weinhold 	// check the read data
325*98da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
326*98da112cSIngo Weinhold 		error = B_ERROR;
327*98da112cSIngo Weinhold 	return error;
328d6b205f3SIngo Weinhold }
329d6b205f3SIngo Weinhold 
330d6b205f3SIngo Weinhold // SetAppFlags
331d6b205f3SIngo Weinhold /*!	\brief Sets the file's application flags.
332d6b205f3SIngo Weinhold 	\param flags The application flags to be assigned to the file.
333d6b205f3SIngo Weinhold 	\return
334d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
335d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
336d6b205f3SIngo Weinhold 	- other error codes
337d6b205f3SIngo Weinhold */
338d6b205f3SIngo Weinhold status_t
339d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
340d6b205f3SIngo Weinhold {
341*98da112cSIngo Weinhold 	// check initialization
342*98da112cSIngo Weinhold 	status_t error = B_OK;
343*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
344*98da112cSIngo Weinhold 		error = B_NO_INIT;
345*98da112cSIngo Weinhold 	if (error == B_OK) {
346*98da112cSIngo Weinhold 		// write the data
347*98da112cSIngo Weinhold 		if (error == B_OK) {
348*98da112cSIngo Weinhold 			error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
349*98da112cSIngo Weinhold 							   B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
350*98da112cSIngo Weinhold 		}
351*98da112cSIngo Weinhold 	}
352*98da112cSIngo Weinhold 	return error;
353d6b205f3SIngo Weinhold }
354d6b205f3SIngo Weinhold 
355d6b205f3SIngo Weinhold // GetSupportedTypes
356d6b205f3SIngo Weinhold /*!	\brief Gets the MIME types supported by the application.
357d6b205f3SIngo Weinhold 
358d6b205f3SIngo Weinhold 	The supported MIME types are added to a field "types" of type
359d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
360d6b205f3SIngo Weinhold 
361d6b205f3SIngo Weinhold 	\param types A pointer to a pre-allocated BMessage into which the
362d6b205f3SIngo Weinhold 		   MIME types supported by the appplication shall be written.
363d6b205f3SIngo Weinhold 	\return
364d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
365d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
366d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a types.
367d6b205f3SIngo Weinhold 	- \c B_BAD_TYPE: The attribute/resources the supported types are stored in
368d6b205f3SIngo Weinhold 	  have the wrong type.
369d6b205f3SIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: No supported types are set on the file.
370d6b205f3SIngo Weinhold 	- other error codes
371d6b205f3SIngo Weinhold */
372d6b205f3SIngo Weinhold status_t
373d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage *types) const
374d6b205f3SIngo Weinhold {
375*98da112cSIngo Weinhold 	// check param and initialization
376*98da112cSIngo Weinhold 	status_t error = (types ? B_OK : B_BAD_VALUE);
377*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
378*98da112cSIngo Weinhold 		error = B_NO_INIT;
379*98da112cSIngo Weinhold 	// read the data
380*98da112cSIngo Weinhold 	size_t read = 0;
381*98da112cSIngo Weinhold 	void *buffer = NULL;
382*98da112cSIngo Weinhold 	if (error == B_OK) {
383*98da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
384*98da112cSIngo Weinhold 						  B_MESSAGE_TYPE, NULL, 0, read, &buffer);
385*98da112cSIngo Weinhold 	}
386*98da112cSIngo Weinhold 	// unflatten the buffer
387*98da112cSIngo Weinhold 	if (error == B_OK)
388*98da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
389*98da112cSIngo Weinhold 	// clean up
390*98da112cSIngo Weinhold 	if (buffer)
391*98da112cSIngo Weinhold 		free(buffer);
392*98da112cSIngo Weinhold 	return error;
393d6b205f3SIngo Weinhold }
394d6b205f3SIngo Weinhold 
395d6b205f3SIngo Weinhold // SetSupportedTypes
396d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
397d6b205f3SIngo Weinhold 
398d6b205f3SIngo Weinhold 	If \a types is \c NULL the application's supported types are unset.
399d6b205f3SIngo Weinhold 
400d6b205f3SIngo Weinhold 	The supported MIME types must be stored in a field "types" of type
401d6b205f3SIngo Weinhold 	\c B_STRING_TYPE in \a types.
402d6b205f3SIngo Weinhold 
40383a812a1SIngo Weinhold 	The method informs the registrar about this news.
40483a812a1SIngo Weinhold 	For each supported type the result of BMimeType::GetSupportingApps() will
40583a812a1SIngo Weinhold 	afterwards include the signature of this application. That is, the
40683a812a1SIngo Weinhold 	application file needs to have a signature set.
40783a812a1SIngo Weinhold 
40883a812a1SIngo Weinhold 	\a syncAll specifies whether the not longer supported types shall be
40983a812a1SIngo Weinhold 	updated as well, i.e. whether this application shall be remove from the
41083a812a1SIngo Weinhold 	lists of supporting applications.
41183a812a1SIngo Weinhold 
412d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
413d6b205f3SIngo Weinhold 		   May be \c NULL.
41483a812a1SIngo Weinhold 	\param syncAll \c true to also synchronize the not longer supported
41583a812a1SIngo Weinhold 		   types, \c false otherwise.
416d6b205f3SIngo Weinhold 	\return
417d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
418d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
419d6b205f3SIngo Weinhold 	- other error codes
420d6b205f3SIngo Weinhold */
421d6b205f3SIngo Weinhold status_t
422d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types, bool syncAll)
423d6b205f3SIngo Weinhold {
424*98da112cSIngo Weinhold 	// check initialization
425*98da112cSIngo Weinhold 	status_t error = B_OK;
426*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
427*98da112cSIngo Weinhold 		error = B_NO_INIT;
428*98da112cSIngo Weinhold 	BMimeType mimeType;
429*98da112cSIngo Weinhold 	if (error == B_OK)
430*98da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
431*98da112cSIngo Weinhold 	if (error == B_OK) {
432*98da112cSIngo Weinhold 		if (types) {
433*98da112cSIngo Weinhold 			// check param
434*98da112cSIngo Weinhold 			ssize_t size = types->FlattenedSize();
435*98da112cSIngo Weinhold 			if (size < 0)
436*98da112cSIngo Weinhold 				error = size;
437*98da112cSIngo Weinhold 			// allocate a buffer for the flattened data
438*98da112cSIngo Weinhold 			char *buffer = NULL;
439*98da112cSIngo Weinhold 			if (error == B_OK) {
440*98da112cSIngo Weinhold 				buffer = new(nothrow) char[size];
441*98da112cSIngo Weinhold 				if (!buffer)
442*98da112cSIngo Weinhold 					error = B_NO_MEMORY;
443*98da112cSIngo Weinhold 			}
444*98da112cSIngo Weinhold 			// flatten the message
445*98da112cSIngo Weinhold 			if (error == B_OK)
446*98da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
447*98da112cSIngo Weinhold 			// write the data
448*98da112cSIngo Weinhold 			if (error == B_OK) {
449*98da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
450*98da112cSIngo Weinhold 								   kSupportedTypesResourceID, B_MESSAGE_TYPE,
451*98da112cSIngo Weinhold 								   buffer, size);
452*98da112cSIngo Weinhold 			}
453*98da112cSIngo Weinhold 			// clean up
454*98da112cSIngo Weinhold 			if (buffer)
455*98da112cSIngo Weinhold 				delete[] buffer;
456*98da112cSIngo Weinhold 		} else
457*98da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
458*98da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
459*98da112cSIngo Weinhold 		if (mimeType.IsInstalled()) {
460*98da112cSIngo Weinhold 			// create a set of the removed types
461*98da112cSIngo Weinhold 			set<string> oldTypes;
462*98da112cSIngo Weinhold 			if (syncAll) {
463*98da112cSIngo Weinhold 				BMessage oldTypeMsg;
464*98da112cSIngo Weinhold 				error = mimeType.GetSupportedTypes(&oldTypeMsg);
465*98da112cSIngo Weinhold 				// add all formerly supported types to the set
466*98da112cSIngo Weinhold 				if (error == B_OK) {
467*98da112cSIngo Weinhold 					BString type;
468*98da112cSIngo Weinhold 					for (int32 i = 0;
469*98da112cSIngo Weinhold 						 oldTypeMsg.FindString("types", i, &type) == B_OK;
470*98da112cSIngo Weinhold 						 i++) {
471*98da112cSIngo Weinhold 						oldTypes.insert(string(type.ToLower().String()));
472*98da112cSIngo Weinhold 					}
473*98da112cSIngo Weinhold 				}
474*98da112cSIngo Weinhold 				// remove the newly supported types from the set
475*98da112cSIngo Weinhold 				if (error == B_OK && types) {
476*98da112cSIngo Weinhold 					BString type;
477*98da112cSIngo Weinhold 					for (int32 i = 0;
478*98da112cSIngo Weinhold 						 types->FindString("types", i, &type) == B_OK;
479*98da112cSIngo Weinhold 						 i++) {
480*98da112cSIngo Weinhold 						oldTypes.erase(string(type.ToLower().String()));
481*98da112cSIngo Weinhold 					}
482*98da112cSIngo Weinhold 				}
483*98da112cSIngo Weinhold 			}
484*98da112cSIngo Weinhold 			// create and send the message
485*98da112cSIngo Weinhold 			if (error == B_OK && oldTypes.size() > 0) {
486*98da112cSIngo Weinhold 				BMessage message(B_REG_MIME_UNSUPPORT_TYPES);
487*98da112cSIngo Weinhold 				error = message.AddString("type", mimeType.Type());
488*98da112cSIngo Weinhold 				for (set<string>::iterator it = oldTypes.begin();
489*98da112cSIngo Weinhold 					 error == B_OK && it != oldTypes.end();
490*98da112cSIngo Weinhold 					 it++) {
491*98da112cSIngo Weinhold 					error = message.AddString("unsupported_types",
492*98da112cSIngo Weinhold 											  it->c_str());
493*98da112cSIngo Weinhold 				}
494*98da112cSIngo Weinhold 				BMessage reply;
495*98da112cSIngo Weinhold 				if (error == B_OK)
496*98da112cSIngo Weinhold 					error = _send_to_roster_(&message, &reply, true);
497*98da112cSIngo Weinhold 				if (error == B_OK)
498*98da112cSIngo Weinhold 					error = (reply.what == B_REG_RESULT ? B_OK : B_BAD_VALUE);
499*98da112cSIngo Weinhold 				status_t result;
500*98da112cSIngo Weinhold 				if (error == B_OK)
501*98da112cSIngo Weinhold 					error = reply.FindInt32("result", &result);
502*98da112cSIngo Weinhold 				if (error == B_OK)
503*98da112cSIngo Weinhold 					error = result;
504*98da112cSIngo Weinhold 			}
505*98da112cSIngo Weinhold 			// set the type's supported types
506*98da112cSIngo Weinhold 			if (error == B_OK)
507*98da112cSIngo Weinhold 				error = mimeType.SetSupportedTypes(types);
508*98da112cSIngo Weinhold 		}
509*98da112cSIngo Weinhold 	}
510*98da112cSIngo Weinhold 	return error;
511d6b205f3SIngo Weinhold }
512d6b205f3SIngo Weinhold 
513d6b205f3SIngo Weinhold // SetSupportedTypes
514d6b205f3SIngo Weinhold /*!	\brief Sets the MIME types supported by the application.
515d6b205f3SIngo Weinhold 
516*98da112cSIngo Weinhold 	This method is a short-hand for SetSupportedTypes(types, false).
51783a812a1SIngo Weinhold 	\see SetSupportedType(const BMessage*, bool) for detailed information.
518d6b205f3SIngo Weinhold 
519d6b205f3SIngo Weinhold 	\param types The supported types to be assigned to the file.
520d6b205f3SIngo Weinhold 		   May be \c NULL.
521d6b205f3SIngo Weinhold 	\return
522d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
523d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
524d6b205f3SIngo Weinhold 	- other error codes
525d6b205f3SIngo Weinhold */
526d6b205f3SIngo Weinhold status_t
527d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage *types)
528d6b205f3SIngo Weinhold {
529*98da112cSIngo Weinhold 	return SetSupportedTypes(types, false);
530d6b205f3SIngo Weinhold }
531d6b205f3SIngo Weinhold 
532d6b205f3SIngo Weinhold // IsSupportedType
533d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type.
534d6b205f3SIngo Weinhold 
535d6b205f3SIngo Weinhold 	If the application supports the wildcard type "application/octet-stream"
536d6b205f3SIngo Weinhold 	any this method returns \c true for any MIME type.
537d6b205f3SIngo Weinhold 
538d6b205f3SIngo Weinhold 	\param type The MIME type in question.
539d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is supported by
540d6b205f3SIngo Weinhold 			the application, \c false otherwise.
541d6b205f3SIngo Weinhold */
542d6b205f3SIngo Weinhold bool
543d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char *type) const
544d6b205f3SIngo Weinhold {
545*98da112cSIngo Weinhold 	status_t error = (type ? B_OK : B_BAD_VALUE);
546*98da112cSIngo Weinhold 	// get the supported types
547*98da112cSIngo Weinhold 	BMessage types;
548*98da112cSIngo Weinhold 	if (error == B_OK)
549*98da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
550*98da112cSIngo Weinhold 	// turn type into a BMimeType
551*98da112cSIngo Weinhold 	BMimeType mimeType;
552*98da112cSIngo Weinhold 	if (error == B_OK)
553*98da112cSIngo Weinhold 		error = mimeType.SetTo(type);
554*98da112cSIngo Weinhold 	// iterate through the supported types
555*98da112cSIngo Weinhold 	bool found = false;
556*98da112cSIngo Weinhold 	if (error == B_OK) {
557*98da112cSIngo Weinhold 		const char *supportedType;
558*98da112cSIngo Weinhold 		for (int32 i = 0;
559*98da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
560*98da112cSIngo Weinhold 			 i++) {
561*98da112cSIngo Weinhold 			found = !strcmp(supportedType, "application/octet-stream")
562*98da112cSIngo Weinhold 					|| BMimeType(supportedType).Contains(&mimeType);
563*98da112cSIngo Weinhold 		}
564*98da112cSIngo Weinhold 	}
565*98da112cSIngo Weinhold 	return found;
566d6b205f3SIngo Weinhold }
567d6b205f3SIngo Weinhold 
568d6b205f3SIngo Weinhold // Supports
569d6b205f3SIngo Weinhold /*!	\brief Returns whether the application supports the supplied MIME type
570d6b205f3SIngo Weinhold 		   explicitly.
571d6b205f3SIngo Weinhold 
572d6b205f3SIngo Weinhold 	Unlike IsSupportedType(), this method returns \c true, only if the type
573d6b205f3SIngo Weinhold 	is explicitly supported, regardless of whether it supports
574d6b205f3SIngo Weinhold 	"application/octet-stream".
575d6b205f3SIngo Weinhold 
576d6b205f3SIngo Weinhold 	\param type The MIME type in question.
577d6b205f3SIngo Weinhold 	\return \c true, if \a type is a valid MIME type and it is explicitly
578d6b205f3SIngo Weinhold 			supported by the application, \c false otherwise.
579d6b205f3SIngo Weinhold */
580d6b205f3SIngo Weinhold bool
581d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType *type) const
582d6b205f3SIngo Weinhold {
583*98da112cSIngo Weinhold 	status_t error = (type && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE);
584*98da112cSIngo Weinhold 	// get the supported types
585*98da112cSIngo Weinhold 	BMessage types;
586*98da112cSIngo Weinhold 	if (error == B_OK)
587*98da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
588*98da112cSIngo Weinhold 	// iterate through the supported types
589*98da112cSIngo Weinhold 	bool found = false;
590*98da112cSIngo Weinhold 	if (error == B_OK) {
591*98da112cSIngo Weinhold 		const char *supportedType;
592*98da112cSIngo Weinhold 		for (int32 i = 0;
593*98da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
594*98da112cSIngo Weinhold 			 i++) {
595*98da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
596*98da112cSIngo Weinhold 		}
597*98da112cSIngo Weinhold 	}
598*98da112cSIngo Weinhold 	return found;
599d6b205f3SIngo Weinhold }
600d6b205f3SIngo Weinhold 
601d6b205f3SIngo Weinhold // GetIcon
602d6b205f3SIngo Weinhold /*!	\brief Gets the file's icon.
603d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
604d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
605d6b205f3SIngo Weinhold 		   large icon).
606d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
607d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
608d6b205f3SIngo Weinhold 	\return
609d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
610d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
611d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size \a which or bitmap
612d6b205f3SIngo Weinhold 		 dimensions (\a icon) and icon size (\a which) do not match.
613d6b205f3SIngo Weinhold 	- other error codes
614d6b205f3SIngo Weinhold */
615d6b205f3SIngo Weinhold status_t
616d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap *icon, icon_size which) const
617d6b205f3SIngo Weinhold {
618*98da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
619d6b205f3SIngo Weinhold }
620d6b205f3SIngo Weinhold 
621d6b205f3SIngo Weinhold // SetIcon
622d6b205f3SIngo Weinhold /*!	\brief Sets the file's icon.
623d6b205f3SIngo Weinhold 
624d6b205f3SIngo Weinhold 	If \a icon is \c NULL the file's icon is unset.
625d6b205f3SIngo Weinhold 
626d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
627d6b205f3SIngo Weinhold 		   May be \c NULL.
628d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
629d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
630d6b205f3SIngo Weinhold 	\return
631d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
632d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
633d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
634d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
635d6b205f3SIngo Weinhold 	- other error codes
636d6b205f3SIngo Weinhold */
637d6b205f3SIngo Weinhold status_t
638d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap *icon, icon_size which)
639d6b205f3SIngo Weinhold {
640*98da112cSIngo Weinhold 	return SetIconForType(NULL, icon, which);
641d6b205f3SIngo Weinhold }
642d6b205f3SIngo Weinhold 
643d6b205f3SIngo Weinhold // GetVersionInfo
644d6b205f3SIngo Weinhold /*!	\brief Gets the file's version info.
645d6b205f3SIngo Weinhold 	\param info A pointer to a pre-allocated version_info structure into which
646d6b205f3SIngo Weinhold 		   the version info should be written.
647d6b205f3SIngo Weinhold 	\param kind Specifies the kind of the version info to be retrieved:
648d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
649d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
650d6b205f3SIngo Weinhold 		   belongs to.
651d6b205f3SIngo Weinhold 	\return
652d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
653d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
654d6b205f3SIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a info.
655d6b205f3SIngo Weinhold 	- other error codes
656d6b205f3SIngo Weinhold */
657d6b205f3SIngo Weinhold status_t
658d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info *info, version_kind kind) const
659d6b205f3SIngo Weinhold {
660*98da112cSIngo Weinhold 	// check params and initialization
661*98da112cSIngo Weinhold 	status_t error = (info ? B_OK : B_BAD_VALUE);
662*98da112cSIngo Weinhold 	int32 index = 0;
663*98da112cSIngo Weinhold 	if (error == B_OK) {
664*98da112cSIngo Weinhold 		switch (kind) {
665*98da112cSIngo Weinhold 			case B_APP_VERSION_KIND:
666*98da112cSIngo Weinhold 				index = 0;
667*98da112cSIngo Weinhold 				break;
668*98da112cSIngo Weinhold 			case B_SYSTEM_VERSION_KIND:
669*98da112cSIngo Weinhold 				index = 1;
670*98da112cSIngo Weinhold 				break;
671*98da112cSIngo Weinhold 			default:
672*98da112cSIngo Weinhold 				error = B_BAD_VALUE;
673*98da112cSIngo Weinhold 				break;
674*98da112cSIngo Weinhold 		}
675*98da112cSIngo Weinhold 	}
676*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
677*98da112cSIngo Weinhold 		error = B_NO_INIT;
678*98da112cSIngo Weinhold 	// read the data
679*98da112cSIngo Weinhold 	size_t read = 0;
680*98da112cSIngo Weinhold 	version_info infos[2];
681*98da112cSIngo Weinhold 	if (error == B_OK) {
682*98da112cSIngo Weinhold 		error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
683*98da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
684*98da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
685*98da112cSIngo Weinhold 	}
686*98da112cSIngo Weinhold 	// check the read data -- null terminate the string
687*98da112cSIngo Weinhold 	if (error == B_OK && read != 2 * sizeof(version_info))
688*98da112cSIngo Weinhold 		error = B_ERROR;
689*98da112cSIngo Weinhold 	if (error == B_OK)
690*98da112cSIngo Weinhold 		*info = infos[index];
691*98da112cSIngo Weinhold 	return error;
692d6b205f3SIngo Weinhold }
693d6b205f3SIngo Weinhold 
694d6b205f3SIngo Weinhold // SetVersionInfo
695d6b205f3SIngo Weinhold /*!	\brief Sets the file's version info.
696d6b205f3SIngo Weinhold 
697d6b205f3SIngo Weinhold 	If \a info is \c NULL the file's version info is unset.
698d6b205f3SIngo Weinhold 
699d6b205f3SIngo Weinhold 	\param info The version info to be set. May be \c NULL.
700d6b205f3SIngo Weinhold 	\param kind Specifies kind of version info to be set:
701d6b205f3SIngo Weinhold 		   \c B_APP_VERSION_KIND for the application's version info and
702d6b205f3SIngo Weinhold 		   \c B_SYSTEM_VERSION_KIND for the suite's info the application
703d6b205f3SIngo Weinhold 		   belongs to.
704d6b205f3SIngo Weinhold 	\return
705d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
706d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
707d6b205f3SIngo Weinhold 	- other error codes
708d6b205f3SIngo Weinhold */
709d6b205f3SIngo Weinhold status_t
710d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info *info, version_kind kind)
711d6b205f3SIngo Weinhold {
712*98da112cSIngo Weinhold 	// check initialization
713*98da112cSIngo Weinhold 	status_t error = B_OK;
714*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
715*98da112cSIngo Weinhold 		error = B_NO_INIT;
716*98da112cSIngo Weinhold 	if (error == B_OK) {
717*98da112cSIngo Weinhold 		if (info) {
718*98da112cSIngo Weinhold 			// check param
719*98da112cSIngo Weinhold 			int32 index = 0;
720*98da112cSIngo Weinhold 			if (error == B_OK) {
721*98da112cSIngo Weinhold 				switch (kind) {
722*98da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
723*98da112cSIngo Weinhold 						index = 0;
724*98da112cSIngo Weinhold 						break;
725*98da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
726*98da112cSIngo Weinhold 						index = 1;
727*98da112cSIngo Weinhold 						break;
728*98da112cSIngo Weinhold 					default:
729*98da112cSIngo Weinhold 						error = B_BAD_VALUE;
730*98da112cSIngo Weinhold 						break;
731*98da112cSIngo Weinhold 				}
732*98da112cSIngo Weinhold 			}
733*98da112cSIngo Weinhold 			// read both infos
734*98da112cSIngo Weinhold 			version_info infos[2];
735*98da112cSIngo Weinhold 			if (error == B_OK) {
736*98da112cSIngo Weinhold 				size_t read;
737*98da112cSIngo Weinhold 				_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
738*98da112cSIngo Weinhold 						  B_VERSION_INFO_TYPE, infos,
739*98da112cSIngo Weinhold 						  2 * sizeof(version_info), read);
740*98da112cSIngo Weinhold 			}
741*98da112cSIngo Weinhold 			infos[index] = *info;
742*98da112cSIngo Weinhold 			// write the data
743*98da112cSIngo Weinhold 			if (error == B_OK) {
744*98da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
745*98da112cSIngo Weinhold 								   kVersionInfoResourceID,
746*98da112cSIngo Weinhold 								   B_VERSION_INFO_TYPE, infos,
747*98da112cSIngo Weinhold 								   2 * sizeof(version_info));
748*98da112cSIngo Weinhold 			}
749*98da112cSIngo Weinhold 		} else
750*98da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
751*98da112cSIngo Weinhold 	}
752*98da112cSIngo Weinhold 	return error;
753d6b205f3SIngo Weinhold }
754d6b205f3SIngo Weinhold 
755d6b205f3SIngo Weinhold // GetIconForType
756d6b205f3SIngo Weinhold /*!	\brief Gets the icon the application provides for a given MIME type.
757*98da112cSIngo Weinhold 
758*98da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is retrieved.
759*98da112cSIngo Weinhold 
760*98da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
761d6b205f3SIngo Weinhold 	\param icon A pointer to a pre-allocated BBitmap of the correct dimension
762d6b205f3SIngo Weinhold 		   to store the requested icon (16x16 for the mini and 32x32 for the
763d6b205f3SIngo Weinhold 		   large icon).
764d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be retrieved:
765d6b205f3SIngo Weinhold 		   \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon.
766d6b205f3SIngo Weinhold 	\return
767d6b205f3SIngo Weinhold 	- \c B_OK: Everything went fine.
768d6b205f3SIngo Weinhold 	- \c B_NO_INIT: The object is not properly initialized.
769*98da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a icon, unsupported icon size
770d6b205f3SIngo Weinhold 		 \a which or bitmap dimensions (\a icon) and icon size (\a which) do
771d6b205f3SIngo Weinhold 		 not match.
772d6b205f3SIngo Weinhold 	- other error codes
773d6b205f3SIngo Weinhold */
774d6b205f3SIngo Weinhold status_t
775d6b205f3SIngo Weinhold BAppFileInfo::GetIconForType(const char *type, BBitmap *icon,
776d6b205f3SIngo Weinhold 							 icon_size which) const
777d6b205f3SIngo Weinhold {
778*98da112cSIngo Weinhold 	status_t error = B_OK;
779*98da112cSIngo Weinhold 	// set some icon size related variables
780*98da112cSIngo Weinhold 	BString attributeString;
781*98da112cSIngo Weinhold 	BRect bounds;
782*98da112cSIngo Weinhold 	uint32 attrType;
783*98da112cSIngo Weinhold 	size_t attrSize;
784*98da112cSIngo Weinhold 	switch (which) {
785*98da112cSIngo Weinhold 		case B_MINI_ICON:
786*98da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
787*98da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
788*98da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
789*98da112cSIngo Weinhold 			attrSize = 16 * 16;
790*98da112cSIngo Weinhold 			break;
791*98da112cSIngo Weinhold 		case B_LARGE_ICON:
792*98da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
793*98da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
794*98da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
795*98da112cSIngo Weinhold 			attrSize = 32 * 32;
796*98da112cSIngo Weinhold 			break;
797*98da112cSIngo Weinhold 		default:
798*98da112cSIngo Weinhold 			error = B_BAD_VALUE;
799*98da112cSIngo Weinhold 			break;
800*98da112cSIngo Weinhold 	}
801*98da112cSIngo Weinhold 	// check type param
802*98da112cSIngo Weinhold 	if (error == B_OK) {
803*98da112cSIngo Weinhold 		if (type) {
804*98da112cSIngo Weinhold 			if (strlen(type) >= B_MIME_TYPE_LENGTH)
805*98da112cSIngo Weinhold 				error = B_BAD_VALUE;
806*98da112cSIngo Weinhold 		} else
807*98da112cSIngo Weinhold 			type = kStandardIconType;
808*98da112cSIngo Weinhold 	}
809*98da112cSIngo Weinhold 	if (error == B_OK)
810*98da112cSIngo Weinhold 		attributeString += type;
811*98da112cSIngo Weinhold 	const char *attribute = attributeString.String();
812*98da112cSIngo Weinhold 	// check parameter and initialization
813*98da112cSIngo Weinhold 	if (error == B_OK
814*98da112cSIngo Weinhold 		&& (!icon || icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
815*98da112cSIngo Weinhold 		error = B_BAD_VALUE;
816*98da112cSIngo Weinhold 	}
817*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
818*98da112cSIngo Weinhold 		error = B_NO_INIT;
819*98da112cSIngo Weinhold 	// read the data
820*98da112cSIngo Weinhold 	if (error == B_OK) {
821*98da112cSIngo Weinhold 		bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
822*98da112cSIngo Weinhold 		char *buffer = NULL;
823*98da112cSIngo Weinhold 		size_t read;
824*98da112cSIngo Weinhold 		if (otherColorSpace) {
825*98da112cSIngo Weinhold 			// other color space than stored in attribute
826*98da112cSIngo Weinhold 			buffer = new(nothrow) char[attrSize];
827*98da112cSIngo Weinhold 			if (!buffer)
828*98da112cSIngo Weinhold 				error = B_NO_MEMORY;
829*98da112cSIngo Weinhold 			if (error == B_OK) {
830*98da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
831*98da112cSIngo Weinhold 								  read);
832*98da112cSIngo Weinhold 			}
833*98da112cSIngo Weinhold 		} else {
834*98da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
835*98da112cSIngo Weinhold 							  read);
836*98da112cSIngo Weinhold 		}
837*98da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
838*98da112cSIngo Weinhold 			error = B_ERROR;
839*98da112cSIngo Weinhold 		if (otherColorSpace) {
840*98da112cSIngo Weinhold 			// other color space than stored in attribute
841*98da112cSIngo Weinhold 			if (error == B_OK)
842*98da112cSIngo Weinhold 				icon->SetBits(buffer, attrSize, 0, B_CMAP8);
843*98da112cSIngo Weinhold 			delete[] buffer;
844*98da112cSIngo Weinhold 		}
845*98da112cSIngo Weinhold 	}
846*98da112cSIngo Weinhold 	return error;
847d6b205f3SIngo Weinhold }
848d6b205f3SIngo Weinhold 
849d6b205f3SIngo Weinhold // SetIconForType
850d6b205f3SIngo Weinhold /*!	\brief Sets the icon the application provides for a given MIME type.
851d6b205f3SIngo Weinhold 
852*98da112cSIngo Weinhold 	If \a type is \c NULL, the application's icon is set.
853d6b205f3SIngo Weinhold 	If \a icon is \c NULL the icon is unset.
854d6b205f3SIngo Weinhold 
855*98da112cSIngo Weinhold 	If the file has a signature, then the icon is also set on the MIME type.
856*98da112cSIngo Weinhold 	If the type for the signature has not been installed yet, it is installed
857*98da112cSIngo Weinhold 	before.
858*98da112cSIngo Weinhold 
859*98da112cSIngo Weinhold 	\param type The MIME type in question. May be \c NULL.
860d6b205f3SIngo Weinhold 	\param icon A pointer to the BBitmap containing the icon to be set.
861d6b205f3SIngo Weinhold 		   May be \c NULL.
862d6b205f3SIngo Weinhold 	\param which Specifies the size of the icon to be set: \c B_MINI_ICON
863d6b205f3SIngo Weinhold 		   for the mini and \c B_LARGE_ICON for the large icon.
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 	- \c B_BAD_VALUE: Unknown icon size \a which or bitmap dimensions (\a icon)
868d6b205f3SIngo Weinhold 		 and icon size (\a which) do not match.
869d6b205f3SIngo Weinhold 	- other error codes
870d6b205f3SIngo Weinhold */
871d6b205f3SIngo Weinhold status_t
872d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char *type, const BBitmap *icon,
873d6b205f3SIngo Weinhold 							 icon_size which)
874d6b205f3SIngo Weinhold {
875*98da112cSIngo Weinhold 	status_t error = B_OK;
876*98da112cSIngo Weinhold 	// set some icon size related variables
877*98da112cSIngo Weinhold 	BString attributeString;
878*98da112cSIngo Weinhold 	BRect bounds;
879*98da112cSIngo Weinhold 	uint32 attrType;
880*98da112cSIngo Weinhold 	size_t attrSize;
881*98da112cSIngo Weinhold 	int32 resourceID;
882*98da112cSIngo Weinhold 	switch (which) {
883*98da112cSIngo Weinhold 		case B_MINI_ICON:
884*98da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
885*98da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
886*98da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
887*98da112cSIngo Weinhold 			attrSize = 16 * 16;
888*98da112cSIngo Weinhold 			resourceID = (type ? kMiniIconForTypeResourceID
889*98da112cSIngo Weinhold 							   : kMiniIconResourceID);
890*98da112cSIngo Weinhold 			break;
891*98da112cSIngo Weinhold 		case B_LARGE_ICON:
892*98da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
893*98da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
894*98da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
895*98da112cSIngo Weinhold 			attrSize = 32 * 32;
896*98da112cSIngo Weinhold 			resourceID = (type ? kLargeIconForTypeResourceID
897*98da112cSIngo Weinhold 							   : kLargeIconResourceID);
898*98da112cSIngo Weinhold 			break;
899*98da112cSIngo Weinhold 		default:
900*98da112cSIngo Weinhold 			error = B_BAD_VALUE;
901*98da112cSIngo Weinhold 			break;
902*98da112cSIngo Weinhold 	}
903*98da112cSIngo Weinhold 	// check type param
904*98da112cSIngo Weinhold 	if (error == B_OK) {
905*98da112cSIngo Weinhold 		if (type) {
906*98da112cSIngo Weinhold 			if (strlen(type) >= B_MIME_TYPE_LENGTH)
907*98da112cSIngo Weinhold 				error = B_BAD_VALUE;
908*98da112cSIngo Weinhold 			else
909*98da112cSIngo Weinhold 				attributeString += type;
910*98da112cSIngo Weinhold 		} else
911*98da112cSIngo Weinhold 			attributeString += kStandardIconType;
912*98da112cSIngo Weinhold 	}
913*98da112cSIngo Weinhold 	const char *attribute = attributeString.String();
914*98da112cSIngo Weinhold 	// check parameter and initialization
915*98da112cSIngo Weinhold 	if (error == B_OK && icon
916*98da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
917*98da112cSIngo Weinhold 		error = B_BAD_VALUE;
918*98da112cSIngo Weinhold 	}
919*98da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
920*98da112cSIngo Weinhold 		error = B_NO_INIT;
921*98da112cSIngo Weinhold 	// write/remove the attribute
922*98da112cSIngo Weinhold 	if (error == B_OK) {
923*98da112cSIngo Weinhold 		if (icon) {
924*98da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
925*98da112cSIngo Weinhold 			if (otherColorSpace) {
926*98da112cSIngo Weinhold 				BBitmap bitmap(bounds, B_CMAP8);
927*98da112cSIngo Weinhold 				error = bitmap.InitCheck();
928*98da112cSIngo Weinhold 				if (error == B_OK) {
929*98da112cSIngo Weinhold 					bitmap.SetBits(icon->Bits(), 0, attrSize, B_CMAP8);
930*98da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
931*98da112cSIngo Weinhold 									   bitmap.Bits(), attrSize, true);
932*98da112cSIngo Weinhold 				}
933*98da112cSIngo Weinhold 			} else {
934*98da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
935*98da112cSIngo Weinhold 								   icon->Bits(), attrSize, true);
936*98da112cSIngo Weinhold 			}
937*98da112cSIngo Weinhold 		} else	// no icon given => remove
938*98da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
939*98da112cSIngo Weinhold 	}
940*98da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
941*98da112cSIngo Weinhold 	BMimeType mimeType;
942*98da112cSIngo Weinhold 	if (error == B_OK && GetMetaMime(&mimeType) == B_OK) {
943*98da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
944*98da112cSIngo Weinhold 			error = mimeType.Install();
945*98da112cSIngo Weinhold 		if (error == B_OK)
946*98da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
947*98da112cSIngo Weinhold 	}
948*98da112cSIngo Weinhold 	return error;
949d6b205f3SIngo Weinhold }
950d6b205f3SIngo Weinhold 
951d6b205f3SIngo Weinhold // SetInfoLocation
952d6b205f3SIngo Weinhold /*!	\brief Specifies the location where the meta data shall be stored.
953d6b205f3SIngo Weinhold 
954d6b205f3SIngo Weinhold 	The options for \a location are:
955d6b205f3SIngo Weinhold 	- \c B_USE_ATTRIBUTES: Store the data in the attributes.
956d6b205f3SIngo Weinhold 	- \c B_USE_RESOURCES: Store the data in the resources.
957d6b205f3SIngo Weinhold 	- \c B_USE_BOTH_LOCATIONS: Store the data in attributes and resources.
958d6b205f3SIngo Weinhold 
959d6b205f3SIngo Weinhold 	\param location The location where the meta data shall be stored.
960d6b205f3SIngo Weinhold */
961d6b205f3SIngo Weinhold void
962d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
963d6b205f3SIngo Weinhold {
964*98da112cSIngo Weinhold 	fWhere = location;
965d6b205f3SIngo Weinhold }
966d6b205f3SIngo Weinhold 
967d6b205f3SIngo Weinhold // IsUsingAttributes
968d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
969d6b205f3SIngo Weinhold 		   file's attributes.
970d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
971d6b205f3SIngo Weinhold 			attributes, \c false otherwise.
972d6b205f3SIngo Weinhold */
973d6b205f3SIngo Weinhold bool
974d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
975d6b205f3SIngo Weinhold {
976*98da112cSIngo Weinhold 	return (fWhere & B_USE_ATTRIBUTES);
977d6b205f3SIngo Weinhold }
978d6b205f3SIngo Weinhold 
979d6b205f3SIngo Weinhold // IsUsingResources
980d6b205f3SIngo Weinhold /*!	\brief Returns whether the object stores the meta data (also) in the
981d6b205f3SIngo Weinhold 		   file's resources.
982d6b205f3SIngo Weinhold 	\return \c true, if the meta data are (also) stored in the file's
983d6b205f3SIngo Weinhold 			resources, \c false otherwise.
984d6b205f3SIngo Weinhold */
985d6b205f3SIngo Weinhold bool
986d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
987d6b205f3SIngo Weinhold {
988*98da112cSIngo Weinhold 	return (fWhere & B_USE_RESOURCES);
989d6b205f3SIngo Weinhold }
990d6b205f3SIngo Weinhold 
991d6b205f3SIngo Weinhold // FBC
992d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
993d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
994d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
995d6b205f3SIngo Weinhold 
996d6b205f3SIngo Weinhold // =
997d6b205f3SIngo Weinhold /*!	\brief Privatized assignment operator to prevent usage.
998d6b205f3SIngo Weinhold */
999d6b205f3SIngo Weinhold BAppFileInfo &
1000d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo &)
1001d6b205f3SIngo Weinhold {
1002d6b205f3SIngo Weinhold 	return *this;
1003d6b205f3SIngo Weinhold }
1004d6b205f3SIngo Weinhold 
1005d6b205f3SIngo Weinhold // copy constructor
1006d6b205f3SIngo Weinhold /*!	\brief Privatized copy constructor to prevent usage.
1007d6b205f3SIngo Weinhold */
1008d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo &)
1009d6b205f3SIngo Weinhold {
1010d6b205f3SIngo Weinhold }
1011d6b205f3SIngo Weinhold 
1012*98da112cSIngo Weinhold // GetMetaMime
1013*98da112cSIngo Weinhold /*!	\brief Initializes a BMimeType to the file's signature.
1014*98da112cSIngo Weinhold 
1015*98da112cSIngo Weinhold 	The parameter \a meta is not checked.
1016*98da112cSIngo Weinhold 
1017*98da112cSIngo Weinhold 	\param meta A pointer to a pre-allocated BMimeType that shall be
1018*98da112cSIngo Weinhold 		   initialized to the file's signature.
1019*98da112cSIngo Weinhold 	\return
1020*98da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
1021*98da112cSIngo Weinhold 	- \c B_BAD_VALUE: \c NULL \a meta
1022*98da112cSIngo Weinhold 	- \c B_ENTRY_NOT_FOUND: The file has not signature or the signature is
1023*98da112cSIngo Weinhold (	  not installed in the MIME database.)
1024*98da112cSIngo Weinhold 	  no valid MIME string.
1025*98da112cSIngo Weinhold 	- other error codes
1026*98da112cSIngo Weinhold */
1027*98da112cSIngo Weinhold status_t
1028*98da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType *meta) const
1029*98da112cSIngo Weinhold {
1030*98da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
1031*98da112cSIngo Weinhold 	status_t error = GetSignature(signature);
1032*98da112cSIngo Weinhold 	if (error == B_OK)
1033*98da112cSIngo Weinhold 		error = meta->SetTo(signature);
1034*98da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
1035*98da112cSIngo Weinhold 		error = B_BAD_VALUE;
1036*98da112cSIngo Weinhold 	return error;
1037*98da112cSIngo Weinhold }
1038*98da112cSIngo Weinhold 
1039*98da112cSIngo Weinhold // _ReadData
1040*98da112cSIngo Weinhold /*!	\brief Reads data from an attribute or resource.
1041*98da112cSIngo Weinhold 
1042*98da112cSIngo Weinhold 	The data are read from the location specified by \a fWhere.
1043*98da112cSIngo Weinhold 
1044*98da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
1045*98da112cSIngo Weinhold 
1046*98da112cSIngo Weinhold 	\param name The name of the attribute/resource to be read.
1047*98da112cSIngo Weinhold 	\param id The resource ID of the resource to be read. Is ignored, when
1048*98da112cSIngo Weinhold 		   < 0.
1049*98da112cSIngo Weinhold 	\param type The type of the attribute/resource to be read.
1050*98da112cSIngo Weinhold 	\param buffer A pre-allocated buffer for the data to be read.
1051*98da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
1052*98da112cSIngo Weinhold 	\param bytesRead A reference parameter, set to the number of bytes
1053*98da112cSIngo Weinhold 		   actually read.
1054*98da112cSIngo Weinhold 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
1055*98da112cSIngo Weinhold 		   large enough too store the whole data and writes a pointer to it
1056*98da112cSIngo Weinhold 		   into this variable. If \c NULL, the supplied buffer is used.
1057*98da112cSIngo Weinhold 	\return
1058*98da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
1059*98da112cSIngo Weinhold 	- error code
1060*98da112cSIngo Weinhold */
1061*98da112cSIngo Weinhold status_t
1062*98da112cSIngo Weinhold BAppFileInfo::_ReadData(const char *name, int32 id, type_code type,
1063*98da112cSIngo Weinhold 						void *buffer, size_t bufferSize,
1064*98da112cSIngo Weinhold 						size_t &bytesRead, void **allocatedBuffer) const
1065*98da112cSIngo Weinhold {
1066*98da112cSIngo Weinhold 	status_t error = B_OK;
1067*98da112cSIngo Weinhold 	if (allocatedBuffer)
1068*98da112cSIngo Weinhold 		buffer = NULL;
1069*98da112cSIngo Weinhold 	if (IsUsingAttributes()) {
1070*98da112cSIngo Weinhold 		// get an attribute info
1071*98da112cSIngo Weinhold 		attr_info info;
1072*98da112cSIngo Weinhold 		if (error == B_OK)
1073*98da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1074*98da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
1075*98da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
1076*98da112cSIngo Weinhold 			error = B_BAD_VALUE;
1077*98da112cSIngo Weinhold 		if (allocatedBuffer) {
1078*98da112cSIngo Weinhold 			buffer = malloc(info.size);
1079*98da112cSIngo Weinhold 			if (!buffer)
1080*98da112cSIngo Weinhold 				error = B_NO_MEMORY;
1081*98da112cSIngo Weinhold 			bufferSize = info.size;
1082*98da112cSIngo Weinhold 		}
1083*98da112cSIngo Weinhold 		if (error == B_OK && bufferSize < info.size)
1084*98da112cSIngo Weinhold 			error = B_BAD_VALUE;
1085*98da112cSIngo Weinhold 		// read the data
1086*98da112cSIngo Weinhold 		if (error == B_OK) {
1087*98da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
1088*98da112cSIngo Weinhold 			if (read < 0)
1089*98da112cSIngo Weinhold 				error = read;
1090*98da112cSIngo Weinhold 			else if (read != info.size)
1091*98da112cSIngo Weinhold 				error = B_ERROR;
1092*98da112cSIngo Weinhold 			else
1093*98da112cSIngo Weinhold 				bytesRead = read;
1094*98da112cSIngo Weinhold 		}
1095*98da112cSIngo Weinhold 	} else if (IsUsingResources()) {
1096*98da112cSIngo Weinhold 		// get a resource info
1097*98da112cSIngo Weinhold 		int32 idFound;
1098*98da112cSIngo Weinhold 		size_t sizeFound;
1099*98da112cSIngo Weinhold 		if (error == B_OK) {
1100*98da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
1101*98da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
1102*98da112cSIngo Weinhold 		}
1103*98da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
1104*98da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
1105*98da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1106*98da112cSIngo Weinhold 		if (allocatedBuffer) {
1107*98da112cSIngo Weinhold 			buffer = malloc(sizeFound);
1108*98da112cSIngo Weinhold 			if (!buffer)
1109*98da112cSIngo Weinhold 				error = B_NO_MEMORY;
1110*98da112cSIngo Weinhold 			bufferSize = sizeFound;
1111*98da112cSIngo Weinhold 		}
1112*98da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
1113*98da112cSIngo Weinhold 			error = B_BAD_VALUE;
1114*98da112cSIngo Weinhold 		// load resource
1115*98da112cSIngo Weinhold 		const void *resourceData = NULL;
1116*98da112cSIngo Weinhold 		if (error == B_OK) {
1117*98da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
1118*98da112cSIngo Weinhold 			if (resourceData && sizeFound == bytesRead)
1119*98da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
1120*98da112cSIngo Weinhold 			else
1121*98da112cSIngo Weinhold 				error = B_ERROR;
1122*98da112cSIngo Weinhold 		}
1123*98da112cSIngo Weinhold 	} else
1124*98da112cSIngo Weinhold 		error = B_BAD_VALUE;
1125*98da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
1126*98da112cSIngo Weinhold 	if (allocatedBuffer) {
1127*98da112cSIngo Weinhold 		if (error == B_OK)
1128*98da112cSIngo Weinhold 			*allocatedBuffer = buffer;
1129*98da112cSIngo Weinhold 		else
1130*98da112cSIngo Weinhold 			free(buffer);
1131*98da112cSIngo Weinhold 	}
1132*98da112cSIngo Weinhold 	return error;
1133*98da112cSIngo Weinhold }
1134*98da112cSIngo Weinhold 
1135*98da112cSIngo Weinhold // _WriteData
1136*98da112cSIngo Weinhold /*!	\brief Writes data to an attribute or resource.
1137*98da112cSIngo Weinhold 
1138*98da112cSIngo Weinhold 	The data are written to the location(s) specified by \a fWhere.
1139*98da112cSIngo Weinhold 
1140*98da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
1141*98da112cSIngo Weinhold 
1142*98da112cSIngo Weinhold 	\param name The name of the attribute/resource to be written.
1143*98da112cSIngo Weinhold 	\param id The resource ID of the resource to be written.
1144*98da112cSIngo Weinhold 	\param type The type of the attribute/resource to be written.
1145*98da112cSIngo Weinhold 	\param buffer A buffer containing the data to be written.
1146*98da112cSIngo Weinhold 	\param bufferSize The size of the supplied buffer.
1147*98da112cSIngo Weinhold 	\param findID If set to \c true use the ID that is already assigned to the
1148*98da112cSIngo Weinhold 		   \a name / \a type pair or take the first unused ID >= \a id.
1149*98da112cSIngo Weinhold 		   If \c false, \a id is used.
1150*98da112cSIngo Weinhold 	If \a id is already in use and .
1151*98da112cSIngo Weinhold 	\return
1152*98da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
1153*98da112cSIngo Weinhold 	- error code
1154*98da112cSIngo Weinhold */
1155*98da112cSIngo Weinhold status_t
1156*98da112cSIngo Weinhold BAppFileInfo::_WriteData(const char *name, int32 id, type_code type,
1157*98da112cSIngo Weinhold 						 const void *buffer, size_t bufferSize, bool findID)
1158*98da112cSIngo Weinhold {
1159*98da112cSIngo Weinhold 	status_t error = B_OK;
1160*98da112cSIngo Weinhold 	// write to attribute
1161*98da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
1162*98da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
1163*98da112cSIngo Weinhold 		if (written < 0)
1164*98da112cSIngo Weinhold 			error = written;
1165*98da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
1166*98da112cSIngo Weinhold 			error = B_ERROR;
1167*98da112cSIngo Weinhold 	}
1168*98da112cSIngo Weinhold 	// write to resource
1169*98da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
1170*98da112cSIngo Weinhold 		if (findID) {
1171*98da112cSIngo Weinhold 			// get the resource info
1172*98da112cSIngo Weinhold 			int32 idFound;
1173*98da112cSIngo Weinhold 			size_t sizeFound;
1174*98da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
1175*98da112cSIngo Weinhold 				id = idFound;
1176*98da112cSIngo Weinhold 			else {
1177*98da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
1178*98da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
1179*98da112cSIngo Weinhold 					id++;
1180*98da112cSIngo Weinhold 			}
1181*98da112cSIngo Weinhold 		}
1182*98da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
1183*98da112cSIngo Weinhold 	}
1184*98da112cSIngo Weinhold 	return error;
1185*98da112cSIngo Weinhold }
1186*98da112cSIngo Weinhold 
1187*98da112cSIngo Weinhold // _RemoveData
1188*98da112cSIngo Weinhold /*!	\brief Removes an attribute or resource.
1189*98da112cSIngo Weinhold 
1190*98da112cSIngo Weinhold 	The removal location is specified by \a fWhere.
1191*98da112cSIngo Weinhold 
1192*98da112cSIngo Weinhold 	The object must be properly initialized. The parameters are NOT checked.
1193*98da112cSIngo Weinhold 
1194*98da112cSIngo Weinhold 	\param name The name of the attribute/resource to be remove.
1195*98da112cSIngo Weinhold 	\param type The type of the attribute/resource to be removed.
1196*98da112cSIngo Weinhold 	\return
1197*98da112cSIngo Weinhold 	- \c B_OK: Everything went fine.
1198*98da112cSIngo Weinhold 	- error code
1199*98da112cSIngo Weinhold */
1200*98da112cSIngo Weinhold status_t
1201*98da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char *name, type_code type)
1202*98da112cSIngo Weinhold {
1203*98da112cSIngo Weinhold 	status_t error = B_OK;
1204*98da112cSIngo Weinhold 	// remove the attribute
1205*98da112cSIngo Weinhold 	if (IsUsingAttributes() && error == B_OK) {
1206*98da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
1207*98da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
1208*98da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
1209*98da112cSIngo Weinhold 			error = B_OK;
1210*98da112cSIngo Weinhold 	}
1211*98da112cSIngo Weinhold 	// remove the resource
1212*98da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
1213*98da112cSIngo Weinhold 		// get a resource info
1214*98da112cSIngo Weinhold 		int32 idFound;
1215*98da112cSIngo Weinhold 		size_t sizeFound;
1216*98da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
1217*98da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
1218*98da112cSIngo Weinhold 	}
1219*98da112cSIngo Weinhold 	return error;
1220*98da112cSIngo Weinhold }
1221*98da112cSIngo Weinhold 
1222