+ 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
This commit is contained in:
Tyler Dauwalder
2002-08-21 10:55:20 +00:00
parent 7385178729
commit 3155eae222
6 changed files with 616 additions and 170 deletions
+8
View File
@@ -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.
+71 -38
View File
@@ -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()
+325 -24
View File
@@ -2,6 +2,7 @@
#include <Application.h>
#include <Bitmap.h>
#include <DataIO.h>
#include <Directory.h>
#include <Entry.h>
#include <Message.h>
@@ -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:
+51 -5
View File
@@ -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
+56 -70
View File
@@ -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;
+105 -33
View File
@@ -19,7 +19,9 @@
#include <Drivers.h> // B_GET_ICON, device_icon
#include <Message.h>
#include <Mime.h>
#include <MimeDatabase.h>
#if !TEST_R5
#include <MimeDatabase.h>
#endif
#include <MimeTypeTest.h>
#include <Path.h> // Only needed for entry_ref dumps
#include <StorageKit.h>
@@ -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,