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 26namespace BPrivate { 27namespace Storage { 28namespace 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 35const char *kMiniIconAttrPrefix = MINI_ICON_ATTR_PREFIX; 36const char *kLargeIconAttrPrefix = LARGE_ICON_ATTR_PREFIX; 37const char *kIconAttrPrefix = ATTR_PREFIX; 38 39// attribute names 40const char *kFileTypeAttr = "BEOS:TYPE"; 41const char *kTypeAttr = ATTR_PREFIX "TYPE"; 42const char *kAppHintAttr = ATTR_PREFIX "PPATH"; 43const char *kAttrInfoAttr = ATTR_PREFIX "ATTR_INFO"; 44const char *kShortDescriptionAttr = ATTR_PREFIX "S:DESC"; 45const char *kLongDescriptionAttr = ATTR_PREFIX "L:DESC"; 46const char *kFileExtensionsAttr = ATTR_PREFIX "EXTENS"; 47const char *kMiniIconAttr = MINI_ICON_ATTR_PREFIX "STD_ICON"; 48const char *kLargeIconAttr = LARGE_ICON_ATTR_PREFIX "STD_ICON"; 49const char *kIconAttr = ATTR_PREFIX "ICON"; 50const char *kPreferredAppAttr = ATTR_PREFIX "PREF_APP"; 51const char *kSnifferRuleAttr = ATTR_PREFIX "SNIFF_RULE"; 52const char *kSupportedTypesAttr = ATTR_PREFIX "FILE_TYPES"; 53 54// attribute data types (as used in the R5 database) 55const int32 kFileTypeType = 'MIMS'; // B_MIME_STRING_TYPE 56const int32 kTypeType = B_STRING_TYPE; 57const int32 kAppHintType = 'MPTH'; 58const int32 kAttrInfoType = B_MESSAGE_TYPE; 59const int32 kShortDescriptionType = 'MSDC'; 60const int32 kLongDescriptionType = 'MLDC'; 61const int32 kFileExtensionsType = B_MESSAGE_TYPE; 62const int32 kMiniIconType = B_MINI_ICON_TYPE; 63const int32 kLargeIconType = B_LARGE_ICON_TYPE; 64const int32 kIconType = B_VECTOR_ICON_TYPE; 65const int32 kPreferredAppType = 'MSIG'; 66const int32 kSnifferRuleType = B_STRING_TYPE; 67const int32 kSupportedTypesType = B_MESSAGE_TYPE; 68 69// Message fields 70const char *kApplicationsField = "applications"; 71const char *kExtensionsField = "extensions"; 72const char *kSupertypesField = "super_types"; 73const char *kSupportingAppsSubCountField = "be:sub"; 74const char *kSupportingAppsSuperCountField = "be:super"; 75const char *kTypesField = "types"; 76 77// Mime types 78const char *kGenericFileType = "application/octet-stream"; 79const char *kDirectoryType = "application/x-vnd.Be-directory"; 80const char *kSymlinkType = "application/x-vnd.Be-symlink"; 81const char *kMetaMimeType = "application/x-vnd.Be-meta-mime"; 82 83// Error codes 84const status_t kMimeGuessFailureError = B_ERRORS_END+1; 85 86 87#if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU) 88 89 90static 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 98static pthread_once_t sDefaultDatabaseLocationInitOnce = PTHREAD_ONCE_INIT; 99static DatabaseLocation* sDefaultDatabaseLocation = NULL; 100 101 102static void 103init_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 126DatabaseLocation* 127default_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 138DatabaseLocation* 139default_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*/ 162status_t 163get_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