xref: /haiku/src/kits/storage/AppFileInfo.cpp (revision b47e8b0cadeb9a9d985d7f72d2e9a099cbcb8f90)
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 
BAppFileInfo()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 
BAppFileInfo(BFile * file)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 
~BAppFileInfo()93d6b205f3SIngo Weinhold BAppFileInfo::~BAppFileInfo()
94d6b205f3SIngo Weinhold {
9598da112cSIngo Weinhold 	delete fResources;
96d6b205f3SIngo Weinhold }
97d6b205f3SIngo Weinhold 
98e1b526b9SJonas Sundström 
99d6b205f3SIngo Weinhold status_t
SetTo(BFile * file)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
GetType(char * type) const156d6b205f3SIngo 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
SetType(const char * type)180d6b205f3SIngo Weinhold BAppFileInfo::SetType(const char* type)
181d6b205f3SIngo Weinhold {
18298da112cSIngo Weinhold 	// check initialization
18398da112cSIngo Weinhold 	status_t error = B_OK;
184c13e346aSAdrien Destugues 	if (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);
190c13e346aSAdrien Destugues 			if (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
GetSignature(char * signature) const205d6b205f3SIngo 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
SetSignature(const char * signature)229d6b205f3SIngo Weinhold BAppFileInfo::SetSignature(const char* signature)
230d6b205f3SIngo Weinhold {
23198da112cSIngo Weinhold 	// check initialization
23298da112cSIngo Weinhold 	status_t error = B_OK;
233c13e346aSAdrien Destugues 	if (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);
239c13e346aSAdrien Destugues 			if (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
GetCatalogEntry(char * catalogEntry) const25482e7ef67SJonas 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
SetCatalogEntry(const char * catalogEntry)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
GetAppFlags(uint32 * flags) const297d6b205f3SIngo 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
SetAppFlags(uint32 flags)317d6b205f3SIngo Weinhold BAppFileInfo::SetAppFlags(uint32 flags)
318d6b205f3SIngo Weinhold {
31998da112cSIngo Weinhold 	// check initialization
32098da112cSIngo Weinhold 	status_t error = B_OK;
321c13e346aSAdrien Destugues 	if (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
RemoveAppFlags()33322920adfSStephan Aßmus BAppFileInfo::RemoveAppFlags()
33422920adfSStephan Aßmus {
33522920adfSStephan Aßmus 	// check initialization
33622920adfSStephan Aßmus 	status_t error = B_OK;
337c13e346aSAdrien Destugues 	if (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
GetSupportedTypes(BMessage * types) const348d6b205f3SIngo 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
SetSupportedTypes(const BMessage * types,bool updateMimeDB,bool syncAll)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;
376c13e346aSAdrien Destugues 	if (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
SetSupportedTypes(const BMessage * types,bool syncAll)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
SetSupportedTypes(const BMessage * types)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
IsSupportedType(const char * type) const448d6b205f3SIngo 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
Supports(BMimeType * type) const475d6b205f3SIngo 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
GetIcon(BBitmap * icon,icon_size which) const498d6b205f3SIngo 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
GetIcon(uint8 ** data,size_t * size) const5057fb6186fSStephan 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
SetIcon(const BBitmap * icon,icon_size which,bool updateMimeDB)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
SetIcon(const BBitmap * icon,icon_size which)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
SetIcon(const uint8 * data,size_t size,bool updateMimeDB)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
SetIcon(const uint8 * data,size_t size)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
GetVersionInfo(version_info * info,version_kind kind) const540d6b205f3SIngo 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
SetVersionInfo(const version_info * info,version_kind kind)587d6b205f3SIngo Weinhold BAppFileInfo::SetVersionInfo(const version_info* info, version_kind kind)
588d6b205f3SIngo Weinhold {
58998da112cSIngo Weinhold 	// check initialization
59098da112cSIngo Weinhold 	status_t error = B_OK;
591c13e346aSAdrien Destugues 	if (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
GetIconForType(const char * type,BBitmap * icon,icon_size size) const6403b07762cSIngo 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
GetIconForType(const char * type,uint8 ** data,size_t * size) const7553b07762cSIngo 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
SetIconForType(const char * type,const BBitmap * icon,icon_size which,bool updateMimeDB)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
SetIconForType(const char * type,const BBitmap * icon,icon_size which)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
SetIconForType(const char * type,const uint8 * data,size_t size,bool updateMimeDB)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
SetIconForType(const char * type,const uint8 * data,size_t size)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
SetInfoLocation(info_location location)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
IsUsingAttributes() const942d6b205f3SIngo 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
IsUsingResources() const949d6b205f3SIngo 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
_ReservedAppFileInfo1()956d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo1() {}
_ReservedAppFileInfo2()957d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo2() {}
_ReservedAppFileInfo3()958d6b205f3SIngo Weinhold void BAppFileInfo::_ReservedAppFileInfo3() {}
959d6b205f3SIngo Weinhold 
960e1b526b9SJonas Sundström 
961*b47e8b0cSAugustin Cavalier #ifdef __HAIKU_BEOS_COMPATIBLE
962a30a4a41SJohn Scipione //!	Privatized assignment operator to prevent usage.
963d6b205f3SIngo Weinhold BAppFileInfo&
operator =(const BAppFileInfo &)964d6b205f3SIngo Weinhold BAppFileInfo::operator=(const BAppFileInfo&)
965d6b205f3SIngo Weinhold {
966d6b205f3SIngo Weinhold 	return *this;
967d6b205f3SIngo Weinhold }
968d6b205f3SIngo Weinhold 
969e1b526b9SJonas Sundström 
970a30a4a41SJohn Scipione //! Privatized copy constructor to prevent usage.
BAppFileInfo(const BAppFileInfo &)971d6b205f3SIngo Weinhold BAppFileInfo::BAppFileInfo(const BAppFileInfo&)
972d6b205f3SIngo Weinhold {
973d6b205f3SIngo Weinhold }
974ebb0db62SAugustin Cavalier #endif
975d6b205f3SIngo Weinhold 
976e1b526b9SJonas Sundström 
977a30a4a41SJohn Scipione /*!	Initializes a BMimeType to the signature of the associated file.
978a30a4a41SJohn Scipione 
979a30a4a41SJohn Scipione 	\warning The parameter \a meta is not checked.
980a30a4a41SJohn Scipione 
981a30a4a41SJohn Scipione 	\param meta A pointer to a pre-allocated BMimeType that shall be
982a30a4a41SJohn Scipione 		   initialized to the signature of the associated file.
983a30a4a41SJohn Scipione 
984a30a4a41SJohn Scipione 	\returns A status code.
985a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
986a30a4a41SJohn Scipione 	\retval B_BAD_VALUE \c NULL \a meta
987a30a4a41SJohn Scipione 	\retval B_ENTRY_NOT_FOUND The file has not signature or the signature is
988a30a4a41SJohn Scipione 	        (not installed in the MIME database.) no valid MIME string.
989a30a4a41SJohn Scipione */
99098da112cSIngo Weinhold status_t
GetMetaMime(BMimeType * meta) const99198da112cSIngo Weinhold BAppFileInfo::GetMetaMime(BMimeType* meta) const
99298da112cSIngo Weinhold {
99398da112cSIngo Weinhold 	char signature[B_MIME_TYPE_LENGTH];
99498da112cSIngo Weinhold 	status_t error = GetSignature(signature);
99598da112cSIngo Weinhold 	if (error == B_OK)
99698da112cSIngo Weinhold 		error = meta->SetTo(signature);
9977f20062dSJérôme Duval 	else if (error == B_BAD_VALUE)
9987f20062dSJérôme Duval 		error = B_ENTRY_NOT_FOUND;
99998da112cSIngo Weinhold 	if (error == B_OK && !meta->IsValid())
100098da112cSIngo Weinhold 		error = B_BAD_VALUE;
100198da112cSIngo Weinhold 	return error;
100298da112cSIngo Weinhold }
100398da112cSIngo Weinhold 
1004e1b526b9SJonas Sundström 
1005a30a4a41SJohn Scipione /*!	Reads data from an attribute or resource.
1006a30a4a41SJohn Scipione 
1007a30a4a41SJohn Scipione 	\note The data is read from the location specified by \a fWhere.
1008a30a4a41SJohn Scipione 
1009a30a4a41SJohn Scipione 	\warning The object must be properly initialized. The parameters are
1010a30a4a41SJohn Scipione 		\b NOT checked.
1011a30a4a41SJohn Scipione 
1012a30a4a41SJohn Scipione 	\param name The name of the attribute/resource to be read.
1013a30a4a41SJohn Scipione 	\param id The resource ID of the resource to be read. It is ignored
1014a30a4a41SJohn Scipione 		   when < 0.
1015a30a4a41SJohn Scipione 	\param type The type of the attribute/resource to be read.
1016a30a4a41SJohn Scipione 	\param buffer A pre-allocated buffer for the data to be read.
1017a30a4a41SJohn Scipione 	\param bufferSize The size of the supplied buffer.
1018a30a4a41SJohn Scipione 	\param bytesRead A reference parameter, set to the number of bytes
1019a30a4a41SJohn Scipione 		   actually read.
1020a30a4a41SJohn Scipione 	\param allocatedBuffer If not \c NULL, the method allocates a buffer
1021a30a4a41SJohn Scipione 		   large enough too store the whole data and writes a pointer to it
1022a30a4a41SJohn Scipione 		   into this variable. If \c NULL, the supplied buffer is used.
1023a30a4a41SJohn Scipione 
1024a30a4a41SJohn Scipione 	\returns A status code.
1025a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
1026a30a4a41SJohn Scipione 	\retval B_ENTRY_NOT_FOUND The entry was not found.
1027a30a4a41SJohn Scipione 	\retval B_NO_MEMORY Ran out of memory allocating the buffer.
1028a30a4a41SJohn Scipione 	\retval B_BAD_VALUE \a type did not match.
1029a30a4a41SJohn Scipione */
103098da112cSIngo Weinhold status_t
_ReadData(const char * name,int32 id,type_code type,void * buffer,size_t bufferSize,size_t & bytesRead,void ** allocatedBuffer) const103198da112cSIngo Weinhold BAppFileInfo::_ReadData(const char* name, int32 id, type_code type,
10323b07762cSIngo Weinhold 	void* buffer, size_t bufferSize, size_t& bytesRead, void** allocatedBuffer)
10333b07762cSIngo Weinhold 	const
103498da112cSIngo Weinhold {
103598da112cSIngo Weinhold 	status_t error = B_OK;
1036338b8dc3SIngo Weinhold 
103798da112cSIngo Weinhold 	if (allocatedBuffer)
103898da112cSIngo Weinhold 		buffer = NULL;
1039338b8dc3SIngo Weinhold 
1040338b8dc3SIngo Weinhold 	bool foundData = false;
1041338b8dc3SIngo Weinhold 
104298da112cSIngo Weinhold 	if (IsUsingAttributes()) {
104398da112cSIngo Weinhold 		// get an attribute info
104498da112cSIngo Weinhold 		attr_info info;
104598da112cSIngo Weinhold 		if (error == B_OK)
104698da112cSIngo Weinhold 			error = fNode->GetAttrInfo(name, &info);
1047338b8dc3SIngo Weinhold 
104898da112cSIngo Weinhold 		// check type and size, allocate a buffer, if required
104998da112cSIngo Weinhold 		if (error == B_OK && info.type != type)
105098da112cSIngo Weinhold 			error = B_BAD_VALUE;
10513b07762cSIngo Weinhold 		if (error == B_OK && allocatedBuffer != NULL) {
105298da112cSIngo Weinhold 			buffer = malloc(info.size);
10533b07762cSIngo Weinhold 			if (buffer == NULL)
105498da112cSIngo Weinhold 				error = B_NO_MEMORY;
105598da112cSIngo Weinhold 			bufferSize = info.size;
105698da112cSIngo Weinhold 		}
10579be774b5SAlex Smith 		if (error == B_OK && (off_t)bufferSize < info.size)
105898da112cSIngo Weinhold 			error = B_BAD_VALUE;
1059338b8dc3SIngo Weinhold 
106098da112cSIngo Weinhold 		// read the data
106198da112cSIngo Weinhold 		if (error == B_OK) {
106298da112cSIngo Weinhold 			ssize_t read = fNode->ReadAttr(name, type, 0, buffer, info.size);
106398da112cSIngo Weinhold 			if (read < 0)
106498da112cSIngo Weinhold 				error = read;
106598da112cSIngo Weinhold 			else if (read != info.size)
106698da112cSIngo Weinhold 				error = B_ERROR;
106798da112cSIngo Weinhold 			else
106898da112cSIngo Weinhold 				bytesRead = read;
106998da112cSIngo Weinhold 		}
1070338b8dc3SIngo Weinhold 
10713b07762cSIngo Weinhold 		foundData = error == B_OK;
1072b4598d95SIngo Weinhold 
1073b4598d95SIngo Weinhold 		// free the allocated buffer on error
10743b07762cSIngo Weinhold 		if (!foundData && allocatedBuffer != NULL && buffer != NULL) {
1075b4598d95SIngo Weinhold 			free(buffer);
1076b4598d95SIngo Weinhold 			buffer = NULL;
1077b4598d95SIngo Weinhold 		}
1078338b8dc3SIngo Weinhold 	}
1079338b8dc3SIngo Weinhold 
1080338b8dc3SIngo Weinhold 	if (!foundData && IsUsingResources()) {
108198da112cSIngo Weinhold 		// get a resource info
1082338b8dc3SIngo Weinhold 		error = B_OK;
108398da112cSIngo Weinhold 		int32 idFound;
108498da112cSIngo Weinhold 		size_t sizeFound;
108598da112cSIngo Weinhold 		if (error == B_OK) {
108698da112cSIngo Weinhold 			if (!fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
108798da112cSIngo Weinhold 				error = B_ENTRY_NOT_FOUND;
108898da112cSIngo Weinhold 		}
1089338b8dc3SIngo Weinhold 
109098da112cSIngo Weinhold 		// check id and size, allocate a buffer, if required
109198da112cSIngo Weinhold 		if (error == B_OK && id >= 0 && idFound != id)
109298da112cSIngo Weinhold 			error = B_ENTRY_NOT_FOUND;
1093b4598d95SIngo Weinhold 		if (error == B_OK && allocatedBuffer) {
109498da112cSIngo Weinhold 			buffer = malloc(sizeFound);
109598da112cSIngo Weinhold 			if (!buffer)
109698da112cSIngo Weinhold 				error = B_NO_MEMORY;
109798da112cSIngo Weinhold 			bufferSize = sizeFound;
109898da112cSIngo Weinhold 		}
109998da112cSIngo Weinhold 		if (error == B_OK && bufferSize < sizeFound)
110098da112cSIngo Weinhold 			error = B_BAD_VALUE;
1101338b8dc3SIngo Weinhold 
110298da112cSIngo Weinhold 		// load resource
110398da112cSIngo Weinhold 		const void* resourceData = NULL;
110498da112cSIngo Weinhold 		if (error == B_OK) {
110598da112cSIngo Weinhold 			resourceData = fResources->LoadResource(type, name, &bytesRead);
11063b07762cSIngo Weinhold 			if (resourceData != NULL && sizeFound == bytesRead)
110798da112cSIngo Weinhold 				memcpy(buffer, resourceData, bytesRead);
110898da112cSIngo Weinhold 			else
110998da112cSIngo Weinhold 				error = B_ERROR;
111098da112cSIngo Weinhold 		}
1111773be699SAxel Dörfler 	} else if (!foundData)
111298da112cSIngo Weinhold 		error = B_BAD_VALUE;
1113338b8dc3SIngo Weinhold 
111498da112cSIngo Weinhold 	// return the allocated buffer, or free it on error
11153b07762cSIngo Weinhold 	if (allocatedBuffer != NULL) {
111698da112cSIngo Weinhold 		if (error == B_OK)
111798da112cSIngo Weinhold 			*allocatedBuffer = buffer;
111898da112cSIngo Weinhold 		else
111998da112cSIngo Weinhold 			free(buffer);
112098da112cSIngo Weinhold 	}
1121338b8dc3SIngo Weinhold 
112298da112cSIngo Weinhold 	return error;
112398da112cSIngo Weinhold }
112498da112cSIngo Weinhold 
1125e1b526b9SJonas Sundström 
1126a30a4a41SJohn Scipione /*!	Writes data to an attribute or resource.
1127a30a4a41SJohn Scipione 
1128a30a4a41SJohn Scipione 	\note The data is written to the location(s) specified by \a fWhere.
1129a30a4a41SJohn Scipione 
1130a30a4a41SJohn Scipione 	\warning The object must be properly initialized. The parameters are
1131a30a4a41SJohn Scipione 		\b NOT checked.
1132a30a4a41SJohn Scipione 
1133a30a4a41SJohn Scipione 	\param name The name of the attribute/resource to be written.
1134a30a4a41SJohn Scipione 	\param id The resource ID of the resource to be written.
1135a30a4a41SJohn Scipione 	\param type The type of the attribute/resource to be written.
1136a30a4a41SJohn Scipione 	\param buffer A buffer containing the data to be written.
1137a30a4a41SJohn Scipione 	\param bufferSize The size of the supplied buffer.
1138a30a4a41SJohn Scipione 	\param findID If set to \c true use the ID that is already assigned to the
1139a30a4a41SJohn Scipione 		   \a name / \a type pair or take the first unused ID >= \a id.
1140a30a4a41SJohn Scipione 		   If \c false, \a id is used.
1141a30a4a41SJohn Scipione 
1142a30a4a41SJohn Scipione 	\returns A status code.
1143a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
1144a30a4a41SJohn Scipione 	\retval B_ERROR An error occurred while trying to write the data.
1145a30a4a41SJohn Scipione */
114698da112cSIngo Weinhold status_t
_WriteData(const char * name,int32 id,type_code type,const void * buffer,size_t bufferSize,bool findID)114798da112cSIngo Weinhold BAppFileInfo::_WriteData(const char* name, int32 id, type_code type,
114898da112cSIngo Weinhold 	const void* buffer, size_t bufferSize, bool findID)
114998da112cSIngo Weinhold {
1150d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1151d0c290bfSAxel Dörfler 		return B_NO_INIT;
1152d0c290bfSAxel Dörfler 
115398da112cSIngo Weinhold 	status_t error = B_OK;
1154d0c290bfSAxel Dörfler 
115598da112cSIngo Weinhold 	// write to attribute
1156d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
115798da112cSIngo Weinhold 		ssize_t written = fNode->WriteAttr(name, type, 0, buffer, bufferSize);
115898da112cSIngo Weinhold 		if (written < 0)
115998da112cSIngo Weinhold 			error = written;
116098da112cSIngo Weinhold 		else if (written != (ssize_t)bufferSize)
116198da112cSIngo Weinhold 			error = B_ERROR;
116298da112cSIngo Weinhold 	}
116398da112cSIngo Weinhold 	// write to resource
116498da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
116598da112cSIngo Weinhold 		if (findID) {
116698da112cSIngo Weinhold 			// get the resource info
116798da112cSIngo Weinhold 			int32 idFound;
116898da112cSIngo Weinhold 			size_t sizeFound;
116998da112cSIngo Weinhold 			if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
117098da112cSIngo Weinhold 				id = idFound;
117198da112cSIngo Weinhold 			else {
117298da112cSIngo Weinhold 				// type-name pair doesn't exist yet -- find unused ID
117398da112cSIngo Weinhold 				while (fResources->HasResource(type, id))
117498da112cSIngo Weinhold 					id++;
117598da112cSIngo Weinhold 			}
117698da112cSIngo Weinhold 		}
117798da112cSIngo Weinhold 		error = fResources->AddResource(type, id, buffer, bufferSize, name);
117898da112cSIngo Weinhold 	}
117998da112cSIngo Weinhold 	return error;
118098da112cSIngo Weinhold }
118198da112cSIngo Weinhold 
118298da112cSIngo Weinhold 
1183a30a4a41SJohn Scipione /*!	Removes an attribute or resource.
1184a30a4a41SJohn Scipione 
1185a30a4a41SJohn Scipione 	\note The removal location is specified by \a fWhere.
1186a30a4a41SJohn Scipione 
1187a30a4a41SJohn Scipione 	\warning The object must be properly initialized. The parameters are
1188a30a4a41SJohn Scipione 		\b NOT checked.
1189a30a4a41SJohn Scipione 
1190a30a4a41SJohn Scipione 	\param name The name of the attribute/resource to be remove.
1191a30a4a41SJohn Scipione 	\param type The type of the attribute/resource to be removed.
1192a30a4a41SJohn Scipione 
1193a30a4a41SJohn Scipione 	\returns A status code.
1194a30a4a41SJohn Scipione 	\retval B_OK Everything went fine.
1195a30a4a41SJohn Scipione 	\retval B_NO_INIT Not using attributes and not using resources.
1196a30a4a41SJohn Scipione 	\retval B_ENTRY_NOT_FOUND The attribute or resource was not found.
1197a30a4a41SJohn Scipione */
119898da112cSIngo Weinhold status_t
_RemoveData(const char * name,type_code type)119998da112cSIngo Weinhold BAppFileInfo::_RemoveData(const char* name, type_code type)
120098da112cSIngo Weinhold {
1201d0c290bfSAxel Dörfler 	if (!IsUsingAttributes() && !IsUsingResources())
1202d0c290bfSAxel Dörfler 		return B_NO_INIT;
1203d0c290bfSAxel Dörfler 
120498da112cSIngo Weinhold 	status_t error = B_OK;
1205d0c290bfSAxel Dörfler 
120698da112cSIngo Weinhold 	// remove the attribute
1207d0c290bfSAxel Dörfler 	if (IsUsingAttributes()) {
120898da112cSIngo Weinhold 		error = fNode->RemoveAttr(name);
120998da112cSIngo Weinhold 		// It's no error, if there has been no attribute.
121098da112cSIngo Weinhold 		if (error == B_ENTRY_NOT_FOUND)
121198da112cSIngo Weinhold 			error = B_OK;
121298da112cSIngo Weinhold 	}
121398da112cSIngo Weinhold 	// remove the resource
121498da112cSIngo Weinhold 	if (IsUsingResources() && error == B_OK) {
121598da112cSIngo Weinhold 		// get a resource info
121698da112cSIngo Weinhold 		int32 idFound;
121798da112cSIngo Weinhold 		size_t sizeFound;
121898da112cSIngo Weinhold 		if (fResources->GetResourceInfo(type, name, &idFound, &sizeFound))
121998da112cSIngo Weinhold 			error = fResources->RemoveResource(type, idFound);
122098da112cSIngo Weinhold 	}
122198da112cSIngo Weinhold 	return error;
122298da112cSIngo Weinhold }
1223