xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision c41356fab56ee714d3930183e09d7ee5ad9c1de4)
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
371*c41356faSIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool updateMimeDB,
372*c41356faSIngo 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;
378*c41356faSIngo Weinhold 
37998da112cSIngo Weinhold 	BMimeType mimeType;
38098da112cSIngo Weinhold 	if (error == B_OK)
38198da112cSIngo Weinhold 		error = GetMetaMime(&mimeType);
382*c41356faSIngo 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 			}
394*c41356faSIngo 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 			}
402*c41356faSIngo 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 			}
410*c41356faSIngo Weinhold 
41198da112cSIngo Weinhold 			// flatten the message
41298da112cSIngo Weinhold 			if (error == B_OK)
41398da112cSIngo Weinhold 				error = types->Flatten(buffer, size);
414*c41356faSIngo 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 			}
420*c41356faSIngo Weinhold 
42198da112cSIngo Weinhold 			delete[] buffer;
42298da112cSIngo Weinhold 		} else
42398da112cSIngo Weinhold 			error = _RemoveData(kSupportedTypesAttribute, B_MESSAGE_TYPE);
424*c41356faSIngo Weinhold 
42598da112cSIngo Weinhold 		// update the MIME database, if the app signature is installed
426*c41356faSIngo 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
434*c41356faSIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types, bool syncAll)
435*c41356faSIngo Weinhold {
436*c41356faSIngo Weinhold 	return SetSupportedTypes(types, true, syncAll);
437*c41356faSIngo Weinhold }
438*c41356faSIngo Weinhold 
439*c41356faSIngo Weinhold 
440*c41356faSIngo Weinhold status_t
441d6b205f3SIngo Weinhold BAppFileInfo::SetSupportedTypes(const BMessage* types)
442d6b205f3SIngo Weinhold {
443*c41356faSIngo 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
512*c41356faSIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which, bool updateMimeDB)
513*c41356faSIngo Weinhold {
514*c41356faSIngo Weinhold 	return SetIconForType(NULL, icon, which, updateMimeDB);
515*c41356faSIngo Weinhold }
516*c41356faSIngo Weinhold 
517*c41356faSIngo Weinhold 
518*c41356faSIngo Weinhold status_t
519d6b205f3SIngo Weinhold BAppFileInfo::SetIcon(const BBitmap* icon, icon_size which)
520d6b205f3SIngo Weinhold {
521*c41356faSIngo Weinhold 	return SetIconForType(NULL, icon, which, true);
522*c41356faSIngo Weinhold }
523*c41356faSIngo Weinhold 
524*c41356faSIngo Weinhold 
525*c41356faSIngo Weinhold status_t
526*c41356faSIngo Weinhold BAppFileInfo::SetIcon(const uint8* data, size_t size, bool updateMimeDB)
527*c41356faSIngo Weinhold {
528*c41356faSIngo 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 {
535*c41356faSIngo 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 
711*c41356faSIngo Weinhold 	// compose attribute name
712*c41356faSIngo 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,
789*c41356faSIngo Weinhold 	icon_size which, bool updateMimeDB)
790d6b205f3SIngo Weinhold {
79198da112cSIngo Weinhold 	status_t error = B_OK;
792*c41356faSIngo 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 	}
820*c41356faSIngo 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();
832*c41356faSIngo 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;
840*c41356faSIngo 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 	}
861*c41356faSIngo Weinhold 
86298da112cSIngo Weinhold 	// set the attribute on the MIME type, if the file has a signature
86398da112cSIngo Weinhold 	BMimeType mimeType;
864*c41356faSIngo 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
875*c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const BBitmap* icon,
876*c41356faSIngo Weinhold 	icon_size which)
877*c41356faSIngo Weinhold {
878*c41356faSIngo Weinhold 	return SetIconForType(type, icon, which, true);
879*c41356faSIngo Weinhold }
880*c41356faSIngo Weinhold 
881*c41356faSIngo Weinhold 
882*c41356faSIngo Weinhold status_t
883*c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const uint8* data, size_t size,
884*c41356faSIngo 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;
914*c41356faSIngo 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 
924*c41356faSIngo Weinhold status_t
925*c41356faSIngo Weinhold BAppFileInfo::SetIconForType(const char* type, const uint8* data, size_t size)
926*c41356faSIngo Weinhold {
927*c41356faSIngo Weinhold 	return SetIconForType(type, data, size, true);
928*c41356faSIngo Weinhold }
929*c41356faSIngo Weinhold 
930*c41356faSIngo 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 
961d6b205f3SIngo Weinhold BAppFileInfo&
962d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo&)
963d6b205f3SIngo Weinhold {
964d6b205f3SIngo Weinhold 	return *this;
965d6b205f3SIngo Weinhold }
966d6b205f3SIngo Weinhold 
967e1b526b9SJonas Sundström 
968d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo&)
969d6b205f3SIngo Weinhold {
970d6b205f3SIngo Weinhold }
971d6b205f3SIngo Weinhold 
972e1b526b9SJonas Sundström 
97398da112cSIngo Weinhold status_t
97498da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType* meta) const
97598da112cSIngo Weinhold {
97698da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
97798da112cSIngo Weinhold 	status_t error = GetSignature(signature);
97898da112cSIngo Weinhold 	if (error == B_OK)
97998da112cSIngo Weinhold 		error = meta->SetTo(signature);
9807f20062dSJérôme Duval 	else if (error == B_BAD_VALUE)
9817f20062dSJérôme Duval 		error = B_ENTRY_NOT_FOUND;
98298da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
98398da112cSIngo Weinhold 		error = B_BAD_VALUE;
98498da112cSIngo Weinhold 	return error;
98598da112cSIngo Weinhold }
98698da112cSIngo Weinhold 
987e1b526b9SJonas Sundström 
98898da112cSIngo Weinhold status_t
98998da112cSIngo Weinhold BAppFileInfo::_ReadData(const char* name, int32 id, type_code type,
9903b07762cSIngo Weinhold 	void* buffer, size_t bufferSize, size_t& bytesRead, void** allocatedBuffer)
9913b07762cSIngo Weinhold 	const
99298da112cSIngo Weinhold {
99398da112cSIngo Weinhold 	status_t error = B_OK;
994338b8dc3SIngo Weinhold 
99598da112cSIngo Weinhold 	if (allocatedBuffer)
99698da112cSIngo Weinhold 		buffer = NULL;
997338b8dc3SIngo Weinhold 
998338b8dc3SIngo Weinhold 	bool foundData = false;
999338b8dc3SIngo Weinhold 
100098da112cSIngo Weinhold 	if (IsUsingAttributes()) {
100198da112cSIngo Weinhold 		// get an attribute info
100298da112cSIngo Weinhold 		attr_info info;
100398da112cSIngo Weinhold 		if (error == B_OK)
100498da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1005338b8dc3SIngo Weinhold 
100698da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
100798da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
100898da112cSIngo Weinhold 			error = B_BAD_VALUE;
10093b07762cSIngo Weinhold 		if (error == B_OK && allocatedBuffer != NULL) {
101098da112cSIngo Weinhold 			buffer = malloc(info.size);
10113b07762cSIngo Weinhold 			if (buffer == NULL)
101298da112cSIngo Weinhold 				error = B_NO_MEMORY;
101398da112cSIngo Weinhold 			bufferSize = info.size;
101498da112cSIngo Weinhold 		}
10159be774b5SAlex Smith 		if (error == B_OK && (off_t)bufferSize < info.size)
101698da112cSIngo Weinhold 			error = B_BAD_VALUE;
1017338b8dc3SIngo Weinhold 
101898da112cSIngo Weinhold 		// read the data
101998da112cSIngo Weinhold 		if (error == B_OK) {
102098da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
102198da112cSIngo Weinhold 			if (read < 0)
102298da112cSIngo Weinhold 				error = read;
102398da112cSIngo Weinhold 			else if (read != info.size)
102498da112cSIngo Weinhold 				error = B_ERROR;
102598da112cSIngo Weinhold 			else
102698da112cSIngo Weinhold 				bytesRead = read;
102798da112cSIngo Weinhold 		}
1028338b8dc3SIngo Weinhold 
10293b07762cSIngo Weinhold 		foundData = error == B_OK;
1030b4598d95SIngo Weinhold 
1031b4598d95SIngo Weinhold 		// free the allocated buffer on error
10323b07762cSIngo Weinhold 		if (!foundData && allocatedBuffer != NULL && buffer != NULL) {
1033b4598d95SIngo Weinhold 			free(buffer);
1034b4598d95SIngo Weinhold 			buffer = NULL;
1035b4598d95SIngo Weinhold 		}
1036338b8dc3SIngo Weinhold 	}
1037338b8dc3SIngo Weinhold 
1038338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
103998da112cSIngo Weinhold 		// get a resource info
1040338b8dc3SIngo Weinhold 		error = B_OK;
104198da112cSIngo Weinhold 		int32 idFound;
104298da112cSIngo Weinhold 		size_t sizeFound;
104398da112cSIngo Weinhold 		if (error == B_OK) {
104498da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
104598da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
104698da112cSIngo Weinhold 		}
1047338b8dc3SIngo Weinhold 
104898da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
104998da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
105098da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1051b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
105298da112cSIngo Weinhold 			buffer = malloc(sizeFound);
105398da112cSIngo Weinhold 			if (!buffer)
105498da112cSIngo Weinhold 				error = B_NO_MEMORY;
105598da112cSIngo Weinhold 			bufferSize = sizeFound;
105698da112cSIngo Weinhold 		}
105798da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
105898da112cSIngo Weinhold 			error = B_BAD_VALUE;
1059338b8dc3SIngo Weinhold 
106098da112cSIngo Weinhold 		// load resource
106198da112cSIngo Weinhold 		const void* resourceData = NULL;
106298da112cSIngo Weinhold 		if (error == B_OK) {
106398da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
10643b07762cSIngo Weinhold 			if (resourceData != NULL && sizeFound == bytesRead)
106598da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
106698da112cSIngo Weinhold 			else
106798da112cSIngo Weinhold 				error = B_ERROR;
106898da112cSIngo Weinhold 		}
1069773be699SAxel Dörfler 	} else if (!foundData)
107098da112cSIngo Weinhold 		error = B_BAD_VALUE;
1071338b8dc3SIngo Weinhold 
107298da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
10733b07762cSIngo Weinhold 	if (allocatedBuffer != NULL) {
107498da112cSIngo Weinhold 		if (error == B_OK)
107598da112cSIngo Weinhold 			*allocatedBuffer = buffer;
107698da112cSIngo Weinhold 		else
107798da112cSIngo Weinhold 			free(buffer);
107898da112cSIngo Weinhold 	}
1079338b8dc3SIngo Weinhold 
108098da112cSIngo Weinhold 	return error;
108198da112cSIngo Weinhold }
108298da112cSIngo Weinhold 
1083e1b526b9SJonas Sundström 
108498da112cSIngo Weinhold status_t
108598da112cSIngo Weinhold BAppFileInfo::_WriteData(const char* name, int32 id, type_code type,
108698da112cSIngo Weinhold 	const void* buffer, size_t bufferSize, bool findID)
108798da112cSIngo Weinhold {
1088d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1089d0c290bfSAxel Dörfler 		return B_NO_INIT;
1090d0c290bfSAxel Dörfler 
109198da112cSIngo Weinhold 	status_t error = B_OK;
1092d0c290bfSAxel Dörfler 
109398da112cSIngo Weinhold 	// write to attribute
1094d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
109598da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
109698da112cSIngo Weinhold 		if (written < 0)
109798da112cSIngo Weinhold 			error = written;
109898da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
109998da112cSIngo Weinhold 			error = B_ERROR;
110098da112cSIngo Weinhold 	}
110198da112cSIngo Weinhold 	// write to resource
110298da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
110398da112cSIngo Weinhold 		if (findID) {
110498da112cSIngo Weinhold 			// get the resource info
110598da112cSIngo Weinhold 			int32 idFound;
110698da112cSIngo Weinhold 			size_t sizeFound;
110798da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
110898da112cSIngo Weinhold 				id = idFound;
110998da112cSIngo Weinhold 			else {
111098da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
111198da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
111298da112cSIngo Weinhold 					id++;
111398da112cSIngo Weinhold 			}
111498da112cSIngo Weinhold 		}
111598da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
111698da112cSIngo Weinhold 	}
111798da112cSIngo Weinhold 	return error;
111898da112cSIngo Weinhold }
111998da112cSIngo Weinhold 
112098da112cSIngo Weinhold 
112198da112cSIngo Weinhold status_t
112298da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char* name, type_code type)
112398da112cSIngo Weinhold {
1124d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1125d0c290bfSAxel Dörfler 		return B_NO_INIT;
1126d0c290bfSAxel Dörfler 
112798da112cSIngo Weinhold 	status_t error = B_OK;
1128d0c290bfSAxel Dörfler 
112998da112cSIngo Weinhold 	// remove the attribute
1130d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
113198da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
113298da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
113398da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
113498da112cSIngo Weinhold 			error = B_OK;
113598da112cSIngo Weinhold 	}
113698da112cSIngo Weinhold 	// remove the resource
113798da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
113898da112cSIngo Weinhold 		// get a resource info
113998da112cSIngo Weinhold 		int32 idFound;
114098da112cSIngo Weinhold 		size_t sizeFound;
114198da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
114298da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
114398da112cSIngo Weinhold 	}
114498da112cSIngo Weinhold 	return error;
114598da112cSIngo Weinhold }
1146