* Construct the MIME data base directories lazily.

* Automatic whitespace cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34399 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-12-01 08:52:13 +00:00
parent 6bb7a8908c
commit bc0693b219
8 changed files with 241 additions and 230 deletions

View File

@ -20,14 +20,14 @@ namespace Storage {
namespace Mime {
// Database directory
extern const std::string kDatabaseDir;
extern const std::string kApplicationDatabaseDir;
const std::string get_database_directory();
const std::string get_application_database_directory();
// Attribute Prefixes
extern const char *kMiniIconAttrPrefix;
extern const char *kLargeIconAttrPrefix;
extern const char *kIconAttrPrefix;
extern const char *kLargeIconAttrPrefix;
extern const char *kIconAttrPrefix;
// Attribute names
extern const char *kFileTypeAttr;
extern const char *kTypeAttr;
@ -43,7 +43,7 @@ extern const char *kPreferredAppAttr;
extern const char *kSnifferRuleAttr;
extern const char *kSupportedTypesAttr;
// Attribute Datatypes
// Attribute Datatypes
extern const int32 kFileTypeType;
extern const int32 kTypeType;
extern const int32 kAppHintType;
@ -85,9 +85,9 @@ ssize_t read_mime_attr(const char *type, const char *attr, void *data,
status_t read_mime_attr_message(const char *type, const char *attr, BMessage *msg);
status_t read_mime_attr_string(const char *type, const char *attr, BString *str);
status_t write_mime_attr(const char *type, const char *attr, const void *data,
size_t len, type_code datatype, bool *didCreate);
size_t len, type_code datatype, bool *didCreate);
status_t write_mime_attr_message(const char *type, const char *attr,
const BMessage *msg, bool *didCreate);
const BMessage *msg, bool *didCreate);
status_t delete_attribute(const char *type, const char *attr);

View File

@ -38,15 +38,6 @@ namespace BPrivate {
namespace Storage {
namespace Mime {
static const char *get_user_settings_dir(BPath &path);
static BPath sSettingsDirPath;
static const std::string sSettingsDir = get_user_settings_dir(sSettingsDirPath);
static const char *sHaikuDBDirName = "beos_mime";
// when running natively under Haiku
const std::string kDatabaseDir = sSettingsDir + "/" + sHaikuDBDirName;
const std::string kApplicationDatabaseDir = kDatabaseDir + "/application";
#define ATTR_PREFIX "META:"
#define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:"
@ -103,27 +94,47 @@ const char *kMetaMimeType = "application/x-vnd.Be-meta-mime";
// Error codes
const status_t kMimeGuessFailureError = B_ERRORS_END+1;
// get_settings_dir
/*! \brief Sets the supplied BPath to the user settings directory and returns
it as C string.
\param path BPath to be set to the user settings path.
\return the user settings path as C string (\code path.Path() \endcode).
*/
static
const char*
get_user_settings_dir(BPath &path)
static pthread_once_t sDatabaseDirectoryInitOnce = PTHREAD_ONCE_INIT;
static std::string sDatabaseDirectory;
static std::string sApplicationDatabaseDirectory;
static void
init_database_directories()
{
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
path.SetTo("/boot/home/config/settings");
return path.Path();
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK)
sDatabaseDirectory = path.Path();
else
sDatabaseDirectory = "/boot/home/config/settings";
sDatabaseDirectory += "/beos_mime";
sApplicationDatabaseDirectory = sDatabaseDirectory + "/application";
}
const std::string
get_database_directory()
{
pthread_once(&sDatabaseDirectoryInitOnce, &init_database_directories);
return sDatabaseDirectory;
}
const std::string
get_application_database_directory()
{
pthread_once(&sDatabaseDirectoryInitOnce, &init_database_directories);
return sApplicationDatabaseDirectory;
}
// type_to_filename
//! Converts the given MIME type to an absolute path in the MIME database.
std::string
type_to_filename(const char *type)
{
return kDatabaseDir + "/" + BPrivate::Storage::to_lower(type);
return get_database_directory() + "/" + BPrivate::Storage::to_lower(type);
}
// open_type
@ -183,7 +194,7 @@ open_or_create_type(const char *type, BNode *result, bool *didCreate)
uint32 pos = typeLower.find_first_of('/');
if (pos == std::string::npos) {
// Supertype == directory
BDirectory parent(kDatabaseDir.c_str());
BDirectory parent(get_database_directory().c_str());
err = parent.InitCheck();
if (!err)
err = parent.CreateDirectory(typeLower.c_str(), NULL);
@ -191,7 +202,7 @@ open_or_create_type(const char *type, BNode *result, bool *didCreate)
// Non-supertype == file
std::string super(typeLower, 0, pos);
std::string sub(typeLower, pos+1);
BDirectory parent((kDatabaseDir + "/" + super).c_str());
BDirectory parent((get_database_directory() + "/" + super).c_str());
err = parent.InitCheck();
if (!err)
err = parent.CreateFile(sub.c_str(), NULL);

View File

@ -1,5 +1,5 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
/*!
@ -51,29 +51,29 @@ AssociatedTypes::~AssociatedTypes()
// GetAssociatedTypes
/*! \brief Returns a list of mime types associated with the given file
extension in the pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetAssociatedTypes() for more information.
*/
status_t
status_t
AssociatedTypes::GetAssociatedTypes(const char *extension, BMessage *types)
{
status_t err = extension && types ? B_OK : B_BAD_VALUE;
std::string extStr;
// See if we need to do our initial build still
if (!err && !fHaveDoneFullBuild) {
err = BuildAssociatedTypesTable();
}
// Format the extension
// Format the extension
if (!err) {
extStr = PrepExtension(extension);
extStr = PrepExtension(extension);
err = extStr.length() > 0 ? B_OK : B_BAD_VALUE;
}
// Build the message
if (!err) {
// Clear the message, as we're just going to add to it
types->MakeEmpty();
// Add the types associated with this extension
std::set<std::string> &assTypes = fAssociatedTypes[extStr];
std::set<std::string>::const_iterator i;
@ -93,7 +93,7 @@ AssociatedTypes::GetAssociatedTypes(const char *extension, BMessage *types)
than \c B_OK, \a result will not be modified.
\return
- \c B_OK: success
- \c other error code: failure
- \c other error code: failure
*/
status_t
AssociatedTypes::GuessMimeType(const char *filename, BString *result)
@ -118,13 +118,13 @@ AssociatedTypes::GuessMimeType(const char *filename, BString *result)
if (!err) {
// Extract the extension from the file
const char *rawExtension = strrchr(filename, '.');
// If there was an extension, grab it and look up its associated
// type(s). Otherwise, the best guess we can offer is
// "application/octect-stream"
if (rawExtension && rawExtension[1] != '\0') {
std::string extension = PrepExtension(rawExtension + 1);
/*! \todo I'm just grabbing the first item in the set here. Should we perhaps
do something different?
*/
@ -138,7 +138,7 @@ AssociatedTypes::GuessMimeType(const char *filename, BString *result)
err = kMimeGuessFailureError;
}
}
return err;
return err;
}
// GuessMimeType
@ -150,7 +150,7 @@ AssociatedTypes::GuessMimeType(const char *filename, BString *result)
than \c B_OK, \a result will not be modified.
\return
- \c B_OK: success
- \c other error code: failure
- \c other error code: failure
*/
status_t
AssociatedTypes::GuessMimeType(const entry_ref *ref, BString *result)
@ -168,17 +168,17 @@ AssociatedTypes::GuessMimeType(const entry_ref *ref, BString *result)
// SetFileExtensions
/*! \brief Sets the list of file extensions for the given type and
updates the associated types mappings.
All listed extensions will including the given mime type in
their list of associated types following this call.
All extensions previously but no longer associated with this
mime type will no longer list this mime type as an associated
type.
\param app The mime type whose associated file extensions you are setting
\param types Pointer to a \c BMessage containing an array of associated
file extensions in its \c Mime::kExtensionsField field.
file extensions in its \c Mime::kExtensionsField field.
*/
status_t
AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions)
@ -186,7 +186,7 @@ AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions)
status_t err = type && extensions ? B_OK : B_BAD_VALUE;
if (!fHaveDoneFullBuild)
return err;
std::set<std::string> oldExtensions;
std::set<std::string> &newExtensions = fFileExtensions[type];
// Make a copy of the previous extensions
@ -206,7 +206,7 @@ AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions)
newExtensions.insert(extension);
AddAssociatedType(extension, type);
}
// Remove any extensions that are still associated from the list
// of previously associated extensions
for (std::set<std::string>::const_iterator i = newExtensions.begin();
@ -215,7 +215,7 @@ AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions)
{
oldExtensions.erase(*i);
}
// Now remove the type as an associated type for any of its previously
// but no longer associated extensions
for (std::set<std::string>::const_iterator i = oldExtensions.begin();
@ -224,7 +224,7 @@ AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions)
{
RemoveAssociatedType(i->c_str(), type);
}
}
}
return err;
}
@ -249,7 +249,7 @@ AssociatedTypes::PrintToStream() const
printf("-----------------\n");
printf("Associated Types:\n");
printf("-----------------\n");
for (std::map<std::string, std::set<std::string> >::const_iterator i = fAssociatedTypes.begin();
i != fAssociatedTypes.end();
i++)
@ -275,7 +275,7 @@ AssociatedTypes::PrintToStream() const
// AddAssociatedType
/*! \brief Adds the given mime type to the set of associated types
for the given extension.
\param extension The file extension
\param type The associated mime type
\return
@ -291,7 +291,7 @@ AssociatedTypes::AddAssociatedType(const char *extension, const char *type)
extStr = PrepExtension(extension);
err = extStr.length() > 0 ? B_OK : B_BAD_VALUE;
}
if (!err)
if (!err)
fAssociatedTypes[extStr].insert(type);
return err;
}
@ -299,7 +299,7 @@ AssociatedTypes::AddAssociatedType(const char *extension, const char *type)
// RemoveAssociatedType
/*! \brief Removes the given mime type from the set of associated types
for the given extension.
\param extension The file extension
\param type The associated mime type
\return
@ -315,7 +315,7 @@ AssociatedTypes::RemoveAssociatedType(const char *extension, const char *type)
extStr = PrepExtension(extension);
err = extStr.length() > 0 ? B_OK : B_BAD_VALUE;
}
if (!err)
if (!err)
fAssociatedTypes[extension].erase(type);
return err;
}
@ -329,71 +329,71 @@ AssociatedTypes::BuildAssociatedTypesTable()
{
fFileExtensions.clear();
fAssociatedTypes.clear();
BDirectory root;
status_t err = root.SetTo(kDatabaseDir.c_str());
status_t err = root.SetTo(get_database_directory().c_str());
if (!err) {
root.Rewind();
while (true) {
while (true) {
BEntry entry;
err = root.GetNextEntry(&entry);
if (err) {
// If we've come to the end of list, it's not an error
if (err == B_ENTRY_NOT_FOUND)
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
// Check that this entry is both a directory and a valid MIME string
char supertype[B_PATH_NAME_LENGTH];
char supertype[B_PATH_NAME_LENGTH];
if (entry.IsDirectory()
&& entry.GetName(supertype) == B_OK
&& BMimeType::IsValid(supertype))
{
// Make sure the supertype string is all lowercase
BPrivate::Storage::to_lower(supertype);
// First, iterate through this supertype directory and process
// all of its subtypes
BDirectory dir;
if (dir.SetTo(&entry) == B_OK) {
dir.Rewind();
while (true) {
BEntry subEntry;
BEntry subEntry;
err = dir.GetNextEntry(&subEntry);
if (err) {
// If we've come to the end of list, it's not an error
if (err == B_ENTRY_NOT_FOUND)
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
} else {
// Get the subtype's name
char subtype[B_PATH_NAME_LENGTH];
if (subEntry.GetName(subtype) == B_OK) {
BPrivate::Storage::to_lower(subtype);
char fulltype[B_PATH_NAME_LENGTH];
sprintf(fulltype, "%s/%s", supertype, subtype);
// Process the subtype
ProcessType(fulltype);
}
}
}
}
} else {
DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable(): "
"Failed opening supertype directory '%s'\n",
supertype));
}
// Second, process the supertype
ProcessType(supertype);
}
}
}
ProcessType(supertype);
}
}
}
} else {
DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable(): "
"Failed opening mime database directory '%s'\n",
kDatabaseDir.c_str()));
get_database_directory().c_str()));
}
if (!err) {
fHaveDoneFullBuild = true;
@ -402,15 +402,15 @@ AssociatedTypes::BuildAssociatedTypesTable()
else
DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable() failed, error code == 0x%lx\n", err));
return err;
}
// ProcessType
/*! \brief Handles a portion of the initial associated types table construction for
the given mime type.
\note To be called by BuildAssociatedTypesTable() *ONLY*. :-)
\param type The mime type of interest. The mime string is expected to be valid
and lowercase. Both "supertype" and "supertype/subtype" mime types
are allowed.
@ -430,7 +430,7 @@ AssociatedTypes::ProcessType(const char *type)
std::set<std::string> &fileExtensions = fFileExtensions[type];
for (int i = 0; msg.FindString(kExtensionsField, i, &extension) == B_OK; i++) {
std::string extStr = PrepExtension(extension);
if (extStr.length() > 0) {
if (extStr.length() > 0) {
fileExtensions.insert(extStr);
AddAssociatedType(extStr.c_str(), type);
}

View File

@ -90,7 +90,7 @@ CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
path.ToLower();
// Signatures and MIME types are case insensitive, but we want to
// preserve the case wherever possible
path.Prepend(kDatabaseDir.c_str());
path.Prepend(get_database_directory().c_str());
status = typeNode.SetTo(path.String());
if (status < B_OK)

View File

@ -50,7 +50,7 @@ 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.
\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
that this sort of checking has been done beforehand.
@ -66,7 +66,7 @@ Database::Database()
fDeferredInstallNotifications()
{
// Do some really minor error checking
BEntry entry(kDatabaseDir.c_str());
BEntry entry(get_database_directory().c_str());
fStatus = entry.Exists() ? B_OK : B_BAD_VALUE;
}
@ -118,7 +118,7 @@ Database::Install(const char *type)
if (!err && didCreate) {
fInstalledTypes.AddType(type);
_SendInstallNotification(type);
}
}
}
}
return err;
@ -237,12 +237,12 @@ Database::SetAppHint(const char *type, const entry_ref *ref)
// 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
\param info Pointer to a pre-allocated and properly formatted BMessage containing
information about the file attributes typically associated with the
MIME type.
\return
@ -278,7 +278,7 @@ Database::SetAttrInfo(const char *type, const BMessage *info)
status_t
Database::SetShortDescription(const char *type, const char *description)
{
DBG(OUT("Database::SetShortDescription()\n"));
DBG(OUT("Database::SetShortDescription()\n"));
return _SetStringValue(type, B_SHORT_DESCRIPTION_CHANGED, kShortDescriptionAttr,
kShortDescriptionType, B_MIME_TYPE_LENGTH, description);
@ -309,7 +309,7 @@ Database::SetLongDescription(const char *type, const char *description)
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
@ -320,7 +320,7 @@ status_t
Database::SetFileExtensions(const char *type, const BMessage *extensions)
{
DBG(OUT("Database::SetFileExtensions()\n"));
if (type == NULL || extensions == NULL)
return B_BAD_VALUE;
@ -348,7 +348,7 @@ Database::SetFileExtensions(const char *type, const BMessage *extensions)
to the registrar somehow. Since R5::BBitmap::Instantiate is causing a
violent crash, I've copied most of the icon color conversion code into
Mime::get_icon_data() so BMimeType::SetIcon() can get at it.
Once we have a sufficiently complete OBOS::BBitmap implementation, we
ought to be able to use this version of SetIcon() again. At that point,
I'll add some real documentation.
@ -373,11 +373,11 @@ Database::SetIcon(const char *type, const void *data, size_t dataSize)
The type of the \c BMimeType object is not required to actually be a subtype of
\c "application/"; that is the intended use however, and application-specific
icons are not expected to be present for non-application types.
The bitmap data pointed to by \c data must be of the proper size (\c 32x32
for \c B_LARGE_ICON, \c 16x16 for \c B_MINI_ICON) and the proper color
space (B_CMAP8).
\param type The MIME type
\param fileType The MIME type whose custom icon you wish to set.
\param data Pointer to an array of bitmap data of proper dimensions and color depth
@ -385,7 +385,7 @@ Database::SetIcon(const char *type, const void *data, size_t dataSize)
\param size The size icon you're expecting (\c B_LARGE_ICON or \c B_MINI_ICON)
\return
- \c B_OK: Success
- "error code": Failure
- "error code": Failure
*/
status_t
@ -398,7 +398,7 @@ Database::SetIconForType(const char *type, const char *fileType,
return B_BAD_VALUE;
int32 attrType = 0;
// Figure out what kind of data we *should* have
switch (which) {
case B_MINI_ICON:
@ -459,14 +459,14 @@ Database::SetIconForType(const char *type, const char *fileType,
The type of the \c BMimeType object is not required to actually be a subtype of
\c "application/"; that is the intended use however, and application-specific
icons are not expected to be present for non-application types.
\param type The MIME type
\param fileType The MIME type whose custom icon you wish to set.
\param data Pointer to an array of vector data
\param dataSize The length of the array pointed to by \c data
\return
- \c B_OK: Success
- "error code": Failure
- "error code": Failure
*/
status_t
@ -479,7 +479,7 @@ Database::SetIconForType(const char *type, const char *fileType,
return B_BAD_VALUE;
int32 attrType = B_VECTOR_ICON_TYPE;
// Construct our attribute name
std::string attr;
if (fileType) {
@ -517,8 +517,8 @@ Database::SetIconForType(const char *type, const char *fileType,
// SetPreferredApp
/*! \brief Sets the signature of the preferred application for the given app verb
Currently, the only supported app verb is \c B_OPEN
Currently, the only supported app verb is \c B_OPEN
\param type Pointer to a NULL-terminated string containing the MIME type of interest
\param signature Pointer to a NULL-terminated string containing the MIME signature
of the new preferred application
@ -567,7 +567,7 @@ Database::SetSnifferRule(const char *type, const char *rule)
/*! \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.
@ -630,8 +630,8 @@ Database::SetSupportedTypes(const char *type, const BMessage *types, bool fullSy
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
\param super_types Pointer to a pre-allocated \c BMessage into which the
MIME supertypes will be copied.
\return
- \c B_OK: Success
@ -646,11 +646,11 @@ Database::GetInstalledSupertypes(BMessage *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
\param types Pointer to a pre-allocated \c BMessage into which the
MIME types will be copied.
\return
- \c B_OK: Success
@ -665,17 +665,17 @@ Database::GetInstalledTypes(BMessage *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
- "error code": Failure
*/
status_t
Database::GetInstalledTypes(const char *supertype, BMessage *subtypes)
@ -686,9 +686,9 @@ Database::GetInstalledTypes(const char *supertype, BMessage *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)
{
@ -709,7 +709,7 @@ Database::GetAssociatedTypes(const char *extension, BMessage *types)
// GuessMimeType
/*! \brief Guesses a MIME type for the entry referred to by the given
\c entry_ref.
This version of GuessMimeType() combines the features of the other
versions, plus adds a few tricks of its own:
- If the entry is a meta mime entry (i.e. has a \c "META:TYPE" attribute),
@ -724,7 +724,7 @@ Database::GetAssociatedTypes(const char *extension, BMessage *types)
- If sniffing fails, the filename is checked for known extensions.
- If the extension check fails, the type returned is
\c "application/octet-stream".
\param ref Pointer to the entry_ref referring to the entry.
\param type Pointer to a pre-allocated BString which is set to the
resulting MIME type.
@ -758,10 +758,10 @@ Database::GuessMimeType(const entry_ref *ref, BString *result)
if (S_ISDIR(statData.st_mode)) {
// Directory
result->SetTo(kDirectoryType);
result->SetTo(kDirectoryType);
} else if (S_ISLNK(statData.st_mode)) {
// Symlink
result->SetTo(kSymlinkType);
result->SetTo(kSymlinkType);
} else if (S_ISREG(statData.st_mode)) {
// Vanilla file: sniff first
status = fSnifferRules.GuessMimeType(ref, result);
@ -847,7 +847,7 @@ Database::GuessMimeType(const char *filename, BString *result)
Notification messages will be sent with a \c BMessage::what value
of \c B_META_MIME_CHANGED. Notification messages have the following
fields:
<table>
<tr>
<td> Name </td>
@ -874,12 +874,12 @@ Database::GuessMimeType(const char *filename, BString *result)
<td> \c B_BOOL_TYPE </td>
<td> \c true if the large icon was changed, \c false if the small icon
was changed (applicable to B_ICON_[FOR_TYPE_]CHANGED updates only) </td>
</tr>
</tr>
</table>
The \c be:which field of the message describes which attributes were updated, and
may be the bitwise \c OR of any of the following values:
<table>
<tr>
<td> Value </td>
@ -936,13 +936,13 @@ Database::StartWatching(BMessenger target)
/*!
Unsubscribes the given BMessenger from the MIME monitor service
\param target The \c BMessenger to unsubscribe
\param target The \c BMessenger to unsubscribe
*/
status_t
Database::StopWatching(BMessenger target)
{
DBG(OUT("Database::StopWatching()\n"));
if (!target.IsValid())
return B_BAD_VALUE;
@ -1087,7 +1087,7 @@ Database::DeleteIcon(const char *type, icon_size which)
return status;
}
/*! \brief Deletes the vector icon for the given type
@ -1111,14 +1111,14 @@ Database::DeleteIcon(const char *type)
return status;
}
/*! \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 fileType The mime type for which you no longer wish \c type to have a custom icon.
@ -1150,10 +1150,10 @@ Database::DeleteIconForType(const char *type, const char *fileType, icon_size wh
/*! \brief Deletes the vector icon 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 fileType The mime type for which you no longer wish \c type to have a custom icon.

View File

@ -56,11 +56,11 @@ InstalledTypes::~InstalledTypes()
/*! \brief Returns a list of all currently installed types in the
pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetInstalledTypes(BMessage*) for more information.
*/
status_t
InstalledTypes::GetInstalledTypes(BMessage *types)
status_t
InstalledTypes::GetInstalledTypes(BMessage *types)
{
status_t err = types ? B_OK : B_BAD_VALUE;
// See if we need to do our initial build still
@ -81,11 +81,11 @@ InstalledTypes::GetInstalledTypes(BMessage *types)
/*! \brief Returns a list of all currently installed types of the given
supertype in the pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetInstalledTypes(const char*, BMessage*) for more
information.
*/
status_t
status_t
InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types)
{
if (supertype == NULL || types == NULL)
@ -107,7 +107,7 @@ InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types)
// Ask the appropriate supertype for its list
if (!err) {
std::map<std::string, Supertype>::iterator i = fSupertypes.find(supertype);
if (i != fSupertypes.end())
if (i != fSupertypes.end())
err = i->second.GetInstalledSubtypes(types);
else
err = B_NAME_NOT_FOUND;
@ -118,10 +118,10 @@ InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types)
/*! \brief Returns a list of all currently installed supertypes in the
pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetInstalledSupertypes() for more information.
*/
status_t
status_t
InstalledTypes::GetInstalledSupertypes(BMessage *types)
{
if (types == NULL)
@ -146,7 +146,7 @@ InstalledTypes::GetInstalledSupertypes(BMessage *types)
/*! \brief Adds the given type to the appropriate lists of installed types.
If cached messages exist, the type is simply appended to the end of
the current type list.
*/
@ -177,10 +177,10 @@ InstalledTypes::AddType(const char *type)
char super[B_PATH_NAME_LENGTH];
strncpy(super, type, i);
super[i] = 0;
// Get a pointer to the subtype
const char *sub = &(type[i+1]);
// Add the subtype (which will add the supertype if necessary)
return _AddSubtype(super, sub);
}
@ -216,11 +216,11 @@ InstalledTypes::RemoveType(const char *type)
char super[B_PATH_NAME_LENGTH];
strncpy(super, type, i);
super[i] = 0;
// Get a pointer to the subtype
const char *sub = &(type[i+1]);
// Remove the subtype
// Remove the subtype
return _RemoveSubtype(super, sub);
}
@ -256,7 +256,7 @@ InstalledTypes::_AddSupertype(const char *super,
/*! \brief Adds the given subtype to the given supertype's lists of installed types.
If the supertype does not yet exist, it is created.
\param super The supertype
\param sub The subtype (subtype only; no "supertype/subtype" types please)
\return
@ -313,7 +313,7 @@ InstalledTypes::_RemoveSupertype(const char *super)
return B_BAD_VALUE;
status_t err = fSupertypes.erase(super) == 1 ? B_OK : B_NAME_NOT_FOUND;
if (!err)
if (!err)
_ClearCachedMessages();
return err;
}
@ -333,7 +333,7 @@ InstalledTypes::_RemoveSubtype(const char *super, const char *sub)
if (i != fSupertypes.end()) {
err = i->second.RemoveSubtype(sub);
if (!err)
_ClearCachedMessages();
_ClearCachedMessages();
}
return err;
@ -368,9 +368,9 @@ InstalledTypes::_ClearCachedMessages()
status_t
InstalledTypes::_BuildInstalledTypesList()
{
status_t err = B_OK;
status_t err = B_OK;
_Unset();
// Create empty "cached messages" so proper messages
// will be built up as we add new types
try {
@ -379,48 +379,48 @@ InstalledTypes::_BuildInstalledTypesList()
} catch (std::bad_alloc) {
err = B_NO_MEMORY;
}
BDirectory root;
if (!err)
err = root.SetTo(kDatabaseDir.c_str());
err = root.SetTo(get_database_directory().c_str());
if (!err) {
root.Rewind();
while (true) {
while (true) {
BEntry entry;
err = root.GetNextEntry(&entry);
if (err) {
// If we've come to the end of list, it's not an error
if (err == B_ENTRY_NOT_FOUND)
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
// Check that this entry is both a directory and a valid MIME string
char supertype[B_PATH_NAME_LENGTH];
char supertype[B_PATH_NAME_LENGTH];
if (entry.IsDirectory()
&& entry.GetName(supertype) == B_OK
&& BMimeType::IsValid(supertype))
{
// Make sure our string is all lowercase
BPrivate::Storage::to_lower(supertype);
// Add this supertype
std::map<std::string, Supertype>::iterator i;
if (_AddSupertype(supertype, i) != B_OK)
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding supertype '%s': 0x%lx\n",
supertype, err));
Supertype &supertypeRef = fSupertypes[supertype];
// Now iterate through this supertype directory and add
// all of its subtypes
BDirectory dir;
if (dir.SetTo(&entry) == B_OK) {
dir.Rewind();
while (true) {
BEntry subEntry;
BEntry subEntry;
err = dir.GetNextEntry(&subEntry);
if (err) {
// If we've come to the end of list, it's not an error
if (err == B_ENTRY_NOT_FOUND)
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
@ -452,11 +452,11 @@ InstalledTypes::_BuildInstalledTypesList()
} else {
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList(): "
"Failed opening mime database directory '%s'\n",
kDatabaseDir.c_str()));
get_database_directory().c_str()));
}
fHaveDoneFullBuild = true;
return err;
}
@ -488,7 +488,7 @@ InstalledTypes::_CreateMessageWithTypes(BMessage **_result) const
err = i->second.FillMessageWithTypes(msg);
}
}
return err;
return err;
}
@ -518,7 +518,7 @@ InstalledTypes::_CreateMessageWithSupertypes(BMessage **_result) const
err = msg.AddString(kSupertypesField, i->first.c_str());
}
}
return err;
return err;
}
} // namespace Mime

View File

@ -43,13 +43,13 @@ using namespace BPrivate::Storage;
/*!
\struct SnifferRules::sniffer_rule
\brief A parsed sniffer rule and its corresponding mime type and rule string
The parse sniffer rule is stored in the \c rule member, which is a pointer
to a \c Sniffer::Rule object. This design was chosen to allow \c sniffer_rule
objects (as opposed to \c sniffer_rule pointers) to be used with STL objects
without unnecessary copying. As a consequence of this decision, the
\c SnifferRules object managing the rule list is responsible for actually
deleting each \c sniffer_rule's \c Sniffer::Rule object.
deleting each \c sniffer_rule's \c Sniffer::Rule object.
*/
// sniffer_rule Constructor
@ -70,12 +70,12 @@ SnifferRules::sniffer_rule::~sniffer_rule()
// private functions
/*! \brief Returns true if \a left's priority is greater than \a right's
This may seem slightly backwards, but since sort() using
operator<() sorts in ascending order, we say "left < right"
if "left.priority > right.priority" to get them sorted in
ascending order. Super, no?
Also, sniffer_rule objects with \c NULL \c rule members are
treated as having minimal priority (and thus are placed at
the end of the list of rules).
@ -98,9 +98,9 @@ bool operator<(SnifferRules::sniffer_rule &left, SnifferRules::sniffer_rule &rig
return left.type > right.type;
}
} else if (left.rule) {
return true; // left < right
return true; // left < right
} else {
return false; // right < left
return false; // right < left
}
}
@ -129,7 +129,7 @@ SnifferRules::~SnifferRules()
{
delete i->rule;
i->rule = NULL;
}
}
}
// GuessMimeType
@ -179,14 +179,14 @@ SnifferRules::GuessMimeType(const entry_ref *ref, BString *type)
if (bytes < 0)
err = bytes;
}
// Now sniff the buffer
if (!err)
err = GuessMimeType(&file, buffer, bytes, type);
delete[] buffer;
return err;
return err;
}
// GuessMimeType
@ -209,15 +209,15 @@ SnifferRules::GuessMimeType(const void *buffer, int32 length, BString *type)
{
return GuessMimeType(NULL, buffer, length, type);
}
// SetSnifferRule
/*! Updates the sniffer rule for the given type
If the a rule currently exists in the rule list for the given type,
it is first removed before the new rule is inserted.
The new rule is inserted in its proper, sorted position in the list.
\param type The type of interest
\param rule The new sniffer rule
\return
@ -230,13 +230,13 @@ SnifferRules::SetSnifferRule(const char *type, const char *rule)
status_t err = type && rule ? B_OK : B_BAD_VALUE;
if (!err && !fHaveDoneFullBuild)
return B_OK;
sniffer_rule item(new Sniffer::Rule());
BString parseError;
// Check the mem alloc
if (!err)
err = item.rule ? B_OK : B_NO_MEMORY;
err = item.rule ? B_OK : B_NO_MEMORY;
// Prepare the sniffer_rule
if (!err) {
item.type = type;
@ -248,7 +248,7 @@ SnifferRules::SetSnifferRule(const char *type, const char *rule)
}
// Remove any previous rule for this type
if (!err)
err = DeleteSnifferRule(type);
err = DeleteSnifferRule(type);
// Insert the new rule at the proper position in
// the sorted rule list (remembering that our list
// is sorted in ascending order using
@ -264,9 +264,9 @@ SnifferRules::SetSnifferRule(const char *type, const char *rule)
}
if (i == fRuleList.end())
fRuleList.push_back(item);
}
}
return err;
return err;
}
// DeleteSnifferRule
@ -306,13 +306,13 @@ SnifferRules::PrintToStream() const
printf("--------------\n");
printf("Sniffer Rules:\n");
printf("--------------\n");
if (fHaveDoneFullBuild) {
if (fHaveDoneFullBuild) {
for (std::list<sniffer_rule>::const_iterator i = fRuleList.begin();
i != fRuleList.end();
i++)
{
printf("%s: '%s'\n", i->type.c_str(), i->rule_string.c_str());
printf("%s: '%s'\n", i->type.c_str(), i->rule_string.c_str());
}
} else {
printf("You haven't built your rule list yet, chump. ;-)\n");
@ -322,87 +322,87 @@ SnifferRules::PrintToStream() const
// BuildRuleList
/*! \brief Crawls through the database, parses each sniffer rule it finds, adds
each parsed rule to the rule list, and sorts the list by priority, largest first.
Initial MaxBytesNeeded() info is compiled by this function as well.
*/
status_t
SnifferRules::BuildRuleList()
{
fRuleList.clear();
ssize_t maxBytesNeeded = 0;
ssize_t maxBytesNeeded = 0;
ssize_t bytesNeeded = 0;
BDirectory root;
status_t err = root.SetTo(kDatabaseDir.c_str());
status_t err = root.SetTo(get_database_directory().c_str());
if (!err) {
root.Rewind();
while (true) {
while (true) {
BEntry entry;
err = root.GetNextEntry(&entry);
if (err) {
// If we've come to the end of list, it's not an error
if (err == B_ENTRY_NOT_FOUND)
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
// Check that this entry is both a directory and a valid MIME string
char supertype[B_PATH_NAME_LENGTH];
char supertype[B_PATH_NAME_LENGTH];
if (entry.IsDirectory()
&& entry.GetName(supertype) == B_OK
&& BMimeType::IsValid(supertype))
{
// Make sure the supertype string is all lowercase
BPrivate::Storage::to_lower(supertype);
// First, iterate through this supertype directory and process
// all of its subtypes
BDirectory dir;
if (dir.SetTo(&entry) == B_OK) {
dir.Rewind();
while (true) {
BEntry subEntry;
BEntry subEntry;
err = dir.GetNextEntry(&subEntry);
if (err) {
// If we've come to the end of list, it's not an error
if (err == B_ENTRY_NOT_FOUND)
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
} else {
// Get the subtype's name
char subtype[B_PATH_NAME_LENGTH];
if (subEntry.GetName(subtype) == B_OK) {
BPrivate::Storage::to_lower(subtype);
char fulltype[B_PATH_NAME_LENGTH];
sprintf(fulltype, "%s/%s", supertype, subtype);
// Process the subtype
ProcessType(fulltype, &bytesNeeded);
if (bytesNeeded > maxBytesNeeded)
maxBytesNeeded = bytesNeeded;
}
}
}
}
} else {
DBG(OUT("Mime::SnifferRules::BuildRuleList(): "
"Failed opening supertype directory '%s'\n",
supertype));
}
// Second, process the supertype
ProcessType(supertype, &bytesNeeded);
ProcessType(supertype, &bytesNeeded);
if (bytesNeeded > maxBytesNeeded)
maxBytesNeeded = bytesNeeded;
}
}
}
}
}
}
} else {
DBG(OUT("Mime::SnifferRules::BuildRuleList(): "
"Failed opening mime database directory '%s'\n",
kDatabaseDir.c_str()));
get_database_directory().c_str()));
}
if (!err) {
fRuleList.sort();
fMaxBytesNeeded = maxBytesNeeded;
@ -410,7 +410,7 @@ SnifferRules::BuildRuleList()
// PrintToStream();
} else
DBG(OUT("Mime::SnifferRules::BuildRuleList() failed, error code == 0x%lx\n", err));
return err;
return err;
}
// GuessMimeType
@ -437,7 +437,7 @@ status_t
SnifferRules::GuessMimeType(BFile* file, const void *buffer, int32 length,
BString *type)
{
status_t err = buffer && type ? B_OK : B_BAD_VALUE;
status_t err = buffer && type ? B_OK : B_BAD_VALUE;
if (err)
return err;
@ -493,7 +493,7 @@ SnifferRules::GuessMimeType(BFile* file, const void *buffer, int32 length,
*type = mimeType.Type();
return B_OK;
}
// If we get here, we didn't find a damn thing
err = kMimeGuessFailureError;
}
@ -504,10 +504,10 @@ SnifferRules::GuessMimeType(BFile* file, const void *buffer, int32 length,
/*! \brief Returns the maxmimum number of bytes needed in a data buffer for
all the currently installed rules to be able to perform a complete sniff,
or an error code if something goes wrong.
If the internal rule list has not yet been built (this includes parsing
all the installed rules), it will be.
\return: If the return value is non-negative, it represents the max number
of bytes needed to do a complete sniff. Otherwise, the number returned is
an error code.
@ -525,14 +525,14 @@ SnifferRules::MaxBytesNeeded()
}
}
return err;
}
}
// ProcessType
/*! \brief Handles a portion of the initial rule list construction for
the given mime type.
\note To be called by BuildRuleList() *ONLY*. :-)
\param type The mime type of interest. The mime string is expected to be valid
and lowercase. Both "supertype" and "supertype/subtype" mime types
are allowed.
@ -555,12 +555,12 @@ SnifferRules::ProcessType(const char *type, ssize_t *bytesNeeded)
BString str;
BString errorMsg;
sniffer_rule rule(new Sniffer::Rule());
// Check the mem alloc
if (!err)
err = rule.rule ? B_OK : B_NO_MEMORY;
err = rule.rule ? B_OK : B_NO_MEMORY;
// Read the attr
if (!err)
if (!err)
err = read_mime_attr_string(type, kSnifferRuleAttr, &str);
// Parse the rule
if (!err) {

View File

@ -53,10 +53,10 @@ SupportingApps::~SupportingApps()
// GetSupportingApps
/*! \brief Returns a list of signatures of supporting applications for the
given type in the pre-allocated \c BMessage pointed to by \c apps.
See \c BMimeType::GetSupportingApps() for more information.
*/
status_t
status_t
SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
{
status_t err = type && apps ? B_OK : B_BAD_VALUE;
@ -81,7 +81,7 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
count++;
}
if (!err)
err = apps->AddInt32(kSupportingAppsSuperCountField, count);
err = apps->AddInt32(kSupportingAppsSuperCountField, count);
} else {
// Add the apps that support this subtype (plus their count)
std::set<std::string> &subApps = fSupportingApps[type];
@ -111,7 +111,7 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
}
if (!err)
err = apps->AddInt32(kSupportingAppsSuperCountField, count);
}
}
}
}
}
@ -121,26 +121,26 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
// SetSupportedTypes
/*! \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
for any types for which it is no longer a supporting application
(including types which were removed as supporting types with
@ -216,9 +216,9 @@ SupportingApps::DeleteSupportedTypes(const char *app, bool fullSync)
// AddSupportingApp
/*! \brief Adds the given application signature to the set of supporting
apps for the given type.
\param type The full mime type
\param app The full application signature (i.e. "application/app-subtype")
\param app The full application signature (i.e. "application/app-subtype")
\return
- B_OK: success, even if the app was already in the supporting apps list
- "error code": failure
@ -227,7 +227,7 @@ status_t
SupportingApps::AddSupportingApp(const char *type, const char *app)
{
status_t err = type && app ? B_OK : B_BAD_VALUE;
if (!err)
if (!err)
fSupportingApps[type].insert(app);
return err;
}
@ -235,7 +235,7 @@ SupportingApps::AddSupportingApp(const char *type, const char *app)
// RemoveSupportingApp
/*! \brief Removes the given application signature from the set of supporting
apps for the given type.
\param type The full mime type
\param app The full application signature (i.e. "application/app-subtype")
\return
@ -246,7 +246,7 @@ status_t
SupportingApps::RemoveSupportingApp(const char *type, const char *app)
{
status_t err = type && app ? B_OK : B_BAD_VALUE;
if (!err)
if (!err)
fSupportingApps[type].erase(app);
return err;
}
@ -263,19 +263,19 @@ SupportingApps::BuildSupportingAppsTable()
fStrandedTypes.clear();
BDirectory dir;
status_t status = dir.SetTo(kApplicationDatabaseDir.c_str());
status_t status = dir.SetTo(get_application_database_directory().c_str());
// Build the supporting apps table based on the mime database
if (status == B_OK) {
dir.Rewind();
// Handle each application type
while (true) {
while (true) {
entry_ref ref;
status = dir.GetNextRef(&ref);
if (status < B_OK) {
// If we've come to the end of list, it's not an error
if (status == B_ENTRY_NOT_FOUND)
if (status == B_ENTRY_NOT_FOUND)
status = B_OK;
break;
}