+ Added SetSupportedTypes() test
+ Modified BMimeType::SetSupportedTypes functionality so it keeps track of stranded types (i.e. previously supported types that have not had the now unsupporting app signature removed from their supporting apps list yet due to a false fullSync parameter) over consecutive SetSupportedTypes(..., false) calls and updates all appropriate stranded types on the next SetSupportedTypes(..., true) call. + Added fullSync parameter to BMimeType::DeleteSupportedTypes + Made BMimeType::Delete() do a DeleteSupportedTypes(..., true) call to properly update the supporting apps lists when a mime type is deleted. + Added initial BMimeType::Get/SetSnifferRule + Updated BMimeType::CheckSnifferRule() to return B_BAD_VALUE when passed a NULL rule string. + Brought CheckSnifferRule() tests up to date + Added lots of Mime::Database doxygen + Added any missing mime monitor notifications in Mime::Database + Possibly made some other changes as well... :-) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1004 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
baa326e0ec
commit
e3a2f2069e
@ -49,7 +49,7 @@ public:
|
||||
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 *);
|
||||
status_t SetSnifferRule(const char *type, const char *rule);
|
||||
status_t SetSupportedTypes(const char *type, const BMessage *types, bool fullSync);
|
||||
|
||||
// Non-atomic Get()
|
||||
@ -80,7 +80,7 @@ public:
|
||||
status_t DeleteIconForType(const char *type, const char *fileType, icon_size which);
|
||||
status_t DeletePreferredApp(const char *type, app_verb verb = B_OPEN);
|
||||
status_t DeleteSnifferRule(const char *type);
|
||||
status_t DeleteSupportedTypes(const char *type);
|
||||
status_t DeleteSupportedTypes(const char *type, bool fullSync);
|
||||
|
||||
private:
|
||||
status_t SendInstallNotification(const char *type);
|
||||
|
@ -28,7 +28,9 @@ public:
|
||||
~SupportingApps();
|
||||
|
||||
status_t GetSupportingApps(const char *type, BMessage *apps);
|
||||
|
||||
status_t SetSupportedTypes(const char *app, const BMessage *types, bool fullSync);
|
||||
status_t DeleteSupportedTypes(const char *app, bool fullSync);
|
||||
private:
|
||||
status_t AddSupportingApp(const char *type, const char *app);
|
||||
status_t RemoveSupportingApp(const char *type, const char *app);
|
||||
@ -37,6 +39,8 @@ private:
|
||||
|
||||
std::map<std::string, std::set<std::string> > fSupportedTypes; // app sig => set of supported types
|
||||
std::map<std::string, std::set<std::string> > fSupportingApps; // mime type => set of supporting apps
|
||||
std::map<std::string, std::set<std::string> > fStrandedTypes; // app sig => set of no longer supported types for whom the
|
||||
// given app is still listed as a supporting app
|
||||
bool fHaveDoneFullBuild;
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@ status_t get_icon(const char *type, BBitmap *icon, icon_size size);
|
||||
status_t get_icon_for_type(const char *type, const char *fileType, BBitmap *icon,
|
||||
icon_size which);
|
||||
status_t get_preferred_app(const char *type, char *signature, app_verb verb);
|
||||
status_t get_sniffer_rule(BString *result);
|
||||
status_t get_sniffer_rule(const char *type, BString *result);
|
||||
status_t get_supported_types(const char *type, BMessage *types);
|
||||
|
||||
bool is_installed(const char *type);
|
||||
|
@ -48,7 +48,6 @@ namespace Mime {
|
||||
\brief Mime::Database is the master of the MIME data base.
|
||||
|
||||
All write and non-atomic read accesses are carried out by this class.
|
||||
Monitoring is handled by
|
||||
|
||||
\note No error checking (other than checks for NULL pointers) is performed
|
||||
by this class on the mime type strings passed to it. It's assumed
|
||||
@ -56,7 +55,7 @@ namespace Mime {
|
||||
*/
|
||||
|
||||
// constructor
|
||||
/*! \brief Creates and initializes a MimeDatabase.
|
||||
/*! \brief Creates and initializes a Mime::Database object.
|
||||
*/
|
||||
Database::Database()
|
||||
: fCStatus(B_NO_INIT)
|
||||
@ -110,8 +109,10 @@ Database::Install(const char *type)
|
||||
bool didCreate = false;
|
||||
BNode node;
|
||||
err = open_or_create_type(type, &node, &didCreate);
|
||||
if (didCreate)
|
||||
if (!err && didCreate) {
|
||||
fInstalledTypes.AddType(type);
|
||||
err = SendInstallNotification(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
@ -129,14 +130,21 @@ Database::Delete(const char *type)
|
||||
{
|
||||
BEntry entry;
|
||||
status_t err = (type ? B_OK : B_BAD_VALUE);
|
||||
// Open the type
|
||||
if (!err)
|
||||
err = entry.SetTo(type_to_filename(type).c_str());
|
||||
err = entry.SetTo(type_to_filename(type).c_str());
|
||||
// Remove it
|
||||
if (!err)
|
||||
err = entry.Remove();
|
||||
if (!err) {
|
||||
// Notify the installed types database
|
||||
if (!err)
|
||||
fInstalledTypes.RemoveType(type);
|
||||
// Notify the supporting apps database
|
||||
if (!err)
|
||||
err = fSupportingApps.DeleteSupportedTypes(type, true);
|
||||
// Notify the monitor service
|
||||
if (!err)
|
||||
err = SendDeleteNotification(type);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -158,6 +166,8 @@ Database::SetAppHint(const char *type, const entry_ref *ref)
|
||||
if (!err)
|
||||
err = write_mime_attr(type, kAppHintAttr, path.Path(), strlen(path.Path())+1,
|
||||
kAppHintType, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_APP_HINT_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
return err;
|
||||
@ -186,6 +196,8 @@ Database::SetAttrInfo(const char *type, const BMessage *info)
|
||||
status_t err = (type && info) ? B_OK : B_BAD_VALUE;
|
||||
if (!err)
|
||||
err = write_mime_attr_message(type, kAttrInfoAttr, info, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_ATTR_INFO_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
return err;
|
||||
@ -224,8 +236,10 @@ Database::SetLongDescription(const char *type, const char *description)
|
||||
if (!err)
|
||||
err = write_mime_attr(type, kLongDescriptionAttr, description, strlen(description)+1,
|
||||
kLongDescriptionType, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
err = SendMonitorUpdate(B_LONG_DESCRIPTION_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -249,6 +263,8 @@ Database::SetFileExtensions(const char *type, const BMessage *extensions)
|
||||
status_t err = (type && extensions) ? B_OK : B_BAD_VALUE;
|
||||
if (!err)
|
||||
err = write_mime_attr_message(type, kFileExtensionsAttr, extensions, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_FILE_EXTENSIONS_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
return err;
|
||||
@ -337,10 +353,18 @@ Database::SetIconForType(const char *type, const char *fileType, const void *dat
|
||||
bool didCreate = false;
|
||||
if (!err)
|
||||
err = open_or_create_type(type, &node, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = node.WriteAttr(attr.c_str(), attrType, 0, data, attrSize);
|
||||
if (err >= 0)
|
||||
err = err == (ssize_t)attrSize ? B_OK : B_FILE_ERROR;
|
||||
if (!err) {
|
||||
if (fileType)
|
||||
err = SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType, (which == B_LARGE_ICON), B_META_MIME_MODIFIED);
|
||||
else
|
||||
err = SendMonitorUpdate(B_ICON_CHANGED, type, (which == B_LARGE_ICON), B_META_MIME_MODIFIED);
|
||||
}
|
||||
return err;
|
||||
|
||||
}
|
||||
@ -363,12 +387,48 @@ Database::SetPreferredApp(const char *type, const char *signature, app_verb verb
|
||||
if (!err)
|
||||
err = write_mime_attr(type, kPreferredAppAttr, signature, strlen(signature)+1,
|
||||
kPreferredAppType, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_PREFERRED_APP_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
return err;
|
||||
}
|
||||
|
||||
// SetSnifferRule
|
||||
/*! \brief Sets the mime sniffer rule for the given mime type
|
||||
|
||||
\todo This ought to trigger an update to the sniffer rule manager whenever we write one
|
||||
*/
|
||||
status_t
|
||||
Database::SetSnifferRule(const char *type, const char *rule)
|
||||
{
|
||||
DBG(OUT("Database::SetSnifferRule()\n"));
|
||||
bool didCreate = false;
|
||||
status_t err = (type && rule) ? B_OK : B_BAD_VALUE;
|
||||
if (!err)
|
||||
err = write_mime_attr(type, kSnifferRuleAttr, rule, strlen(rule)+1,
|
||||
kSnifferRuleType, &didCreate);
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_SNIFFER_RULE_CHANGED, type, B_META_MIME_MODIFIED);
|
||||
return err;
|
||||
}
|
||||
|
||||
// SetSupportedTypes
|
||||
/*! \brief Sets the list of MIME types supported by the MIME type and
|
||||
syncs the internal supporting apps database either partially or
|
||||
completely.
|
||||
|
||||
Please see BMimeType::SetSupportedTypes() for details.
|
||||
\param type The mime type of interest
|
||||
\param types The supported types to be assigned to the file.
|
||||
\param syncAll \c true to also synchronize the previously supported
|
||||
types, \c false otherwise.
|
||||
\return
|
||||
- \c B_OK: success
|
||||
- other error codes: failure
|
||||
*/
|
||||
status_t
|
||||
Database::SetSupportedTypes(const char *type, const BMessage *types, bool fullSync)
|
||||
{
|
||||
@ -389,6 +449,9 @@ Database::SetSupportedTypes(const char *type, const BMessage *types, bool fullSy
|
||||
// Write the attr
|
||||
if (!err)
|
||||
err = write_mime_attr_message(type, kSupportedTypesAttr, types, &didCreate);
|
||||
// Notify the monitor if we created the type when we opened it
|
||||
if (!err && didCreate)
|
||||
err = SendInstallNotification(type);
|
||||
// Update the supporting apps map
|
||||
if (!err)
|
||||
err = fSupportingApps.SetSupportedTypes(type, types, fullSync);
|
||||
@ -398,24 +461,71 @@ Database::SetSupportedTypes(const char *type, const BMessage *types, bool fullSy
|
||||
return err;
|
||||
}
|
||||
|
||||
// GetInstalledSupertypes
|
||||
/*! \brief Fetches a BMessage listing all the MIME supertypes currently
|
||||
installed in the MIME database.
|
||||
|
||||
The types are copied into the \c "super_types" field of the passed-in \c BMessage.
|
||||
The \c BMessage must be pre-allocated.
|
||||
|
||||
\param super_types Pointer to a pre-allocated \c BMessage into which the
|
||||
MIME supertypes will be copied.
|
||||
\return
|
||||
- \c B_OK: Success
|
||||
- "error code": Failure
|
||||
*/
|
||||
status_t
|
||||
Database::GetInstalledSupertypes(BMessage *supertypes)
|
||||
{
|
||||
return fInstalledTypes.GetInstalledSupertypes(supertypes);
|
||||
}
|
||||
|
||||
// GetInstalledTypes
|
||||
/*! \brief Fetches a BMessage listing all the MIME types currently installed
|
||||
in the MIME database.
|
||||
|
||||
The types are copied into the \c "types" field of the passed-in \c BMessage.
|
||||
The \c BMessage must be pre-allocated.
|
||||
|
||||
\param types Pointer to a pre-allocated \c BMessage into which the
|
||||
MIME types will be copied.
|
||||
\return
|
||||
- \c B_OK: Success
|
||||
- "error code": Failure
|
||||
*/
|
||||
status_t
|
||||
Database::GetInstalledTypes(BMessage *types)
|
||||
{
|
||||
return fInstalledTypes.GetInstalledTypes(types);
|
||||
}
|
||||
|
||||
// GetInstalledTypes
|
||||
/*! \brief Fetches a BMessage listing all the MIME subtypes of the given
|
||||
supertype currently installed in the MIME database.
|
||||
|
||||
The types are copied into the \c "types" field of the passed-in \c BMessage.
|
||||
The \c BMessage must be pre-allocated.
|
||||
|
||||
\param super_type Pointer to a string containing the MIME supertype whose
|
||||
subtypes you wish to retrieve.
|
||||
\param subtypes Pointer to a pre-allocated \c BMessage into which the appropriate
|
||||
MIME subtypes will be copied.
|
||||
\return
|
||||
- \c B_OK: Success
|
||||
- "error code": Failure
|
||||
*/
|
||||
status_t
|
||||
Database::GetInstalledTypes(const char *supertype, BMessage *subtypes)
|
||||
{
|
||||
return fInstalledTypes.GetInstalledTypes(supertype, subtypes);
|
||||
}
|
||||
|
||||
// GetSupportingApps
|
||||
/*! \brief Fetches a \c BMessage containing a list of MIME signatures of
|
||||
applications that are able to handle files of this MIME type.
|
||||
|
||||
Please see BMimeType::GetSupportingApps() for more details.
|
||||
*/
|
||||
status_t
|
||||
Database::GetSupportingApps(const char *type, BMessage *signatures)
|
||||
{
|
||||
@ -520,12 +630,23 @@ status_t
|
||||
Database::StopWatching(BMessenger target)
|
||||
{
|
||||
DBG(OUT("Database::StopWatching()\n"));
|
||||
status_t err = fMonitorMessengers.find(target) != fMonitorMessengers.end() ? B_OK : B_ENTRY_NOT_FOUND;
|
||||
status_t err = target.IsValid() ? B_OK : B_BAD_VALUE;
|
||||
if (!err)
|
||||
err = fMonitorMessengers.find(target) != fMonitorMessengers.end() ? B_OK : B_ENTRY_NOT_FOUND;
|
||||
if (!err)
|
||||
fMonitorMessengers.erase(target);
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteAppHint
|
||||
//! Deletes the app hint attribute for the given type
|
||||
/*! A \c B_APP_HINT_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteAppHint(const char *type)
|
||||
{
|
||||
@ -535,6 +656,15 @@ Database::DeleteAppHint(const char *type)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteAttrInfo
|
||||
//! Deletes the attribute info attribute for the given type
|
||||
/*! A \c B_ATTR_INFO_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteAttrInfo(const char *type)
|
||||
{
|
||||
@ -544,6 +674,15 @@ Database::DeleteAttrInfo(const char *type)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteShortDescription
|
||||
//! Deletes the short description attribute for the given type
|
||||
/*! A \c B_SHORT_DESCRIPTION_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteShortDescription(const char *type)
|
||||
{
|
||||
@ -553,6 +692,15 @@ Database::DeleteShortDescription(const char *type)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteLongDescription
|
||||
//! Deletes the long description attribute for the given type
|
||||
/*! A \c B_LONG_DESCRIPTION_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteLongDescription(const char *type)
|
||||
{
|
||||
@ -562,6 +710,15 @@ Database::DeleteLongDescription(const char *type)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteFileExtensions
|
||||
//! Deletes the associated file extensions attribute for the given type
|
||||
/*! A \c B_FILE_EXTENSIONS_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteFileExtensions(const char *type)
|
||||
{
|
||||
@ -571,6 +728,16 @@ Database::DeleteFileExtensions(const char *type)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteIcon
|
||||
//! Deletes the icon of the given size for the given type
|
||||
/*! A \c B_ICON_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\param which The icon size of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteIcon(const char *type, icon_size which)
|
||||
{
|
||||
@ -581,6 +748,22 @@ Database::DeleteIcon(const char *type, icon_size which)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteIconForType
|
||||
/*! \brief Deletes the icon of the given size associated with the given file type for the given
|
||||
application signature.
|
||||
|
||||
(If this function seems confusing, please see BMimeType::GetIconForType() for a
|
||||
better description of what the *IconForType() functions are used for.)
|
||||
|
||||
A \c B_ICON_FOR_TYPE_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of the application whose custom icon you are deleting.
|
||||
\param which The mime type for which you no longer wish \c type to have a custom icon.
|
||||
\param which The icon size of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteIconForType(const char *type, const char *fileType, icon_size which)
|
||||
{
|
||||
@ -596,6 +779,16 @@ Database::DeleteIconForType(const char *type, const char *fileType, icon_size wh
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeletePreferredApp
|
||||
//! Deletes the preferred app for the given app verb for the given type
|
||||
/*! A \c B_PREFERRED_APP_CHANGED notification is sent to the mime monitor service.
|
||||
\param type The mime type of interest
|
||||
\param which The app verb of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeletePreferredApp(const char *type, app_verb verb = B_OPEN)
|
||||
{
|
||||
@ -618,6 +811,17 @@ Database::DeletePreferredApp(const char *type, app_verb verb = B_OPEN)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteSnifferRule
|
||||
//! Deletes the sniffer rule for the given type
|
||||
/*! A \c B_SNIFFER_RULE_CHANGED notification is sent to the mime monitor service,
|
||||
and the corresponding rule is removed from the internal database of sniffer
|
||||
rules.
|
||||
\param type The mime type of interest
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteSnifferRule(const char *type)
|
||||
{
|
||||
@ -627,15 +831,42 @@ Database::DeleteSnifferRule(const char *type)
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteSupportedTypes
|
||||
//! Deletes the supported types list for the given type
|
||||
/*! A \c B_SUPPORTED_TYPES_CHANGED notification is sent to the mime monitor service.
|
||||
If \c fullSync is \c true, the given type is removed from the internal list
|
||||
of supporting applictions for each previously supported type. If \c fullSync
|
||||
is \c false, the said removal will occur the next time SetSupportedTypes() or
|
||||
DeleteSupportedTypes() is called with a \c true \c fullSync paramter, or
|
||||
\c Delete() is called for the given type.
|
||||
\param type The mime type of interest
|
||||
\param fullSync Whether or not to remove the type as a supporting app for
|
||||
all previously supported types
|
||||
\return
|
||||
- B_OK: success
|
||||
- B_ENTRY_NOT_FOUND: no such attribute existed
|
||||
- "error code": failure
|
||||
*/
|
||||
status_t
|
||||
Database::DeleteSupportedTypes(const char *type)
|
||||
Database::DeleteSupportedTypes(const char *type, bool fullSync)
|
||||
{
|
||||
status_t err = delete_attribute(type, kSupportedTypesAttr);
|
||||
// Update the supporting apps database. If fullSync is specified,
|
||||
// do so even if the supported types attribute didn't exist, as
|
||||
// stranded types *may* exist in the database due to previous
|
||||
// calls to {Set,Delete}SupportedTypes() with fullSync == false.
|
||||
if (!err)
|
||||
err = fSupportingApps.DeleteSupportedTypes(type, fullSync);
|
||||
else if (fullSync && err == B_ENTRY_NOT_FOUND)
|
||||
fSupportingApps.DeleteSupportedTypes(type, fullSync);
|
||||
// Send a monitor notification
|
||||
if (!err)
|
||||
err = SendMonitorUpdate(B_SUPPORTED_TYPES_CHANGED, type, B_META_MIME_DELETED);
|
||||
return err;
|
||||
}
|
||||
|
||||
// SendInstallNotification
|
||||
//! \brief Sends a \c B_MIME_TYPE_CREATED notification to the mime monitor service
|
||||
status_t
|
||||
Database::SendInstallNotification(const char *type)
|
||||
{
|
||||
@ -645,6 +876,7 @@ Database::SendInstallNotification(const char *type)
|
||||
}
|
||||
|
||||
status_t
|
||||
//! \brief Sends a \c B_MIME_TYPE_DELETED notification to the mime monitor service
|
||||
Database::SendDeleteNotification(const char *type)
|
||||
{
|
||||
// Tell the backend first
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
#define DBG(x) x
|
||||
//#define DBG(x)
|
||||
@ -114,14 +115,34 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
|
||||
}
|
||||
|
||||
// SetSupportedTypes
|
||||
/*! \brief Sets the list of supported types for the given application.
|
||||
/*! \brief Sets the list of supported types for the given application and
|
||||
updates the supporting apps mappings.
|
||||
|
||||
All types listed as being supported types will including the given
|
||||
app signature in their list of supporting apps following this call.
|
||||
|
||||
If \a fullSync is true, all types previously but no longer supported
|
||||
by this application with no longer list this application as a
|
||||
supporting app.
|
||||
|
||||
If \a fullSync is false, said previously supported types will be
|
||||
saved to a "stranded types" mapping and appropriately synchronized
|
||||
the next time SetSupportedTypes() is called with a \c true \a fullSync
|
||||
parameter.
|
||||
|
||||
The stranded types mapping is properly maintained even in the event
|
||||
of types being removed and then re-added to the list of supporting
|
||||
types with consecutive \c false \a fullSync parameters.
|
||||
|
||||
\param app The application whose supported types you are setting
|
||||
\param types Pointer to a \c BMessage containing an array of supported
|
||||
mime types in its \c Mime::kTypesField field.
|
||||
mime types in its \c Mime::kTypesField field.
|
||||
\param fullSync If \c true, \c app is removed as a supporting application
|
||||
of any types for which it is no longer a supporting application
|
||||
as of this call to SetSupportedTypes(). If \c false, said
|
||||
mappings are not updated.
|
||||
for any types for which it is no longer a supporting application
|
||||
(including types which were removed as supporting types with
|
||||
previous callsto SetSupportedTypes(..., false)). If \c false,
|
||||
said mappings are not updated until the next SetSupportedTypes(..., true)
|
||||
call.
|
||||
*/
|
||||
status_t
|
||||
SupportingApps::SetSupportedTypes(const char *app, const BMessage *types, bool fullSync)
|
||||
@ -132,9 +153,11 @@ SupportingApps::SetSupportedTypes(const char *app, const BMessage *types, bool f
|
||||
|
||||
std::set<std::string> oldTypes;
|
||||
std::set<std::string> &newTypes = fSupportedTypes[app];
|
||||
std::set<std::string> &strandedTypes = fStrandedTypes[app];
|
||||
// Make a copy of the previous types if we're doing a full sync
|
||||
if (!err && fullSync)
|
||||
if (!err)
|
||||
oldTypes = newTypes;
|
||||
|
||||
if (!err) {
|
||||
// Read through the list of new supported types, creating the new
|
||||
// supported types list and adding the app as a supporting app for
|
||||
@ -148,21 +171,51 @@ SupportingApps::SetSupportedTypes(const char *app, const BMessage *types, bool f
|
||||
AddSupportingApp(type, app);
|
||||
}
|
||||
|
||||
// Update the list of stranded types by removing any types that are newly
|
||||
// re-supported and adding any types that are newly un-supported
|
||||
for (std::set<std::string>::const_iterator i = newTypes.begin();
|
||||
i != newTypes.end();
|
||||
i++)
|
||||
{
|
||||
strandedTypes.erase(*i);
|
||||
}
|
||||
for (std::set<std::string>::const_iterator i = oldTypes.begin();
|
||||
i != oldTypes.end();
|
||||
i++)
|
||||
{
|
||||
if (newTypes.find(*i) == newTypes.end())
|
||||
strandedTypes.insert(*i);
|
||||
}
|
||||
|
||||
// Now, if we're doing a full sync, remove the app as a supporting
|
||||
// app for any types it no longer supports
|
||||
if (fullSync) {
|
||||
for (std::set<std::string>::iterator i = oldTypes.begin();
|
||||
i != oldTypes.end();
|
||||
// app for any of its stranded types and then clear said list of
|
||||
// stranded types.
|
||||
if (fullSync) {
|
||||
for (std::set<std::string>::const_iterator i = strandedTypes.begin();
|
||||
i != strandedTypes.end();
|
||||
i++)
|
||||
{
|
||||
if (newTypes.find(*i) == newTypes.end())
|
||||
RemoveSupportingApp((*i).c_str(), app);
|
||||
}
|
||||
}
|
||||
RemoveSupportingApp((*i).c_str(), app);
|
||||
}
|
||||
strandedTypes.clear();
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// DeleteSupportedTypes
|
||||
/*! \brief Clears the given application's supported types list and optionally
|
||||
removes the application from each of said types' supporting apps list.
|
||||
\param app The application whose supported types you are clearing
|
||||
\param fullSync See SupportingApps::SetSupportedTypes()
|
||||
*/
|
||||
status_t
|
||||
SupportingApps::DeleteSupportedTypes(const char *app, bool fullSync)
|
||||
{
|
||||
BMessage types;
|
||||
return SetSupportedTypes(app, &types, fullSync);
|
||||
}
|
||||
|
||||
// AddSupportingApp
|
||||
/*! \brief Adds the given application signature to the set of supporting
|
||||
apps for the given type.
|
||||
@ -210,6 +263,7 @@ SupportingApps::BuildSupportingAppsTable()
|
||||
{
|
||||
fSupportedTypes.clear();
|
||||
fSupportingApps.clear();
|
||||
fStrandedTypes.clear();
|
||||
|
||||
BDirectory dir;
|
||||
status_t err = dir.SetTo(kApplicationDatabaseDir.c_str());
|
||||
|
@ -307,6 +307,28 @@ get_preferred_app(const char *type, char *signature, app_verb verb = B_OPEN)
|
||||
return err >= 0 ? B_OK : err ;
|
||||
}
|
||||
|
||||
// get_sniffer_rule
|
||||
/*! \brief Fetches the sniffer rule for the given MIME type.
|
||||
\param type The MIME type of interest
|
||||
\param result Pointer to a pre-allocated BString into which the type's
|
||||
sniffer rule is copied.
|
||||
\return
|
||||
- \c B_OK: Success
|
||||
- \c B_ENTRY_NOT_FOUND: No such preferred application exists
|
||||
- "error code": Failure
|
||||
*/
|
||||
status_t
|
||||
get_sniffer_rule(const char *type, BString *result)
|
||||
{
|
||||
BNode node;
|
||||
status_t err = result ? B_OK : B_BAD_VALUE;
|
||||
if (!err)
|
||||
err = open_type(type, &node);
|
||||
if (!err)
|
||||
err = node.ReadAttrString(kSnifferRuleAttr, result);
|
||||
return err;
|
||||
}
|
||||
|
||||
// get_supported_types
|
||||
status_t
|
||||
get_supported_types(const char *type, BMessage *types)
|
||||
|
@ -1037,7 +1037,7 @@ Parser::Parse(const char *rule, Rule *result, BString *parseError) {
|
||||
if (parseError)
|
||||
parseError->SetTo(ErrorMessage(err, rule).c_str());
|
||||
delete err;
|
||||
return B_BAD_MIME_SNIFFER_RULE;
|
||||
return rule ? B_BAD_MIME_SNIFFER_RULE : B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,44 +89,39 @@ MIMEManager::MessageReceived(BMessage *message)
|
||||
|
||||
case B_REG_MIME_GET_INSTALLED_TYPES:
|
||||
{
|
||||
BMessage types;
|
||||
const char *supertype;
|
||||
err = message->FindString("supertype", &supertype);
|
||||
if (err == B_NAME_NOT_FOUND)
|
||||
err = fDatabase.GetInstalledTypes(&types);
|
||||
err = fDatabase.GetInstalledTypes(&reply);
|
||||
else if (!err)
|
||||
err = fDatabase.GetInstalledTypes(supertype, &types);
|
||||
err = fDatabase.GetInstalledTypes(supertype, &reply);
|
||||
|
||||
reply.what = B_REG_RESULT;
|
||||
reply.AddInt32("result", err);
|
||||
reply.AddMessage("types", &types);
|
||||
message->SendReply(&reply, this);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_REG_MIME_GET_INSTALLED_SUPERTYPES:
|
||||
{
|
||||
BMessage types;
|
||||
err = fDatabase.GetInstalledSupertypes(&types);
|
||||
err = fDatabase.GetInstalledSupertypes(&reply);
|
||||
|
||||
reply.what = B_REG_RESULT;
|
||||
reply.AddInt32("result", err);
|
||||
reply.AddMessage("types", &types);
|
||||
message->SendReply(&reply, this);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_REG_MIME_GET_SUPPORTING_APPS:
|
||||
{
|
||||
BMessage apps;
|
||||
BMessage reply;
|
||||
const char *type;
|
||||
err = message->FindString("type", &type);
|
||||
if (!err)
|
||||
err = fDatabase.GetSupportingApps(type, &apps);
|
||||
err = fDatabase.GetSupportingApps(type, &reply);
|
||||
|
||||
reply.what = B_REG_RESULT;
|
||||
reply.AddInt32("result", err);
|
||||
reply.AddMessage("signatures", &apps);
|
||||
message->SendReply(&reply, this);
|
||||
break;
|
||||
}
|
||||
@ -228,7 +223,16 @@ MIMEManager::HandleSetParam(BMessage *message)
|
||||
if (!err)
|
||||
err = fDatabase.SetPreferredApp(type, signature, (app_verb)verb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case B_REG_MIME_SNIFFER_RULE:
|
||||
{
|
||||
const char *rule;
|
||||
err = message->FindString("sniffer rule", &rule);
|
||||
if (!err)
|
||||
err = fDatabase.SetSnifferRule(type, rule);
|
||||
break;
|
||||
}
|
||||
|
||||
case B_REG_MIME_SUPPORTED_TYPES:
|
||||
{
|
||||
@ -324,8 +328,13 @@ MIMEManager::HandleDeleteParam(BMessage *message)
|
||||
break;
|
||||
|
||||
case B_REG_MIME_SUPPORTED_TYPES:
|
||||
err = fDatabase.DeleteSupportedTypes(type);
|
||||
break;
|
||||
{
|
||||
bool fullSync;
|
||||
err = message->FindBool("full sync", &fullSync);
|
||||
if (!err)
|
||||
err = fDatabase.DeleteSupportedTypes(type, fullSync);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
err = B_BAD_VALUE;
|
||||
|
@ -70,7 +70,9 @@ static const char *testApp2 = "/boot/beos/apps/CDPlayer";
|
||||
static const char *fakeTestApp = "/__this_isn't_likely_to_exist__";
|
||||
|
||||
// BMessage field names
|
||||
static const char *applicationsField = "applications";
|
||||
static const char *typeField = "type";
|
||||
static const char *typesField = "types";
|
||||
static const char *fileExtField = "extensions";
|
||||
static const char *attrInfoField_Name = "attr:name";
|
||||
static const char *attrInfoField_PublicName = "attr:public_name";
|
||||
@ -195,6 +197,10 @@ MimeTypeTest::Suite() {
|
||||
&MimeTypeTest::InstalledTypesTest) );
|
||||
suite->addTest( new TC("BMimeType::Preferred App Test",
|
||||
&MimeTypeTest::PreferredAppTest) );
|
||||
suite->addTest( new TC("BMimeType::Supporting Apps Test",
|
||||
&MimeTypeTest::SupportingAppsTest) );
|
||||
suite->addTest( new TC("BMimeType::Supported Types Test",
|
||||
&MimeTypeTest::SupportedTypesTest) );
|
||||
suite->addTest( new TC("BMimeType::Wildcard Apps Test",
|
||||
&MimeTypeTest::WildcardAppsTest) );
|
||||
|
||||
@ -215,10 +221,6 @@ MimeTypeTest::Suite() {
|
||||
&MimeTypeTest::SnifferRuleTest) );
|
||||
suite->addTest( new TC("BMimeType::Sniffing Test",
|
||||
&MimeTypeTest::SniffingTest) );
|
||||
|
||||
// In progress
|
||||
suite->addTest( new TC("BMimeType::Supporting Apps Test",
|
||||
&MimeTypeTest::SupportingAppsTest) );
|
||||
|
||||
|
||||
return suite;
|
||||
@ -2233,7 +2235,7 @@ MimeTypeTest::InstallDeleteTest() {
|
||||
CHK(type_exists(testType));
|
||||
CHK(mime.IsInstalled());
|
||||
#if !TEST_R5
|
||||
CHK(mime.Install() != B_OK); // We ought to return something standard and logical here
|
||||
CHK(mime.Install() != B_OK); // We ought to return something standard and logical here, as R5 is random
|
||||
#endif
|
||||
CHK(mime.Delete() == B_OK);
|
||||
CHK(!type_exists(testType));
|
||||
@ -2271,6 +2273,256 @@ void FillWithMimeTypes(ContainerAdapter &container, BMessage &typeMessage, const
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
types_fields_are_identical(const BMessage &msg1, const BMessage &msg2)
|
||||
{
|
||||
const char *str1;
|
||||
const char *str2;
|
||||
int i = 0;
|
||||
bool result = true;
|
||||
while (true) {
|
||||
status_t err1 = msg1.FindString(typesField, i, &str1);
|
||||
status_t err2 = msg2.FindString(typesField, i, &str2);
|
||||
if (err1 != err2) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
if (err1 != B_OK)
|
||||
break;
|
||||
result &= to_lower(str1) == to_lower(str2);
|
||||
i++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
is_supporting_app_for_all_types_in_message(const char *app, const BMessage &msg)
|
||||
{
|
||||
const char *str;
|
||||
bool result = true;
|
||||
for (int i = 0; msg.FindString(typesField, i, &str) == B_OK; i++) {
|
||||
BMimeType supportedType(str);
|
||||
BMessage appMsg;
|
||||
|
||||
// Get a list of supporting apps
|
||||
CHK(supportedType.InitCheck() == B_OK);
|
||||
CHK(supportedType.GetSupportingApps(&appMsg) == B_OK);
|
||||
// cout << "-----------------------------------------------------------" << endl;
|
||||
// cout << str << endl;
|
||||
// cout << "-----------------------------------------------------------" << endl;
|
||||
// appMsg.PrintToStream();
|
||||
|
||||
// Look for our supporting app
|
||||
int32 directlySupportingAppsCount;
|
||||
CHK(appMsg.FindInt32("be:sub", &directlySupportingAppsCount) == B_OK);
|
||||
bool foundType = false;
|
||||
const char *supportingApp;
|
||||
for (int j = 0;
|
||||
j < directlySupportingAppsCount
|
||||
&& appMsg.FindString(applicationsField, &supportingApp) == B_OK;
|
||||
j++)
|
||||
{
|
||||
foundType |= to_lower(app) == to_lower(supportingApp);
|
||||
}
|
||||
result &= foundType;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
MimeTypeTest::SupportedTypesTest() {
|
||||
#if TEST_R5
|
||||
Outputf("(no tests actually performed for R5 version)\n");
|
||||
#else
|
||||
// Create some messages to sling around
|
||||
const int32 WHAT = 0;
|
||||
BMessage msg1a(WHAT), msg1b(WHAT), msg2(WHAT), msg3(WHAT), msgEmpty(WHAT);
|
||||
|
||||
CHK(msg3.AddString(typesField, testType1) == B_OK);
|
||||
CHK(msg3.AddString(typesField, testType2) == B_OK);
|
||||
CHK(msg3.AddString(typesField, testType3) == B_OK);
|
||||
|
||||
CHK(msg2.AddString(typesField, testType2) == B_OK);
|
||||
CHK(msg2.AddString(typesField, testType3) == B_OK);
|
||||
|
||||
CHK(msg1a.AddString(typesField, testType5) == B_OK);
|
||||
|
||||
CHK(msg1b.AddString(typesField, testType2) == B_OK);
|
||||
|
||||
CHK(msg1a == msg1a);
|
||||
CHK(msg1b == msg1b);
|
||||
CHK(msg2 == msg2);
|
||||
CHK(msg3 == msg3);
|
||||
CHK(msg1a != msg2);
|
||||
CHK(msg1a != msg3);
|
||||
CHK(msg1a != msgEmpty);
|
||||
|
||||
// Uninitialized
|
||||
NextSubTest();
|
||||
{
|
||||
BMimeType mime;
|
||||
BMessage msg;
|
||||
|
||||
CHK(mime.InitCheck() == B_NO_INIT);
|
||||
CHK(mime.SetSupportedTypes(&msg, true) != B_OK);
|
||||
CHK(mime.SetSupportedTypes(&msg, false) != B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) != B_OK);
|
||||
CHK(mime.DeleteSupportedTypes() != B_OK);
|
||||
}
|
||||
|
||||
// Test that deleting a type from the database also removes
|
||||
// the app as a supporting app for all types it previously
|
||||
// supported
|
||||
NextSubTest();
|
||||
{
|
||||
BMessage msg;
|
||||
BMimeType mime(testType);
|
||||
CHK(mime.InitCheck() == B_OK);
|
||||
if (!mime.IsInstalled())
|
||||
CHK(mime.Install() == B_OK);
|
||||
|
||||
// Set a list of supported types
|
||||
CHK(mime.SetSupportedTypes(&msg3, true) == B_OK);
|
||||
|
||||
// Verify that each of those types now lists the
|
||||
// type as a directly supporting app
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == true);
|
||||
|
||||
// Delete the type
|
||||
CHK(mime.Delete() == B_OK);
|
||||
|
||||
// Verify that each of those types no longer lists the
|
||||
// type as a directly supporting app
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == false);
|
||||
}
|
||||
|
||||
// Test that SetSupportedTypes(..., false) does not remove the app as a supporting
|
||||
// app for newly unsupported types, while SetSupportedTypes(..., true) does. Also
|
||||
// test that supported types stranded by multiple sequential calls to
|
||||
// SetSupportedTypes(..., false) are properly updated so as to no longer list the
|
||||
// app as a supporting app once SetSupportedTypes(..., true) is finally called.
|
||||
NextSubTest();
|
||||
{
|
||||
BMessage msg;
|
||||
BMimeType mime(testType);
|
||||
CHK(mime.InitCheck() == B_OK);
|
||||
|
||||
// Uninstall then reinstall to clear attributes, etc
|
||||
if (mime.IsInstalled())
|
||||
CHK(mime.Delete() == B_OK);
|
||||
if (!mime.IsInstalled())
|
||||
CHK(mime.Install() == B_OK);
|
||||
CHK(mime.IsInstalled());
|
||||
|
||||
// Set a list of supported types
|
||||
CHK(mime.SetSupportedTypes(&msg3, true) == B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_OK);
|
||||
CHK(types_fields_are_identical(msg3, msg) == true);
|
||||
CHK(types_fields_are_identical(msg2, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1a, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1b, msg) == false);
|
||||
CHK(types_fields_are_identical(msgEmpty, msg) == false);
|
||||
|
||||
// Verify that each of those types now lists the
|
||||
// type as a directly supporting app
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == true);
|
||||
|
||||
// Set (no sync) to a new list of supported types containing one
|
||||
// fewer type than the original list
|
||||
CHK(mime.SetSupportedTypes(&msg2, false) == B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_OK);
|
||||
CHK(types_fields_are_identical(msg3, msg) == false);
|
||||
CHK(types_fields_are_identical(msg2, msg) == true);
|
||||
CHK(types_fields_are_identical(msg1a, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1b, msg) == false);
|
||||
CHK(types_fields_are_identical(msgEmpty, msg) == false);
|
||||
|
||||
// Verify that the app is still listed as a supporting app for
|
||||
// *all* of the originally supported types (even the one no longer
|
||||
// listed as being supported)
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == true);
|
||||
|
||||
// Set (no sync) to a new list of supported types containing an
|
||||
// entirely new, never supported type
|
||||
CHK(mime.SetSupportedTypes(&msg1a, false) == B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_OK);
|
||||
CHK(types_fields_are_identical(msg3, msg) == false);
|
||||
CHK(types_fields_are_identical(msg2, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1a, msg) == true);
|
||||
CHK(types_fields_are_identical(msg1b, msg) == false);
|
||||
CHK(types_fields_are_identical(msgEmpty, msg) == false);
|
||||
|
||||
// Verify that the app is still listed as a supporting app for
|
||||
// *all* of the originally supported types (none of which are
|
||||
// supported any longer) as well as the newly supported type.
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == true);
|
||||
|
||||
// Set (no sync) to a new list of supported types containing only
|
||||
// one of the originally supported types that had been previously
|
||||
// removed.
|
||||
CHK(mime.SetSupportedTypes(&msg1b, false) == B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_OK);
|
||||
CHK(types_fields_are_identical(msg3, msg) == false);
|
||||
CHK(types_fields_are_identical(msg2, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1a, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1b, msg) == true);
|
||||
CHK(types_fields_are_identical(msgEmpty, msg) == false);
|
||||
|
||||
// Verify that the app is still listed as a supporting app for
|
||||
// *all* of the originally supported types (only one of which is
|
||||
// supported any longer) as well as the previous supported type.
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == true);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == true);
|
||||
|
||||
// Set (with sync) to the same list as last time (containing the
|
||||
// one type from the original list of supported types)
|
||||
CHK(mime.SetSupportedTypes(&msg1b, true) == B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_OK);
|
||||
CHK(types_fields_are_identical(msg3, msg) == false);
|
||||
CHK(types_fields_are_identical(msg2, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1a, msg) == false);
|
||||
CHK(types_fields_are_identical(msg1b, msg) == true);
|
||||
CHK(types_fields_are_identical(msgEmpty, msg) == false);
|
||||
|
||||
// Verify that the app is now only listed as a supporting app for the
|
||||
// most recently supported type.
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == true);
|
||||
|
||||
// Test SetSupportedTypes(NULL, false) for shits and giggles
|
||||
CHK(mime.SetSupportedTypes(NULL, false) == B_OK);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_ENTRY_NOT_FOUND);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == true);
|
||||
|
||||
// Now test that SetSupportedTypes(NULL, true) updates the supporting
|
||||
// apps mappings, even if the supported types attribute has already
|
||||
// been removed.
|
||||
CHK(mime.SetSupportedTypes(NULL, true) == B_ENTRY_NOT_FOUND);
|
||||
CHK(mime.GetSupportedTypes(&msg) == B_ENTRY_NOT_FOUND);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg3) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg2) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1a) == false);
|
||||
CHK(is_supporting_app_for_all_types_in_message(testType, msg1b) == false);
|
||||
}
|
||||
#endif // #if TEST_R5 else
|
||||
}
|
||||
|
||||
void
|
||||
MimeTypeTest::SupportingAppsTest() {
|
||||
/* {
|
||||
@ -2305,6 +2557,7 @@ MimeTypeTest::SupportingAppsTest() {
|
||||
std::set<std::string> typeList; // Stores all installed MIME types
|
||||
std::set<std::string> appList; // Stores all installed application subtypes
|
||||
std::map< std::string, std::set<std::string> > typeAppMap; // Stores mapping of types to apps that support them
|
||||
std::map< std::string, std::set<std::string> > fakeTypeAppMap; // Used to keep timing info for R5 and OBOS tests orthogonal
|
||||
|
||||
// Get a list of all the types in the database
|
||||
{
|
||||
@ -2362,7 +2615,8 @@ MimeTypeTest::SupportingAppsTest() {
|
||||
type++)
|
||||
{
|
||||
NextSubTest();
|
||||
typeAppMap[*type].insert(app);
|
||||
typeAppMap[*type].insert(app);
|
||||
fakeTypeAppMap[*type].insert(app);
|
||||
}
|
||||
} else {
|
||||
// Just in case some bozo writes something other than a flattened
|
||||
@ -2378,7 +2632,7 @@ MimeTypeTest::SupportingAppsTest() {
|
||||
}
|
||||
}
|
||||
|
||||
#if !TEST_R5
|
||||
//#if !TEST_R5
|
||||
// Now, add in all the types listed in MIME_DB_DIR/__mime_table
|
||||
{
|
||||
BEntry entry((std::string(mimeDatabaseDir) + "/__mime_table").c_str());
|
||||
@ -2402,12 +2656,16 @@ MimeTypeTest::SupportingAppsTest() {
|
||||
const char *app;
|
||||
for (int j = 0; j < count; j++) {
|
||||
CHK(msg.FindString(type, j, &app) == B_OK);
|
||||
#if TEST_R5
|
||||
typeAppMap[type].insert(to_lower(app));
|
||||
#else
|
||||
fakeTypeAppMap[type].insert(to_lower(app));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
// For each installed type, get a list of the supported apps, and
|
||||
// verify that the list matches the list we generated. Also check
|
||||
@ -3147,13 +3405,13 @@ MimeTypeTest::MonitoringTest()
|
||||
CHK(target3.IsValid() == false);
|
||||
// R5: An invalid messenger is fine for any reason?!
|
||||
#if !TEST_R5
|
||||
CHK(RES(BMimeType::StartWatching(target3)) == B_BAD_VALUE);
|
||||
CHK(BMimeType::StartWatching(target3) == B_BAD_VALUE);
|
||||
#endif
|
||||
CHK(BMimeType::StartWatching(target) == B_OK);
|
||||
#if !TEST_R5
|
||||
CHK(BMimeType::StopWatching(target3) == B_BAD_VALUE);
|
||||
#endif
|
||||
CHK(BMimeType::StopWatching(target2) == B_BAD_VALUE);
|
||||
CHK(BMimeType::StopWatching(target2) != B_OK); // R5 == B_BAD_VALUE, OBOS == B_ENTRY_NOT_FOUND
|
||||
CHK(BMimeType::StopWatching(target) == B_OK);
|
||||
// delete
|
||||
CHK(type.Delete() == B_OK);
|
||||
@ -3814,8 +4072,15 @@ MimeTypeTest::SnifferRuleTest()
|
||||
{ "0.5 \n [0:3] \t ('ABCD' \n | 'abcd' | 'EFGH')", NULL },
|
||||
{ "0.8 [ 0 : 3 ] ('ABCDEFG' | 'abcdefghij')", NULL },
|
||||
{ "0.8 [0:3] ('ABCDEFG' & 'abcdefg')", NULL },
|
||||
// These two rules are accepted by the R5 sniffer checker, but not
|
||||
// by the parser. Thus, we're not accepting them with either.
|
||||
#if TEST_R5
|
||||
{ "1.0 ('ABCD') | ('EFGH')", NULL },
|
||||
{ "1.0 [0:3] ('ABCD') | [2:4] ('EFGH')", NULL },
|
||||
#else
|
||||
{ "1.0 ('ABCD') | ('EFGH')", "Sniffer pattern error: missing pattern" },
|
||||
{ "1.0 [0:3] ('ABCD') | [2:4] ('EFGH')", "Sniffer pattern error: missing pattern" },
|
||||
#endif
|
||||
{ "0.8 [0:3] (\\077Mkl0x34 & 'abcdefgh')", NULL },
|
||||
{ "0.8 [0:3] (\\077034 & 'abcd')", NULL },
|
||||
{ "0.8 [0:3] (\\077\\034 & 'ab')", NULL },
|
||||
@ -3834,55 +4099,229 @@ MimeTypeTest::SnifferRuleTest()
|
||||
{ "0.8 [0:3] (\"ab'\" & 'abc')", NULL },
|
||||
{ "0.8 [0:3] (\"ab\\\\\" & 'abc')", NULL },
|
||||
{ "0.8 [-5:-3] (\"abc\" & 'abc')", NULL },
|
||||
// Also accepted by the R5 sniffer but not the R5 parser. We reject.
|
||||
#if TEST_R5
|
||||
{ "0.8 [5:3] (\"abc\" & 'abc')", NULL },
|
||||
{ "1.2 ('ABCD')", NULL },
|
||||
#else
|
||||
{ "0.8 [5:3] (\"abc\" & 'abc')", "Sniffer Parser Error -- Invalid range: [5:3]" },
|
||||
#endif
|
||||
{ "1.0 ('ABCD')", NULL },
|
||||
{ ".2 ('ABCD')", NULL },
|
||||
{ "0. ('ABCD')", NULL },
|
||||
{ "-1 ('ABCD')", NULL },
|
||||
{ "1 ('ABCD')", NULL },
|
||||
{ "+1 ('ABCD')", NULL },
|
||||
{ "1E25 ('ABCD')", NULL },
|
||||
// We accept extended notation floating point numbers now, but
|
||||
// not invalid priorities. Thus our checker chokes on these rules,
|
||||
// whilest R5's does not
|
||||
#if TEST_R5
|
||||
{ "1E25 ('ABCD')", NULL },
|
||||
{ "1e25 ('ABCD')", NULL },
|
||||
#else
|
||||
{ "1E25 ('ABCD')", "Sniffer pattern error: invalid priority" },
|
||||
{ "1e25 ('ABCD')", "Sniffer pattern error: invalid priority" },
|
||||
#endif
|
||||
|
||||
// R5 chokes on this rule :-( Why? I don't know. :-)
|
||||
#if TEST_R5
|
||||
{ "1e-3 ('ABCD')", "Sniffer pattern error: missing pattern" },
|
||||
#else
|
||||
{ "1e-3 ('ABCD')", NULL },
|
||||
#endif
|
||||
{ "+.003e2 ('ABCD')", NULL },
|
||||
// R5 chokes on this one too. See how much better our checker/parser is? ;-)
|
||||
#if TEST_R5
|
||||
{ "-123e-9999999999 ('ABCD')", "Sniffer pattern error: bad token" }, // Hooray for the stunning accuracy of floating point :-)
|
||||
#else
|
||||
{ "-123e-9999999999 ('ABCD')", NULL }, // Hooray for the stunning accuracy of floating point :-)
|
||||
#endif
|
||||
// invalid rules
|
||||
{ "0.0 ('')", "Sniffer pattern error: illegal empty pattern" },
|
||||
{ "('ABCD')", "Sniffer pattern error: match level expected" },
|
||||
{ "[0:3] ('ABCD')", "Sniffer pattern error: match level expected" },
|
||||
{ "0.0 ('')",
|
||||
"Sniffer pattern error: illegal empty pattern" },
|
||||
{ "('ABCD')",
|
||||
"Sniffer pattern error: match level expected" },
|
||||
{ "[0:3] ('ABCD')",
|
||||
"Sniffer pattern error: match level expected" },
|
||||
{ "0.8 [0:3] ( | 'abcdefghij')",
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
{ "0.8 [0:3] ('ABCDEFG' | )",
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
{ "[0:3] ('ABCD')", "Sniffer pattern error: match level expected" },
|
||||
{ "1.0 (ABCD')", "Sniffer pattern error: misplaced single quote" },
|
||||
{ "1.0 ('ABCD)", "Sniffer pattern error: unterminated rule" },
|
||||
{ "1.0 (ABCD)", "Sniffer pattern error: missing pattern" },
|
||||
{ "1.0 (ABCD 'ABCD')", "Sniffer pattern error: missing pattern" },
|
||||
{ "1.0 'ABCD')", "Sniffer pattern error: missing pattern" },
|
||||
{ "1.0 ('ABCD'", "Sniffer pattern error: unterminated rule" },
|
||||
{ "1.0 'ABCD'", "Sniffer pattern error: missing sniff pattern" },
|
||||
{ "[0:3] ('ABCD')",
|
||||
"Sniffer pattern error: match level expected" },
|
||||
{ "1.0 (ABCD')",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: misplaced single quote"
|
||||
#else
|
||||
"Sniffer pattern error: invalid character 'A'"
|
||||
#endif
|
||||
},
|
||||
{ "1.0 ('ABCD)",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: unterminated rule"
|
||||
#else
|
||||
"Sniffer pattern error: unterminated single-quoted string"
|
||||
#endif
|
||||
},
|
||||
{ "1.0 (ABCD)",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: missing pattern"
|
||||
#else
|
||||
"Sniffer pattern error: invalid character 'A'"
|
||||
#endif
|
||||
},
|
||||
{ "1.0 (ABCD 'ABCD')",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: missing pattern"
|
||||
#else
|
||||
"Sniffer pattern error: invalid character 'A'"
|
||||
#endif
|
||||
},
|
||||
{ "1.0 'ABCD')",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: missing pattern"
|
||||
#else
|
||||
"Sniffer pattern error: missing pattern"
|
||||
#endif
|
||||
},
|
||||
{ "1.0 ('ABCD'",
|
||||
"Sniffer pattern error: unterminated rule" },
|
||||
{ "1.0 'ABCD'",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: missing sniff pattern"
|
||||
#else
|
||||
"Sniffer pattern error: missing pattern"
|
||||
#endif
|
||||
},
|
||||
{ "0.5 [0:3] ('ABCD' | 'abcd' | [13] 'EFGH')",
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
{ "0.5('ABCD'|'abcd'|[13]'EFGH')",
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
{ "0.5[0:3]([10]'ABCD'|[17]'abcd'|[13]'EFGH')",
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
"Sniffer pattern error: missing pattern" },
|
||||
{ "0.8 [0x10:3] ('ABCDEFG' | 'abcdefghij')",
|
||||
"Sniffer pattern error: pattern offset expected" },
|
||||
"Sniffer pattern error: pattern offset expected" },
|
||||
{ "0.8 [0:A] ('ABCDEFG' | 'abcdefghij')",
|
||||
"Sniffer pattern error: pattern range end expected" },
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: pattern range end expected"
|
||||
#else
|
||||
"Sniffer pattern error: invalid character 'A'"
|
||||
#endif
|
||||
},
|
||||
{ "0.8 [0:3] ('ABCDEFG' & 'abcdefghij')",
|
||||
"Sniffer pattern error: pattern and mask lengths do not match" },
|
||||
"Sniffer pattern error: pattern and mask lengths do not match" },
|
||||
{ "0.8 [0:3] ('ABCDEFG' & 'abcdefg' & 'xyzwmno')",
|
||||
"Sniffer pattern error: unterminated rule" },
|
||||
{ "0.8 [0:3] (\\g&b & 'a')", "Sniffer pattern error: missing mask" },
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: unterminated rule"
|
||||
#else
|
||||
"Sniffer pattern error: expecting '|', ')', or possibly '&'"
|
||||
#endif
|
||||
},
|
||||
{ "0.8 [0:3] (\\g&b & 'a')",
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: missing mask"
|
||||
#else
|
||||
"Sniffer pattern error: invalid character 'b'"
|
||||
#endif
|
||||
},
|
||||
{ "0.8 [0:3] (\\19 & 'a')",
|
||||
"Sniffer pattern error: pattern and mask lengths do not match" },
|
||||
"Sniffer pattern error: pattern and mask lengths do not match" },
|
||||
{ "0.8 [0:3] (0x345 & 'ab')",
|
||||
"Sniffer pattern error: bad hex literal" },
|
||||
"Sniffer pattern error: bad hex literal" },
|
||||
{ "0.8 [0:3] (0x3457M & 'abc')",
|
||||
"Sniffer pattern error: expecting '|' or '&'" },
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: expecting '|' or '&'"
|
||||
#else
|
||||
"Sniffer pattern error: invalid character 'M'"
|
||||
#endif
|
||||
},
|
||||
{ "0.8 [0:3] (0x3457\\7 & 'abc')",
|
||||
"Sniffer pattern error: expecting '|' or '&'" },
|
||||
#if TEST_R5
|
||||
"Sniffer pattern error: expecting '|' or '&'"
|
||||
#else
|
||||
"Sniffer pattern error: expecting '|', ')', or possibly '&'"
|
||||
#endif
|
||||
},
|
||||
|
||||
// Miscellaneous tests designed to hit every remaining
|
||||
// relevant "throw new Err()" statement in our scanner.
|
||||
// R5 versions may come later, but I don't really see any
|
||||
// good reason why at this point...
|
||||
#if !TEST_R5
|
||||
{ "\x03 ", "Sniffer pattern error: invalid character '\x03'" },
|
||||
{ "\"blah", "Sniffer pattern error: unterminated double-quoted string" },
|
||||
{ "0xThisIsNotAHexCode", "Sniffer pattern error: incomplete hex code" },
|
||||
{ "0xAndNeitherIsThis:-)", "Sniffer pattern error: bad hex literal" },
|
||||
{ ".NotAFloat", "Sniffer pattern error: incomplete floating point number" },
|
||||
{ "-NotANumber", "Sniffer pattern error: incomplete signed number" },
|
||||
{ "+NotANumber", "Sniffer pattern error: incomplete signed number" },
|
||||
|
||||
{ "0.0e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "1.0e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ ".0e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "0e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "1e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1.e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1.e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1.0e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1.0e", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
|
||||
{ "0.0e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "1.0e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ ".0e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "0e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "1e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1.e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1.e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1.0e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1.0e-", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
|
||||
{ "0.0e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "1.0e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ ".0e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "0e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "1e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1.e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1.e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "-1.0e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
{ "+1.0e+", "Sniffer pattern error: incomplete extended-notation floating point number" },
|
||||
|
||||
{ "\\11\\", "Sniffer pattern error: incomplete escape sequence" },
|
||||
{ "\"Escape!! \\", "Sniffer pattern error: incomplete escape sequence" },
|
||||
{ "'Escape!! \\", "Sniffer pattern error: incomplete escape sequence" },
|
||||
|
||||
{ "\\x", "Sniffer pattern error: incomplete escaped hex code" },
|
||||
{ "\\xNotAHexCode", "Sniffer pattern error: incomplete escaped hex code" },
|
||||
{ "\\xAlsoNotAHexCode", "Sniffer pattern error: incomplete escaped hex code" },
|
||||
{ "\\x0", "Sniffer pattern error: incomplete escaped hex code" },
|
||||
|
||||
{ "1.0 (\\377)", NULL },
|
||||
{ "\\400", "Sniffer pattern error: invalid octal literal (octals must be between octal 0 and octal 377 inclusive)" },
|
||||
{ "\\777", "Sniffer pattern error: invalid octal literal (octals must be between octal 0 and octal 377 inclusive)" },
|
||||
{ "1.0 (\\800)", NULL },
|
||||
|
||||
{ NULL, "Sniffer pattern error: NULL pattern" },
|
||||
|
||||
{ "-2", "Sniffer pattern error: invalid priority" },
|
||||
{ "+2", "Sniffer pattern error: invalid priority" },
|
||||
|
||||
{ "1.0", "Sniffer pattern error: missing expression" },
|
||||
#endif // !TEST_R5
|
||||
|
||||
//! \todo Our parser chokes on this rule and I have no idea why
|
||||
// I don't currently understand what's wrong with the following rule...
|
||||
// R5 rejects it though, for whatever reason.
|
||||
#if TEST_R5
|
||||
{ "1E-25 ('ABCD')", "Sniffer pattern error: missing pattern" },
|
||||
#else
|
||||
// { "1E-25 ('ABCD')", NULL },
|
||||
#endif
|
||||
};
|
||||
|
||||
const int testCaseCount = sizeof(testCases) / sizeof(test_case);
|
||||
BMimeType type;
|
||||
CHK(type.SetTo(testType) == B_OK);
|
||||
@ -3893,18 +4332,37 @@ MimeTypeTest::SnifferRuleTest()
|
||||
BString parseError;
|
||||
status_t error = BMimeType::CheckSnifferRule(testCase.rule,
|
||||
&parseError);
|
||||
// printf("\n---------------------\n");
|
||||
// printf("rule == '%s', %s\n", testCase.rule, (testCase.error ? "should not pass" : "should pass"));
|
||||
if (testCase.error == NULL) {
|
||||
if (error != B_OK)
|
||||
printf("error: %s\n", parseError.String());
|
||||
printf("\nerror:\n%s\n", parseError.String());
|
||||
CHK(error == B_OK);
|
||||
CHK(type.SetSnifferRule(testCase.rule) == B_OK);
|
||||
BString rule;
|
||||
CHK(type.GetSnifferRule(&rule) == B_OK);
|
||||
CHK(rule == testCase.rule);
|
||||
} else {
|
||||
CHK(error == B_BAD_MIME_SNIFFER_RULE);
|
||||
// printf("error == 0x%lx\n", error);
|
||||
// if (parseError.FindLast(testCase.error) < 0) {
|
||||
// printf("\nexpected:\n%s\n", testCase.error);
|
||||
// printf("\nfound:\n%s\n", parseError.String());
|
||||
// }
|
||||
CHK(error == (testCase.rule ? B_BAD_MIME_SNIFFER_RULE : B_BAD_VALUE));
|
||||
CHK(parseError.FindLast(testCase.error) >= 0);
|
||||
|
||||
// R5 treats a NULL rule string as an error, and thus R5::SetSnifferRule(NULL) fails.
|
||||
// We also treat a NULL rule string as an error, but OBOS::SetSnifferRule(NULL) does
|
||||
// not fail, as all OBOS::BMimeType::Set*(NULL) calls are equivalent to the
|
||||
// corresponding OBOS::BMimeType::Delete*() calls.
|
||||
#if TEST_R5
|
||||
CHK(type.SetSnifferRule(testCase.rule) == B_BAD_MIME_SNIFFER_RULE);
|
||||
#else
|
||||
if (testCase.rule)
|
||||
CHK(type.SetSnifferRule(testCase.rule) == B_BAD_MIME_SNIFFER_RULE);
|
||||
else
|
||||
CHK(type.SetSnifferRule(testCase.rule) == B_OK);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -3920,23 +4378,38 @@ printf("error: %s\n", parseError.String());
|
||||
CHK(type.GetSnifferRule(NULL) == B_BAD_VALUE);
|
||||
#endif
|
||||
|
||||
BString rule;
|
||||
|
||||
// NULL rule to SetSnifferRule unsets the attribute
|
||||
NextSubTest();
|
||||
#if TEST_R5
|
||||
CHK(type.IsInstalled() == true);
|
||||
CHK(type.SetSnifferRule(NULL) == B_OK);
|
||||
BString rule;
|
||||
CHK(type.GetSnifferRule(&rule) == B_ENTRY_NOT_FOUND);
|
||||
#else
|
||||
CHK(type.IsInstalled() == true);
|
||||
if (type.GetSnifferRule(&rule) == B_ENTRY_NOT_FOUND)
|
||||
CHK(type.SetSnifferRule("0.0 ('abc')") == B_OK);
|
||||
CHK(type.GetSnifferRule(&rule) == B_OK);
|
||||
CHK(type.SetSnifferRule(NULL) == B_OK);
|
||||
CHK(type.GetSnifferRule(&rule) == B_ENTRY_NOT_FOUND);
|
||||
CHK(type.SetSnifferRule(NULL) == B_ENTRY_NOT_FOUND);
|
||||
#endif
|
||||
|
||||
// bad args: uninstalled type
|
||||
CHK(type.Delete() == B_OK);
|
||||
CHK(type.GetSnifferRule(&rule) == B_ENTRY_NOT_FOUND);
|
||||
CHK(type.SetSnifferRule("0.0 ('ABC')") == B_OK);
|
||||
#if TEST_R5
|
||||
CHK(type.GetSnifferRule(&rule) == B_ENTRY_NOT_FOUND);
|
||||
#else
|
||||
CHK(type.GetSnifferRule(&rule) == B_OK);
|
||||
#endif
|
||||
|
||||
// bad args: uninitialized BMimeType
|
||||
type.Unset();
|
||||
CHK(type.GetSnifferRule(&rule) == B_BAD_VALUE);
|
||||
CHK(type.SetSnifferRule("0.0 ('ABC')") == B_BAD_VALUE);
|
||||
CHK(type.GetSnifferRule(&rule) != B_OK);
|
||||
CHK(type.SetSnifferRule("0.0 ('ABC')") != B_OK);
|
||||
}
|
||||
|
||||
// helper class for GuessMimeType() tests
|
||||
@ -4016,8 +4489,12 @@ MimeTypeTest::SniffingTest()
|
||||
CHK(type.SetSnifferRule("0.4 ('ABCD')") == B_OK);
|
||||
CHK(type.SetTo(testType2) == B_OK);
|
||||
CHK(type.Install() == B_OK);
|
||||
// This rule is invalid!
|
||||
#if TEST_R5
|
||||
// This rule is invalid!
|
||||
CHK(type.SetSnifferRule("0.4 [0] ('XYZ') | [0:5] ('CD E')") == B_OK);
|
||||
#else
|
||||
CHK(type.SetSnifferRule("0.4 ([0] 'XYZ' | [0:5] 'CD E')") == B_OK);
|
||||
#endif
|
||||
CHK(type.SetTo(testType3) == B_OK);
|
||||
CHK(type.Install() == B_OK);
|
||||
CHK(type.SetSnifferRule("0.3 [0:8] ('ABCD' | 'EFGH')") == B_OK);
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
void ShortDescriptionTest();
|
||||
void PreferredAppTest();
|
||||
void SupportingAppsTest();
|
||||
void SupportedTypesTest();
|
||||
void WildcardAppsTest();
|
||||
|
||||
void InitTest();
|
||||
|
Loading…
Reference in New Issue
Block a user