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