From 3155eae222d119aa730971cebdfad8575838eb44 Mon Sep 17 00:00:00 2001 From: Tyler Dauwalder Date: Wed, 21 Aug 2002 10:55:20 +0000 Subject: [PATCH] + Added code/updated tests for - AttrInfo - FileExtensions + Updated Delete() code to send monitor updates + Tenatively added "be:action" field to monitor messages + Added data type constants git-svn-id: file:///srv/svn/repos/haiku/trunk/current@847 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/storage/MimeType.h | 8 + headers/private/storage/MimeDatabase.h | 109 +++++--- src/kits/storage/MimeDatabase.cpp | 349 ++++++++++++++++++++++-- src/kits/storage/MimeType.cpp | 56 +++- src/servers/registrar/MIMEManager.cpp | 126 ++++----- src/tests/kits/storage/MimeTypeTest.cpp | 138 +++++++--- 6 files changed, 616 insertions(+), 170 deletions(-) diff --git a/headers/os/storage/MimeType.h b/headers/os/storage/MimeType.h index 3b06574e07..0239955c1f 100644 --- a/headers/os/storage/MimeType.h +++ b/headers/os/storage/MimeType.h @@ -39,10 +39,12 @@ extern const char *B_FILE_MIME_TYPE; // "application/octet-stream" /* ------------------------------------------------------------- */ +// MIME Monitor BMessage::what value enum { B_META_MIME_CHANGED = 'MMCH' }; +// MIME Monitor "be:which" values enum { B_ICON_CHANGED = 0x00000001, B_PREFERRED_APP_CHANGED = 0x00000002, @@ -59,6 +61,12 @@ enum { B_EVERYTHING_CHANGED = (int)0xFFFFFFFF }; +// MIME Monitor "be:action" values +enum { + B_META_MIME_MODIFIED = 'MMMD', + B_META_MIME_DELETED = 'MMDL', +}; + /* ------------------------------------------------------------- */ //! File typing functionality. diff --git a/headers/private/storage/MimeDatabase.h b/headers/private/storage/MimeDatabase.h index 3114d06a00..1dc91eaa22 100644 --- a/headers/private/storage/MimeDatabase.h +++ b/headers/private/storage/MimeDatabase.h @@ -20,89 +20,122 @@ public: status_t InitCheck(); - /* These functions are for managing data in the meta mime file*/ + // Type management status_t Install(const char *type); status_t Delete(const char *type); bool IsInstalled(const char *type) const; + + // Get() + status_t GetAppHint(const char *type, entry_ref *ref) const; + status_t GetAttrInfo(const char *type, BMessage *info) const; + status_t GetFileExtensions(const char *type, BMessage *extensions) const; status_t GetIcon(const char *type, BBitmap *icon, icon_size size) const; - status_t GetPreferredApp(const char *type, char *signature, app_verb verb) const; -// status_t GetAttrInfo(BMessage *info) const; -// status_t GetFileExtensions(BMessage *extensions) const; + status_t GetIconForType(const char *type, const char *fileType, BBitmap *icon, + icon_size which) const; status_t GetShortDescription(const char *type, char *description) const; status_t GetLongDescription(const char *type, char *description) const; -// status_t GetSupportingApps(BMessage *signatures) const; + status_t GetPreferredApp(const char *type, char *signature, app_verb verb) const; +// status_t GetSnifferRule(BString *result) const; -// status_t SetIcon(const char *type, const BBitmap *icon, icon_size which); - status_t SetIcon(const char *type, const void *data, size_t dataSize, icon_size which); - status_t SetPreferredApp(const char *type, const char *signature, app_verb verb = B_OPEN); -// status_t SetAttrInfo(const BMessage *info); -// status_t SetFileExtensions(const BMessage *extensions); + // Set() + status_t SetAppHint(const char *type, const entry_ref *ref); + status_t SetAttrInfo(const char *type, const BMessage *info); status_t SetShortDescription(const char *type, const char *description); status_t SetLongDescription(const char *type, const char *description); + status_t SetFileExtensions(const char *type, const BMessage *extensions); + status_t SetIcon(const char *type, const void *data, size_t dataSize, icon_size which); + status_t SetIconForType(const char *type, const char *fileType, const void *data, + size_t dataSize, icon_size which); + status_t SetPreferredApp(const char *type, const char *signature, app_verb verb = B_OPEN); +// status_t SetSnifferRule(const char *); + // Non-atomic Get() // static status_t GetInstalledSupertypes(BMessage *super_types); // static status_t GetInstalledTypes(BMessage *types); // static status_t GetInstalledTypes(const char *super_type, // BMessage *subtypes); -// static status_t GetWildcardApps(BMessage *wild_ones); -// static bool IsValid(const char *mimeType); -// - status_t GetAppHint(const char *type, entry_ref *ref) const; - status_t SetAppHint(const char *type, const entry_ref *ref); +// status_t GetSupportingApps(BMessage *signatures) const; - /* for application signatures only.*/ - status_t GetIconForType(const char *type, const char *fileType, BBitmap *icon, - icon_size which) const; - status_t SetIconForType(const char *type, const char *fileType, const void *data, - size_t dataSize, icon_size which); - - /* sniffer rule manipulation */ -// status_t GetSnifferRule(BString *result) const; -// status_t SetSnifferRule(const char *); + // Sniffer // static status_t CheckSnifferRule(const char *rule, BString *parseError); - - /* calls to ask the sniffer to identify the MIME type of a file or data in - memory */ // static status_t GuessMimeType(const entry_ref *file, BMimeType *result); // static status_t GuessMimeType(const void *buffer, int32 length, // BMimeType *result); // static status_t GuessMimeType(const char *filename, BMimeType *result); + // Monitor status_t StartWatching(BMessenger target); status_t StopWatching(BMessenger target); + // Delete() + status_t DeleteIcon(const char *type, icon_size size); + status_t DeletePreferredApp(const char *type, app_verb verb = B_OPEN); + status_t DeleteAttrInfo(const char *type); + status_t DeleteFileExtensions(const char *type); + status_t DeleteShortDescription(const char *type); + status_t DeleteLongDescription(const char *type); + status_t DeleteSnifferRule(const char *type); + status_t DeleteIconForType(const char *type, const char *fileType, icon_size which); + status_t DeleteAppHint(const char *type); + + // Misc static status_t GetIconData(const BBitmap *icon, icon_size size, void **data, int32 *dataSize); - - status_t DeleteAttribute(const char *type, const char *attr); - static std::string ToLower(const char *str); - static const char *kDefaultDatabaseDir; + // Constants + static const char *kDefaultDatabaseDir; static const char *kMiniIconAttrPrefix; static const char *kLargeIconAttrPrefix; + static const char *kFileTypeAttr; static const char *kTypeAttr; - static const char *kPreferredAppAttr; + static const char *kAttrInfoAttr; static const char *kAppHintAttr; + static const char *kShortDescriptionAttr; + static const char *kLongDescriptionAttr; + static const char *kFileExtensionsAttr; static const char *kMiniIconAttr; static const char *kLargeIconAttr; - static const char *kShortDescriptionAttr; - static const char *kLongDescriptionAttr; + static const char *kPreferredAppAttr; + static const char *kSnifferRuleAttr; + static const char *kSupportedTypesAttr; + + static const int32 kFileTypeType; + static const int32 kTypeType; + static const int32 kAppHintType; + static const int32 kAttrInfoType; + static const int32 kShortDescriptionType; + static const int32 kLongDescriptionType; + static const int32 kFileExtensionsType; + static const int32 kMiniIconType; + static const int32 kLargeIconType; + static const int32 kPreferredAppType; + static const int32 kSnifferRuleType; + static const int32 kSupportedTypesType; + private: + status_t DeleteAttribute(const char *type, const char *attr); ssize_t ReadMimeAttr(const char *type, const char *attr, void *data, size_t len, type_code datatype) const; + status_t ReadMimeAttrMessage(const char *type, const char *attr, BMessage *msg) const; status_t WriteMimeAttr(const char *type, const char *attr, const void *data, size_t len, type_code datatype); + status_t WriteMimeAttrMessage(const char *type, const char *attr, const BMessage *msg); + status_t OpenType(const char *type, BNode *result) const; status_t OpenOrCreateType(const char *type, BNode *result); inline std::string TypeToFilename(const char *type) const; - status_t SendMonitorUpdate(int32 which, const char *type, const char *extraType, bool largeIcon); - status_t SendMonitorUpdate(int32 which, const char *type, const char *extraType); - status_t SendMonitorUpdate(int32 which, const char *type, bool largeIcon); - status_t SendMonitorUpdate(int32 which, const char *type); + status_t SendMonitorUpdate(int32 which, const char *type, const char *extraType, + bool largeIcon, int32 action); + status_t SendMonitorUpdate(int32 which, const char *type, const char *extraType, + int32 action); + status_t SendMonitorUpdate(int32 which, const char *type, bool largeIcon, + int32 action); + status_t SendMonitorUpdate(int32 which, const char *type, + int32 action); status_t SendMonitorUpdate(BMessage &msg); // General icon functions used by {Get,Set}Icon() and {Get,Set}IconForType() diff --git a/src/kits/storage/MimeDatabase.cpp b/src/kits/storage/MimeDatabase.cpp index a39554d18a..6609e4b1f7 100644 --- a/src/kits/storage/MimeDatabase.cpp +++ b/src/kits/storage/MimeDatabase.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -34,7 +35,6 @@ namespace BPrivate { //const char* MimeDatabase::kDefaultDatabaseDir = "/boot/home/config/settings/beos_mime"; const char* MimeDatabase::kDefaultDatabaseDir = "/boot/home/config/settings/obos_mime"; -// attribute names #define ATTR_PREFIX "META:" #define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:" #define LARGE_ICON_ATTR_PREFIX ATTR_PREFIX "L:" @@ -42,13 +42,34 @@ const char* MimeDatabase::kDefaultDatabaseDir = "/boot/home/config/settings/obos const char *MimeDatabase::kMiniIconAttrPrefix = MINI_ICON_ATTR_PREFIX; const char *MimeDatabase::kLargeIconAttrPrefix = LARGE_ICON_ATTR_PREFIX; +// attribute names +const char *MimeDatabase::kFileTypeAttr = "BEOS:TYPE"; const char *MimeDatabase::kTypeAttr = ATTR_PREFIX "TYPE"; -const char *MimeDatabase::kPreferredAppAttr = ATTR_PREFIX "PREF_APP"; const char *MimeDatabase::kAppHintAttr = ATTR_PREFIX "PPATH"; -const char *MimeDatabase::kMiniIconAttr = MINI_ICON_ATTR_PREFIX "STD_ICON"; -const char *MimeDatabase::kLargeIconAttr = LARGE_ICON_ATTR_PREFIX "STD_ICON"; +const char *MimeDatabase::kAttrInfoAttr = ATTR_PREFIX "ATTR_INFO"; const char *MimeDatabase::kShortDescriptionAttr = ATTR_PREFIX "S:DESC"; const char *MimeDatabase::kLongDescriptionAttr = ATTR_PREFIX "L:DESC"; +const char *MimeDatabase::kFileExtensionsAttr = ATTR_PREFIX "EXTENS"; +const char *MimeDatabase::kMiniIconAttr = MINI_ICON_ATTR_PREFIX "STD_ICON"; +const char *MimeDatabase::kLargeIconAttr = LARGE_ICON_ATTR_PREFIX "STD_ICON"; +const char *MimeDatabase::kPreferredAppAttr = ATTR_PREFIX "PREF_APP"; +const char *MimeDatabase::kSnifferRuleAttr = ATTR_PREFIX "SNIFF_RULE"; +const char *MimeDatabase::kSupportedTypesAttr = ATTR_PREFIX "FILE_TYPES"; + +// attribute data types (as used in the R5 database) +const int32 MimeDatabase::kFileTypeType = 'MIMS'; // B_MIME_STRING_TYPE +const int32 MimeDatabase::kTypeType = B_STRING_TYPE; +const int32 MimeDatabase::kAppHintType = 'MPTH'; +const int32 MimeDatabase::kAttrInfoType = B_MESSAGE_TYPE; +const int32 MimeDatabase::kShortDescriptionType = 'MSDC'; +const int32 MimeDatabase::kLongDescriptionType = 'MLDC'; +const int32 MimeDatabase::kFileExtensionsType = B_MESSAGE_TYPE; +const int32 MimeDatabase::kMiniIconType = B_MINI_ICON_TYPE; +const int32 MimeDatabase::kLargeIconType = B_LARGE_ICON_TYPE; +const int32 MimeDatabase::kPreferredAppType = 'MSIG'; +const int32 MimeDatabase::kSnifferRuleType = B_STRING_TYPE; +const int32 MimeDatabase::kSupportedTypesType = B_MESSAGE_TYPE; + #undef ATTR_PREFIX #undef MINI_ICON_ATTR_PREFIX @@ -208,10 +229,35 @@ status_t MimeDatabase::GetPreferredApp(const char *type, char *signature, app_verb verb = B_OPEN) const { // Since B_OPEN is the currently the only app_verb, it is essentially ignored - ssize_t err = ReadMimeAttr(type, kPreferredAppAttr, signature, B_MIME_TYPE_LENGTH, B_RAW_TYPE); + ssize_t err = ReadMimeAttr(type, kPreferredAppAttr, signature, B_MIME_TYPE_LENGTH, kPreferredAppType); return err >= 0 ? B_OK : err ; } +// GetAttrInfo +/*! \brief Fetches from the MIME database a BMessage describing the attributes + typically associated with files of the given MIME type + + The attribute information is returned in a pre-allocated BMessage pointed to by + the \c info parameter (note that the any prior contents of the message + will be destroyed). Please see BMimeType::SetAttrInfo() for a description + of the expected format of such a message. + + \param info Pointer to a pre-allocated BMessage into which information about + the MIME type's associated file attributes is stored. + \return + - \c B_OK: Success + - "error code": Failure +*/ +status_t +MimeDatabase::GetAttrInfo(const char *type, BMessage *info) const +{ + status_t err = ReadMimeAttrMessage(type, kAttrInfoAttr, info); + if (!err) { + info->what = 233; // Don't know why, but that's what R5 does. + err = info->AddString("type", type); + } + return err; +} // GetShortDescription //! Fetches the short description for the given MIME type. @@ -233,7 +279,7 @@ status_t MimeDatabase::GetShortDescription(const char *type, char *description) const { /// DBG(OUT("MimeDatabase::GetShortDescription()\n")); - ssize_t err = ReadMimeAttr(type, kShortDescriptionAttr, description, B_MIME_TYPE_LENGTH, B_RAW_TYPE); + ssize_t err = ReadMimeAttr(type, kShortDescriptionAttr, description, B_MIME_TYPE_LENGTH, kShortDescriptionType); return err >= 0 ? B_OK : err ; } @@ -256,10 +302,34 @@ MimeDatabase::GetShortDescription(const char *type, char *description) const status_t MimeDatabase::GetLongDescription(const char *type, char *description) const { // DBG(OUT("MimeDatabase::GetLongDescription()\n")); - ssize_t err = ReadMimeAttr(type, kLongDescriptionAttr, description, B_MIME_TYPE_LENGTH, B_RAW_TYPE); + ssize_t err = ReadMimeAttr(type, kLongDescriptionAttr, description, B_MIME_TYPE_LENGTH, kLongDescriptionType); return err >= 0 ? B_OK : err ; } +// GetFileExtensions +//! Fetches a BMessage describing the MIME type's associated filename extensions +/*! The list of extensions is returned in a pre-allocated BMessage pointed to by + the \c extensions parameter (note that the any prior contents of the message + will be destroyed). Please see BMimeType::GetFileExtensions() for a description + of the message format. + + \param extensions Pointer to a pre-allocated BMessage into which the MIME + type's associated file extensions will be stored. + \return + - \c B_OK: Success + - "error code": Failure +*/ +status_t +MimeDatabase::GetFileExtensions(const char *type, BMessage *extensions) const +{ + status_t err = ReadMimeAttrMessage(type, kFileExtensionsAttr, extensions); + if (!err) { + extensions->what = 234; // Don't know why, but that's what R5 does. + err = extensions->AddString("type", type); + } + return err; +} + //! Sets the icon for the given mime type /*! This is the version I would have used if I could have gotten a BBitmap to the registrar somehow. Since R5::BBitmap::Instantiate is causing a @@ -293,9 +363,60 @@ MimeDatabase::SetPreferredApp(const char *type, const char *signature, app_verb DBG(OUT("MimeDatabase::SetPreferredApp()\n")); status_t err = (type && signature && strlen(signature) < B_MIME_TYPE_LENGTH) ? B_OK : B_BAD_VALUE; if (!err) - err = WriteMimeAttr(type, kPreferredAppAttr, signature, strlen(signature)+1, B_RAW_TYPE); + err = WriteMimeAttr(type, kPreferredAppAttr, signature, strlen(signature)+1, kPreferredAppType); if (!err) - err = SendMonitorUpdate(B_PREFERRED_APP_CHANGED, type); + err = SendMonitorUpdate(B_PREFERRED_APP_CHANGED, type, B_META_MIME_MODIFIED); + return err; +} + +// SetAttrInfo +/*! \brief Stores a BMessage describing the format of attributes typically associated with + files of the given MIME type + + See BMimeType::SetAttrInfo() for description of the expected message format. + + The \c BMessage::what value is ignored. + + \param info Pointer to a pre-allocated and properly formatted BMessage containing + information about the file attributes typically associated with the + MIME type. + \return + - \c B_OK: Success + - "error code": Failure +*/ +status_t +MimeDatabase::SetAttrInfo(const char *type, const BMessage *info) +{ + DBG(OUT("MimeDatabase::SetAttrInfo()\n")); + status_t err = (type && info) ? B_OK : B_BAD_VALUE; + if (!err) + err = WriteMimeAttrMessage(type, kAttrInfoAttr, info); + if (!err) + err = SendMonitorUpdate(B_ATTR_INFO_CHANGED, type, B_META_MIME_MODIFIED); + return err; +} + +// SetFileExtensions +//! Sets the list of filename extensions associated with the MIME type +/*! The list of extensions is given in a pre-allocated BMessage pointed to by + the \c extensions parameter. Please see BMimeType::SetFileExtensions() + for a description of the expected message format. + + \param extensions Pointer to a pre-allocated, properly formatted BMessage containing + the new list of file extensions to associate with this MIME type. + \return + - \c B_OK: Success + - "error code": Failure +*/ +status_t +MimeDatabase::SetFileExtensions(const char *type, const BMessage *extensions) +{ + DBG(OUT("MimeDatabase::SetFileExtensions()\n")); + status_t err = (type && extensions) ? B_OK : B_BAD_VALUE; + if (!err) + err = WriteMimeAttrMessage(type, kFileExtensionsAttr, extensions); + if (!err) + err = SendMonitorUpdate(B_FILE_EXTENSIONS_CHANGED, type, B_META_MIME_MODIFIED); return err; } @@ -310,9 +431,9 @@ MimeDatabase::SetShortDescription(const char *type, const char *description) DBG(OUT("MimeDatabase::SetShortDescription()\n")); status_t err = (type && description && strlen(description) < B_MIME_TYPE_LENGTH) ? B_OK : B_BAD_VALUE; if (!err) - err = WriteMimeAttr(type, kShortDescriptionAttr, description, strlen(description)+1, B_RAW_TYPE); + err = WriteMimeAttr(type, kShortDescriptionAttr, description, strlen(description)+1, kShortDescriptionType); if (!err) - err = SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type); + err = SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type, B_META_MIME_MODIFIED); return err; } @@ -327,9 +448,9 @@ MimeDatabase::SetLongDescription(const char *type, const char *description) DBG(OUT("MimeDatabase::SetLongDescription()\n")); status_t err = (type && description && strlen(description) < B_MIME_TYPE_LENGTH) ? B_OK : B_BAD_VALUE; if (!err) - err = WriteMimeAttr(type, kLongDescriptionAttr, description, strlen(description)+1, B_RAW_TYPE); + err = WriteMimeAttr(type, kLongDescriptionAttr, description, strlen(description)+1, kLongDescriptionType); if (!err) - err = SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type); + err = SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type, B_META_MIME_MODIFIED); return err; } @@ -353,7 +474,7 @@ MimeDatabase::GetAppHint(const char *type, entry_ref *ref) const BEntry entry; ssize_t err = ref ? B_OK : B_BAD_VALUE; if (!err) - err = ReadMimeAttr(type, kAppHintAttr, path, B_MIME_TYPE_LENGTH, B_RAW_TYPE); + err = ReadMimeAttr(type, kAppHintAttr, path, B_MIME_TYPE_LENGTH, kAppHintType); if (err >= 0) err = entry.SetTo(path); if (!err) @@ -376,9 +497,9 @@ MimeDatabase::SetAppHint(const char *type, const entry_ref *ref) if (!err) err = path.SetTo(ref); if (!err) - err = WriteMimeAttr(type, kAppHintAttr, path.Path(), strlen(path.Path())+1, B_RAW_TYPE); + err = WriteMimeAttr(type, kAppHintAttr, path.Path(), strlen(path.Path())+1, kAppHintType); if (!err) - err = SendMonitorUpdate(B_APP_HINT_CHANGED, type); + err = SendMonitorUpdate(B_APP_HINT_CHANGED, type, B_META_MIME_MODIFIED); return err; } @@ -553,6 +674,106 @@ MimeDatabase::StopWatching(BMessenger target) return err; } +status_t +MimeDatabase::DeleteAppHint(const char *type) +{ + status_t err = DeleteAttribute(type, kAppHintAttr); + if (!err) + err = SendMonitorUpdate(B_APP_HINT_CHANGED, type, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeleteAttrInfo(const char *type) +{ + status_t err = DeleteAttribute(type, kAttrInfoAttr); + if (!err) + err = SendMonitorUpdate(B_ATTR_INFO_CHANGED, type, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeleteShortDescription(const char *type) +{ + status_t err = DeleteAttribute(type, kShortDescriptionAttr); + if (!err) + err = SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeleteLongDescription(const char *type) +{ + status_t err = DeleteAttribute(type, kLongDescriptionAttr); + if (!err) + err = SendMonitorUpdate(B_LONG_DESCRIPTION_CHANGED, type, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeleteFileExtensions(const char *type) +{ + status_t err = DeleteAttribute(type, kFileExtensionsAttr); + if (!err) + err = SendMonitorUpdate(B_FILE_EXTENSIONS_CHANGED, type, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeleteIcon(const char *type, icon_size which) +{ + const char *attr = which == B_MINI_ICON ? kMiniIconAttr : kLargeIconAttr; + status_t err = DeleteAttribute(type, attr); + if (!err) + err = SendMonitorUpdate(B_ICON_CHANGED, type, which, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeleteIconForType(const char *type, const char *fileType, icon_size which) +{ + std::string attr; + status_t err = fileType ? B_OK : B_BAD_VALUE; + if (!err) { + attr = (which == B_MINI_ICON ? kMiniIconAttrPrefix : kLargeIconAttrPrefix) + ToLower(fileType); + err = DeleteAttribute(type, attr.c_str()); + } + if (!err) + err = SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType, + which == B_LARGE_ICON, B_META_MIME_DELETED); + return err; +} + +status_t +MimeDatabase::DeletePreferredApp(const char *type, app_verb verb = B_OPEN) +{ + status_t err; + switch (verb) { + case B_OPEN: + err = DeleteAttribute(type, kPreferredAppAttr); + break; + + default: + err = B_BAD_VALUE; + break; + } + /*! \todo The R5 monitor makes no note of which app_verb value was updated. If + additional app_verb values besides \c B_OPEN are someday added, the format + of the MIME monitor messages will need to be augmented. + */ + if (!err) + err = SendMonitorUpdate(B_PREFERRED_APP_CHANGED, type, B_META_MIME_DELETED); +} + +status_t +MimeDatabase::DeleteSnifferRule(const char *type) +{ + status_t err = DeleteAttribute(type, kSnifferRuleAttr); + if (!err) + err = SendMonitorUpdate(B_SNIFFER_RULE_CHANGED, type, B_META_MIME_DELETED); + return err; +} + // GetIconData /*! \brief Returns properly formatted raw bitmap data, ready to be shipped off to the hacked up 4-parameter version of MimeDatabase::SetIcon() @@ -699,6 +920,46 @@ MimeDatabase::ReadMimeAttr(const char *type, const char *attr, void *data, return err; } +// ReadMimeAttrMessage +/*! \brief Reads a flattened BMessage from the given attribute of the given + MIME type. + + If no entry for the given type exists in the database, or if the data + stored in the attribute is not a flattened BMessage, the function fails + and the contents of \c msg are undefined. + + \param type The MIME type + \param attr The attribute name + \param data Pointer to a pre-allocated BMessage into which the attribute + data is unflattened. +*/ +status_t +MimeDatabase::ReadMimeAttrMessage(const char *type, const char *attr, BMessage *msg) const +{ + BNode node; + attr_info info; + char *buffer = NULL; + ssize_t err = (type && attr && msg ? B_OK : B_BAD_VALUE); + if (!err) + err = OpenType(type, &node); + if (!err) + err = node.GetAttrInfo(attr, &info); + if (!err) + err = info.type == B_MESSAGE_TYPE ? B_OK : B_BAD_VALUE; + if (!err) { + buffer = new char[info.size]; + if (!buffer) + err = B_NO_MEMORY; + } + if (!err) + err = node.ReadAttr(attr, B_MESSAGE_TYPE, 0, buffer, info.size); + if (err >= 0) + err = err == info.size ? B_OK : B_FILE_ERROR; + if (!err) + err = msg->Unflatten(buffer); + delete [] buffer; + return err; +} // WriteMimeAttr /*! \brief Writes \c len bytes of the given data to the given attribute @@ -730,6 +991,38 @@ MimeDatabase::WriteMimeAttr(const char *type, const char *attr, const void *data return err; } +// WriteMimeAttr +/*! \brief Flattens the given \c BMessage and writes it to the given attribute + of the given MIME type. + + If no entry for the given type exists in the database, it is created. + + \param type The MIME type + \param attr The attribute name + \param msg The BMessage to flatten and write +*/ +status_t +MimeDatabase::WriteMimeAttrMessage(const char *type, const char *attr, const BMessage *msg) +{ + BNode node; + BMallocIO data; + ssize_t bytes; + ssize_t err = (type && attr && msg ? B_OK : B_BAD_VALUE); + if (!err) + err = data.SetSize(msg->FlattenedSize()); + if (!err) + err = msg->Flatten(&data, &bytes); + if (!err) + err = bytes == msg->FlattenedSize() ? B_OK : B_ERROR; + if (!err) + err = OpenOrCreateType(type, &node); + if (!err) + err = node.WriteAttr(attr, B_MESSAGE_TYPE, 0, data.Buffer(), data.BufferLength()); + if (err >= 0) + err = err == data.BufferLength() ? B_OK : B_FILE_ERROR; + return err; +} + // OpenType /*! \brief Opens a BNode on the given type, failing if the type has no corresponding file in the database. @@ -810,7 +1103,7 @@ MimeDatabase::TypeToFilename(const char *type) const small icon was updated */ status_t -MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extraType, bool largeIcon) { +MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extraType, bool largeIcon, int32 action) { BMessage msg(B_META_MIME_CHANGED); status_t err; @@ -821,6 +1114,8 @@ MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extra err = msg.AddString("be:extra_type", extraType); if (!err) err = msg.AddBool("be:large_icon", largeIcon); + if (!err) + err = msg.AddInt32("be:action", action); if (!err) err = SendMonitorUpdate(msg); return err; @@ -834,7 +1129,7 @@ MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extra \param extraType The MIME type to which the change is applies */ status_t -MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extraType) { +MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extraType, int32 action) { BMessage msg(B_META_MIME_CHANGED); status_t err; @@ -843,6 +1138,8 @@ MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extra err = msg.AddString("be:type", type); if (!err) err = msg.AddString("be:extra_type", extraType); + if (!err) + err = msg.AddInt32("be:action", action); if (!err) err = SendMonitorUpdate(msg); return err; @@ -857,7 +1154,7 @@ MimeDatabase::SendMonitorUpdate(int32 which, const char *type, const char *extra small icon was updated */ status_t -MimeDatabase::SendMonitorUpdate(int32 which, const char *type, bool largeIcon) { +MimeDatabase::SendMonitorUpdate(int32 which, const char *type, bool largeIcon, int32 action) { BMessage msg(B_META_MIME_CHANGED); status_t err; @@ -866,6 +1163,8 @@ MimeDatabase::SendMonitorUpdate(int32 which, const char *type, bool largeIcon) { err = msg.AddString("be:type", type); if (!err) err = msg.AddBool("be:large_icon", largeIcon); + if (!err) + err = msg.AddInt32("be:action", action); if (!err) err = SendMonitorUpdate(msg); return err; @@ -878,13 +1177,15 @@ MimeDatabase::SendMonitorUpdate(int32 which, const char *type, bool largeIcon) { \param which Bitmask describing which attribute was updated */ status_t -MimeDatabase::SendMonitorUpdate(int32 which, const char *type) { +MimeDatabase::SendMonitorUpdate(int32 which, const char *type, int32 action) { BMessage msg(B_META_MIME_CHANGED); status_t err; err = msg.AddInt32("be:which", which); if (!err) err = msg.AddString("be:type", type); + if (!err) + err = msg.AddInt32("be:action", action); if (!err) err = SendMonitorUpdate(msg); return err; @@ -936,12 +1237,12 @@ MimeDatabase::GetIcon(const char *type, const char *attr, BBitmap *icon, icon_si switch (which) { case B_MINI_ICON: bounds.Set(0, 0, 15, 15); - attrType = B_MINI_ICON_TYPE; + attrType = kMiniIconType; attrSize = 16 * 16; break; case B_LARGE_ICON: bounds.Set(0, 0, 31, 31); - attrType = B_LARGE_ICON_TYPE; + attrType = kLargeIconType; attrSize = 32 * 32; break; default: @@ -1011,11 +1312,11 @@ MimeDatabase::SetIcon(const char *type, const char *attr, const void *data, size if (!err) { switch (which) { case B_MINI_ICON: - attrType = B_MINI_ICON_TYPE; + attrType = kMiniIconType; attrSize = 16 * 16; break; case B_LARGE_ICON: - attrType = B_LARGE_ICON_TYPE; + attrType = kLargeIconType; attrSize = 32 * 32; break; default: diff --git a/src/kits/storage/MimeType.cpp b/src/kits/storage/MimeType.cpp index b6c6d6a76d..6516ec5133 100644 --- a/src/kits/storage/MimeType.cpp +++ b/src/kits/storage/MimeType.cpp @@ -470,7 +470,7 @@ BMimeType::GetPreferredApp(char *signature, app_verb verb) const status_t BMimeType::GetAttrInfo(BMessage *info) const { - return NOT_IMPLEMENTED; + return fMimeDatabase->GetAttrInfo(Type(), info); } // GetFileExtensions @@ -504,7 +504,7 @@ BMimeType::GetAttrInfo(BMessage *info) const status_t BMimeType::GetFileExtensions(BMessage *extensions) const { - return NOT_IMPLEMENTED; + return fMimeDatabase->GetFileExtensions(Type(), extensions); } // GetShortDescription @@ -729,7 +729,28 @@ BMimeType::SetPreferredApp(const char *signature, app_verb verb) status_t BMimeType::SetAttrInfo(const BMessage *info) { - return NOT_IMPLEMENTED; + status_t err = InitCheck(); + + BMessage msg(info ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM); + BMessage reply; + status_t result; + + // Build and send the message, read the reply + if (!err) + err = msg.AddString("type", Type()); + if (!err) + err = msg.AddInt32("which", B_REG_MIME_ATTR_INFO); + if (!err && info) + err = msg.AddMessage("attr info", info); + if (!err) + err = _send_to_roster_(&msg, &reply, true); + if (!err) + err = reply.what == B_REG_RESULT ? B_OK : B_BAD_VALUE; + if (!err) + err = reply.FindInt32("result", &result); + if (!err) + err = result; + return err; } // SetFileExtensions @@ -765,7 +786,28 @@ BMimeType::SetAttrInfo(const BMessage *info) status_t BMimeType::SetFileExtensions(const BMessage *extensions) { - return NOT_IMPLEMENTED; + status_t err = InitCheck(); + + BMessage msg(extensions ? B_REG_MIME_SET_PARAM : B_REG_MIME_DELETE_PARAM); + BMessage reply; + status_t result; + + // Build and send the message, read the reply + if (!err) + err = msg.AddString("type", Type()); + if (!err) + err = msg.AddInt32("which", B_REG_MIME_FILE_EXTENSIONS); + if (!err && extensions) + err = msg.AddMessage("extensions", extensions); + if (!err) + err = _send_to_roster_(&msg, &reply, true); + if (!err) + err = reply.what == B_REG_RESULT ? B_OK : B_BAD_VALUE; + if (!err) + err = reply.FindInt32("result", &result); + if (!err) + err = result; + return err; } // SetShortDescription @@ -930,7 +972,11 @@ BMimeType::GetInstalledTypes(const char *super_type, BMessage *subtypes) status_t BMimeType::GetWildcardApps(BMessage *wild_ones) { - return NOT_IMPLEMENTED; + BMimeType mime; + status_t err = mime.SetTo("application/octet-stream"); + if (!err) + err = mime.GetSupportingApps(wild_ones); + return err; } // IsValid diff --git a/src/servers/registrar/MIMEManager.cpp b/src/servers/registrar/MIMEManager.cpp index fd6f38f8ed..a0e8b8aa1f 100644 --- a/src/servers/registrar/MIMEManager.cpp +++ b/src/servers/registrar/MIMEManager.cpp @@ -116,6 +116,15 @@ MIMEManager::HandleSetParam(BMessage *message) break; } + case B_REG_MIME_ATTR_INFO: + { + BMessage info; + err = message->FindMessage("attr info", &info); + if (!err) + err = fMimeDatabase.SetAttrInfo(type, &info); + break; + } + case B_REG_MIME_DESCRIPTION: { bool isLong; @@ -130,18 +139,16 @@ MIMEManager::HandleSetParam(BMessage *message) break; } - case B_REG_MIME_PREFERRED_APP: + case B_REG_MIME_FILE_EXTENSIONS: { - const char *signature; - int32 verb; - err = message->FindString("signature", &signature); + BMessage extensions; + err = message->FindMessage("extensions", &extensions); if (!err) - err = message->FindInt32("app verb", &verb); - if (!err) - err = fMimeDatabase.SetPreferredApp(type, signature, (app_verb)verb); + err = fMimeDatabase.SetFileExtensions(type, &extensions); break; } - + + case B_REG_MIME_ICON: case B_REG_MIME_ICON_FOR_TYPE: { @@ -165,33 +172,19 @@ MIMEManager::HandleSetParam(BMessage *message) } break; // End temporary fix code - -/* This is the code I was using until BBitmap::Instantiate blew up on me. - - BMessage iconArchive; - int32 size; - err = message->FindMessage("icon archive", &iconArchive); - if (!err) - err = message->FindInt32("size", &size); - iconArchive.PrintToStream(); - if (!err) { - BArchivable *unarchived = instantiate_object(&iconArchive); - if (unarchived) { - BBitmap *icon = cast_as(unarchived, BBitmap); - if (icon) { - err = icon->InitCheck(); - if (!err) - err = fMimeDatabase.SetIcon(type, icon, (icon_size)size); - delete icon; - } else - err = B_BAD_VALUE; - - } else - err = B_NO_MEMORY; - } - break; -*/ } + + case B_REG_MIME_PREFERRED_APP: + { + const char *signature; + int32 verb; + err = message->FindString("signature", &signature); + if (!err) + err = message->FindInt32("app verb", &verb); + if (!err) + err = fMimeDatabase.SetPreferredApp(type, signature, (app_verb)verb); + break; + } default: err = B_BAD_VALUE; @@ -221,40 +214,28 @@ MIMEManager::HandleDeleteParam(BMessage *message) if (!err) { switch (which) { case B_REG_MIME_APP_HINT: - err = fMimeDatabase.DeleteAttribute(type, BPrivate::MimeDatabase::kAppHintAttr); + err = fMimeDatabase.DeleteAppHint(type); break; + case B_REG_MIME_ATTR_INFO: + err = fMimeDatabase.DeleteAttrInfo(type); + break; + case B_REG_MIME_DESCRIPTION: { bool isLong; - const char *description; err = message->FindBool("long", &isLong); if (!err) - err = fMimeDatabase.DeleteAttribute(type, - (isLong - ? BPrivate::MimeDatabase::kLongDescriptionAttr - : BPrivate::MimeDatabase::kShortDescriptionAttr)); - break; - } - - case B_REG_MIME_PREFERRED_APP: - { - int32 verb; - err = message->FindInt32("app verb", &verb); - if (!err) { - switch (verb) { - case B_OPEN: - err = fMimeDatabase.DeleteAttribute(type, BPrivate::MimeDatabase::kPreferredAppAttr); - break; - - default: - err = B_BAD_VALUE; - break; - } - } + err = isLong + ? fMimeDatabase.DeleteLongDescription(type) + : fMimeDatabase.DeleteShortDescription(type); break; } + case B_REG_MIME_FILE_EXTENSIONS: + err = fMimeDatabase.DeleteFileExtensions(type); + break; + case B_REG_MIME_ICON: case B_REG_MIME_ICON_FOR_TYPE: { @@ -264,23 +245,28 @@ MIMEManager::HandleDeleteParam(BMessage *message) const char *fileType; if (!err) err = message->FindString("file type", &fileType); - if (!err) { - std::string attr = ((size == B_MINI_ICON) - ? BPrivate::MimeDatabase::kMiniIconAttrPrefix - : BPrivate::MimeDatabase::kLargeIconAttrPrefix) - + BPrivate::MimeDatabase::ToLower(fileType); - err = fMimeDatabase.DeleteAttribute(type, attr.c_str()); - } + if (!err) + err = fMimeDatabase.DeleteIconForType(type, fileType, (icon_size)size); } else { - if (!err) { - err = fMimeDatabase.DeleteAttribute(type, (size == B_MINI_ICON - ? BPrivate::MimeDatabase::kMiniIconAttr - : BPrivate::MimeDatabase::kLargeIconAttr)); - } + if (!err) + err = fMimeDatabase.DeleteIcon(type, (icon_size)size); } break; } + case B_REG_MIME_PREFERRED_APP: + { + int32 verb; + err = message->FindInt32("app verb", &verb); + if (!err) + err = fMimeDatabase.DeletePreferredApp(type, (app_verb)verb); + break; + } + + case B_REG_MIME_SNIFFER_RULE: + err = fMimeDatabase.DeleteSnifferRule(type); + break; + default: err = B_BAD_VALUE; break; diff --git a/src/tests/kits/storage/MimeTypeTest.cpp b/src/tests/kits/storage/MimeTypeTest.cpp index b79a7d1780..277525d465 100644 --- a/src/tests/kits/storage/MimeTypeTest.cpp +++ b/src/tests/kits/storage/MimeTypeTest.cpp @@ -19,7 +19,9 @@ #include // B_GET_ICON, device_icon #include #include -#include +#if !TEST_R5 + #include +#endif #include #include // Only needed for entry_ref dumps #include @@ -848,29 +850,51 @@ MimeTypeTest::AttrInfoTest() { // NULL params NextSubTest(); { - BMimeType mime(testType); +#if !TEST_R5 BMessage msg; - + BMimeType mime(testType); CHK(mime.InitCheck() == B_OK); // Make sure the type isn't installed if (mime.IsInstalled()) CHK(mime.Delete() == B_OK); - - // Non-installed CHK(!mime.IsInstalled()); - CHK(mime.GetAttrInfo(NULL) != B_OK); // R5 == B_ENTRY_NOT_FOUND + CHK(mime.DeleteAttrInfo() != B_OK); CHK(!mime.IsInstalled()); -#if !TEST_R5 - CHK(RES(mime.SetAttrInfo(NULL)) != B_OK); // R5 == CRASH!!! -#endif - - // Installed - NextSubTest(); - CHK(mime.Install() == B_OK); + msg1.RemoveName(typeField); // Clear "type" field, since SAI() just adds another + CHK(mime.SetAttrInfo(&msg1) == B_OK); CHK(mime.IsInstalled()); - CHK(mime.GetAttrInfo(NULL) != B_OK); // R5 == B_ENTRY_NOT_FOUND + CHK(msg != msg1); + CHK(mime.GetAttrInfo(&msg) == B_OK); + CHK(msg1.AddString(typeField, testType) == B_OK); // Add in "type" field as GAI() does + CHK(msg == msg1); + CHK(mime.SetAttrInfo(NULL) == B_OK); + CHK(mime.IsInstalled()); + CHK(mime.GetAttrInfo(&msg) != B_OK); +#endif + } + // Delete test + NextSubTest(); + { #if !TEST_R5 - CHK(RES(mime.SetAttrInfo(NULL)) != B_OK); // R5 == CRASH!!! + BMessage msg; + BMimeType mime(testType); + CHK(mime.InitCheck() == B_OK); + // Make sure the type isn't installed + if (mime.IsInstalled()) + CHK(mime.Delete() == B_OK); + CHK(!mime.IsInstalled()); + CHK(mime.DeleteAttrInfo() != B_OK); + CHK(!mime.IsInstalled()); + msg1.RemoveName(typeField); // Clear "type" field, since SAI() just adds another + CHK(mime.SetAttrInfo(&msg1) == B_OK); + CHK(mime.IsInstalled()); + CHK(msg != msg1); + CHK(mime.GetAttrInfo(&msg) == B_OK); + CHK(msg1.AddString(typeField, testType) == B_OK); // Add in "type" field as GAI() does + CHK(msg == msg1); + CHK(mime.DeleteAttrInfo() == B_OK); + CHK(mime.IsInstalled()); + CHK(mime.GetAttrInfo(&msg) != B_OK); #endif } @@ -1067,8 +1091,8 @@ MimeTypeTest::AttrInfoTest() { CHK(msg != msg1); CHK(msg != msg2); #if !TEST_R5 - CHK(RES(mime.SetAttrInfo(NULL)) == B_OK); // R5 == CRASH! despite what one might think should happen - CHK(RES(mime.GetAttrInfo(&msg)) != B_OK); + CHK(mime.SetAttrInfo(NULL) == B_OK); // R5 == CRASH! despite what one might think should happen + CHK(mime.GetAttrInfo(&msg) != B_OK); CHK(msg1.AddString(typeField, testType) == B_OK); // Add in "type" fields as GFE() does CHK(msg2.AddString(typeField, testType) == B_OK); CHK(msg != msg1); @@ -1116,28 +1140,51 @@ MimeTypeTest::FileExtensionsTest() { // NULL params NextSubTest(); { - BMessage msg(WHAT); +#if !TEST_R5 + BMessage msg; BMimeType mime(testType); - CHK(mime.InitCheck() == B_OK); // Make sure the type isn't installed if (mime.IsInstalled()) CHK(mime.Delete() == B_OK); CHK(!mime.IsInstalled()); - // Not installed - CHK(mime.GetFileExtensions(NULL) != B_OK); // R5 == B_BAD_VALUE + CHK(mime.DeleteFileExtensions() != B_OK); CHK(!mime.IsInstalled()); -#if !TEST_R5 - CHK(RES(mime.SetFileExtensions(NULL)) == B_OK); // R5 == CRASH! + msg1.RemoveName(typeField); // Clear "type" field, since SAI() just adds another + CHK(mime.SetFileExtensions(&msg1) == B_OK); CHK(mime.IsInstalled()); - CHK(RES(mime.GetFileExtensions(&msg)) != B_OK); // R5 == B_ENTRY_NOT_FOUND - // Installed -/* CHK(mime.GetFileExtensions(NULL) != B_OK); // R5 == B_BAD_VALUE - CHK(mime.SetFileExtensions(helper.Bitmap1()) == B_OK); - CHK(mime.GetFileExtensions(bmp) == B_OK); - CHK(*bmp == *helper.Bitmap1()); - CHK(mime.SetFileExtensions(NULL) == B_OK); - CHK(mime.GetFileExtensions(bmp) != B_OK); // R5 == B_ENTRY_NOT_FOUND*/ + CHK(msg != msg1); + CHK(mime.GetFileExtensions(&msg) == B_OK); + CHK(msg1.AddString(typeField, testType) == B_OK); // Add in "type" field as GAI() does + CHK(msg == msg1); + CHK(mime.SetFileExtensions(NULL) == B_OK); + CHK(mime.IsInstalled()); + CHK(mime.GetFileExtensions(&msg) != B_OK); +#endif + } + // Delete test + NextSubTest(); + { +#if !TEST_R5 + BMessage msg; + BMimeType mime(testType); + CHK(mime.InitCheck() == B_OK); + // Make sure the type isn't installed + if (mime.IsInstalled()) + CHK(mime.Delete() == B_OK); + CHK(!mime.IsInstalled()); + CHK(mime.DeleteFileExtensions() != B_OK); + CHK(!mime.IsInstalled()); + msg1.RemoveName(typeField); // Clear "type" field, since SAI() just adds another + CHK(mime.SetFileExtensions(&msg1) == B_OK); + CHK(mime.IsInstalled()); + CHK(msg != msg1); + CHK(mime.GetFileExtensions(&msg) == B_OK); + CHK(msg1.AddString(typeField, testType) == B_OK); // Add in "type" field as GAI() does + CHK(msg == msg1); + CHK(mime.DeleteFileExtensions() == B_OK); + CHK(mime.IsInstalled()); + CHK(mime.GetFileExtensions(&msg) != B_OK); #endif } // Set() with empty message @@ -1255,8 +1302,8 @@ MimeTypeTest::FileExtensionsTest() { CHK(msg != msg1); CHK(msg != msg2); #if !TEST_R5 - CHK(RES(mime.SetFileExtensions(NULL)) == B_OK); // R5 == CRASH! despite what the BeBook says - CHK(RES(mime.GetFileExtensions(&msg)) != B_OK); + CHK(mime.SetFileExtensions(NULL) == B_OK); // R5 == CRASH! despite what the BeBook says + CHK(mime.GetFileExtensions(&msg) != B_OK); CHK(msg1.AddString(typeField, testType) == B_OK); // Add in "type" fields as GFE() does CHK(msg2.AddString(typeField, testType) == B_OK); CHK(msg != msg1); @@ -2169,6 +2216,8 @@ void FillWithMimeTypes(ContainerAdapter &container, BMessage &typeMessage, const int32 count; status_t err; +// typeMessage.PrintToStream(); + // Get a count of types in the message err = typeMessage.GetInfo(fieldName, &type, &count); if (err == B_NAME_NOT_FOUND) @@ -2982,6 +3031,8 @@ MimeTypeTest::MonitoringTest() // icon for type CHK(type.SetIconForType("text/plain", iconHelperLarge.Bitmap2(), B_LARGE_ICON) == B_OK); + CHK(type.SetIconForType("text/plain", NULL, + B_LARGE_ICON) == B_OK); CHK(type.SetIconForType("text/plain", iconHelperMini.Bitmap2(), B_MINI_ICON) == B_OK); // app hint @@ -3006,6 +3057,7 @@ MimeTypeTest::MonitoringTest() NM(B_LONG_DESCRIPTION_CHANGED, testType), NM(B_SHORT_DESCRIPTION_CHANGED, testType), NM(B_ICON_FOR_TYPE_CHANGED, testType, "text/plain", true), + NM(B_ICON_FOR_TYPE_CHANGED, testType, "text/plain", true), NM(B_ICON_FOR_TYPE_CHANGED, testType, "text/plain", false), NM(B_APP_HINT_CHANGED, testType), NM(B_SNIFFER_RULE_CHANGED, testType), @@ -3398,6 +3450,25 @@ public: error = resources.AddResource(MINI_ICON_TYPE, 101, miniIcon, 256, "BEOS:M:STD_ICON"); } + // file types +/* if (error == B_OK) { + BMessage msg; + char *buffer = NULL; + error = msg.AddString("types", "text/x-email"); + if (!error) + error = msg.AddString("types", "video/mpeg"); + if (!error) { + buffer = new char[msg.FlattenedSize()]; + if (!buffer) + error = B_NO_MEMORY; + } + if (!error) + error = msg.Flatten(buffer, msg.FlattenedSize()); + if (!error) + error = resources.AddResource(B_MESSAGE_TYPE, 1, buffer, + msg.FlattenedSize(), "BEOS:FILE_TYPES"); + delete [] buffer; + }*/ } return error; } @@ -3441,6 +3512,7 @@ CheckAppMetaMime(AppMimeTestFile &file) // META:PPATH BNode typeFile; string typeFilename(string(mimeDatabaseDir) + "/" + file.signature); +// cout << "typeFilename == '" << typeFilename << "'" << endl; CHK(typeFile.SetTo(typeFilename.c_str()) == B_OK); char filePath[B_PATH_NAME_LENGTH + 1]; CHK(typeFile.ReadAttr("META:PPATH", B_STRING_TYPE, 0, filePath,