xref: /haiku/src/kits/storage/mime/database_support.cpp (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
1 /*
2  * Copyright 2002-2013, Haiku.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Tyler Dauwalder
7  *		Ingo Weinhold <ingo_weinhold@gmx.de>
8  */
9 
10 
11 #include <mime/database_support.h>
12 
13 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
14 #	include <pthread.h>
15 #endif
16 
17 #include <new>
18 
19 #include <Bitmap.h>
20 #include <FindDirectory.h>
21 #include <Path.h>
22 
23 #include <mime/DatabaseLocation.h>
24 
25 
26 namespace BPrivate {
27 namespace Storage {
28 namespace Mime {
29 
30 
31 #define ATTR_PREFIX "META:"
32 #define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:"
33 #define LARGE_ICON_ATTR_PREFIX ATTR_PREFIX "L:"
34 
35 const char *kMiniIconAttrPrefix		= MINI_ICON_ATTR_PREFIX;
36 const char *kLargeIconAttrPrefix	= LARGE_ICON_ATTR_PREFIX;
37 const char *kIconAttrPrefix			= ATTR_PREFIX;
38 
39 // attribute names
40 const char *kFileTypeAttr			= "BEOS:TYPE";
41 const char *kTypeAttr				= ATTR_PREFIX "TYPE";
42 const char *kAppHintAttr			= ATTR_PREFIX "PPATH";
43 const char *kAttrInfoAttr			= ATTR_PREFIX "ATTR_INFO";
44 const char *kShortDescriptionAttr	= ATTR_PREFIX "S:DESC";
45 const char *kLongDescriptionAttr	= ATTR_PREFIX "L:DESC";
46 const char *kFileExtensionsAttr		= ATTR_PREFIX "EXTENS";
47 const char *kMiniIconAttr			= MINI_ICON_ATTR_PREFIX "STD_ICON";
48 const char *kLargeIconAttr			= LARGE_ICON_ATTR_PREFIX "STD_ICON";
49 const char *kIconAttr				= ATTR_PREFIX "ICON";
50 const char *kPreferredAppAttr		= ATTR_PREFIX "PREF_APP";
51 const char *kSnifferRuleAttr		= ATTR_PREFIX "SNIFF_RULE";
52 const char *kSupportedTypesAttr		= ATTR_PREFIX "FILE_TYPES";
53 
54 // attribute data types (as used in the R5 database)
55 const int32 kFileTypeType			= 'MIMS';	// B_MIME_STRING_TYPE
56 const int32 kTypeType				= B_STRING_TYPE;
57 const int32 kAppHintType			= 'MPTH';
58 const int32 kAttrInfoType			= B_MESSAGE_TYPE;
59 const int32 kShortDescriptionType	= 'MSDC';
60 const int32 kLongDescriptionType	= 'MLDC';
61 const int32 kFileExtensionsType		= B_MESSAGE_TYPE;
62 const int32 kMiniIconType			= B_MINI_ICON_TYPE;
63 const int32 kLargeIconType			= B_LARGE_ICON_TYPE;
64 const int32 kIconType				= B_VECTOR_ICON_TYPE;
65 const int32 kPreferredAppType		= 'MSIG';
66 const int32 kSnifferRuleType		= B_STRING_TYPE;
67 const int32 kSupportedTypesType		= B_MESSAGE_TYPE;
68 
69 // Message fields
70 const char *kApplicationsField				= "applications";
71 const char *kExtensionsField				= "extensions";
72 const char *kSupertypesField				= "super_types";
73 const char *kSupportingAppsSubCountField	= "be:sub";
74 const char *kSupportingAppsSuperCountField	= "be:super";
75 const char *kTypesField						= "types";
76 
77 // Mime types
78 const char *kGenericFileType	= "application/octet-stream";
79 const char *kDirectoryType		= "application/x-vnd.Be-directory";
80 const char *kSymlinkType		= "application/x-vnd.Be-symlink";
81 const char *kMetaMimeType		= "application/x-vnd.Be-meta-mime";
82 
83 // Error codes
84 const status_t kMimeGuessFailureError	= B_ERRORS_END+1;
85 
86 
87 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
88 
89 
90 static const directory_which kBaseDirectoryConstants[] = {
91 	B_USER_SETTINGS_DIRECTORY,
92 	B_USER_NONPACKAGED_DATA_DIRECTORY,
93 	B_USER_DATA_DIRECTORY,
94 	B_SYSTEM_NONPACKAGED_DATA_DIRECTORY,
95 	B_SYSTEM_DATA_DIRECTORY
96 };
97 
98 static pthread_once_t sDefaultDatabaseLocationInitOnce = PTHREAD_ONCE_INIT;
99 static DatabaseLocation* sDefaultDatabaseLocation = NULL;
100 
101 
102 static void
init_default_database_location()103 init_default_database_location()
104 {
105 	static DatabaseLocation databaseLocation;
106 	sDefaultDatabaseLocation = &databaseLocation;
107 
108 	for (size_t i = 0;
109 		i < sizeof(kBaseDirectoryConstants)
110 			/ sizeof(kBaseDirectoryConstants[0]); i++) {
111 		BString directoryPath;
112 		BPath path;
113 		if (find_directory(kBaseDirectoryConstants[i], &path) == B_OK)
114 			directoryPath = path.Path();
115 		else if (i == 0)
116 			directoryPath = "/boot/home/config/settings";
117 		else
118 			continue;
119 
120 		directoryPath += "/mime_db";
121 		databaseLocation.AddDirectory(directoryPath);
122 	}
123 }
124 
125 
126 DatabaseLocation*
default_database_location()127 default_database_location()
128 {
129 	pthread_once(&sDefaultDatabaseLocationInitOnce,
130 		&init_default_database_location);
131 	return sDefaultDatabaseLocation;
132 }
133 
134 
135 #else	// building for the host platform
136 
137 
138 DatabaseLocation*
default_database_location()139 default_database_location()
140 {
141 	// Should never actually be used, but make it valid, anyway.
142 	static DatabaseLocation location;
143 	if (location.Directories().IsEmpty())
144 		location.AddDirectory("/tmp");
145 	return &location;
146 }
147 
148 
149 #endif
150 
151 
152 /*! \brief Returns properly formatted raw bitmap data, ready to be shipped off
153 	to the hacked up 4-parameter version of Database::SetIcon()
154 
155 	BBitmap implemented.  This function takes the given bitmap, converts it to the
156 	B_CMAP8 color space if necessary and able, and returns said bitmap data in
157 	a newly allocated array pointed to by the pointer that's pointed to by
158 	\c data. The length of the array is stored in the integer pointed to by
159 	\c dataSize. The array is allocated with \c new[], and it's your
160 	responsibility to \c delete[] it when you're finished.
161 */
162 status_t
get_icon_data(const BBitmap * icon,icon_size which,void ** data,int32 * dataSize)163 get_icon_data(const BBitmap *icon, icon_size which, void **data,
164 	int32 *dataSize)
165 {
166 	if (icon == NULL || data == NULL || dataSize == 0
167 		|| icon->InitCheck() != B_OK)
168 		return B_BAD_VALUE;
169 
170 	BRect bounds;
171 	BBitmap *icon8 = NULL;
172 	void *srcData = NULL;
173 	bool otherColorSpace = false;
174 
175 	// Figure out what kind of data we *should* have
176 	switch (which) {
177 		case B_MINI_ICON:
178 			bounds.Set(0, 0, 15, 15);
179 			break;
180 		case B_LARGE_ICON:
181 			bounds.Set(0, 0, 31, 31);
182 			break;
183 		default:
184 			return B_BAD_VALUE;
185 	}
186 
187 	// Check the icon
188 	status_t err = icon->Bounds() == bounds ? B_OK : B_BAD_VALUE;
189 
190 	// Convert to B_CMAP8 if necessary
191 	if (!err) {
192 		otherColorSpace = (icon->ColorSpace() != B_CMAP8);
193 		if (otherColorSpace) {
194 			icon8 = new(std::nothrow) BBitmap(bounds, B_BITMAP_NO_SERVER_LINK,
195 				B_CMAP8);
196 			if (!icon8)
197 				err = B_NO_MEMORY;
198 			if (!err)
199 				err = icon8->ImportBits(icon);
200 			if (!err) {
201 				srcData = icon8->Bits();
202 				*dataSize = icon8->BitsLength();
203 			}
204 		} else {
205 			srcData = icon->Bits();
206 			*dataSize = icon->BitsLength();
207 		}
208 	}
209 
210 	// Alloc a new data buffer
211 	if (!err) {
212 		*data = new(std::nothrow) char[*dataSize];
213 		if (!*data)
214 			err = B_NO_MEMORY;
215 	}
216 
217 	// Copy the data into it.
218 	if (!err)
219 		memcpy(*data, srcData, *dataSize);
220 	if (otherColorSpace)
221 		delete icon8;
222 	return err;
223 }
224 
225 
226 } // namespace Mime
227 } // namespace Storage
228 } // namespace BPrivate
229 
230