* 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
@@ -20,14 +20,14 @@ namespace Storage {
namespace Mime { namespace Mime {
// Database directory // Database directory
extern const std::string kDatabaseDir; const std::string get_database_directory();
extern const std::string kApplicationDatabaseDir; const std::string get_application_database_directory();
// Attribute Prefixes // Attribute Prefixes
extern const char *kMiniIconAttrPrefix; extern const char *kMiniIconAttrPrefix;
extern const char *kLargeIconAttrPrefix; extern const char *kLargeIconAttrPrefix;
extern const char *kIconAttrPrefix; extern const char *kIconAttrPrefix;
// Attribute names // Attribute names
extern const char *kFileTypeAttr; extern const char *kFileTypeAttr;
extern const char *kTypeAttr; extern const char *kTypeAttr;
@@ -43,7 +43,7 @@ extern const char *kPreferredAppAttr;
extern const char *kSnifferRuleAttr; extern const char *kSnifferRuleAttr;
extern const char *kSupportedTypesAttr; extern const char *kSupportedTypesAttr;
// Attribute Datatypes // Attribute Datatypes
extern const int32 kFileTypeType; extern const int32 kFileTypeType;
extern const int32 kTypeType; extern const int32 kTypeType;
extern const int32 kAppHintType; 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_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 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, 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, 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); status_t delete_attribute(const char *type, const char *attr);
+35 -24
View File
@@ -38,15 +38,6 @@ namespace BPrivate {
namespace Storage { namespace Storage {
namespace Mime { 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 ATTR_PREFIX "META:"
#define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:" #define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:"
@@ -103,27 +94,47 @@ const char *kMetaMimeType = "application/x-vnd.Be-meta-mime";
// Error codes // Error codes
const status_t kMimeGuessFailureError = B_ERRORS_END+1; const status_t kMimeGuessFailureError = B_ERRORS_END+1;
// get_settings_dir static pthread_once_t sDatabaseDirectoryInitOnce = PTHREAD_ONCE_INIT;
/*! \brief Sets the supplied BPath to the user settings directory and returns static std::string sDatabaseDirectory;
it as C string. static std::string sApplicationDatabaseDirectory;
\param path BPath to be set to the user settings path.
\return the user settings path as C string (\code path.Path() \endcode).
*/ static void
static init_database_directories()
const char*
get_user_settings_dir(BPath &path)
{ {
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) BPath path;
path.SetTo("/boot/home/config/settings"); if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK)
return path.Path(); 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 // type_to_filename
//! Converts the given MIME type to an absolute path in the MIME database. //! Converts the given MIME type to an absolute path in the MIME database.
std::string std::string
type_to_filename(const char *type) type_to_filename(const char *type)
{ {
return kDatabaseDir + "/" + BPrivate::Storage::to_lower(type); return get_database_directory() + "/" + BPrivate::Storage::to_lower(type);
} }
// open_type // open_type
@@ -183,7 +194,7 @@ open_or_create_type(const char *type, BNode *result, bool *didCreate)
uint32 pos = typeLower.find_first_of('/'); uint32 pos = typeLower.find_first_of('/');
if (pos == std::string::npos) { if (pos == std::string::npos) {
// Supertype == directory // Supertype == directory
BDirectory parent(kDatabaseDir.c_str()); BDirectory parent(get_database_directory().c_str());
err = parent.InitCheck(); err = parent.InitCheck();
if (!err) if (!err)
err = parent.CreateDirectory(typeLower.c_str(), NULL); 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 // Non-supertype == file
std::string super(typeLower, 0, pos); std::string super(typeLower, 0, pos);
std::string sub(typeLower, pos+1); std::string sub(typeLower, pos+1);
BDirectory parent((kDatabaseDir + "/" + super).c_str()); BDirectory parent((get_database_directory() + "/" + super).c_str());
err = parent.InitCheck(); err = parent.InitCheck();
if (!err) if (!err)
err = parent.CreateFile(sub.c_str(), NULL); err = parent.CreateFile(sub.c_str(), NULL);
+47 -47
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. // by the OpenBeOS license.
//--------------------------------------------------------------------- //---------------------------------------------------------------------
/*! /*!
@@ -51,29 +51,29 @@ AssociatedTypes::~AssociatedTypes()
// GetAssociatedTypes // GetAssociatedTypes
/*! \brief Returns a list of mime types associated with the given file /*! \brief Returns a list of mime types associated with the given file
extension in the pre-allocated \c BMessage pointed to by \c types. extension in the pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetAssociatedTypes() for more information. See \c BMimeType::GetAssociatedTypes() for more information.
*/ */
status_t status_t
AssociatedTypes::GetAssociatedTypes(const char *extension, BMessage *types) AssociatedTypes::GetAssociatedTypes(const char *extension, BMessage *types)
{ {
status_t err = extension && types ? B_OK : B_BAD_VALUE; status_t err = extension && types ? B_OK : B_BAD_VALUE;
std::string extStr; std::string extStr;
// See if we need to do our initial build still // See if we need to do our initial build still
if (!err && !fHaveDoneFullBuild) { if (!err && !fHaveDoneFullBuild) {
err = BuildAssociatedTypesTable(); err = BuildAssociatedTypesTable();
} }
// Format the extension // Format the extension
if (!err) { if (!err) {
extStr = PrepExtension(extension); extStr = PrepExtension(extension);
err = extStr.length() > 0 ? B_OK : B_BAD_VALUE; err = extStr.length() > 0 ? B_OK : B_BAD_VALUE;
} }
// Build the message // Build the message
if (!err) { if (!err) {
// Clear the message, as we're just going to add to it // Clear the message, as we're just going to add to it
types->MakeEmpty(); types->MakeEmpty();
// Add the types associated with this extension // Add the types associated with this extension
std::set<std::string> &assTypes = fAssociatedTypes[extStr]; std::set<std::string> &assTypes = fAssociatedTypes[extStr];
std::set<std::string>::const_iterator i; 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. than \c B_OK, \a result will not be modified.
\return \return
- \c B_OK: success - \c B_OK: success
- \c other error code: failure - \c other error code: failure
*/ */
status_t status_t
AssociatedTypes::GuessMimeType(const char *filename, BString *result) AssociatedTypes::GuessMimeType(const char *filename, BString *result)
@@ -118,13 +118,13 @@ AssociatedTypes::GuessMimeType(const char *filename, BString *result)
if (!err) { if (!err) {
// Extract the extension from the file // Extract the extension from the file
const char *rawExtension = strrchr(filename, '.'); const char *rawExtension = strrchr(filename, '.');
// If there was an extension, grab it and look up its associated // If there was an extension, grab it and look up its associated
// type(s). Otherwise, the best guess we can offer is // type(s). Otherwise, the best guess we can offer is
// "application/octect-stream" // "application/octect-stream"
if (rawExtension && rawExtension[1] != '\0') { if (rawExtension && rawExtension[1] != '\0') {
std::string extension = PrepExtension(rawExtension + 1); std::string extension = PrepExtension(rawExtension + 1);
/*! \todo I'm just grabbing the first item in the set here. Should we perhaps /*! \todo I'm just grabbing the first item in the set here. Should we perhaps
do something different? do something different?
*/ */
@@ -138,7 +138,7 @@ AssociatedTypes::GuessMimeType(const char *filename, BString *result)
err = kMimeGuessFailureError; err = kMimeGuessFailureError;
} }
} }
return err; return err;
} }
// GuessMimeType // GuessMimeType
@@ -150,7 +150,7 @@ AssociatedTypes::GuessMimeType(const char *filename, BString *result)
than \c B_OK, \a result will not be modified. than \c B_OK, \a result will not be modified.
\return \return
- \c B_OK: success - \c B_OK: success
- \c other error code: failure - \c other error code: failure
*/ */
status_t status_t
AssociatedTypes::GuessMimeType(const entry_ref *ref, BString *result) AssociatedTypes::GuessMimeType(const entry_ref *ref, BString *result)
@@ -168,17 +168,17 @@ AssociatedTypes::GuessMimeType(const entry_ref *ref, BString *result)
// SetFileExtensions // SetFileExtensions
/*! \brief Sets the list of file extensions for the given type and /*! \brief Sets the list of file extensions for the given type and
updates the associated types mappings. updates the associated types mappings.
All listed extensions will including the given mime type in All listed extensions will including the given mime type in
their list of associated types following this call. their list of associated types following this call.
All extensions previously but no longer associated with this All extensions previously but no longer associated with this
mime type will no longer list this mime type as an associated mime type will no longer list this mime type as an associated
type. type.
\param app The mime type whose associated file extensions you are setting \param app The mime type whose associated file extensions you are setting
\param types Pointer to a \c BMessage containing an array of associated \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 status_t
AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions) 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; status_t err = type && extensions ? B_OK : B_BAD_VALUE;
if (!fHaveDoneFullBuild) if (!fHaveDoneFullBuild)
return err; return err;
std::set<std::string> oldExtensions; std::set<std::string> oldExtensions;
std::set<std::string> &newExtensions = fFileExtensions[type]; std::set<std::string> &newExtensions = fFileExtensions[type];
// Make a copy of the previous extensions // Make a copy of the previous extensions
@@ -206,7 +206,7 @@ AssociatedTypes::SetFileExtensions(const char *type, const BMessage *extensions)
newExtensions.insert(extension); newExtensions.insert(extension);
AddAssociatedType(extension, type); AddAssociatedType(extension, type);
} }
// Remove any extensions that are still associated from the list // Remove any extensions that are still associated from the list
// of previously associated extensions // of previously associated extensions
for (std::set<std::string>::const_iterator i = newExtensions.begin(); 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); oldExtensions.erase(*i);
} }
// Now remove the type as an associated type for any of its previously // Now remove the type as an associated type for any of its previously
// but no longer associated extensions // but no longer associated extensions
for (std::set<std::string>::const_iterator i = oldExtensions.begin(); 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); RemoveAssociatedType(i->c_str(), type);
} }
} }
return err; return err;
} }
@@ -249,7 +249,7 @@ AssociatedTypes::PrintToStream() const
printf("-----------------\n"); printf("-----------------\n");
printf("Associated Types:\n"); printf("Associated Types:\n");
printf("-----------------\n"); printf("-----------------\n");
for (std::map<std::string, std::set<std::string> >::const_iterator i = fAssociatedTypes.begin(); for (std::map<std::string, std::set<std::string> >::const_iterator i = fAssociatedTypes.begin();
i != fAssociatedTypes.end(); i != fAssociatedTypes.end();
i++) i++)
@@ -275,7 +275,7 @@ AssociatedTypes::PrintToStream() const
// AddAssociatedType // AddAssociatedType
/*! \brief Adds the given mime type to the set of associated types /*! \brief Adds the given mime type to the set of associated types
for the given extension. for the given extension.
\param extension The file extension \param extension The file extension
\param type The associated mime type \param type The associated mime type
\return \return
@@ -291,7 +291,7 @@ AssociatedTypes::AddAssociatedType(const char *extension, const char *type)
extStr = PrepExtension(extension); extStr = PrepExtension(extension);
err = extStr.length() > 0 ? B_OK : B_BAD_VALUE; err = extStr.length() > 0 ? B_OK : B_BAD_VALUE;
} }
if (!err) if (!err)
fAssociatedTypes[extStr].insert(type); fAssociatedTypes[extStr].insert(type);
return err; return err;
} }
@@ -299,7 +299,7 @@ AssociatedTypes::AddAssociatedType(const char *extension, const char *type)
// RemoveAssociatedType // RemoveAssociatedType
/*! \brief Removes the given mime type from the set of associated types /*! \brief Removes the given mime type from the set of associated types
for the given extension. for the given extension.
\param extension The file extension \param extension The file extension
\param type The associated mime type \param type The associated mime type
\return \return
@@ -315,7 +315,7 @@ AssociatedTypes::RemoveAssociatedType(const char *extension, const char *type)
extStr = PrepExtension(extension); extStr = PrepExtension(extension);
err = extStr.length() > 0 ? B_OK : B_BAD_VALUE; err = extStr.length() > 0 ? B_OK : B_BAD_VALUE;
} }
if (!err) if (!err)
fAssociatedTypes[extension].erase(type); fAssociatedTypes[extension].erase(type);
return err; return err;
} }
@@ -329,71 +329,71 @@ AssociatedTypes::BuildAssociatedTypesTable()
{ {
fFileExtensions.clear(); fFileExtensions.clear();
fAssociatedTypes.clear(); fAssociatedTypes.clear();
BDirectory root; BDirectory root;
status_t err = root.SetTo(kDatabaseDir.c_str()); status_t err = root.SetTo(get_database_directory().c_str());
if (!err) { if (!err) {
root.Rewind(); root.Rewind();
while (true) { while (true) {
BEntry entry; BEntry entry;
err = root.GetNextEntry(&entry); err = root.GetNextEntry(&entry);
if (err) { if (err) {
// If we've come to the end of list, it's not an error // 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; err = B_OK;
break; break;
} else { } else {
// Check that this entry is both a directory and a valid MIME string // 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() if (entry.IsDirectory()
&& entry.GetName(supertype) == B_OK && entry.GetName(supertype) == B_OK
&& BMimeType::IsValid(supertype)) && BMimeType::IsValid(supertype))
{ {
// Make sure the supertype string is all lowercase // Make sure the supertype string is all lowercase
BPrivate::Storage::to_lower(supertype); BPrivate::Storage::to_lower(supertype);
// First, iterate through this supertype directory and process // First, iterate through this supertype directory and process
// all of its subtypes // all of its subtypes
BDirectory dir; BDirectory dir;
if (dir.SetTo(&entry) == B_OK) { if (dir.SetTo(&entry) == B_OK) {
dir.Rewind(); dir.Rewind();
while (true) { while (true) {
BEntry subEntry; BEntry subEntry;
err = dir.GetNextEntry(&subEntry); err = dir.GetNextEntry(&subEntry);
if (err) { if (err) {
// If we've come to the end of list, it's not an error // 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; err = B_OK;
break; break;
} else { } else {
// Get the subtype's name // Get the subtype's name
char subtype[B_PATH_NAME_LENGTH]; char subtype[B_PATH_NAME_LENGTH];
if (subEntry.GetName(subtype) == B_OK) { if (subEntry.GetName(subtype) == B_OK) {
BPrivate::Storage::to_lower(subtype); BPrivate::Storage::to_lower(subtype);
char fulltype[B_PATH_NAME_LENGTH]; char fulltype[B_PATH_NAME_LENGTH];
sprintf(fulltype, "%s/%s", supertype, subtype); sprintf(fulltype, "%s/%s", supertype, subtype);
// Process the subtype // Process the subtype
ProcessType(fulltype); ProcessType(fulltype);
} }
} }
} }
} else { } else {
DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable(): " DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable(): "
"Failed opening supertype directory '%s'\n", "Failed opening supertype directory '%s'\n",
supertype)); supertype));
} }
// Second, process the supertype // Second, process the supertype
ProcessType(supertype); ProcessType(supertype);
} }
} }
} }
} else { } else {
DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable(): " DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable(): "
"Failed opening mime database directory '%s'\n", "Failed opening mime database directory '%s'\n",
kDatabaseDir.c_str())); get_database_directory().c_str()));
} }
if (!err) { if (!err) {
fHaveDoneFullBuild = true; fHaveDoneFullBuild = true;
@@ -402,15 +402,15 @@ AssociatedTypes::BuildAssociatedTypesTable()
else else
DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable() failed, error code == 0x%lx\n", err)); DBG(OUT("Mime::AssociatedTypes::BuildAssociatedTypesTable() failed, error code == 0x%lx\n", err));
return err; return err;
} }
// ProcessType // ProcessType
/*! \brief Handles a portion of the initial associated types table construction for /*! \brief Handles a portion of the initial associated types table construction for
the given mime type. the given mime type.
\note To be called by BuildAssociatedTypesTable() *ONLY*. :-) \note To be called by BuildAssociatedTypesTable() *ONLY*. :-)
\param type The mime type of interest. The mime string is expected to be valid \param type The mime type of interest. The mime string is expected to be valid
and lowercase. Both "supertype" and "supertype/subtype" mime types and lowercase. Both "supertype" and "supertype/subtype" mime types
are allowed. are allowed.
@@ -430,7 +430,7 @@ AssociatedTypes::ProcessType(const char *type)
std::set<std::string> &fileExtensions = fFileExtensions[type]; std::set<std::string> &fileExtensions = fFileExtensions[type];
for (int i = 0; msg.FindString(kExtensionsField, i, &extension) == B_OK; i++) { for (int i = 0; msg.FindString(kExtensionsField, i, &extension) == B_OK; i++) {
std::string extStr = PrepExtension(extension); std::string extStr = PrepExtension(extension);
if (extStr.length() > 0) { if (extStr.length() > 0) {
fileExtensions.insert(extStr); fileExtensions.insert(extStr);
AddAssociatedType(extStr.c_str(), type); AddAssociatedType(extStr.c_str(), type);
} }
@@ -90,7 +90,7 @@ CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
path.ToLower(); path.ToLower();
// Signatures and MIME types are case insensitive, but we want to // Signatures and MIME types are case insensitive, but we want to
// preserve the case wherever possible // preserve the case wherever possible
path.Prepend(kDatabaseDir.c_str()); path.Prepend(get_database_directory().c_str());
status = typeNode.SetTo(path.String()); status = typeNode.SetTo(path.String());
if (status < B_OK) if (status < B_OK)
+46 -46
View File
@@ -50,7 +50,7 @@ namespace Mime {
\brief Mime::Database is the master of the MIME data base. \brief Mime::Database is the master of the MIME data base.
All write and non-atomic read accesses are carried out by this class. 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 \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 by this class on the mime type strings passed to it. It's assumed
that this sort of checking has been done beforehand. that this sort of checking has been done beforehand.
@@ -66,7 +66,7 @@ Database::Database()
fDeferredInstallNotifications() fDeferredInstallNotifications()
{ {
// Do some really minor error checking // 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; fStatus = entry.Exists() ? B_OK : B_BAD_VALUE;
} }
@@ -118,7 +118,7 @@ Database::Install(const char *type)
if (!err && didCreate) { if (!err && didCreate) {
fInstalledTypes.AddType(type); fInstalledTypes.AddType(type);
_SendInstallNotification(type); _SendInstallNotification(type);
} }
} }
} }
return err; return err;
@@ -237,12 +237,12 @@ Database::SetAppHint(const char *type, const entry_ref *ref)
// SetAttrInfo // SetAttrInfo
/*! \brief Stores a BMessage describing the format of attributes typically associated with /*! \brief Stores a BMessage describing the format of attributes typically associated with
files of the given MIME type files of the given MIME type
See BMimeType::SetAttrInfo() for description of the expected message format. See BMimeType::SetAttrInfo() for description of the expected message format.
The \c BMessage::what value is ignored. 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 information about the file attributes typically associated with the
MIME type. MIME type.
\return \return
@@ -278,7 +278,7 @@ Database::SetAttrInfo(const char *type, const BMessage *info)
status_t status_t
Database::SetShortDescription(const char *type, const char *description) 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, return _SetStringValue(type, B_SHORT_DESCRIPTION_CHANGED, kShortDescriptionAttr,
kShortDescriptionType, B_MIME_TYPE_LENGTH, description); 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 list of extensions is given in a pre-allocated BMessage pointed to by
the \c extensions parameter. Please see BMimeType::SetFileExtensions() the \c extensions parameter. Please see BMimeType::SetFileExtensions()
for a description of the expected message format. for a description of the expected message format.
\param extensions Pointer to a pre-allocated, properly formatted BMessage containing \param extensions Pointer to a pre-allocated, properly formatted BMessage containing
the new list of file extensions to associate with this MIME type. the new list of file extensions to associate with this MIME type.
\return \return
@@ -320,7 +320,7 @@ status_t
Database::SetFileExtensions(const char *type, const BMessage *extensions) Database::SetFileExtensions(const char *type, const BMessage *extensions)
{ {
DBG(OUT("Database::SetFileExtensions()\n")); DBG(OUT("Database::SetFileExtensions()\n"));
if (type == NULL || extensions == NULL) if (type == NULL || extensions == NULL)
return B_BAD_VALUE; 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 to the registrar somehow. Since R5::BBitmap::Instantiate is causing a
violent crash, I've copied most of the icon color conversion code into violent crash, I've copied most of the icon color conversion code into
Mime::get_icon_data() so BMimeType::SetIcon() can get at it. Mime::get_icon_data() so BMimeType::SetIcon() can get at it.
Once we have a sufficiently complete OBOS::BBitmap implementation, we Once we have a sufficiently complete OBOS::BBitmap implementation, we
ought to be able to use this version of SetIcon() again. At that point, ought to be able to use this version of SetIcon() again. At that point,
I'll add some real documentation. 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 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 \c "application/"; that is the intended use however, and application-specific
icons are not expected to be present for non-application types. 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 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 for \c B_LARGE_ICON, \c 16x16 for \c B_MINI_ICON) and the proper color
space (B_CMAP8). space (B_CMAP8).
\param type The MIME type \param type The MIME type
\param fileType The MIME type whose custom icon you wish to set. \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 \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) \param size The size icon you're expecting (\c B_LARGE_ICON or \c B_MINI_ICON)
\return \return
- \c B_OK: Success - \c B_OK: Success
- "error code": Failure - "error code": Failure
*/ */
status_t status_t
@@ -398,7 +398,7 @@ Database::SetIconForType(const char *type, const char *fileType,
return B_BAD_VALUE; return B_BAD_VALUE;
int32 attrType = 0; int32 attrType = 0;
// Figure out what kind of data we *should* have // Figure out what kind of data we *should* have
switch (which) { switch (which) {
case B_MINI_ICON: 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 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 \c "application/"; that is the intended use however, and application-specific
icons are not expected to be present for non-application types. icons are not expected to be present for non-application types.
\param type The MIME type \param type The MIME type
\param fileType The MIME type whose custom icon you wish to set. \param fileType The MIME type whose custom icon you wish to set.
\param data Pointer to an array of vector data \param data Pointer to an array of vector data
\param dataSize The length of the array pointed to by \c data \param dataSize The length of the array pointed to by \c data
\return \return
- \c B_OK: Success - \c B_OK: Success
- "error code": Failure - "error code": Failure
*/ */
status_t status_t
@@ -479,7 +479,7 @@ Database::SetIconForType(const char *type, const char *fileType,
return B_BAD_VALUE; return B_BAD_VALUE;
int32 attrType = B_VECTOR_ICON_TYPE; int32 attrType = B_VECTOR_ICON_TYPE;
// Construct our attribute name // Construct our attribute name
std::string attr; std::string attr;
if (fileType) { if (fileType) {
@@ -517,8 +517,8 @@ Database::SetIconForType(const char *type, const char *fileType,
// SetPreferredApp // SetPreferredApp
/*! \brief Sets the signature of the preferred application for the given app verb /*! \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 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 \param signature Pointer to a NULL-terminated string containing the MIME signature
of the new preferred application 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 /*! \brief Sets the list of MIME types supported by the MIME type and
syncs the internal supporting apps database either partially or syncs the internal supporting apps database either partially or
completely. completely.
Please see BMimeType::SetSupportedTypes() for details. Please see BMimeType::SetSupportedTypes() for details.
\param type The mime type of interest \param type The mime type of interest
\param types The supported types to be assigned to the file. \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 types are copied into the \c "super_types" field of the passed-in \c BMessage.
The \c BMessage must be pre-allocated. 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. MIME supertypes will be copied.
\return \return
- \c B_OK: Success - \c B_OK: Success
@@ -646,11 +646,11 @@ Database::GetInstalledSupertypes(BMessage *supertypes)
// GetInstalledTypes // GetInstalledTypes
/*! \brief Fetches a BMessage listing all the MIME types currently installed /*! \brief Fetches a BMessage listing all the MIME types currently installed
in the MIME database. in the MIME database.
The types are copied into the \c "types" field of the passed-in \c BMessage. The types are copied into the \c "types" field of the passed-in \c BMessage.
The \c BMessage must be pre-allocated. 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. MIME types will be copied.
\return \return
- \c B_OK: Success - \c B_OK: Success
@@ -665,17 +665,17 @@ Database::GetInstalledTypes(BMessage *types)
// GetInstalledTypes // GetInstalledTypes
/*! \brief Fetches a BMessage listing all the MIME subtypes of the given /*! \brief Fetches a BMessage listing all the MIME subtypes of the given
supertype currently installed in the MIME database. supertype currently installed in the MIME database.
The types are copied into the \c "types" field of the passed-in \c BMessage. The types are copied into the \c "types" field of the passed-in \c BMessage.
The \c BMessage must be pre-allocated. The \c BMessage must be pre-allocated.
\param super_type Pointer to a string containing the MIME supertype whose \param super_type Pointer to a string containing the MIME supertype whose
subtypes you wish to retrieve. subtypes you wish to retrieve.
\param subtypes Pointer to a pre-allocated \c BMessage into which the appropriate \param subtypes Pointer to a pre-allocated \c BMessage into which the appropriate
MIME subtypes will be copied. MIME subtypes will be copied.
\return \return
- \c B_OK: Success - \c B_OK: Success
- "error code": Failure - "error code": Failure
*/ */
status_t status_t
Database::GetInstalledTypes(const char *supertype, BMessage *subtypes) Database::GetInstalledTypes(const char *supertype, BMessage *subtypes)
@@ -686,9 +686,9 @@ Database::GetInstalledTypes(const char *supertype, BMessage *subtypes)
// GetSupportingApps // GetSupportingApps
/*! \brief Fetches a \c BMessage containing a list of MIME signatures of /*! \brief Fetches a \c BMessage containing a list of MIME signatures of
applications that are able to handle files of this MIME type. applications that are able to handle files of this MIME type.
Please see BMimeType::GetSupportingApps() for more details. Please see BMimeType::GetSupportingApps() for more details.
*/ */
status_t status_t
Database::GetSupportingApps(const char *type, BMessage *signatures) Database::GetSupportingApps(const char *type, BMessage *signatures)
{ {
@@ -709,7 +709,7 @@ Database::GetAssociatedTypes(const char *extension, BMessage *types)
// GuessMimeType // GuessMimeType
/*! \brief Guesses a MIME type for the entry referred to by the given /*! \brief Guesses a MIME type for the entry referred to by the given
\c entry_ref. \c entry_ref.
This version of GuessMimeType() combines the features of the other This version of GuessMimeType() combines the features of the other
versions, plus adds a few tricks of its own: 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), - 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 sniffing fails, the filename is checked for known extensions.
- If the extension check fails, the type returned is - If the extension check fails, the type returned is
\c "application/octet-stream". \c "application/octet-stream".
\param ref Pointer to the entry_ref referring to the entry. \param ref Pointer to the entry_ref referring to the entry.
\param type Pointer to a pre-allocated BString which is set to the \param type Pointer to a pre-allocated BString which is set to the
resulting MIME type. resulting MIME type.
@@ -758,10 +758,10 @@ Database::GuessMimeType(const entry_ref *ref, BString *result)
if (S_ISDIR(statData.st_mode)) { if (S_ISDIR(statData.st_mode)) {
// Directory // Directory
result->SetTo(kDirectoryType); result->SetTo(kDirectoryType);
} else if (S_ISLNK(statData.st_mode)) { } else if (S_ISLNK(statData.st_mode)) {
// Symlink // Symlink
result->SetTo(kSymlinkType); result->SetTo(kSymlinkType);
} else if (S_ISREG(statData.st_mode)) { } else if (S_ISREG(statData.st_mode)) {
// Vanilla file: sniff first // Vanilla file: sniff first
status = fSnifferRules.GuessMimeType(ref, result); 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 Notification messages will be sent with a \c BMessage::what value
of \c B_META_MIME_CHANGED. Notification messages have the following of \c B_META_MIME_CHANGED. Notification messages have the following
fields: fields:
<table> <table>
<tr> <tr>
<td> Name </td> <td> Name </td>
@@ -874,12 +874,12 @@ Database::GuessMimeType(const char *filename, BString *result)
<td> \c B_BOOL_TYPE </td> <td> \c B_BOOL_TYPE </td>
<td> \c true if the large icon was changed, \c false if the small icon <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> was changed (applicable to B_ICON_[FOR_TYPE_]CHANGED updates only) </td>
</tr> </tr>
</table> </table>
The \c be:which field of the message describes which attributes were updated, and 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: may be the bitwise \c OR of any of the following values:
<table> <table>
<tr> <tr>
<td> Value </td> <td> Value </td>
@@ -936,13 +936,13 @@ Database::StartWatching(BMessenger target)
/*! /*!
Unsubscribes the given BMessenger from the MIME monitor service 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 status_t
Database::StopWatching(BMessenger target) Database::StopWatching(BMessenger target)
{ {
DBG(OUT("Database::StopWatching()\n")); DBG(OUT("Database::StopWatching()\n"));
if (!target.IsValid()) if (!target.IsValid())
return B_BAD_VALUE; return B_BAD_VALUE;
@@ -1087,7 +1087,7 @@ Database::DeleteIcon(const char *type, icon_size which)
return status; return status;
} }
/*! \brief Deletes the vector icon for the given type /*! \brief Deletes the vector icon for the given type
@@ -1111,14 +1111,14 @@ Database::DeleteIcon(const char *type)
return status; return status;
} }
/*! \brief Deletes the icon of the given size associated with the given file /*! \brief Deletes the icon of the given size associated with the given file
type for the given application signature. type for the given application signature.
(If this function seems confusing, please see BMimeType::GetIconForType() for a (If this function seems confusing, please see BMimeType::GetIconForType() for a
better description of what the *IconForType() functions are used for.) 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. 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 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. \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 /*! \brief Deletes the vector icon associated with the given file
type for the given application signature. type for the given application signature.
(If this function seems confusing, please see BMimeType::GetIconForType() for a (If this function seems confusing, please see BMimeType::GetIconForType() for a
better description of what the *IconForType() functions are used for.) 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. 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 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. \param fileType The mime type for which you no longer wish \c type to have a custom icon.
+32 -32
View File
@@ -56,11 +56,11 @@ InstalledTypes::~InstalledTypes()
/*! \brief Returns a list of all currently installed types in the /*! \brief Returns a list of all currently installed types in the
pre-allocated \c BMessage pointed to by \c types. pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetInstalledTypes(BMessage*) for more information. See \c BMimeType::GetInstalledTypes(BMessage*) for more information.
*/ */
status_t status_t
InstalledTypes::GetInstalledTypes(BMessage *types) InstalledTypes::GetInstalledTypes(BMessage *types)
{ {
status_t err = types ? B_OK : B_BAD_VALUE; status_t err = types ? B_OK : B_BAD_VALUE;
// See if we need to do our initial build still // 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 /*! \brief Returns a list of all currently installed types of the given
supertype in the pre-allocated \c BMessage pointed to by \c types. supertype in the pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetInstalledTypes(const char*, BMessage*) for more See \c BMimeType::GetInstalledTypes(const char*, BMessage*) for more
information. information.
*/ */
status_t status_t
InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types) InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types)
{ {
if (supertype == NULL || types == NULL) if (supertype == NULL || types == NULL)
@@ -107,7 +107,7 @@ InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types)
// Ask the appropriate supertype for its list // Ask the appropriate supertype for its list
if (!err) { if (!err) {
std::map<std::string, Supertype>::iterator i = fSupertypes.find(supertype); std::map<std::string, Supertype>::iterator i = fSupertypes.find(supertype);
if (i != fSupertypes.end()) if (i != fSupertypes.end())
err = i->second.GetInstalledSubtypes(types); err = i->second.GetInstalledSubtypes(types);
else else
err = B_NAME_NOT_FOUND; 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 /*! \brief Returns a list of all currently installed supertypes in the
pre-allocated \c BMessage pointed to by \c types. pre-allocated \c BMessage pointed to by \c types.
See \c BMimeType::GetInstalledSupertypes() for more information. See \c BMimeType::GetInstalledSupertypes() for more information.
*/ */
status_t status_t
InstalledTypes::GetInstalledSupertypes(BMessage *types) InstalledTypes::GetInstalledSupertypes(BMessage *types)
{ {
if (types == NULL) if (types == NULL)
@@ -146,7 +146,7 @@ InstalledTypes::GetInstalledSupertypes(BMessage *types)
/*! \brief Adds the given type to the appropriate lists of installed 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 If cached messages exist, the type is simply appended to the end of
the current type list. the current type list.
*/ */
@@ -177,10 +177,10 @@ InstalledTypes::AddType(const char *type)
char super[B_PATH_NAME_LENGTH]; char super[B_PATH_NAME_LENGTH];
strncpy(super, type, i); strncpy(super, type, i);
super[i] = 0; super[i] = 0;
// Get a pointer to the subtype // Get a pointer to the subtype
const char *sub = &(type[i+1]); const char *sub = &(type[i+1]);
// Add the subtype (which will add the supertype if necessary) // Add the subtype (which will add the supertype if necessary)
return _AddSubtype(super, sub); return _AddSubtype(super, sub);
} }
@@ -216,11 +216,11 @@ InstalledTypes::RemoveType(const char *type)
char super[B_PATH_NAME_LENGTH]; char super[B_PATH_NAME_LENGTH];
strncpy(super, type, i); strncpy(super, type, i);
super[i] = 0; super[i] = 0;
// Get a pointer to the subtype // Get a pointer to the subtype
const char *sub = &(type[i+1]); const char *sub = &(type[i+1]);
// Remove the subtype // Remove the subtype
return _RemoveSubtype(super, sub); 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. /*! \brief Adds the given subtype to the given supertype's lists of installed types.
If the supertype does not yet exist, it is created. If the supertype does not yet exist, it is created.
\param super The supertype \param super The supertype
\param sub The subtype (subtype only; no "supertype/subtype" types please) \param sub The subtype (subtype only; no "supertype/subtype" types please)
\return \return
@@ -313,7 +313,7 @@ InstalledTypes::_RemoveSupertype(const char *super)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t err = fSupertypes.erase(super) == 1 ? B_OK : B_NAME_NOT_FOUND; status_t err = fSupertypes.erase(super) == 1 ? B_OK : B_NAME_NOT_FOUND;
if (!err) if (!err)
_ClearCachedMessages(); _ClearCachedMessages();
return err; return err;
} }
@@ -333,7 +333,7 @@ InstalledTypes::_RemoveSubtype(const char *super, const char *sub)
if (i != fSupertypes.end()) { if (i != fSupertypes.end()) {
err = i->second.RemoveSubtype(sub); err = i->second.RemoveSubtype(sub);
if (!err) if (!err)
_ClearCachedMessages(); _ClearCachedMessages();
} }
return err; return err;
@@ -368,9 +368,9 @@ InstalledTypes::_ClearCachedMessages()
status_t status_t
InstalledTypes::_BuildInstalledTypesList() InstalledTypes::_BuildInstalledTypesList()
{ {
status_t err = B_OK; status_t err = B_OK;
_Unset(); _Unset();
// Create empty "cached messages" so proper messages // Create empty "cached messages" so proper messages
// will be built up as we add new types // will be built up as we add new types
try { try {
@@ -379,48 +379,48 @@ InstalledTypes::_BuildInstalledTypesList()
} catch (std::bad_alloc) { } catch (std::bad_alloc) {
err = B_NO_MEMORY; err = B_NO_MEMORY;
} }
BDirectory root; BDirectory root;
if (!err) if (!err)
err = root.SetTo(kDatabaseDir.c_str()); err = root.SetTo(get_database_directory().c_str());
if (!err) { if (!err) {
root.Rewind(); root.Rewind();
while (true) { while (true) {
BEntry entry; BEntry entry;
err = root.GetNextEntry(&entry); err = root.GetNextEntry(&entry);
if (err) { if (err) {
// If we've come to the end of list, it's not an error // 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; err = B_OK;
break; break;
} else { } else {
// Check that this entry is both a directory and a valid MIME string // 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() if (entry.IsDirectory()
&& entry.GetName(supertype) == B_OK && entry.GetName(supertype) == B_OK
&& BMimeType::IsValid(supertype)) && BMimeType::IsValid(supertype))
{ {
// Make sure our string is all lowercase // Make sure our string is all lowercase
BPrivate::Storage::to_lower(supertype); BPrivate::Storage::to_lower(supertype);
// Add this supertype // Add this supertype
std::map<std::string, Supertype>::iterator i; std::map<std::string, Supertype>::iterator i;
if (_AddSupertype(supertype, i) != B_OK) if (_AddSupertype(supertype, i) != B_OK)
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding supertype '%s': 0x%lx\n", DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding supertype '%s': 0x%lx\n",
supertype, err)); supertype, err));
Supertype &supertypeRef = fSupertypes[supertype]; Supertype &supertypeRef = fSupertypes[supertype];
// Now iterate through this supertype directory and add // Now iterate through this supertype directory and add
// all of its subtypes // all of its subtypes
BDirectory dir; BDirectory dir;
if (dir.SetTo(&entry) == B_OK) { if (dir.SetTo(&entry) == B_OK) {
dir.Rewind(); dir.Rewind();
while (true) { while (true) {
BEntry subEntry; BEntry subEntry;
err = dir.GetNextEntry(&subEntry); err = dir.GetNextEntry(&subEntry);
if (err) { if (err) {
// If we've come to the end of list, it's not an error // 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; err = B_OK;
break; break;
} else { } else {
@@ -452,11 +452,11 @@ InstalledTypes::_BuildInstalledTypesList()
} else { } else {
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList(): " DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList(): "
"Failed opening mime database directory '%s'\n", "Failed opening mime database directory '%s'\n",
kDatabaseDir.c_str())); get_database_directory().c_str()));
} }
fHaveDoneFullBuild = true; fHaveDoneFullBuild = true;
return err; return err;
} }
@@ -488,7 +488,7 @@ InstalledTypes::_CreateMessageWithTypes(BMessage **_result) const
err = i->second.FillMessageWithTypes(msg); 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()); err = msg.AddString(kSupertypesField, i->first.c_str());
} }
} }
return err; return err;
} }
} // namespace Mime } // namespace Mime
+54 -54
View File
@@ -43,13 +43,13 @@ using namespace BPrivate::Storage;
/*! /*!
\struct SnifferRules::sniffer_rule \struct SnifferRules::sniffer_rule
\brief A parsed sniffer rule and its corresponding mime type and rule string \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 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 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 objects (as opposed to \c sniffer_rule pointers) to be used with STL objects
without unnecessary copying. As a consequence of this decision, the without unnecessary copying. As a consequence of this decision, the
\c SnifferRules object managing the rule list is responsible for actually \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 // sniffer_rule Constructor
@@ -70,12 +70,12 @@ SnifferRules::sniffer_rule::~sniffer_rule()
// private functions // private functions
/*! \brief Returns true if \a left's priority is greater than \a right's /*! \brief Returns true if \a left's priority is greater than \a right's
This may seem slightly backwards, but since sort() using This may seem slightly backwards, but since sort() using
operator<() sorts in ascending order, we say "left < right" operator<() sorts in ascending order, we say "left < right"
if "left.priority > right.priority" to get them sorted in if "left.priority > right.priority" to get them sorted in
ascending order. Super, no? ascending order. Super, no?
Also, sniffer_rule objects with \c NULL \c rule members are Also, sniffer_rule objects with \c NULL \c rule members are
treated as having minimal priority (and thus are placed at treated as having minimal priority (and thus are placed at
the end of the list of rules). 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; return left.type > right.type;
} }
} else if (left.rule) { } else if (left.rule) {
return true; // left < right return true; // left < right
} else { } else {
return false; // right < left return false; // right < left
} }
} }
@@ -129,7 +129,7 @@ SnifferRules::~SnifferRules()
{ {
delete i->rule; delete i->rule;
i->rule = NULL; i->rule = NULL;
} }
} }
// GuessMimeType // GuessMimeType
@@ -179,14 +179,14 @@ SnifferRules::GuessMimeType(const entry_ref *ref, BString *type)
if (bytes < 0) if (bytes < 0)
err = bytes; err = bytes;
} }
// Now sniff the buffer // Now sniff the buffer
if (!err) if (!err)
err = GuessMimeType(&file, buffer, bytes, type); err = GuessMimeType(&file, buffer, bytes, type);
delete[] buffer; delete[] buffer;
return err; return err;
} }
// GuessMimeType // GuessMimeType
@@ -209,15 +209,15 @@ SnifferRules::GuessMimeType(const void *buffer, int32 length, BString *type)
{ {
return GuessMimeType(NULL, buffer, length, type); return GuessMimeType(NULL, buffer, length, type);
} }
// SetSnifferRule // SetSnifferRule
/*! Updates the sniffer rule for the given type /*! Updates the sniffer rule for the given type
If the a rule currently exists in the rule list 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. it is first removed before the new rule is inserted.
The new rule is inserted in its proper, sorted position in the list. The new rule is inserted in its proper, sorted position in the list.
\param type The type of interest \param type The type of interest
\param rule The new sniffer rule \param rule The new sniffer rule
\return \return
@@ -230,13 +230,13 @@ SnifferRules::SetSnifferRule(const char *type, const char *rule)
status_t err = type && rule ? B_OK : B_BAD_VALUE; status_t err = type && rule ? B_OK : B_BAD_VALUE;
if (!err && !fHaveDoneFullBuild) if (!err && !fHaveDoneFullBuild)
return B_OK; return B_OK;
sniffer_rule item(new Sniffer::Rule()); sniffer_rule item(new Sniffer::Rule());
BString parseError; BString parseError;
// Check the mem alloc // Check the mem alloc
if (!err) if (!err)
err = item.rule ? B_OK : B_NO_MEMORY; err = item.rule ? B_OK : B_NO_MEMORY;
// Prepare the sniffer_rule // Prepare the sniffer_rule
if (!err) { if (!err) {
item.type = type; item.type = type;
@@ -248,7 +248,7 @@ SnifferRules::SetSnifferRule(const char *type, const char *rule)
} }
// Remove any previous rule for this type // Remove any previous rule for this type
if (!err) if (!err)
err = DeleteSnifferRule(type); err = DeleteSnifferRule(type);
// Insert the new rule at the proper position in // Insert the new rule at the proper position in
// the sorted rule list (remembering that our list // the sorted rule list (remembering that our list
// is sorted in ascending order using // is sorted in ascending order using
@@ -264,9 +264,9 @@ SnifferRules::SetSnifferRule(const char *type, const char *rule)
} }
if (i == fRuleList.end()) if (i == fRuleList.end())
fRuleList.push_back(item); fRuleList.push_back(item);
} }
return err; return err;
} }
// DeleteSnifferRule // DeleteSnifferRule
@@ -306,13 +306,13 @@ SnifferRules::PrintToStream() const
printf("--------------\n"); printf("--------------\n");
printf("Sniffer Rules:\n"); printf("Sniffer Rules:\n");
printf("--------------\n"); printf("--------------\n");
if (fHaveDoneFullBuild) { if (fHaveDoneFullBuild) {
for (std::list<sniffer_rule>::const_iterator i = fRuleList.begin(); for (std::list<sniffer_rule>::const_iterator i = fRuleList.begin();
i != fRuleList.end(); i != fRuleList.end();
i++) 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 { } else {
printf("You haven't built your rule list yet, chump. ;-)\n"); printf("You haven't built your rule list yet, chump. ;-)\n");
@@ -322,87 +322,87 @@ SnifferRules::PrintToStream() const
// BuildRuleList // BuildRuleList
/*! \brief Crawls through the database, parses each sniffer rule it finds, adds /*! \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. 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. Initial MaxBytesNeeded() info is compiled by this function as well.
*/ */
status_t status_t
SnifferRules::BuildRuleList() SnifferRules::BuildRuleList()
{ {
fRuleList.clear(); fRuleList.clear();
ssize_t maxBytesNeeded = 0; ssize_t maxBytesNeeded = 0;
ssize_t bytesNeeded = 0; ssize_t bytesNeeded = 0;
BDirectory root; BDirectory root;
status_t err = root.SetTo(kDatabaseDir.c_str()); status_t err = root.SetTo(get_database_directory().c_str());
if (!err) { if (!err) {
root.Rewind(); root.Rewind();
while (true) { while (true) {
BEntry entry; BEntry entry;
err = root.GetNextEntry(&entry); err = root.GetNextEntry(&entry);
if (err) { if (err) {
// If we've come to the end of list, it's not an error // 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; err = B_OK;
break; break;
} else { } else {
// Check that this entry is both a directory and a valid MIME string // 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() if (entry.IsDirectory()
&& entry.GetName(supertype) == B_OK && entry.GetName(supertype) == B_OK
&& BMimeType::IsValid(supertype)) && BMimeType::IsValid(supertype))
{ {
// Make sure the supertype string is all lowercase // Make sure the supertype string is all lowercase
BPrivate::Storage::to_lower(supertype); BPrivate::Storage::to_lower(supertype);
// First, iterate through this supertype directory and process // First, iterate through this supertype directory and process
// all of its subtypes // all of its subtypes
BDirectory dir; BDirectory dir;
if (dir.SetTo(&entry) == B_OK) { if (dir.SetTo(&entry) == B_OK) {
dir.Rewind(); dir.Rewind();
while (true) { while (true) {
BEntry subEntry; BEntry subEntry;
err = dir.GetNextEntry(&subEntry); err = dir.GetNextEntry(&subEntry);
if (err) { if (err) {
// If we've come to the end of list, it's not an error // 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; err = B_OK;
break; break;
} else { } else {
// Get the subtype's name // Get the subtype's name
char subtype[B_PATH_NAME_LENGTH]; char subtype[B_PATH_NAME_LENGTH];
if (subEntry.GetName(subtype) == B_OK) { if (subEntry.GetName(subtype) == B_OK) {
BPrivate::Storage::to_lower(subtype); BPrivate::Storage::to_lower(subtype);
char fulltype[B_PATH_NAME_LENGTH]; char fulltype[B_PATH_NAME_LENGTH];
sprintf(fulltype, "%s/%s", supertype, subtype); sprintf(fulltype, "%s/%s", supertype, subtype);
// Process the subtype // Process the subtype
ProcessType(fulltype, &bytesNeeded); ProcessType(fulltype, &bytesNeeded);
if (bytesNeeded > maxBytesNeeded) if (bytesNeeded > maxBytesNeeded)
maxBytesNeeded = bytesNeeded; maxBytesNeeded = bytesNeeded;
} }
} }
} }
} else { } else {
DBG(OUT("Mime::SnifferRules::BuildRuleList(): " DBG(OUT("Mime::SnifferRules::BuildRuleList(): "
"Failed opening supertype directory '%s'\n", "Failed opening supertype directory '%s'\n",
supertype)); supertype));
} }
// Second, process the supertype // Second, process the supertype
ProcessType(supertype, &bytesNeeded); ProcessType(supertype, &bytesNeeded);
if (bytesNeeded > maxBytesNeeded) if (bytesNeeded > maxBytesNeeded)
maxBytesNeeded = bytesNeeded; maxBytesNeeded = bytesNeeded;
} }
} }
} }
} else { } else {
DBG(OUT("Mime::SnifferRules::BuildRuleList(): " DBG(OUT("Mime::SnifferRules::BuildRuleList(): "
"Failed opening mime database directory '%s'\n", "Failed opening mime database directory '%s'\n",
kDatabaseDir.c_str())); get_database_directory().c_str()));
} }
if (!err) { if (!err) {
fRuleList.sort(); fRuleList.sort();
fMaxBytesNeeded = maxBytesNeeded; fMaxBytesNeeded = maxBytesNeeded;
@@ -410,7 +410,7 @@ SnifferRules::BuildRuleList()
// PrintToStream(); // PrintToStream();
} else } else
DBG(OUT("Mime::SnifferRules::BuildRuleList() failed, error code == 0x%lx\n", err)); DBG(OUT("Mime::SnifferRules::BuildRuleList() failed, error code == 0x%lx\n", err));
return err; return err;
} }
// GuessMimeType // GuessMimeType
@@ -437,7 +437,7 @@ status_t
SnifferRules::GuessMimeType(BFile* file, const void *buffer, int32 length, SnifferRules::GuessMimeType(BFile* file, const void *buffer, int32 length,
BString *type) BString *type)
{ {
status_t err = buffer && type ? B_OK : B_BAD_VALUE; status_t err = buffer && type ? B_OK : B_BAD_VALUE;
if (err) if (err)
return err; return err;
@@ -493,7 +493,7 @@ SnifferRules::GuessMimeType(BFile* file, const void *buffer, int32 length,
*type = mimeType.Type(); *type = mimeType.Type();
return B_OK; return B_OK;
} }
// If we get here, we didn't find a damn thing // If we get here, we didn't find a damn thing
err = kMimeGuessFailureError; 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 /*! \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, all the currently installed rules to be able to perform a complete sniff,
or an error code if something goes wrong. or an error code if something goes wrong.
If the internal rule list has not yet been built (this includes parsing If the internal rule list has not yet been built (this includes parsing
all the installed rules), it will be. all the installed rules), it will be.
\return: If the return value is non-negative, it represents the max number \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 of bytes needed to do a complete sniff. Otherwise, the number returned is
an error code. an error code.
@@ -525,14 +525,14 @@ SnifferRules::MaxBytesNeeded()
} }
} }
return err; return err;
} }
// ProcessType // ProcessType
/*! \brief Handles a portion of the initial rule list construction for /*! \brief Handles a portion of the initial rule list construction for
the given mime type. the given mime type.
\note To be called by BuildRuleList() *ONLY*. :-) \note To be called by BuildRuleList() *ONLY*. :-)
\param type The mime type of interest. The mime string is expected to be valid \param type The mime type of interest. The mime string is expected to be valid
and lowercase. Both "supertype" and "supertype/subtype" mime types and lowercase. Both "supertype" and "supertype/subtype" mime types
are allowed. are allowed.
@@ -555,12 +555,12 @@ SnifferRules::ProcessType(const char *type, ssize_t *bytesNeeded)
BString str; BString str;
BString errorMsg; BString errorMsg;
sniffer_rule rule(new Sniffer::Rule()); sniffer_rule rule(new Sniffer::Rule());
// Check the mem alloc // Check the mem alloc
if (!err) if (!err)
err = rule.rule ? B_OK : B_NO_MEMORY; err = rule.rule ? B_OK : B_NO_MEMORY;
// Read the attr // Read the attr
if (!err) if (!err)
err = read_mime_attr_string(type, kSnifferRuleAttr, &str); err = read_mime_attr_string(type, kSnifferRuleAttr, &str);
// Parse the rule // Parse the rule
if (!err) { if (!err) {
+17 -17
View File
@@ -53,10 +53,10 @@ SupportingApps::~SupportingApps()
// GetSupportingApps // GetSupportingApps
/*! \brief Returns a list of signatures of supporting applications for the /*! \brief Returns a list of signatures of supporting applications for the
given type in the pre-allocated \c BMessage pointed to by \c apps. given type in the pre-allocated \c BMessage pointed to by \c apps.
See \c BMimeType::GetSupportingApps() for more information. See \c BMimeType::GetSupportingApps() for more information.
*/ */
status_t status_t
SupportingApps::GetSupportingApps(const char *type, BMessage *apps) SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
{ {
status_t err = type && apps ? B_OK : B_BAD_VALUE; status_t err = type && apps ? B_OK : B_BAD_VALUE;
@@ -81,7 +81,7 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
count++; count++;
} }
if (!err) if (!err)
err = apps->AddInt32(kSupportingAppsSuperCountField, count); err = apps->AddInt32(kSupportingAppsSuperCountField, count);
} else { } else {
// Add the apps that support this subtype (plus their count) // Add the apps that support this subtype (plus their count)
std::set<std::string> &subApps = fSupportingApps[type]; std::set<std::string> &subApps = fSupportingApps[type];
@@ -111,7 +111,7 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
} }
if (!err) if (!err)
err = apps->AddInt32(kSupportingAppsSuperCountField, count); err = apps->AddInt32(kSupportingAppsSuperCountField, count);
} }
} }
} }
} }
@@ -121,26 +121,26 @@ SupportingApps::GetSupportingApps(const char *type, BMessage *apps)
// SetSupportedTypes // SetSupportedTypes
/*! \brief Sets the list of supported types for the given application and /*! \brief Sets the list of supported types for the given application and
updates the supporting apps mappings. updates the supporting apps mappings.
All types listed as being supported types will including the given All types listed as being supported types will including the given
app signature in their list of supporting apps following this call. app signature in their list of supporting apps following this call.
If \a fullSync is true, all types previously but no longer supported If \a fullSync is true, all types previously but no longer supported
by this application with no longer list this application as a by this application with no longer list this application as a
supporting app. supporting app.
If \a fullSync is false, said previously supported types will be If \a fullSync is false, said previously supported types will be
saved to a "stranded types" mapping and appropriately synchronized saved to a "stranded types" mapping and appropriately synchronized
the next time SetSupportedTypes() is called with a \c true \a fullSync the next time SetSupportedTypes() is called with a \c true \a fullSync
parameter. parameter.
The stranded types mapping is properly maintained even in the event The stranded types mapping is properly maintained even in the event
of types being removed and then re-added to the list of supporting of types being removed and then re-added to the list of supporting
types with consecutive \c false \a fullSync parameters. types with consecutive \c false \a fullSync parameters.
\param app The application whose supported types you are setting \param app The application whose supported types you are setting
\param types Pointer to a \c BMessage containing an array of supported \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 \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 for any types for which it is no longer a supporting application
(including types which were removed as supporting types with (including types which were removed as supporting types with
@@ -216,9 +216,9 @@ SupportingApps::DeleteSupportedTypes(const char *app, bool fullSync)
// AddSupportingApp // AddSupportingApp
/*! \brief Adds the given application signature to the set of supporting /*! \brief Adds the given application signature to the set of supporting
apps for the given type. apps for the given type.
\param type The full mime 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 \return
- B_OK: success, even if the app was already in the supporting apps list - B_OK: success, even if the app was already in the supporting apps list
- "error code": failure - "error code": failure
@@ -227,7 +227,7 @@ status_t
SupportingApps::AddSupportingApp(const char *type, const char *app) SupportingApps::AddSupportingApp(const char *type, const char *app)
{ {
status_t err = type && app ? B_OK : B_BAD_VALUE; status_t err = type && app ? B_OK : B_BAD_VALUE;
if (!err) if (!err)
fSupportingApps[type].insert(app); fSupportingApps[type].insert(app);
return err; return err;
} }
@@ -235,7 +235,7 @@ SupportingApps::AddSupportingApp(const char *type, const char *app)
// RemoveSupportingApp // RemoveSupportingApp
/*! \brief Removes the given application signature from the set of supporting /*! \brief Removes the given application signature from the set of supporting
apps for the given type. apps for the given type.
\param type The full mime 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 \return
@@ -246,7 +246,7 @@ status_t
SupportingApps::RemoveSupportingApp(const char *type, const char *app) SupportingApps::RemoveSupportingApp(const char *type, const char *app)
{ {
status_t err = type && app ? B_OK : B_BAD_VALUE; status_t err = type && app ? B_OK : B_BAD_VALUE;
if (!err) if (!err)
fSupportingApps[type].erase(app); fSupportingApps[type].erase(app);
return err; return err;
} }
@@ -263,19 +263,19 @@ SupportingApps::BuildSupportingAppsTable()
fStrandedTypes.clear(); fStrandedTypes.clear();
BDirectory dir; 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 // Build the supporting apps table based on the mime database
if (status == B_OK) { if (status == B_OK) {
dir.Rewind(); dir.Rewind();
// Handle each application type // Handle each application type
while (true) { while (true) {
entry_ref ref; entry_ref ref;
status = dir.GetNextRef(&ref); status = dir.GetNextRef(&ref);
if (status < B_OK) { if (status < B_OK) {
// If we've come to the end of list, it's not an error // 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; status = B_OK;
break; break;
} }