xref: /haiku/src/kits/storage/mime/database_support.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
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
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*
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*
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 	This function exists as something of a hack until an OBOS::BBitmap
156 	implementation is available. It takes the given bitmap, converts it to the
157 	B_CMAP8 color space if necessary and able, and returns said bitmap data in
158 	a newly allocated array pointed to by the pointer that's pointed to by
159 	\c data. The length of the array is stored in the integer pointed to by
160 	\c dataSize. The array is allocated with \c new[], and it's your
161 	responsibility to \c delete[] it when you're finished.
162 */
163 status_t
164 get_icon_data(const BBitmap *icon, icon_size which, void **data,
165 	int32 *dataSize)
166 {
167 	if (icon == NULL || data == NULL || dataSize == 0
168 		|| icon->InitCheck() != B_OK)
169 		return B_BAD_VALUE;
170 
171 	BRect bounds;
172 	BBitmap *icon8 = NULL;
173 	void *srcData = NULL;
174 	bool otherColorSpace = false;
175 
176 	// Figure out what kind of data we *should* have
177 	switch (which) {
178 		case B_MINI_ICON:
179 			bounds.Set(0, 0, 15, 15);
180 			break;
181 		case B_LARGE_ICON:
182 			bounds.Set(0, 0, 31, 31);
183 			break;
184 		default:
185 			return B_BAD_VALUE;
186 	}
187 
188 	// Check the icon
189 	status_t err = icon->Bounds() == bounds ? B_OK : B_BAD_VALUE;
190 
191 	// Convert to B_CMAP8 if necessary
192 	if (!err) {
193 		otherColorSpace = (icon->ColorSpace() != B_CMAP8);
194 		if (otherColorSpace) {
195 			icon8 = new(std::nothrow) BBitmap(bounds, B_BITMAP_NO_SERVER_LINK,
196 				B_CMAP8);
197 			if (!icon8)
198 				err = B_NO_MEMORY;
199 			if (!err)
200 				err = icon8->ImportBits(icon);
201 			if (!err) {
202 				srcData = icon8->Bits();
203 				*dataSize = icon8->BitsLength();
204 			}
205 		} else {
206 			srcData = icon->Bits();
207 			*dataSize = icon->BitsLength();
208 		}
209 	}
210 
211 	// Alloc a new data buffer
212 	if (!err) {
213 		*data = new(std::nothrow) char[*dataSize];
214 		if (!*data)
215 			err = B_NO_MEMORY;
216 	}
217 
218 	// Copy the data into it.
219 	if (!err)
220 		memcpy(*data, srcData, *dataSize);
221 	if (otherColorSpace)
222 		delete icon8;
223 	return err;
224 }
225 
226 
227 } // namespace Mime
228 } // namespace Storage
229 } // namespace BPrivate
230 
231