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 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 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