xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision a30a4a41f948ebb03b95dab065a27a584ac0c97a)
131dc79a1SAxel Dörfler /*
23b07762cSIngo Weinhold  * Copyright 2002-2014, Haiku, Inc.
331dc79a1SAxel Dörfler  * Distributed under the terms of the MIT License.
431dc79a1SAxel Dörfler  *
531dc79a1SAxel Dörfler  * Authors:
63b07762cSIngo Weinhold  *		Ingo Weinhold, ingo_weinhold@gmx.de
721881ce5SIngo Weinhold  */
8d6b205f3SIngo Weinhold 
931dc79a1SAxel Dörfler 
1098da112cSIngo Weinhold #include <new>
1198da112cSIngo Weinhold #include <set>
1218cd67c7SMichael Lotz #include <stdlib.h>
1398da112cSIngo Weinhold #include <string>
1498da112cSIngo Weinhold 
15d6b205f3SIngo Weinhold #include <AppFileInfo.h>
1698da112cSIngo Weinhold #include <Bitmap.h>
1798da112cSIngo Weinhold #include <File.h>
1898da112cSIngo Weinhold #include <fs_attr.h>
199ecf9d1cSIngo Weinhold #include <IconUtils.h>
2098da112cSIngo Weinhold #include <MimeType.h>
2198da112cSIngo Weinhold #include <RegistrarDefs.h>
2298da112cSIngo Weinhold #include <Resources.h>
2398da112cSIngo Weinhold #include <Roster.h>
2498da112cSIngo Weinhold #include <String.h>
2598da112cSIngo Weinhold 
263b07762cSIngo Weinhold 
273b07762cSIngo Weinhold // debugging
283b07762cSIngo Weinhold //#define DBG(x) x
293b07762cSIngo Weinhold #define DBG(x)
303b07762cSIngo Weinhold #define OUT	printf
313b07762cSIngo Weinhold 
323b07762cSIngo Weinhold 
333b07762cSIngo Weinhold // type codes
343b07762cSIngo Weinhold enum {
353b07762cSIngo Weinhold 	B_APP_FLAGS_TYPE	= 'APPF',
363b07762cSIngo Weinhold 	B_VERSION_INFO_TYPE	= 'APPV',
373b07762cSIngo Weinhold };
383b07762cSIngo Weinhold 
3950f17542Shaydentech 
4098da112cSIngo Weinhold // attributes
4198da112cSIngo Weinhold static const char* kTypeAttribute				= "BEOS:TYPE";
4298da112cSIngo Weinhold static const char* kSignatureAttribute			= "BEOS:APP_SIG";
4398da112cSIngo Weinhold static const char* kAppFlagsAttribute			= "BEOS:APP_FLAGS";
4498da112cSIngo Weinhold static const char* kSupportedTypesAttribute		= "BEOS:FILE_TYPES";
4598da112cSIngo Weinhold static const char* kVersionInfoAttribute		= "BEOS:APP_VERSION";
4698da112cSIngo Weinhold static const char* kMiniIconAttribute			= "BEOS:M:";
4798da112cSIngo Weinhold static const char* kLargeIconAttribute			= "BEOS:L:";
489ecf9d1cSIngo Weinhold static const char* kIconAttribute				= "BEOS:";
4998da112cSIngo Weinhold static const char* kStandardIconType			= "STD_ICON";
509ecf9d1cSIngo Weinhold static const char* kIconType					= "ICON";
5182e7ef67SJonas Sundström static const char* kCatalogEntryAttribute		= "SYS:NAME";
5298da112cSIngo Weinhold 
5398da112cSIngo Weinhold // resource IDs
5498da112cSIngo Weinhold static const int32 kTypeResourceID				= 2;
5598da112cSIngo Weinhold static const int32 kSignatureResourceID			= 1;
5698da112cSIngo Weinhold static const int32 kAppFlagsResourceID			= 1;
5798da112cSIngo Weinhold static const int32 kSupportedTypesResourceID	= 1;
5898da112cSIngo Weinhold static const int32 kMiniIconResourceID			= 101;
5998da112cSIngo Weinhold static const int32 kLargeIconResourceID			= 101;
607fb6186fSStephan Aßmus static const int32 kIconResourceID				= 101;
6198da112cSIngo Weinhold static const int32 kVersionInfoResourceID		= 1;
6298da112cSIngo Weinhold static const int32 kMiniIconForTypeResourceID	= 0;
6398da112cSIngo Weinhold static const int32 kLargeIconForTypeResourceID	= 0;
647fb6186fSStephan Aßmus static const int32 kIconForTypeResourceID		= 0;
6582e7ef67SJonas Sundström static const int32 kCatalogEntryResourceID		= 1;
6698da112cSIngo Weinhold 
6788706bbeSAxel Dörfler // R5 also exports these (Tracker is using them):
6888706bbeSAxel Dörfler // (maybe we better want to drop them silently and declare
6988706bbeSAxel Dörfler // the above in a public Haiku header - and use that one in
7088706bbeSAxel Dörfler // Tracker when compiled for Haiku)
7188706bbeSAxel Dörfler extern const uint32 MINI_ICON_TYPE, LARGE_ICON_TYPE;
7288706bbeSAxel Dörfler const uint32 MINI_ICON_TYPE = 'MICN';
7388706bbeSAxel Dörfler const uint32 LARGE_ICON_TYPE = 'ICON';
7488706bbeSAxel Dörfler 
75d6b205f3SIngo Weinhold 
76d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo()
77e1b526b9SJonas Sundström 	:
78e1b526b9SJonas Sundström 	fResources(NULL),
79d6b205f3SIngo Weinhold 	fWhere(B_USE_BOTH_LOCATIONS)
80d6b205f3SIngo Weinhold {
81d6b205f3SIngo Weinhold }
82d6b205f3SIngo Weinhold 
83e1b526b9SJonas Sundström 
84d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(BFile* file)
85e1b526b9SJonas Sundström 	:
86e1b526b9SJonas Sundström 	fResources(NULL),
87d6b205f3SIngo Weinhold 	fWhere(B_USE_BOTH_LOCATIONS)
88d6b205f3SIngo Weinhold {
8998da112cSIngo Weinhold 	SetTo(file);
90d6b205f3SIngo Weinhold }
91d6b205f3SIngo Weinhold 
92e1b526b9SJonas Sundström 
93d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
94d6b205f3SIngo Weinhold {
9598da112cSIngo Weinhold 	delete fResources;
96d6b205f3SIngo Weinhold }
97d6b205f3SIngo Weinhold 
98e1b526b9SJonas Sundström 
99d6b205f3SIngo Weinhold status_t
100d6b205f3SIngo Weinhold BAppFileInfo::SetTo(BFile* file)
101d6b205f3SIngo Weinhold {
10298da112cSIngo Weinhold 	// unset the old file
10398da112cSIngo Weinhold 	BNodeInfo::SetTo(NULL);
10498da112cSIngo Weinhold 	if (fResources) {
10598da112cSIngo Weinhold 		delete fResources;
10698da112cSIngo Weinhold 		fResources = NULL;
10798da112cSIngo Weinhold 	}
108c2a2369dSAxel Dörfler 
10998da112cSIngo Weinhold 	// check param
1103b07762cSIngo Weinhold 	status_t error
1113b07762cSIngo Weinhold 		= file != NULL && file->InitCheck() == B_OK ? B_OK : B_BAD_VALUE;
112c2a2369dSAxel Dörfler 
113c2a2369dSAxel Dörfler 	info_location where = B_USE_BOTH_LOCATIONS;
114c2a2369dSAxel Dörfler 
11598da112cSIngo Weinhold 	// create resources
11698da112cSIngo Weinhold 	if (error == B_OK) {
1173b07762cSIngo Weinhold 		fResources = new(std::nothrow) BResources();
118c2a2369dSAxel Dörfler 		if (fResources) {
11998da112cSIngo Weinhold 			error = fResources->SetTo(file);
120c2a2369dSAxel Dörfler 			if (error != B_OK) {
121c2a2369dSAxel Dörfler 				// no resources - this is no critical error, we'll just use
122c2a2369dSAxel Dörfler 				// attributes only, then
123c2a2369dSAxel Dörfler 				where = B_USE_ATTRIBUTES;
124c2a2369dSAxel Dörfler 				error = B_OK;
125c2a2369dSAxel Dörfler 			}
126c2a2369dSAxel Dörfler 		} else
12798da112cSIngo Weinhold 			error = B_NO_MEMORY;
12898da112cSIngo Weinhold 	}
129c2a2369dSAxel Dörfler 
13098da112cSIngo Weinhold 	// set node info
13198da112cSIngo Weinhold 	if (error == B_OK)
13298da112cSIngo Weinhold 		error = BNodeInfo::SetTo(file);
133c2a2369dSAxel Dörfler 
134c2a2369dSAxel Dörfler 	if (error != B_OK || (where & B_USE_RESOURCES) == 0) {
13598da112cSIngo Weinhold 		delete fResources;
13698da112cSIngo Weinhold 		fResources = NULL;
13798da112cSIngo Weinhold 	}
138c2a2369dSAxel Dörfler 
139c2a2369dSAxel Dörfler 	// clean up on error
140c2a2369dSAxel Dörfler 	if (error != B_OK) {
14198da112cSIngo Weinhold 		if (InitCheck() == B_OK)
14298da112cSIngo Weinhold 			BNodeInfo::SetTo(NULL);
14398da112cSIngo Weinhold 	}
144c2a2369dSAxel Dörfler 
14598da112cSIngo Weinhold 	// set data location
14698da112cSIngo Weinhold 	if (error == B_OK)
147c2a2369dSAxel Dörfler 		SetInfoLocation(where);
148c2a2369dSAxel Dörfler 
14998da112cSIngo Weinhold 	// set error
15098da112cSIngo Weinhold 	fCStatus = error;
15198da112cSIngo Weinhold 	return error;
152d6b205f3SIngo Weinhold }
153d6b205f3SIngo Weinhold 
154e1b526b9SJonas Sundström 
155d6b205f3SIngo Weinhold status_t
156d6b205f3SIngo Weinhold BAppFileInfo::GetType(char* type) const
157d6b205f3SIngo Weinhold {
15898da112cSIngo Weinhold 	// check param and initialization
1593b07762cSIngo Weinhold 	status_t error = type != NULL ? B_OK : B_BAD_VALUE;
16098da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
16198da112cSIngo Weinhold 		error = B_NO_INIT;
16298da112cSIngo Weinhold 	// read the data
16398da112cSIngo Weinhold 	size_t read = 0;
16498da112cSIngo Weinhold 	if (error == B_OK) {
16598da112cSIngo Weinhold 		error = _ReadData(kTypeAttribute, kTypeResourceID, B_MIME_STRING_TYPE,
16698da112cSIngo Weinhold 			type, B_MIME_TYPE_LENGTH, read);
16798da112cSIngo Weinhold 	}
16898da112cSIngo Weinhold 	// check the read data -- null terminate the string
16998da112cSIngo Weinhold 	if (error == B_OK && type[read - 1] != '\0') {
17098da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
17198da112cSIngo Weinhold 			error = B_ERROR;
17298da112cSIngo Weinhold 		else
17398da112cSIngo Weinhold 			type[read] = '\0';
17498da112cSIngo Weinhold 	}
17598da112cSIngo Weinhold 	return error;
176d6b205f3SIngo Weinhold }
177d6b205f3SIngo Weinhold 
178e1b526b9SJonas Sundström 
179d6b205f3SIngo Weinhold status_t
180d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char* type)
181d6b205f3SIngo Weinhold {
18298da112cSIngo Weinhold 	// check initialization
18398da112cSIngo Weinhold 	status_t error = B_OK;
18498da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
18598da112cSIngo Weinhold 		error = B_NO_INIT;
18698da112cSIngo Weinhold 	if (error == B_OK) {
1873b07762cSIngo Weinhold 		if (type != NULL) {
18898da112cSIngo Weinhold 			// check param
18998da112cSIngo Weinhold 			size_t typeLen = strlen(type);
19098da112cSIngo Weinhold 			if (error == B_OK && typeLen >= B_MIME_TYPE_LENGTH)
19198da112cSIngo Weinhold 				error = B_BAD_VALUE;
19298da112cSIngo Weinhold 			// write the data
19398da112cSIngo Weinhold 			if (error == B_OK) {
19498da112cSIngo Weinhold 				error = _WriteData(kTypeAttribute, kTypeResourceID,
19598da112cSIngo Weinhold 					B_MIME_STRING_TYPE, type, typeLen + 1);
19698da112cSIngo Weinhold 			}
19798da112cSIngo Weinhold 		} else
19898da112cSIngo Weinhold 			error = _RemoveData(kTypeAttribute, B_MIME_STRING_TYPE);
19998da112cSIngo Weinhold 	}
20098da112cSIngo Weinhold 	return error;
201d6b205f3SIngo Weinhold }
202d6b205f3SIngo Weinhold 
203e1b526b9SJonas Sundström 
204d6b205f3SIngo Weinhold status_t
205d6b205f3SIngo Weinhold BAppFileInfo::GetSignature(char* signature) const
206d6b205f3SIngo Weinhold {
20798da112cSIngo Weinhold 	// check param and initialization
20898da112cSIngo Weinhold 	status_t error = (signature ? B_OK : B_BAD_VALUE);
20998da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
21098da112cSIngo Weinhold 		error = B_NO_INIT;
21198da112cSIngo Weinhold 	// read the data
21298da112cSIngo Weinhold 	size_t read = 0;
21398da112cSIngo Weinhold 	if (error == B_OK) {
21498da112cSIngo Weinhold 		error = _ReadData(kSignatureAttribute, kSignatureResourceID,
2153b07762cSIngo Weinhold 			B_MIME_STRING_TYPE, signature, B_MIME_TYPE_LENGTH, read);
21698da112cSIngo Weinhold 	}
21798da112cSIngo Weinhold 	// check the read data -- null terminate the string
21898da112cSIngo Weinhold 	if (error == B_OK && signature[read - 1] != '\0') {
21998da112cSIngo Weinhold 		if (read == B_MIME_TYPE_LENGTH)
22098da112cSIngo Weinhold 			error = B_ERROR;
22198da112cSIngo Weinhold 		else
22298da112cSIngo Weinhold 			signature[read] = '\0';
22398da112cSIngo Weinhold 	}
22498da112cSIngo Weinhold 	return error;
225d6b205f3SIngo Weinhold }
226d6b205f3SIngo Weinhold 
227e1b526b9SJonas Sundström 
228d6b205f3SIngo Weinhold status_t
229d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char* signature)
230d6b205f3SIngo Weinhold {
23198da112cSIngo Weinhold 	// check initialization
23298da112cSIngo Weinhold 	status_t error = B_OK;
23398da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
23498da112cSIngo Weinhold 		error = B_NO_INIT;
23598da112cSIngo Weinhold 	if (error == B_OK) {
23698da112cSIngo Weinhold 		if (signature) {
23798da112cSIngo Weinhold 			// check param
23898da112cSIngo Weinhold 			size_t signatureLen = strlen(signature);
23998da112cSIngo Weinhold 			if (error == B_OK && signatureLen >= B_MIME_TYPE_LENGTH)
24098da112cSIngo Weinhold 				error = B_BAD_VALUE;
24198da112cSIngo Weinhold 			// write the data
24298da112cSIngo Weinhold 			if (error == B_OK) {
24398da112cSIngo Weinhold 				error = _WriteData(kSignatureAttribute, kSignatureResourceID,
2443b07762cSIngo Weinhold 					B_MIME_STRING_TYPE, signature, signatureLen + 1);
24598da112cSIngo Weinhold 			}
24698da112cSIngo Weinhold 		} else
24798da112cSIngo Weinhold 			error = _RemoveData(kSignatureAttribute, B_MIME_STRING_TYPE);
24898da112cSIngo Weinhold 	}
24998da112cSIngo Weinhold 	return error;
250d6b205f3SIngo Weinhold }
251d6b205f3SIngo Weinhold 
25282e7ef67SJonas Sundström 
25382e7ef67SJonas Sundström status_t
25482e7ef67SJonas Sundström BAppFileInfo::GetCatalogEntry(char* catalogEntry) const
25582e7ef67SJonas Sundström {
25682e7ef67SJonas Sundström 	if (catalogEntry == NULL)
25782e7ef67SJonas Sundström 		return B_BAD_VALUE;
25882e7ef67SJonas Sundström 
25982e7ef67SJonas Sundström 	if (InitCheck() != B_OK)
26082e7ef67SJonas Sundström 		return B_NO_INIT;
26182e7ef67SJonas Sundström 
26282e7ef67SJonas Sundström 	size_t read = 0;
26382e7ef67SJonas Sundström 	status_t error = _ReadData(kCatalogEntryAttribute, kCatalogEntryResourceID,
26482e7ef67SJonas Sundström 		B_STRING_TYPE, catalogEntry, B_MIME_TYPE_LENGTH * 3, read);
26582e7ef67SJonas Sundström 
26682e7ef67SJonas Sundström 	if (error != B_OK)
26782e7ef67SJonas Sundström 		return error;
26882e7ef67SJonas Sundström 
26982e7ef67SJonas Sundström 	if (read >= B_MIME_TYPE_LENGTH * 3)
27082e7ef67SJonas Sundström 		return B_ERROR;
27182e7ef67SJonas Sundström 
27282e7ef67SJonas Sundström 	catalogEntry[read] = '\0';
27382e7ef67SJonas Sundström 
27482e7ef67SJonas Sundström 	return B_OK;
27582e7ef67SJonas Sundström }
27682e7ef67SJonas Sundström 
27782e7ef67SJonas Sundström 
27882e7ef67SJonas Sundström status_t
27982e7ef67SJonas Sundström BAppFileInfo::SetCatalogEntry(const char* catalogEntry)
28082e7ef67SJonas Sundström {
28182e7ef67SJonas Sundström 	if (InitCheck() != B_OK)
28282e7ef67SJonas Sundström 		return B_NO_INIT;
28382e7ef67SJonas Sundström 
28482e7ef67SJonas Sundström 	if (catalogEntry == NULL)
28582e7ef67SJonas Sundström 		return _RemoveData(kCatalogEntryAttribute, B_STRING_TYPE);
28682e7ef67SJonas Sundström 
28782e7ef67SJonas Sundström 	size_t nameLength = strlen(catalogEntry);
28882e7ef67SJonas Sundström 	if (nameLength > B_MIME_TYPE_LENGTH * 3)
28982e7ef67SJonas Sundström 		return B_BAD_VALUE;
29082e7ef67SJonas Sundström 
29182e7ef67SJonas Sundström 	return _WriteData(kCatalogEntryAttribute, kCatalogEntryResourceID,
29282e7ef67SJonas Sundström 		B_STRING_TYPE, catalogEntry, nameLength + 1);
29382e7ef67SJonas Sundström }
29482e7ef67SJonas Sundström 
29582e7ef67SJonas Sundström 
296d6b205f3SIngo Weinhold status_t
297d6b205f3SIngo Weinhold BAppFileInfo::GetAppFlags(uint32* flags) const
298d6b205f3SIngo Weinhold {
29998da112cSIngo Weinhold 	// check param and initialization
3003b07762cSIngo Weinhold 	status_t error = flags != NULL ? B_OK : B_BAD_VALUE;
30198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
30298da112cSIngo Weinhold 		error = B_NO_INIT;
30398da112cSIngo Weinhold 	// read the data
30498da112cSIngo Weinhold 	size_t read = 0;
30598da112cSIngo Weinhold 	if (error == B_OK) {
30698da112cSIngo Weinhold 		error = _ReadData(kAppFlagsAttribute, kAppFlagsResourceID,
3073b07762cSIngo Weinhold 			B_APP_FLAGS_TYPE, flags, sizeof(uint32), read);
30898da112cSIngo Weinhold 	}
30998da112cSIngo Weinhold 	// check the read data
31098da112cSIngo Weinhold 	if (error == B_OK && read != sizeof(uint32))
31198da112cSIngo Weinhold 		error = B_ERROR;
31298da112cSIngo Weinhold 	return error;
313d6b205f3SIngo Weinhold }
314d6b205f3SIngo Weinhold 
315e1b526b9SJonas Sundström 
316d6b205f3SIngo Weinhold status_t
317d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
318d6b205f3SIngo Weinhold {
31998da112cSIngo Weinhold 	// check initialization
32098da112cSIngo Weinhold 	status_t error = B_OK;
32198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
32298da112cSIngo Weinhold 		error = B_NO_INIT;
32398da112cSIngo Weinhold 	if (error == B_OK) {
32498da112cSIngo Weinhold 		// write the data
32598da112cSIngo Weinhold 		error = _WriteData(kAppFlagsAttribute, kAppFlagsResourceID,
32698da112cSIngo Weinhold 			B_APP_FLAGS_TYPE, &flags, sizeof(uint32));
32798da112cSIngo Weinhold 	}
32822920adfSStephan Aßmus 	return error;
32922920adfSStephan Aßmus }
33022920adfSStephan Aßmus 
331e1b526b9SJonas Sundström 
33222920adfSStephan Aßmus status_t
33322920adfSStephan Aßmus BAppFileInfo::RemoveAppFlags()
33422920adfSStephan Aßmus {
33522920adfSStephan Aßmus 	// check initialization
33622920adfSStephan Aßmus 	status_t error = B_OK;
33722920adfSStephan Aßmus 	if (error == B_OK && InitCheck() != B_OK)
33822920adfSStephan Aßmus 		error = B_NO_INIT;
33922920adfSStephan Aßmus 	if (error == B_OK) {
34022920adfSStephan Aßmus 		// remove the data
34122920adfSStephan Aßmus 		error = _RemoveData(kAppFlagsAttribute, B_APP_FLAGS_TYPE);
34298da112cSIngo Weinhold 	}
34398da112cSIngo Weinhold 	return error;
344d6b205f3SIngo Weinhold }
345d6b205f3SIngo Weinhold 
346e1b526b9SJonas Sundström 
347d6b205f3SIngo Weinhold status_t
348d6b205f3SIngo Weinhold BAppFileInfo::GetSupportedTypes(BMessage* types) const
349d6b205f3SIngo Weinhold {
35098da112cSIngo Weinhold 	// check param and initialization
3513b07762cSIngo Weinhold 	status_t error = types != NULL ? B_OK : B_BAD_VALUE;
35298da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
35398da112cSIngo Weinhold 		error = B_NO_INIT;
35498da112cSIngo Weinhold 	// read the data
35598da112cSIngo Weinhold 	size_t read = 0;
35698da112cSIngo Weinhold 	void* buffer = NULL;
35798da112cSIngo Weinhold 	if (error == B_OK) {
35898da112cSIngo Weinhold 		error = _ReadData(kSupportedTypesAttribute, kSupportedTypesResourceID,
35998da112cSIngo Weinhold 			B_MESSAGE_TYPE, NULL, 0, read, &buffer);
36098da112cSIngo Weinhold 	}
36198da112cSIngo Weinhold 	// unflatten the buffer
36298da112cSIngo Weinhold 	if (error == B_OK)
36398da112cSIngo Weinhold 		error = types->Unflatten((const char*)buffer);
36498da112cSIngo Weinhold 	// clean up
36598da112cSIngo Weinhold 	free(buffer);
36698da112cSIngo Weinhold 	return error;
367d6b205f3SIngo Weinhold }
368d6b205f3SIngo Weinhold 
369e1b526b9SJonas Sundström 
370d6b205f3SIngo Weinhold status_t
371c41356faSIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool updateMimeDB,
372c41356faSIngo Weinhold 	bool syncAll)
373d6b205f3SIngo Weinhold {
37498da112cSIngo Weinhold 	// check initialization
37598da112cSIngo Weinhold 	status_t error = B_OK;
37698da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
37798da112cSIngo Weinhold 		error = B_NO_INIT;
378c41356faSIngo Weinhold 
37998da112cSIngo Weinhold 	BMimeType mimeType;
38098da112cSIngo Weinhold 	if (error == B_OK)
38198da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
382c41356faSIngo Weinhold 
3837f20062dSJérôme Duval 	if (error == B_OK || error == B_ENTRY_NOT_FOUND) {
3847f20062dSJérôme Duval 		error = B_OK;
38598da112cSIngo Weinhold 		if (types) {
38617819be3SIngo Weinhold 			// check param -- supported types must be valid
38717819be3SIngo Weinhold 			const char* type;
38817819be3SIngo Weinhold 			for (int32 i = 0;
38917819be3SIngo Weinhold 				 error == B_OK && types->FindString("types", i, &type) == B_OK;
39017819be3SIngo Weinhold 				 i++) {
39117819be3SIngo Weinhold 				if (!BMimeType::IsValid(type))
39217819be3SIngo Weinhold 					error = B_BAD_VALUE;
39317819be3SIngo Weinhold 			}
394c41356faSIngo Weinhold 
39517819be3SIngo Weinhold 			// get flattened size
39617819be3SIngo Weinhold 			ssize_t size = 0;
39717819be3SIngo Weinhold 			if (error == B_OK) {
39817819be3SIngo Weinhold 				size = types->FlattenedSize();
39998da112cSIngo Weinhold 				if (size < 0)
40098da112cSIngo Weinhold 					error = size;
40117819be3SIngo Weinhold 			}
402c41356faSIngo Weinhold 
40398da112cSIngo Weinhold 			// allocate a buffer for the flattened data
40498da112cSIngo Weinhold 			char* buffer = NULL;
40598da112cSIngo Weinhold 			if (error == B_OK) {
4063b07762cSIngo Weinhold 				buffer = new(std::nothrow) char[size];
40798da112cSIngo Weinhold 				if (!buffer)
40898da112cSIngo Weinhold 					error = B_NO_MEMORY;
40998da112cSIngo Weinhold 			}
410c41356faSIngo Weinhold 
41198da112cSIngo Weinhold 			// flatten the message
41298da112cSIngo Weinhold 			if (error == B_OK)
41398da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
414c41356faSIngo Weinhold 
41598da112cSIngo Weinhold 			// write the data
41698da112cSIngo Weinhold 			if (error == B_OK) {
41798da112cSIngo Weinhold 				error = _WriteData(kSupportedTypesAttribute,
4183b07762cSIngo Weinhold 					kSupportedTypesResourceID, B_MESSAGE_TYPE, buffer, size);
41998da112cSIngo Weinhold 			}
420c41356faSIngo Weinhold 
42198da112cSIngo Weinhold 			delete[] buffer;
42298da112cSIngo Weinhold 		} else
42398da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
424c41356faSIngo Weinhold 
42598da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
426c41356faSIngo Weinhold 		if (updateMimeDB && error == B_OK && mimeType.IsInstalled())
42717819be3SIngo Weinhold 			error = mimeType.SetSupportedTypes(types, syncAll);
42898da112cSIngo Weinhold 	}
42998da112cSIngo Weinhold 	return error;
430d6b205f3SIngo Weinhold }
431d6b205f3SIngo Weinhold 
432e1b526b9SJonas Sundström 
433d6b205f3SIngo Weinhold status_t
434c41356faSIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool syncAll)
435c41356faSIngo Weinhold {
436c41356faSIngo Weinhold 	return SetSupportedTypes(types, true, syncAll);
437c41356faSIngo Weinhold }
438c41356faSIngo Weinhold 
439c41356faSIngo Weinhold 
440c41356faSIngo Weinhold status_t
441d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types)
442d6b205f3SIngo Weinhold {
443c41356faSIngo Weinhold 	return SetSupportedTypes(types, true, false);
444d6b205f3SIngo Weinhold }
445d6b205f3SIngo Weinhold 
446e1b526b9SJonas Sundström 
447d6b205f3SIngo Weinhold bool
448d6b205f3SIngo Weinhold BAppFileInfo::IsSupportedType(const char* type) const
449d6b205f3SIngo Weinhold {
4503b07762cSIngo Weinhold 	status_t error = type != NULL ? B_OK : B_BAD_VALUE;
45198da112cSIngo Weinhold 	// get the supported types
45298da112cSIngo Weinhold 	BMessage types;
45398da112cSIngo Weinhold 	if (error == B_OK)
45498da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
45598da112cSIngo Weinhold 	// turn type into a BMimeType
45698da112cSIngo Weinhold 	BMimeType mimeType;
45798da112cSIngo Weinhold 	if (error == B_OK)
45898da112cSIngo Weinhold 		error = mimeType.SetTo(type);
45998da112cSIngo Weinhold 	// iterate through the supported types
46098da112cSIngo Weinhold 	bool found = false;
46198da112cSIngo Weinhold 	if (error == B_OK) {
46298da112cSIngo Weinhold 		const char* supportedType;
46398da112cSIngo Weinhold 		for (int32 i = 0;
46498da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
46598da112cSIngo Weinhold 			 i++) {
4663b07762cSIngo Weinhold 			found = strcmp(supportedType, "application/octet-stream") == 0
46798da112cSIngo Weinhold 				|| BMimeType(supportedType).Contains(&mimeType);
46898da112cSIngo Weinhold 		}
46998da112cSIngo Weinhold 	}
47098da112cSIngo Weinhold 	return found;
471d6b205f3SIngo Weinhold }
472d6b205f3SIngo Weinhold 
473e1b526b9SJonas Sundström 
474d6b205f3SIngo Weinhold bool
475d6b205f3SIngo Weinhold BAppFileInfo::Supports(BMimeType* type) const
476d6b205f3SIngo Weinhold {
4773b07762cSIngo Weinhold 	status_t error
4783b07762cSIngo Weinhold 		= type != NULL && type->InitCheck() == B_OK ? B_OK : B_BAD_VALUE;
47998da112cSIngo Weinhold 	// get the supported types
48098da112cSIngo Weinhold 	BMessage types;
48198da112cSIngo Weinhold 	if (error == B_OK)
48298da112cSIngo Weinhold 		error = GetSupportedTypes(&types);
48398da112cSIngo Weinhold 	// iterate through the supported types
48498da112cSIngo Weinhold 	bool found = false;
48598da112cSIngo Weinhold 	if (error == B_OK) {
48698da112cSIngo Weinhold 		const char* supportedType;
48798da112cSIngo Weinhold 		for (int32 i = 0;
48898da112cSIngo Weinhold 			 !found && types.FindString("types", i, &supportedType) == B_OK;
48998da112cSIngo Weinhold 			 i++) {
49098da112cSIngo Weinhold 			found = BMimeType(supportedType).Contains(type);
49198da112cSIngo Weinhold 		}
49298da112cSIngo Weinhold 	}
49398da112cSIngo Weinhold 	return found;
494d6b205f3SIngo Weinhold }
495d6b205f3SIngo Weinhold 
496e1b526b9SJonas Sundström 
497d6b205f3SIngo Weinhold status_t
498d6b205f3SIngo Weinhold BAppFileInfo::GetIcon(BBitmap* icon, icon_size which) const
499d6b205f3SIngo Weinhold {
50098da112cSIngo Weinhold 	return GetIconForType(NULL, icon, which);
501d6b205f3SIngo Weinhold }
502d6b205f3SIngo Weinhold 
503e1b526b9SJonas Sundström 
5047fb6186fSStephan Aßmus status_t
5057fb6186fSStephan Aßmus BAppFileInfo::GetIcon(uint8** data, size_t* size) const
5067fb6186fSStephan Aßmus {
5077fb6186fSStephan Aßmus 	return GetIconForType(NULL, data, size);
5087fb6186fSStephan Aßmus }
5097fb6186fSStephan Aßmus 
510e1b526b9SJonas Sundström 
511d6b205f3SIngo Weinhold status_t
512c41356faSIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which, bool updateMimeDB)
513c41356faSIngo Weinhold {
514c41356faSIngo Weinhold 	return SetIconForType(NULL, icon, which, updateMimeDB);
515c41356faSIngo Weinhold }
516c41356faSIngo Weinhold 
517c41356faSIngo Weinhold 
518c41356faSIngo Weinhold status_t
519d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which)
520d6b205f3SIngo Weinhold {
521c41356faSIngo Weinhold 	return SetIconForType(NULL, icon, which, true);
522c41356faSIngo Weinhold }
523c41356faSIngo Weinhold 
524c41356faSIngo Weinhold 
525c41356faSIngo Weinhold status_t
526c41356faSIngo Weinhold BAppFileInfo::SetIcon(const uint8* data, size_t size, bool updateMimeDB)
527c41356faSIngo Weinhold {
528c41356faSIngo Weinhold 	return SetIconForType(NULL, data, size, updateMimeDB);
529d6b205f3SIngo Weinhold }
530d6b205f3SIngo Weinhold 
531e1b526b9SJonas Sundström 
5327fb6186fSStephan Aßmus status_t
5337fb6186fSStephan Aßmus BAppFileInfo::SetIcon(const uint8* data, size_t size)
5347fb6186fSStephan Aßmus {
535c41356faSIngo Weinhold 	return SetIconForType(NULL, data, size, true);
5367fb6186fSStephan Aßmus }
5377fb6186fSStephan Aßmus 
538e1b526b9SJonas Sundström 
539d6b205f3SIngo Weinhold status_t
540d6b205f3SIngo Weinhold BAppFileInfo::GetVersionInfo(version_info* info, version_kind kind) const
541d6b205f3SIngo Weinhold {
54298da112cSIngo Weinhold 	// check params and initialization
5433b07762cSIngo Weinhold 	if (info == NULL)
544b1970bb8SIngo Weinhold 		return B_BAD_VALUE;
545b1970bb8SIngo Weinhold 
54698da112cSIngo Weinhold 	int32 index = 0;
54798da112cSIngo Weinhold 	switch (kind) {
54898da112cSIngo Weinhold 		case B_APP_VERSION_KIND:
54998da112cSIngo Weinhold 			index = 0;
55098da112cSIngo Weinhold 			break;
55198da112cSIngo Weinhold 		case B_SYSTEM_VERSION_KIND:
55298da112cSIngo Weinhold 			index = 1;
55398da112cSIngo Weinhold 			break;
55498da112cSIngo Weinhold 		default:
555b1970bb8SIngo Weinhold 			return B_BAD_VALUE;
55698da112cSIngo Weinhold 	}
557b1970bb8SIngo Weinhold 
558b1970bb8SIngo Weinhold 	if (InitCheck() != B_OK)
559b1970bb8SIngo Weinhold 		return B_NO_INIT;
560b1970bb8SIngo Weinhold 
56198da112cSIngo Weinhold 	// read the data
56298da112cSIngo Weinhold 	size_t read = 0;
56398da112cSIngo Weinhold 	version_info infos[2];
564b1970bb8SIngo Weinhold 	status_t error = _ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
565b1970bb8SIngo Weinhold 		B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info), read);
566b1970bb8SIngo Weinhold 	if (error != B_OK)
56798da112cSIngo Weinhold 		return error;
568b1970bb8SIngo Weinhold 
569b1970bb8SIngo Weinhold 	// check the read data
570b1970bb8SIngo Weinhold 	if (read == sizeof(version_info)) {
571b1970bb8SIngo Weinhold 		// only the app version info is there -- return a cleared system info
572b1970bb8SIngo Weinhold 		if (index == 0)
573b1970bb8SIngo Weinhold 			*info = infos[index];
574b1970bb8SIngo Weinhold 		else if (index == 1)
575b1970bb8SIngo Weinhold 			memset(info, 0, sizeof(version_info));
576b1970bb8SIngo Weinhold 	} else if (read == 2 * sizeof(version_info)) {
577b1970bb8SIngo Weinhold 		*info = infos[index];
578b1970bb8SIngo Weinhold 	} else
579b1970bb8SIngo Weinhold 		return B_ERROR;
580b1970bb8SIngo Weinhold 
581b1970bb8SIngo Weinhold 	// return result
582b1970bb8SIngo Weinhold 	return B_OK;
583d6b205f3SIngo Weinhold }
584d6b205f3SIngo Weinhold 
585e1b526b9SJonas Sundström 
586d6b205f3SIngo Weinhold status_t
587d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info* info, version_kind kind)
588d6b205f3SIngo Weinhold {
58998da112cSIngo Weinhold 	// check initialization
59098da112cSIngo Weinhold 	status_t error = B_OK;
59198da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
59298da112cSIngo Weinhold 		error = B_NO_INIT;
59398da112cSIngo Weinhold 	if (error == B_OK) {
5943b07762cSIngo Weinhold 		if (info != NULL) {
59598da112cSIngo Weinhold 			// check param
59698da112cSIngo Weinhold 			int32 index = 0;
59798da112cSIngo Weinhold 			if (error == B_OK) {
59898da112cSIngo Weinhold 				switch (kind) {
59998da112cSIngo Weinhold 					case B_APP_VERSION_KIND:
60098da112cSIngo Weinhold 						index = 0;
60198da112cSIngo Weinhold 						break;
60298da112cSIngo Weinhold 					case B_SYSTEM_VERSION_KIND:
60398da112cSIngo Weinhold 						index = 1;
60498da112cSIngo Weinhold 						break;
60598da112cSIngo Weinhold 					default:
60698da112cSIngo Weinhold 						error = B_BAD_VALUE;
60798da112cSIngo Weinhold 						break;
60898da112cSIngo Weinhold 				}
60998da112cSIngo Weinhold 			}
61098da112cSIngo Weinhold 			// read both infos
61198da112cSIngo Weinhold 			version_info infos[2];
61298da112cSIngo Weinhold 			if (error == B_OK) {
61398da112cSIngo Weinhold 				size_t read;
614b1970bb8SIngo Weinhold 				if (_ReadData(kVersionInfoAttribute, kVersionInfoResourceID,
615b1970bb8SIngo Weinhold 						B_VERSION_INFO_TYPE, infos, 2 * sizeof(version_info),
616b1970bb8SIngo Weinhold 						read) == B_OK) {
617b1970bb8SIngo Weinhold 					// clear the part that hasn't been read
618b1970bb8SIngo Weinhold 					if (read < sizeof(infos))
619b1970bb8SIngo Weinhold 						memset((char*)infos + read, 0, sizeof(infos) - read);
620b1970bb8SIngo Weinhold 				} else {
621b1970bb8SIngo Weinhold 					// failed to read -- clear
622b1970bb8SIngo Weinhold 					memset(infos, 0, sizeof(infos));
623b1970bb8SIngo Weinhold 				}
62498da112cSIngo Weinhold 			}
62598da112cSIngo Weinhold 			infos[index] = *info;
62698da112cSIngo Weinhold 			// write the data
62798da112cSIngo Weinhold 			if (error == B_OK) {
62898da112cSIngo Weinhold 				error = _WriteData(kVersionInfoAttribute,
6293b07762cSIngo Weinhold 					kVersionInfoResourceID, B_VERSION_INFO_TYPE, infos,
63098da112cSIngo Weinhold 					2 * sizeof(version_info));
63198da112cSIngo Weinhold 			}
63298da112cSIngo Weinhold 		} else
63398da112cSIngo Weinhold 			error = _RemoveData(kVersionInfoAttribute, B_VERSION_INFO_TYPE);
63498da112cSIngo Weinhold 	}
63598da112cSIngo Weinhold 	return error;
636d6b205f3SIngo Weinhold }
637d6b205f3SIngo Weinhold 
638e1b526b9SJonas Sundström 
639d6b205f3SIngo Weinhold status_t
6403b07762cSIngo Weinhold BAppFileInfo::GetIconForType(const char* type, BBitmap* icon, icon_size size)
6413b07762cSIngo Weinhold 	const
642d6b205f3SIngo Weinhold {
6439ecf9d1cSIngo Weinhold 	if (InitCheck() != B_OK)
6449ecf9d1cSIngo Weinhold 		return B_NO_INIT;
6459ecf9d1cSIngo Weinhold 
6463b07762cSIngo Weinhold 	if (icon == NULL || icon->InitCheck() != B_OK)
6479ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
6489ecf9d1cSIngo Weinhold 
6492a74c553SStephan Aßmus 	// TODO: for consistency with attribute based icon reading, we
6502a74c553SStephan Aßmus 	// could also prefer B_CMAP8 icons here if the provided bitmap
6512a74c553SStephan Aßmus 	// is in that format. Right now, an existing B_CMAP8 icon resource
6522a74c553SStephan Aßmus 	// would be ignored as soon as a vector icon is present. On the other
6532a74c553SStephan Aßmus 	// hand, maybe this still results in a more consistent user interface,
6542a74c553SStephan Aßmus 	// since Tracker/Deskbar would surely show the vector icon.
6552a74c553SStephan Aßmus 
6569ecf9d1cSIngo Weinhold 	// try vector icon first
6579ecf9d1cSIngo Weinhold 	BString vectorAttributeName(kIconAttribute);
6589ecf9d1cSIngo Weinhold 
6599ecf9d1cSIngo Weinhold 	// check type param
6603b07762cSIngo Weinhold 	if (type != NULL) {
6619ecf9d1cSIngo Weinhold 		if (BMimeType::IsValid(type))
6629ecf9d1cSIngo Weinhold 			vectorAttributeName += type;
6639ecf9d1cSIngo Weinhold 		else
6649ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
6659ecf9d1cSIngo Weinhold 	} else {
6669ecf9d1cSIngo Weinhold 		vectorAttributeName += kIconType;
6679ecf9d1cSIngo Weinhold 	}
6689ecf9d1cSIngo Weinhold 	const char* attribute = vectorAttributeName.String();
6699ecf9d1cSIngo Weinhold 
6709ecf9d1cSIngo Weinhold 	size_t bytesRead;
6719ecf9d1cSIngo Weinhold 	void* allocatedBuffer;
672bae87c91SAxel Dörfler 	status_t error = _ReadData(attribute, -1, B_VECTOR_ICON_TYPE, NULL, 0,
6739ecf9d1cSIngo Weinhold 		bytesRead, &allocatedBuffer);
6749ecf9d1cSIngo Weinhold 	if (error == B_OK) {
6757fb6186fSStephan Aßmus 		error = BIconUtils::GetVectorIcon((uint8*)allocatedBuffer,
6769ecf9d1cSIngo Weinhold 										  bytesRead, icon);
6777fb6186fSStephan Aßmus 		free(allocatedBuffer);
6787fb6186fSStephan Aßmus 		return error;
6799ecf9d1cSIngo Weinhold 	}
6809ecf9d1cSIngo Weinhold 
6819f507806SStephan Aßmus 	// no vector icon if we got this far,
6829f507806SStephan Aßmus 	// align size argument just in case
6839f507806SStephan Aßmus 	if (size < B_LARGE_ICON)
6849f507806SStephan Aßmus 		size = B_MINI_ICON;
6859f507806SStephan Aßmus 	else
6869f507806SStephan Aßmus 		size = B_LARGE_ICON;
6879ecf9d1cSIngo Weinhold 
6889ecf9d1cSIngo Weinhold 	error = B_OK;
68998da112cSIngo Weinhold 	// set some icon size related variables
69098da112cSIngo Weinhold 	BString attributeString;
69198da112cSIngo Weinhold 	BRect bounds;
692a04efc92SIngo Weinhold 	uint32 attrType = 0;
693a04efc92SIngo Weinhold 	size_t attrSize = 0;
6949f507806SStephan Aßmus 	switch (size) {
69598da112cSIngo Weinhold 		case B_MINI_ICON:
69698da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
69798da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
69898da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
69998da112cSIngo Weinhold 			attrSize = 16 * 16;
70098da112cSIngo Weinhold 			break;
70198da112cSIngo Weinhold 		case B_LARGE_ICON:
70298da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
70398da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
70498da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
70598da112cSIngo Weinhold 			attrSize = 32 * 32;
70698da112cSIngo Weinhold 			break;
70798da112cSIngo Weinhold 		default:
7089ecf9d1cSIngo Weinhold 			return B_BAD_VALUE;
70998da112cSIngo Weinhold 	}
7109ecf9d1cSIngo Weinhold 
711c41356faSIngo Weinhold 	// compose attribute name
712c41356faSIngo Weinhold 	attributeString += type != NULL ? type : kStandardIconType;
7139ecf9d1cSIngo Weinhold 	attribute = attributeString.String();
71417819be3SIngo Weinhold 
7159f507806SStephan Aßmus 	// check parameters
7169f507806SStephan Aßmus 	// currently, scaling B_CMAP8 icons is not supported
7179f507806SStephan Aßmus 	if (icon->ColorSpace() == B_CMAP8 && icon->Bounds() != bounds)
7189ecf9d1cSIngo Weinhold 		return B_BAD_VALUE;
7199ecf9d1cSIngo Weinhold 
72098da112cSIngo Weinhold 	// read the data
72198da112cSIngo Weinhold 	if (error == B_OK) {
7223b07762cSIngo Weinhold 		bool tempBuffer
7233b07762cSIngo Weinhold 			= icon->ColorSpace() != B_CMAP8 || icon->Bounds() != bounds;
7249f507806SStephan Aßmus 		uint8* buffer = NULL;
72598da112cSIngo Weinhold 		size_t read;
7269f507806SStephan Aßmus 		if (tempBuffer) {
7279f507806SStephan Aßmus 			// other color space or bitmap size than stored in attribute
7283b07762cSIngo Weinhold 			buffer = new(std::nothrow) uint8[attrSize];
7299f507806SStephan Aßmus 			if (!buffer) {
73098da112cSIngo Weinhold 				error = B_NO_MEMORY;
7319f507806SStephan Aßmus 			} else {
73298da112cSIngo Weinhold 				error = _ReadData(attribute, -1, attrType, buffer, attrSize,
73398da112cSIngo Weinhold 					read);
73498da112cSIngo Weinhold 			}
73598da112cSIngo Weinhold 		} else {
73698da112cSIngo Weinhold 			error = _ReadData(attribute, -1, attrType, icon->Bits(), attrSize,
73798da112cSIngo Weinhold 				read);
73898da112cSIngo Weinhold 		}
73998da112cSIngo Weinhold 		if (error == B_OK && read != attrSize)
74098da112cSIngo Weinhold 			error = B_ERROR;
7419f507806SStephan Aßmus 		if (tempBuffer) {
74298da112cSIngo Weinhold 			// other color space than stored in attribute
74376ba3434SIngo Weinhold 			if (error == B_OK) {
7443b07762cSIngo Weinhold 				error = BIconUtils::ConvertFromCMAP8(buffer, (uint32)size,
7453b07762cSIngo Weinhold 					(uint32)size, (uint32)size, icon);
74676ba3434SIngo Weinhold 			}
74798da112cSIngo Weinhold 			delete[] buffer;
74898da112cSIngo Weinhold 		}
74998da112cSIngo Weinhold 	}
75098da112cSIngo Weinhold 	return error;
751d6b205f3SIngo Weinhold }
752d6b205f3SIngo Weinhold 
753e1b526b9SJonas Sundström 
7547fb6186fSStephan Aßmus status_t
7553b07762cSIngo Weinhold BAppFileInfo::GetIconForType(const char* type, uint8** data, size_t* size) const
7567fb6186fSStephan Aßmus {
7577fb6186fSStephan Aßmus 	if (InitCheck() != B_OK)
7587fb6186fSStephan Aßmus 		return B_NO_INIT;
7597fb6186fSStephan Aßmus 
7603b07762cSIngo Weinhold 	if (data == NULL || size == NULL)
7617fb6186fSStephan Aßmus 		return B_BAD_VALUE;
7627fb6186fSStephan Aßmus 
7637fb6186fSStephan Aßmus 	// get vector icon
7647fb6186fSStephan Aßmus 	BString attributeName(kIconAttribute);
7657fb6186fSStephan Aßmus 
7667fb6186fSStephan Aßmus 	// check type param
7673b07762cSIngo Weinhold 	if (type != NULL) {
7687fb6186fSStephan Aßmus 		if (BMimeType::IsValid(type))
7697fb6186fSStephan Aßmus 			attributeName += type;
7707fb6186fSStephan Aßmus 		else
7717fb6186fSStephan Aßmus 			return B_BAD_VALUE;
7723b07762cSIngo Weinhold 	} else
7737fb6186fSStephan Aßmus 		attributeName += kIconType;
7747fb6186fSStephan Aßmus 
7757fb6186fSStephan Aßmus 	void* allocatedBuffer = NULL;
7763b07762cSIngo Weinhold 	status_t ret = _ReadData(attributeName.String(), -1, B_VECTOR_ICON_TYPE,
7773b07762cSIngo Weinhold 		NULL, 0, *size, &allocatedBuffer);
7787fb6186fSStephan Aßmus 
7797fb6186fSStephan Aßmus 	if (ret < B_OK)
7807fb6186fSStephan Aßmus 		return ret;
7817fb6186fSStephan Aßmus 
7827fb6186fSStephan Aßmus 	*data = (uint8*)allocatedBuffer;
7837fb6186fSStephan Aßmus 	return B_OK;
7847fb6186fSStephan Aßmus }
7857fb6186fSStephan Aßmus 
786e1b526b9SJonas Sundström 
787d6b205f3SIngo Weinhold status_t
788d6b205f3SIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const BBitmap* icon,
789c41356faSIngo Weinhold 	icon_size which, bool updateMimeDB)
790d6b205f3SIngo Weinhold {
79198da112cSIngo Weinhold 	status_t error = B_OK;
792c41356faSIngo Weinhold 
79398da112cSIngo Weinhold 	// set some icon size related variables
79498da112cSIngo Weinhold 	BString attributeString;
79598da112cSIngo Weinhold 	BRect bounds;
796a04efc92SIngo Weinhold 	uint32 attrType = 0;
797a04efc92SIngo Weinhold 	size_t attrSize = 0;
798a04efc92SIngo Weinhold 	int32 resourceID = 0;
79998da112cSIngo Weinhold 	switch (which) {
80098da112cSIngo Weinhold 		case B_MINI_ICON:
80198da112cSIngo Weinhold 			attributeString = kMiniIconAttribute;
80298da112cSIngo Weinhold 			bounds.Set(0, 0, 15, 15);
80398da112cSIngo Weinhold 			attrType = B_MINI_ICON_TYPE;
80498da112cSIngo Weinhold 			attrSize = 16 * 16;
8053b07762cSIngo Weinhold 			resourceID = type != NULL
8063b07762cSIngo Weinhold 				? kMiniIconForTypeResourceID : kMiniIconResourceID;
80798da112cSIngo Weinhold 			break;
80898da112cSIngo Weinhold 		case B_LARGE_ICON:
80998da112cSIngo Weinhold 			attributeString = kLargeIconAttribute;
81098da112cSIngo Weinhold 			bounds.Set(0, 0, 31, 31);
81198da112cSIngo Weinhold 			attrType = B_LARGE_ICON_TYPE;
81298da112cSIngo Weinhold 			attrSize = 32 * 32;
8133b07762cSIngo Weinhold 			resourceID = type != NULL
8143b07762cSIngo Weinhold 				? kLargeIconForTypeResourceID : kLargeIconResourceID;
81598da112cSIngo Weinhold 			break;
81698da112cSIngo Weinhold 		default:
81798da112cSIngo Weinhold 			error = B_BAD_VALUE;
81898da112cSIngo Weinhold 			break;
81998da112cSIngo Weinhold 	}
820c41356faSIngo Weinhold 
82198da112cSIngo Weinhold 	// check type param
82298da112cSIngo Weinhold 	if (error == B_OK) {
8233b07762cSIngo Weinhold 		if (type != NULL) {
82417819be3SIngo Weinhold 			if (BMimeType::IsValid(type))
82598da112cSIngo Weinhold 				attributeString += type;
82617819be3SIngo Weinhold 			else
82717819be3SIngo Weinhold 				error = B_BAD_VALUE;
82898da112cSIngo Weinhold 		} else
82998da112cSIngo Weinhold 			attributeString += kStandardIconType;
83098da112cSIngo Weinhold 	}
83198da112cSIngo Weinhold 	const char* attribute = attributeString.String();
832c41356faSIngo Weinhold 
83398da112cSIngo Weinhold 	// check parameter and initialization
8343b07762cSIngo Weinhold 	if (error == B_OK && icon != NULL
83598da112cSIngo Weinhold 		&& (icon->InitCheck() != B_OK || icon->Bounds() != bounds)) {
83698da112cSIngo Weinhold 		error = B_BAD_VALUE;
83798da112cSIngo Weinhold 	}
83898da112cSIngo Weinhold 	if (error == B_OK && InitCheck() != B_OK)
83998da112cSIngo Weinhold 		error = B_NO_INIT;
840c41356faSIngo Weinhold 
84198da112cSIngo Weinhold 	// write/remove the attribute
84298da112cSIngo Weinhold 	if (error == B_OK) {
8433b07762cSIngo Weinhold 		if (icon != NULL) {
84498da112cSIngo Weinhold 			bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
84598da112cSIngo Weinhold 			if (otherColorSpace) {
846290bc091SIngo Weinhold 				BBitmap bitmap(bounds, B_BITMAP_NO_SERVER_LINK, B_CMAP8);
84798da112cSIngo Weinhold 				error = bitmap.InitCheck();
84876ba3434SIngo Weinhold 				if (error == B_OK)
84976ba3434SIngo Weinhold 					error = bitmap.ImportBits(icon);
85098da112cSIngo Weinhold 				if (error == B_OK) {
85198da112cSIngo Weinhold 					error = _WriteData(attribute, resourceID, attrType,
85298da112cSIngo Weinhold 						bitmap.Bits(), attrSize, true);
85398da112cSIngo Weinhold 				}
85498da112cSIngo Weinhold 			} else {
85598da112cSIngo Weinhold 				error = _WriteData(attribute, resourceID, attrType,
85698da112cSIngo Weinhold 					icon->Bits(), attrSize, true);
85798da112cSIngo Weinhold 			}
85898da112cSIngo Weinhold 		} else	// no icon given => remove
85998da112cSIngo Weinhold 			error = _RemoveData(attribute, attrType);
86098da112cSIngo Weinhold 	}
861c41356faSIngo Weinhold 
86298da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
86398da112cSIngo Weinhold 	BMimeType mimeType;
864c41356faSIngo Weinhold 	if (updateMimeDB && error == B_OK && GetMetaMime(&mimeType) == B_OK) {
86598da112cSIngo Weinhold 		if (!mimeType.IsInstalled())
86698da112cSIngo Weinhold 			error = mimeType.Install();
86798da112cSIngo Weinhold 		if (error == B_OK)
86898da112cSIngo Weinhold 			error = mimeType.SetIconForType(type, icon, which);
86998da112cSIngo Weinhold 	}
87098da112cSIngo Weinhold 	return error;
871d6b205f3SIngo Weinhold }
872d6b205f3SIngo Weinhold 
873e1b526b9SJonas Sundström 
8747fb6186fSStephan Aßmus status_t
875c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const BBitmap* icon,
876c41356faSIngo Weinhold 	icon_size which)
877c41356faSIngo Weinhold {
878c41356faSIngo Weinhold 	return SetIconForType(type, icon, which, true);
879c41356faSIngo Weinhold }
880c41356faSIngo Weinhold 
881c41356faSIngo Weinhold 
882c41356faSIngo Weinhold status_t
883c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const uint8* data, size_t size,
884c41356faSIngo Weinhold 	bool updateMimeDB)
8857fb6186fSStephan Aßmus {
8867fb6186fSStephan Aßmus 	if (InitCheck() != B_OK)
8877fb6186fSStephan Aßmus 		return B_NO_INIT;
8887fb6186fSStephan Aßmus 
8897fb6186fSStephan Aßmus 	// set some icon related variables
8907fb6186fSStephan Aßmus 	BString attributeString = kIconAttribute;
8917fb6186fSStephan Aßmus 	int32 resourceID = type ? kIconForTypeResourceID : kIconResourceID;
892bae87c91SAxel Dörfler 	uint32 attrType = B_VECTOR_ICON_TYPE;
8937fb6186fSStephan Aßmus 
8947fb6186fSStephan Aßmus 	// check type param
8953b07762cSIngo Weinhold 	if (type != NULL) {
8967fb6186fSStephan Aßmus 		if (BMimeType::IsValid(type))
8977fb6186fSStephan Aßmus 			attributeString += type;
8987fb6186fSStephan Aßmus 		else
8997fb6186fSStephan Aßmus 			return B_BAD_VALUE;
9007fb6186fSStephan Aßmus 	} else
9017fb6186fSStephan Aßmus 		attributeString += kIconType;
9027fb6186fSStephan Aßmus 
9037fb6186fSStephan Aßmus 	const char* attribute = attributeString.String();
9047fb6186fSStephan Aßmus 
9057fb6186fSStephan Aßmus 	status_t error;
9067fb6186fSStephan Aßmus 	// write/remove the attribute
9073b07762cSIngo Weinhold 	if (data != NULL)
9087fb6186fSStephan Aßmus 		error = _WriteData(attribute, resourceID, attrType, data, size, true);
9097fb6186fSStephan Aßmus 	else	// no icon given => remove
9107fb6186fSStephan Aßmus 		error = _RemoveData(attribute, attrType);
9117fb6186fSStephan Aßmus 
9127fb6186fSStephan Aßmus 	// set the attribute on the MIME type, if the file has a signature
9137fb6186fSStephan Aßmus 	BMimeType mimeType;
914c41356faSIngo Weinhold 	if (updateMimeDB && error == B_OK && GetMetaMime(&mimeType) == B_OK) {
9157fb6186fSStephan Aßmus 		if (!mimeType.IsInstalled())
9167fb6186fSStephan Aßmus 			error = mimeType.Install();
9177fb6186fSStephan Aßmus 		if (error == B_OK)
9187fb6186fSStephan Aßmus 			error = mimeType.SetIconForType(type, data, size);
9197fb6186fSStephan Aßmus 	}
9207fb6186fSStephan Aßmus 	return error;
9217fb6186fSStephan Aßmus }
9227fb6186fSStephan Aßmus 
923e1b526b9SJonas Sundström 
924c41356faSIngo Weinhold status_t
925c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const uint8* data, size_t size)
926c41356faSIngo Weinhold {
927c41356faSIngo Weinhold 	return SetIconForType(type, data, size, true);
928c41356faSIngo Weinhold }
929c41356faSIngo Weinhold 
930c41356faSIngo Weinhold 
931d6b205f3SIngo Weinhold void
932d6b205f3SIngo Weinhold BAppFileInfo::SetInfoLocation(info_location location)
933d6b205f3SIngo Weinhold {
934d0c290bfSAxel Dörfler 	// if the resources failed to initialize, we must not use them
935d0c290bfSAxel Dörfler 	if (fResources == NULL)
936d0c290bfSAxel Dörfler 		location = info_location(location & ~B_USE_RESOURCES);
937d0c290bfSAxel Dörfler 
93898da112cSIngo Weinhold 	fWhere = location;
939d6b205f3SIngo Weinhold }
940d6b205f3SIngo Weinhold 
941d6b205f3SIngo Weinhold bool
942d6b205f3SIngo Weinhold BAppFileInfo::IsUsingAttributes() const
943d6b205f3SIngo Weinhold {
944d0c290bfSAxel Dörfler 	return (fWhere & B_USE_ATTRIBUTES) != 0;
945d6b205f3SIngo Weinhold }
946d6b205f3SIngo Weinhold 
947e1b526b9SJonas Sundström 
948d6b205f3SIngo Weinhold bool
949d6b205f3SIngo Weinhold BAppFileInfo::IsUsingResources() const
950d6b205f3SIngo Weinhold {
951d0c290bfSAxel Dörfler 	return (fWhere & B_USE_RESOURCES) != 0;
952d6b205f3SIngo Weinhold }
953d6b205f3SIngo Weinhold 
954e1b526b9SJonas Sundström 
955d6b205f3SIngo Weinhold // FBC
956d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
957d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
958d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
959d6b205f3SIngo Weinhold 
960e1b526b9SJonas Sundström 
961*a30a4a41SJohn Scipione //!	Privatized assignment operator to prevent usage.
962d6b205f3SIngo Weinhold BAppFileInfo&
963d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo&)
964d6b205f3SIngo Weinhold {
965d6b205f3SIngo Weinhold 	return *this;
966d6b205f3SIngo Weinhold }
967d6b205f3SIngo Weinhold 
968e1b526b9SJonas Sundström 
969*a30a4a41SJohn Scipione //! Privatized copy constructor to prevent usage.
970d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo&)
971d6b205f3SIngo Weinhold {
972d6b205f3SIngo Weinhold }
973d6b205f3SIngo Weinhold 
974e1b526b9SJonas Sundström 
975*a30a4a41SJohn Scipione /*!	Initializes a BMimeType to the signature of the associated file.
976*a30a4a41SJohn Scipione 
977*a30a4a41SJohn Scipione 	\warning The parameter \a meta is not checked.
978*a30a4a41SJohn Scipione 
979*a30a4a41SJohn Scipione 	\param meta A pointer to a pre-allocated BMimeType that shall be
980*a30a4a41SJohn Scipione 		   initialized to the signature of the associated file.
981*a30a4a41SJohn Scipione 
982*a30a4a41SJohn Scipione 	\returns A status code.
983*a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
984*a30a4a41SJohn Scipione 	\retval B_BAD_VALUE \c NULL \a meta
985*a30a4a41SJohn Scipione 	\retval B_ENTRY_NOT_FOUND The file has not signature or the signature is
986*a30a4a41SJohn Scipione 	        (not installed in the MIME database.) no valid MIME string.
987*a30a4a41SJohn Scipione */
98898da112cSIngo Weinhold status_t
98998da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType* meta) const
99098da112cSIngo Weinhold {
99198da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
99298da112cSIngo Weinhold 	status_t error = GetSignature(signature);
99398da112cSIngo Weinhold 	if (error == B_OK)
99498da112cSIngo Weinhold 		error = meta->SetTo(signature);
9957f20062dSJérôme Duval 	else if (error == B_BAD_VALUE)
9967f20062dSJérôme Duval 		error = B_ENTRY_NOT_FOUND;
99798da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
99898da112cSIngo Weinhold 		error = B_BAD_VALUE;
99998da112cSIngo Weinhold 	return error;
100098da112cSIngo Weinhold }
100198da112cSIngo Weinhold 
1002e1b526b9SJonas Sundström 
1003*a30a4a41SJohn Scipione /*!	Reads data from an attribute or resource.
1004*a30a4a41SJohn Scipione 
1005*a30a4a41SJohn Scipione 	\note The data is read from the location specified by \a fWhere.
1006*a30a4a41SJohn Scipione 
1007*a30a4a41SJohn Scipione 	\warning The object must be properly initialized. The parameters are
1008*a30a4a41SJohn Scipione 		\b NOT checked.
1009*a30a4a41SJohn Scipione 
1010*a30a4a41SJohn Scipione 	\param name The name of the attribute/resource to be read.
1011*a30a4a41SJohn Scipione 	\param id The resource ID of the resource to be read. It is ignored
1012*a30a4a41SJohn Scipione 		   when < 0.
1013*a30a4a41SJohn Scipione 	\param type The type of the attribute/resource to be read.
1014*a30a4a41SJohn Scipione 	\param buffer A pre-allocated buffer for the data to be read.
1015*a30a4a41SJohn Scipione 	\param bufferSize The size of the supplied buffer.
1016*a30a4a41SJohn Scipione 	\param bytesRead A reference parameter, set to the number of bytes
1017*a30a4a41SJohn Scipione 		   actually read.
1018*a30a4a41SJohn Scipione 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
1019*a30a4a41SJohn Scipione 		   large enough too store the whole data and writes a pointer to it
1020*a30a4a41SJohn Scipione 		   into this variable. If \c NULL, the supplied buffer is used.
1021*a30a4a41SJohn Scipione 
1022*a30a4a41SJohn Scipione 	\returns A status code.
1023*a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
1024*a30a4a41SJohn Scipione 	\retval B_ENTRY_NOT_FOUND The entry was not found.
1025*a30a4a41SJohn Scipione 	\retval B_NO_MEMORY Ran out of memory allocating the buffer.
1026*a30a4a41SJohn Scipione 	\retval B_BAD_VALUE \a type did not match.
1027*a30a4a41SJohn Scipione */
102898da112cSIngo Weinhold status_t
102998da112cSIngo Weinhold BAppFileInfo::_ReadData(const char* name, int32 id, type_code type,
10303b07762cSIngo Weinhold 	void* buffer, size_t bufferSize, size_t& bytesRead, void** allocatedBuffer)
10313b07762cSIngo Weinhold 	const
103298da112cSIngo Weinhold {
103398da112cSIngo Weinhold 	status_t error = B_OK;
1034338b8dc3SIngo Weinhold 
103598da112cSIngo Weinhold 	if (allocatedBuffer)
103698da112cSIngo Weinhold 		buffer = NULL;
1037338b8dc3SIngo Weinhold 
1038338b8dc3SIngo Weinhold 	bool foundData = false;
1039338b8dc3SIngo Weinhold 
104098da112cSIngo Weinhold 	if (IsUsingAttributes()) {
104198da112cSIngo Weinhold 		// get an attribute info
104298da112cSIngo Weinhold 		attr_info info;
104398da112cSIngo Weinhold 		if (error == B_OK)
104498da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1045338b8dc3SIngo Weinhold 
104698da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
104798da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
104898da112cSIngo Weinhold 			error = B_BAD_VALUE;
10493b07762cSIngo Weinhold 		if (error == B_OK && allocatedBuffer != NULL) {
105098da112cSIngo Weinhold 			buffer = malloc(info.size);
10513b07762cSIngo Weinhold 			if (buffer == NULL)
105298da112cSIngo Weinhold 				error = B_NO_MEMORY;
105398da112cSIngo Weinhold 			bufferSize = info.size;
105498da112cSIngo Weinhold 		}
10559be774b5SAlex Smith 		if (error == B_OK && (off_t)bufferSize < info.size)
105698da112cSIngo Weinhold 			error = B_BAD_VALUE;
1057338b8dc3SIngo Weinhold 
105898da112cSIngo Weinhold 		// read the data
105998da112cSIngo Weinhold 		if (error == B_OK) {
106098da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
106198da112cSIngo Weinhold 			if (read < 0)
106298da112cSIngo Weinhold 				error = read;
106398da112cSIngo Weinhold 			else if (read != info.size)
106498da112cSIngo Weinhold 				error = B_ERROR;
106598da112cSIngo Weinhold 			else
106698da112cSIngo Weinhold 				bytesRead = read;
106798da112cSIngo Weinhold 		}
1068338b8dc3SIngo Weinhold 
10693b07762cSIngo Weinhold 		foundData = error == B_OK;
1070b4598d95SIngo Weinhold 
1071b4598d95SIngo Weinhold 		// free the allocated buffer on error
10723b07762cSIngo Weinhold 		if (!foundData && allocatedBuffer != NULL && buffer != NULL) {
1073b4598d95SIngo Weinhold 			free(buffer);
1074b4598d95SIngo Weinhold 			buffer = NULL;
1075b4598d95SIngo Weinhold 		}
1076338b8dc3SIngo Weinhold 	}
1077338b8dc3SIngo Weinhold 
1078338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
107998da112cSIngo Weinhold 		// get a resource info
1080338b8dc3SIngo Weinhold 		error = B_OK;
108198da112cSIngo Weinhold 		int32 idFound;
108298da112cSIngo Weinhold 		size_t sizeFound;
108398da112cSIngo Weinhold 		if (error == B_OK) {
108498da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
108598da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
108698da112cSIngo Weinhold 		}
1087338b8dc3SIngo Weinhold 
108898da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
108998da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
109098da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1091b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
109298da112cSIngo Weinhold 			buffer = malloc(sizeFound);
109398da112cSIngo Weinhold 			if (!buffer)
109498da112cSIngo Weinhold 				error = B_NO_MEMORY;
109598da112cSIngo Weinhold 			bufferSize = sizeFound;
109698da112cSIngo Weinhold 		}
109798da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
109898da112cSIngo Weinhold 			error = B_BAD_VALUE;
1099338b8dc3SIngo Weinhold 
110098da112cSIngo Weinhold 		// load resource
110198da112cSIngo Weinhold 		const void* resourceData = NULL;
110298da112cSIngo Weinhold 		if (error == B_OK) {
110398da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
11043b07762cSIngo Weinhold 			if (resourceData != NULL && sizeFound == bytesRead)
110598da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
110698da112cSIngo Weinhold 			else
110798da112cSIngo Weinhold 				error = B_ERROR;
110898da112cSIngo Weinhold 		}
1109773be699SAxel Dörfler 	} else if (!foundData)
111098da112cSIngo Weinhold 		error = B_BAD_VALUE;
1111338b8dc3SIngo Weinhold 
111298da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
11133b07762cSIngo Weinhold 	if (allocatedBuffer != NULL) {
111498da112cSIngo Weinhold 		if (error == B_OK)
111598da112cSIngo Weinhold 			*allocatedBuffer = buffer;
111698da112cSIngo Weinhold 		else
111798da112cSIngo Weinhold 			free(buffer);
111898da112cSIngo Weinhold 	}
1119338b8dc3SIngo Weinhold 
112098da112cSIngo Weinhold 	return error;
112198da112cSIngo Weinhold }
112298da112cSIngo Weinhold 
1123e1b526b9SJonas Sundström 
1124*a30a4a41SJohn Scipione /*!	Writes data to an attribute or resource.
1125*a30a4a41SJohn Scipione 
1126*a30a4a41SJohn Scipione 	\note The data is written to the location(s) specified by \a fWhere.
1127*a30a4a41SJohn Scipione 
1128*a30a4a41SJohn Scipione 	\warning The object must be properly initialized. The parameters are
1129*a30a4a41SJohn Scipione 		\b NOT checked.
1130*a30a4a41SJohn Scipione 
1131*a30a4a41SJohn Scipione 	\param name The name of the attribute/resource to be written.
1132*a30a4a41SJohn Scipione 	\param id The resource ID of the resource to be written.
1133*a30a4a41SJohn Scipione 	\param type The type of the attribute/resource to be written.
1134*a30a4a41SJohn Scipione 	\param buffer A buffer containing the data to be written.
1135*a30a4a41SJohn Scipione 	\param bufferSize The size of the supplied buffer.
1136*a30a4a41SJohn Scipione 	\param findID If set to \c true use the ID that is already assigned to the
1137*a30a4a41SJohn Scipione 		   \a name / \a type pair or take the first unused ID >= \a id.
1138*a30a4a41SJohn Scipione 		   If \c false, \a id is used.
1139*a30a4a41SJohn Scipione 
1140*a30a4a41SJohn Scipione 	\returns A status code.
1141*a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
1142*a30a4a41SJohn Scipione 	\retval B_ERROR An error occurred while trying to write the data.
1143*a30a4a41SJohn Scipione */
114498da112cSIngo Weinhold status_t
114598da112cSIngo Weinhold BAppFileInfo::_WriteData(const char* name, int32 id, type_code type,
114698da112cSIngo Weinhold 	const void* buffer, size_t bufferSize, bool findID)
114798da112cSIngo Weinhold {
1148d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1149d0c290bfSAxel Dörfler 		return B_NO_INIT;
1150d0c290bfSAxel Dörfler 
115198da112cSIngo Weinhold 	status_t error = B_OK;
1152d0c290bfSAxel Dörfler 
115398da112cSIngo Weinhold 	// write to attribute
1154d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
115598da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
115698da112cSIngo Weinhold 		if (written < 0)
115798da112cSIngo Weinhold 			error = written;
115898da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
115998da112cSIngo Weinhold 			error = B_ERROR;
116098da112cSIngo Weinhold 	}
116198da112cSIngo Weinhold 	// write to resource
116298da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
116398da112cSIngo Weinhold 		if (findID) {
116498da112cSIngo Weinhold 			// get the resource info
116598da112cSIngo Weinhold 			int32 idFound;
116698da112cSIngo Weinhold 			size_t sizeFound;
116798da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
116898da112cSIngo Weinhold 				id = idFound;
116998da112cSIngo Weinhold 			else {
117098da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
117198da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
117298da112cSIngo Weinhold 					id++;
117398da112cSIngo Weinhold 			}
117498da112cSIngo Weinhold 		}
117598da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
117698da112cSIngo Weinhold 	}
117798da112cSIngo Weinhold 	return error;
117898da112cSIngo Weinhold }
117998da112cSIngo Weinhold 
118098da112cSIngo Weinhold 
1181*a30a4a41SJohn Scipione /*!	Removes an attribute or resource.
1182*a30a4a41SJohn Scipione 
1183*a30a4a41SJohn Scipione 	\note The removal location is specified by \a fWhere.
1184*a30a4a41SJohn Scipione 
1185*a30a4a41SJohn Scipione 	\warning The object must be properly initialized. The parameters are
1186*a30a4a41SJohn Scipione 		\b NOT checked.
1187*a30a4a41SJohn Scipione 
1188*a30a4a41SJohn Scipione 	\param name The name of the attribute/resource to be remove.
1189*a30a4a41SJohn Scipione 	\param type The type of the attribute/resource to be removed.
1190*a30a4a41SJohn Scipione 
1191*a30a4a41SJohn Scipione 	\returns A status code.
1192*a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
1193*a30a4a41SJohn Scipione 	\retval B_NO_INIT Not using attributes and not using resources.
1194*a30a4a41SJohn Scipione 	\retval B_ENTRY_NOT_FOUND The attribute or resource was not found.
1195*a30a4a41SJohn Scipione */
119698da112cSIngo Weinhold status_t
119798da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char* name, type_code type)
119898da112cSIngo Weinhold {
1199d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1200d0c290bfSAxel Dörfler 		return B_NO_INIT;
1201d0c290bfSAxel Dörfler 
120298da112cSIngo Weinhold 	status_t error = B_OK;
1203d0c290bfSAxel Dörfler 
120498da112cSIngo Weinhold 	// remove the attribute
1205d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
120698da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
120798da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
120898da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
120998da112cSIngo Weinhold 			error = B_OK;
121098da112cSIngo Weinhold 	}
121198da112cSIngo Weinhold 	// remove the resource
121298da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
121398da112cSIngo Weinhold 		// get a resource info
121498da112cSIngo Weinhold 		int32 idFound;
121598da112cSIngo Weinhold 		size_t sizeFound;
121698da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
121798da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
121898da112cSIngo Weinhold 	}
121998da112cSIngo Weinhold 	return error;
122098da112cSIngo Weinhold }
1221