headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / storage / mime / database_support.cpp
blobea68496ea85aba2a451fddb9fddd254faa4c297f
1 /*
2 * Copyright 2002-2013, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Tyler Dauwalder
7 * Ingo Weinhold <ingo_weinhold@gmx.de>
8 */
11 #include <mime/database_support.h>
13 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
14 # include <pthread.h>
15 #endif
17 #include <new>
19 #include <Bitmap.h>
20 #include <FindDirectory.h>
21 #include <Path.h>
23 #include <mime/DatabaseLocation.h>
26 namespace BPrivate {
27 namespace Storage {
28 namespace Mime {
31 #define ATTR_PREFIX "META:"
32 #define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:"
33 #define LARGE_ICON_ATTR_PREFIX ATTR_PREFIX "L:"
35 const char *kMiniIconAttrPrefix = MINI_ICON_ATTR_PREFIX;
36 const char *kLargeIconAttrPrefix = LARGE_ICON_ATTR_PREFIX;
37 const char *kIconAttrPrefix = ATTR_PREFIX;
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";
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;
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";
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";
83 // Error codes
84 const status_t kMimeGuessFailureError = B_ERRORS_END+1;
87 #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU)
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
98 static pthread_once_t sDefaultDatabaseLocationInitOnce = PTHREAD_ONCE_INIT;
99 static DatabaseLocation* sDefaultDatabaseLocation = NULL;
102 static void
103 init_default_database_location()
105 static DatabaseLocation databaseLocation;
106 sDefaultDatabaseLocation = &databaseLocation;
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;
120 directoryPath += "/mime_db";
121 databaseLocation.AddDirectory(directoryPath);
126 DatabaseLocation*
127 default_database_location()
129 pthread_once(&sDefaultDatabaseLocationInitOnce,
130 &init_default_database_location);
131 return sDefaultDatabaseLocation;
135 #else // building for the host platform
138 DatabaseLocation*
139 default_database_location()
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;
149 #endif
152 /*! \brief Returns properly formatted raw bitmap data, ready to be shipped off
153 to the hacked up 4-parameter version of Database::SetIcon()
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.
163 status_t
164 get_icon_data(const BBitmap *icon, icon_size which, void **data,
165 int32 *dataSize)
167 if (icon == NULL || data == NULL || dataSize == 0
168 || icon->InitCheck() != B_OK)
169 return B_BAD_VALUE;
171 BRect bounds;
172 BBitmap *icon8 = NULL;
173 void *srcData = NULL;
174 bool otherColorSpace = false;
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;
188 // Check the icon
189 status_t err = icon->Bounds() == bounds ? B_OK : B_BAD_VALUE;
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();
205 } else {
206 srcData = icon->Bits();
207 *dataSize = icon->BitsLength();
211 // Alloc a new data buffer
212 if (!err) {
213 *data = new(std::nothrow) char[*dataSize];
214 if (!*data)
215 err = B_NO_MEMORY;
218 // Copy the data into it.
219 if (!err)
220 memcpy(*data, srcData, *dataSize);
221 if (otherColorSpace)
222 delete icon8;
223 return err;
227 } // namespace Mime
228 } // namespace Storage
229 } // namespace BPrivate