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