+ Added GetInstalled[Super]Types functionality
+ Cleaned up warnings + Added documentation git-svn-id: file:///srv/svn/repos/haiku/trunk/current@899 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,4 +1,11 @@
|
|||||||
// mime/Database.h
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file Database.cpp
|
||||||
|
Database class declarations
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _MIME_DATABASE_H
|
#ifndef _MIME_DATABASE_H
|
||||||
#define _MIME_DATABASE_H
|
#define _MIME_DATABASE_H
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// mime/InstalledTypes.h
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file InstalledTypes.h
|
||||||
|
InstalledTypes class declarations
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _MIME_INSTALLED_TYPES_H
|
#ifndef _MIME_INSTALLED_TYPES_H
|
||||||
#define _MIME_INSTALLED_TYPES_H
|
#define _MIME_INSTALLED_TYPES_H
|
||||||
@@ -24,15 +31,29 @@ public:
|
|||||||
status_t GetInstalledTypes(const char *supertype, BMessage *types);
|
status_t GetInstalledTypes(const char *supertype, BMessage *types);
|
||||||
status_t GetInstalledSupertypes(BMessage *types);
|
status_t GetInstalledSupertypes(BMessage *types);
|
||||||
|
|
||||||
void AddType(const char *type);
|
status_t AddType(const char *type);
|
||||||
void AddSupertype(const char *type);
|
status_t RemoveType(const char *type);
|
||||||
void AddSubtype(const char *super, const char *sub);
|
|
||||||
private:
|
private:
|
||||||
void FillMessageWithTypes(BMessage *msg);
|
status_t AddSupertype(const char *super, std::map<std::string, Supertype>::iterator &i);
|
||||||
|
status_t AddSubtype(const char *super, const char *sub);
|
||||||
|
status_t AddSubtype(Supertype &super, const char *sub);
|
||||||
|
|
||||||
|
status_t RemoveSupertype(const char *super);
|
||||||
|
status_t RemoveSubtype(const char *super, const char *sub);
|
||||||
|
|
||||||
|
void Unset();
|
||||||
|
void ClearCachedMessages();
|
||||||
|
|
||||||
|
status_t CreateMessageWithTypes(BMessage **result) const;
|
||||||
|
status_t CreateMessageWithSupertypes(BMessage **result) const;
|
||||||
void FillMessageWithSupertypes(BMessage *msg);
|
void FillMessageWithSupertypes(BMessage *msg);
|
||||||
|
|
||||||
|
status_t BuildInstalledTypesList();
|
||||||
|
|
||||||
std::map<std::string, Supertype> fSupertypes;
|
std::map<std::string, Supertype> fSupertypes;
|
||||||
BMessage *fCachedMessage;
|
BMessage *fCachedMessage;
|
||||||
|
BMessage *fCachedSupertypesMessage;
|
||||||
|
bool fHaveDoneFullBuild;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// mime/Supertype.h
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file Supertype.h
|
||||||
|
Supertype class declarations
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _MIME_SUPERTYPE_H
|
#ifndef _MIME_SUPERTYPE_H
|
||||||
#define _MIME_SUPERTYPE_H
|
#define _MIME_SUPERTYPE_H
|
||||||
@@ -16,15 +23,24 @@ namespace Mime {
|
|||||||
|
|
||||||
class Supertype {
|
class Supertype {
|
||||||
public:
|
public:
|
||||||
Supertype(const char *super);
|
Supertype(const char *super = NULL);
|
||||||
~Supertype();
|
~Supertype();
|
||||||
|
|
||||||
|
status_t GetInstalledSubtypes(BMessage *types);
|
||||||
|
|
||||||
void AddSubtype(const char *sub);
|
status_t AddSubtype(const char *sub);
|
||||||
void FillMessageWithTypes(BMessage *msg);
|
status_t RemoveSubtype(const char *sub);
|
||||||
|
|
||||||
|
void SetName(const char *super);
|
||||||
|
const char* GetName();
|
||||||
|
|
||||||
|
status_t FillMessageWithTypes(BMessage &msg) const;
|
||||||
private:
|
private:
|
||||||
|
status_t CreateMessageWithTypes(BMessage **result) const;
|
||||||
|
|
||||||
std::set<std::string> fSubtypes;
|
std::set<std::string> fSubtypes;
|
||||||
BMessage *fCachedMessage;
|
BMessage *fCachedMessage;
|
||||||
std::string fType;
|
std::string fName;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// mime/database_access.h
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file database_access.h
|
||||||
|
Mime database atomic read function declarations
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _MIME_DATABASE_ACCESS_H
|
#ifndef _MIME_DATABASE_ACCESS_H
|
||||||
#define _MIME_DATABASE_ACCESS_H
|
#define _MIME_DATABASE_ACCESS_H
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// mime/database_support.h
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file database_support.h
|
||||||
|
Private mime database function and constant declarations
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef _MIME_DATABASE_SUPPORT_H
|
#ifndef _MIME_DATABASE_SUPPORT_H
|
||||||
#define _MIME_DATABASE_SUPPORT_H
|
#define _MIME_DATABASE_SUPPORT_H
|
||||||
@@ -49,6 +56,10 @@ extern const int32 kPreferredAppType;
|
|||||||
extern const int32 kSnifferRuleType;
|
extern const int32 kSnifferRuleType;
|
||||||
extern const int32 kSupportedTypesType;
|
extern const int32 kSupportedTypesType;
|
||||||
|
|
||||||
|
// Message fields
|
||||||
|
extern const char *kTypesField;
|
||||||
|
extern const char *kSupertypesField;
|
||||||
|
|
||||||
std::string type_to_filename(const char *type);
|
std::string type_to_filename(const char *type);
|
||||||
|
|
||||||
status_t open_type(const char *type, BNode *result);
|
status_t open_type(const char *type, BNode *result);
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// mime/Database.cpp
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file Database.cpp
|
||||||
|
Database class implementation
|
||||||
|
*/
|
||||||
|
|
||||||
#include <Application.h>
|
#include <Application.h>
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
@@ -103,6 +110,8 @@ Database::Install(const char *type)
|
|||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
BNode node;
|
BNode node;
|
||||||
err = open_or_create_type(type, &node, &didCreate);
|
err = open_or_create_type(type, &node, &didCreate);
|
||||||
|
if (didCreate)
|
||||||
|
fInstalledTypes.AddType(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@@ -124,8 +133,10 @@ Database::Delete(const char *type)
|
|||||||
err = entry.SetTo(type_to_filename(type).c_str());
|
err = entry.SetTo(type_to_filename(type).c_str());
|
||||||
if (!err)
|
if (!err)
|
||||||
err = entry.Remove();
|
err = entry.Remove();
|
||||||
if (!err)
|
if (!err) {
|
||||||
|
fInstalledTypes.RemoveType(type);
|
||||||
err = SendDeleteNotification(type);
|
err = SendDeleteNotification(type);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,8 +299,8 @@ Database::SetIconForType(const char *type, const char *fileType, const void *dat
|
|||||||
ssize_t err = (type && data) ? B_OK : B_BAD_VALUE;
|
ssize_t err = (type && data) ? B_OK : B_BAD_VALUE;
|
||||||
|
|
||||||
std::string attr;
|
std::string attr;
|
||||||
int32 attrType;
|
int32 attrType = 0;
|
||||||
int32 attrSize;
|
size_t attrSize = 0;
|
||||||
|
|
||||||
// Figure out what kind of data we *should* have
|
// Figure out what kind of data we *should* have
|
||||||
if (!err) {
|
if (!err) {
|
||||||
@@ -329,7 +340,7 @@ Database::SetIconForType(const char *type, const char *fileType, const void *dat
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = node.WriteAttr(attr.c_str(), attrType, 0, data, attrSize);
|
err = node.WriteAttr(attr.c_str(), attrType, 0, data, attrSize);
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
err = err == attrSize ? B_OK : B_FILE_ERROR;
|
err = err == (ssize_t)attrSize ? B_OK : B_FILE_ERROR;
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -374,22 +385,19 @@ Database::SetSupportedTypes(const char *type, const BMessage *types)
|
|||||||
status_t
|
status_t
|
||||||
Database::GetInstalledSupertypes(BMessage *supertypes)
|
Database::GetInstalledSupertypes(BMessage *supertypes)
|
||||||
{
|
{
|
||||||
// return fInstalledTypes.GetInstalledSupertypes(supertypes);
|
return fInstalledTypes.GetInstalledSupertypes(supertypes);
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Database::GetInstalledTypes(BMessage *types)
|
Database::GetInstalledTypes(BMessage *types)
|
||||||
{
|
{
|
||||||
// return fInstalledTypes.GetInstalledTypes(types);
|
return fInstalledTypes.GetInstalledTypes(types);
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Database::GetInstalledTypes(const char *supertype, BMessage *subtypes)
|
Database::GetInstalledTypes(const char *supertype, BMessage *subtypes)
|
||||||
{
|
{
|
||||||
// return fInstalledTypes.GetInstalledTypes(supertype, subtypes);
|
return fInstalledTypes.GetInstalledTypes(supertype, subtypes);
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
// mime/InstalledTypes.cpp
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file InstalledTypes.cpp
|
||||||
|
InstalledTypes class implementation
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mime/InstalledTypes.h"
|
#include "mime/InstalledTypes.h"
|
||||||
|
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <Entry.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <MimeType.h>
|
||||||
|
#include <mime/database_support.h>
|
||||||
|
#include <storage_support.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define DBG(x) x
|
#define DBG(x) x
|
||||||
@@ -14,195 +27,350 @@ namespace BPrivate {
|
|||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class InstalledTypes
|
||||||
|
\brief Installed types information for the entire database
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
//! Constructs a new InstalledTypes object
|
||||||
InstalledTypes::InstalledTypes()
|
InstalledTypes::InstalledTypes()
|
||||||
: fCachedMessage(NULL)
|
: fCachedMessage(NULL)
|
||||||
|
, fCachedSupertypesMessage(NULL)
|
||||||
|
, fHaveDoneFullBuild(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
//! Destroys the InstalledTypes object
|
||||||
InstalledTypes::~InstalledTypes()
|
InstalledTypes::~InstalledTypes()
|
||||||
{
|
{
|
||||||
|
delete fCachedSupertypesMessage;
|
||||||
delete fCachedMessage;
|
delete fCachedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// GetInstalledTypes
|
||||||
MimeDatabaseBackend::MimeDatabaseBackend()
|
/*! \brief Returns a list of all currently installed types in the
|
||||||
: fCachedInstalledTypesMessage(NULL)
|
pre-allocated \c BMessage pointed to by \c types.
|
||||||
, fCachedInstalledSupertypesMessage(NULL)
|
|
||||||
|
See \c BMimeType::GetInstalledTypes(BMessage*) for more information.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::GetInstalledTypes(BMessage *types)
|
||||||
{
|
{
|
||||||
}
|
|
||||||
|
|
||||||
MimeDatabaseBackend::~MimeDatabaseBackend()
|
|
||||||
{
|
|
||||||
delete fCachedInstalledTypesMessage;
|
|
||||||
delete fCachedInstalledSupertypesMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t
|
|
||||||
MimeDatabaseBackend::GetInstalledTypes(BMessage *types)
|
|
||||||
{
|
|
||||||
DBG(OUT("MimeDatabaseBackend::GetInstalledTypes(1)\n"));
|
|
||||||
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
|
||||||
|
if (!err && !fHaveDoneFullBuild) {
|
||||||
|
err = BuildInstalledTypesList();
|
||||||
|
}
|
||||||
|
// See if we need to fill up a new message
|
||||||
|
if (!err && !fCachedMessage) {
|
||||||
|
err = CreateMessageWithTypes(&fCachedMessage);
|
||||||
|
}
|
||||||
|
// If we get this far, there a cached message waiting
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (!fCachedInstalledTypesMessage) {
|
*types = *fCachedMessage;
|
||||||
if (fInstalledTypes.begin() == fInstalledTypes.end())
|
}
|
||||||
err = BuildInstalledTypesList(&fCachedInstalledTypesMessage);
|
return err;
|
||||||
else
|
}
|
||||||
err = BuildInstalledTypesMessage(&fCachedInstalledTypesMessage);
|
|
||||||
|
// GetInstalledTypes
|
||||||
|
/*! \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
|
||||||
|
InstalledTypes::GetInstalledTypes(const char *supertype, BMessage *types)
|
||||||
|
{
|
||||||
|
status_t err = supertype && types ? B_OK : B_BAD_VALUE;
|
||||||
|
// Verify the supertype is valid *and* is a supertype
|
||||||
|
BMimeType mime;
|
||||||
|
BMimeType super;
|
||||||
|
// Make sure the supertype is valid
|
||||||
|
if (!err)
|
||||||
|
err = mime.SetTo(supertype);
|
||||||
|
// Make sure it's really a supertype
|
||||||
|
if (!err && !mime.IsSupertypeOnly())
|
||||||
|
err = B_BAD_VALUE;
|
||||||
|
// See if we need to do our initial build still
|
||||||
|
if (!err && !fHaveDoneFullBuild) {
|
||||||
|
err = BuildInstalledTypesList();
|
||||||
|
}
|
||||||
|
// Ask the appropriate supertype for its list
|
||||||
|
if (!err) {
|
||||||
|
std::map<std::string, Supertype>::iterator i = fSupertypes.find(supertype);
|
||||||
|
if (i != fSupertypes.end())
|
||||||
|
err = i->second.GetInstalledSubtypes(types);
|
||||||
|
else
|
||||||
|
err = B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInstalledSupertypes
|
||||||
|
/*! \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
|
||||||
|
InstalledTypes::GetInstalledSupertypes(BMessage *types)
|
||||||
|
{
|
||||||
|
status_t err = types ? B_OK : B_BAD_VALUE;
|
||||||
|
// See if we need to do our initial build still
|
||||||
|
if (!err && !fHaveDoneFullBuild) {
|
||||||
|
err = BuildInstalledTypesList();
|
||||||
|
}
|
||||||
|
// See if we need to fill up a new message
|
||||||
|
if (!err && !fCachedSupertypesMessage) {
|
||||||
|
err = CreateMessageWithSupertypes(&fCachedSupertypesMessage);
|
||||||
|
}
|
||||||
|
// If we get this far, there's a cached message waiting
|
||||||
|
if (!err) {
|
||||||
|
*types = *fCachedSupertypesMessage;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddType
|
||||||
|
/*! \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.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::AddType(const char *type)
|
||||||
|
{
|
||||||
|
status_t err;
|
||||||
|
if (fHaveDoneFullBuild) {
|
||||||
|
BMimeType mime(type);
|
||||||
|
BMimeType super;
|
||||||
|
err = type ? mime.InitCheck() : B_BAD_VALUE;
|
||||||
|
if (!err) {
|
||||||
|
// Find the / in the string, if one exists
|
||||||
|
uint i;
|
||||||
|
size_t len = strlen(type);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (type[i] == '/')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == len) {
|
||||||
|
// Supertype only
|
||||||
|
std::map<std::string, Supertype>::iterator i;
|
||||||
|
err = AddSupertype(type, i);
|
||||||
|
} else {
|
||||||
|
// Copy the supertype
|
||||||
|
char super[B_PATH_NAME_LENGTH+1];
|
||||||
|
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)
|
||||||
|
err = AddSubtype(super, sub);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*types = *fCachedInstalledTypesMessage;
|
} else {
|
||||||
|
err = B_OK;
|
||||||
}
|
}
|
||||||
DBG(OUT("MimeDatabaseBackend::GetInstalledTypes(1) done\n"));
|
return err;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveType
|
||||||
|
/*! \brief Removes the given type from the appropriate installed types lists.
|
||||||
|
|
||||||
|
Any corresponding cached messages are invalidated.
|
||||||
|
*/
|
||||||
status_t
|
status_t
|
||||||
MimeDatabaseBackend::GetInstalledTypes(const char *supertype, BMessage *types)
|
InstalledTypes::RemoveType(const char *type)
|
||||||
{
|
{
|
||||||
DBG(OUT("MimeDatabaseBackend::GetInstalledTypes(2)\n"));
|
status_t err;
|
||||||
status_t err = supertype && types && BMimeType::IsValid(supertype) ? B_OK : B_BAD_VALUE;
|
if (fHaveDoneFullBuild) {
|
||||||
|
BMimeType mime(type);
|
||||||
// Types are not case sensitive, so we always use lowercase
|
BMimeType super;
|
||||||
char lowertype[B_PATH_NAME_LENGTH+1];
|
err = type ? mime.InitCheck() : B_BAD_VALUE;
|
||||||
BPrivate::Storage::to_lower(supertype, lowertype);
|
if (!err) {
|
||||||
installed_subtypes_info *info;
|
// Find the / in the string, if one exists
|
||||||
|
uint i;
|
||||||
// See if we need to build the main list
|
size_t len = strlen(type);
|
||||||
if (!err && fSupertypesMap.empty())
|
for (i = 0; i < len; i++) {
|
||||||
err = BuildInstalledTypesList();
|
if (type[i] == '/')
|
||||||
// See if the supertype even exists
|
break;
|
||||||
if (!err) {
|
}
|
||||||
std::map<std::string, installed_subtypes_info>::iterator i = fSupertypesMap.find(supertype);
|
if (i == len) {
|
||||||
err = i != fSupertypesMap.end() ? B_OK : B_BAD_VALUE;
|
// Supertype only
|
||||||
if (!err)
|
err = RemoveSupertype(type);
|
||||||
info = &(i->second);
|
} else {
|
||||||
}
|
// Copy the supertype
|
||||||
// Make sure there's a cached message waiting for us
|
char super[B_PATH_NAME_LENGTH+1];
|
||||||
if (!err && !info->cached_message)
|
strncpy(super, type, i);
|
||||||
err = BuildInstalledTypesMessage(info->subtypes, &(info->cached_message));
|
super[i] = 0;
|
||||||
// Copy the message into the result
|
|
||||||
if (!err)
|
// Get a pointer to the subtype
|
||||||
*types = *info->cached_message;
|
const char *sub = &(type[i+1]);
|
||||||
DBG(OUT("MimeDatabaseBackend::GetInstalledTypes(2) done\n"));
|
|
||||||
return err;
|
// Remove the subtype
|
||||||
}
|
err = RemoveSubtype(super, sub);
|
||||||
|
}
|
||||||
status_t
|
}
|
||||||
MimeDatabaseBackend::GetInstalledSupertypes(BMessage *types)
|
|
||||||
{
|
|
||||||
DBG(OUT("MimeDatabaseBackend::GetInstalledSupertypes()\n"));
|
|
||||||
status_t err = types ? B_OK : B_BAD_VALUE;
|
|
||||||
|
|
||||||
// See if we need to build the main list
|
|
||||||
if (!err && fSupertypesMap.empty())
|
|
||||||
err = BuildInstalledTypesList();
|
|
||||||
// Make sure there's a cached message waiting for us
|
|
||||||
if (!err && !fCachedInstalledSupertypesMessage)
|
|
||||||
err = BuildInstalledSupertypesMessage(fSupertypesMap, &fCachedInstalledSupertypesMessage);
|
|
||||||
// Copy the message into the result
|
|
||||||
if (!err)
|
|
||||||
*types = *fCachedInstalledSupertypesMessage;
|
|
||||||
DBG(OUT("MimeDatabaseBackend::GetInstalledSupertypes() done\n"));
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t
|
|
||||||
MimeDatabaseBackend::GetSupportingApps(const char *type, BMessage *signatures)
|
|
||||||
{
|
|
||||||
return B_ERROR; // not implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MimeDatabaseBackend::InstallType(const char *type)
|
|
||||||
{
|
|
||||||
DBG(OUT("MimeDatabaseBackend::InstallType()\n"));
|
|
||||||
if (fInstalledTypes.empty())
|
|
||||||
return;
|
|
||||||
// Remove any cached messages
|
|
||||||
if (fCachedInstalledTypesMessage) {
|
|
||||||
delete fCachedInstalledTypesMessage;
|
|
||||||
fCachedInstalledTypesMessage = NULL;
|
|
||||||
}
|
|
||||||
if (fCachedInstalledSupertypesMessage) {
|
|
||||||
delete fCachedInstalledSupertypesMessage;
|
|
||||||
fCachedInstalledSupertypesMessage = NULL;
|
|
||||||
}
|
|
||||||
char lowertype[B_PATH_NAME_LENGTH+1];
|
|
||||||
char supertype[B_PATH_NAME_LENGTH+1];
|
|
||||||
Storage::to_lower(type, lowertype);
|
|
||||||
fInstalledTypes.insert(lowertype);
|
|
||||||
BMimeType mime(lowertype);
|
|
||||||
BMimeType super;
|
|
||||||
status_t err = mime.InitCheck();
|
|
||||||
if (!err)
|
|
||||||
err = mime.GetSupertype(&super);
|
|
||||||
if (!err) {
|
|
||||||
Storage::to_lower(super.Type(), supertype);
|
|
||||||
installed_subtypes_info &info = fSupertypesMap[supertype];
|
|
||||||
delete info.cached_message;
|
|
||||||
info.cached_message = NULL;
|
|
||||||
info.subtypes.insert(lowertype);
|
|
||||||
}
|
|
||||||
DBG(OUT("MimeDatabaseBackend::InstallType() done\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
MimeDatabaseBackend::DeleteType(const char *type)
|
|
||||||
{
|
|
||||||
if (fInstalledTypes.empty())
|
|
||||||
return;
|
|
||||||
printf("fuCK\n");
|
|
||||||
// Remove any cached messages
|
|
||||||
if (fCachedInstalledTypesMessage) {
|
|
||||||
delete fCachedInstalledTypesMessage;
|
|
||||||
fCachedInstalledTypesMessage = NULL;
|
|
||||||
}
|
|
||||||
printf("fuCK\n");
|
|
||||||
if (fCachedInstalledSupertypesMessage) {
|
|
||||||
delete fCachedInstalledSupertypesMessage;
|
|
||||||
fCachedInstalledSupertypesMessage = NULL;
|
|
||||||
}
|
|
||||||
printf("fuCK\n");
|
|
||||||
char lowertype[B_PATH_NAME_LENGTH+1];
|
|
||||||
char supertype[B_PATH_NAME_LENGTH+1];
|
|
||||||
printf("fuCK\n");
|
|
||||||
Storage::to_lower(type, lowertype);
|
|
||||||
fInstalledTypes.erase(lowertype);
|
|
||||||
printf("fuCK\n");
|
|
||||||
BMimeType mime(lowertype);
|
|
||||||
BMimeType super;
|
|
||||||
printf("fuCK\n");
|
|
||||||
status_t err = mime.InitCheck();
|
|
||||||
printf("fuCK\n");
|
|
||||||
if (!err)
|
|
||||||
err = mime.GetSupertype(&super);
|
|
||||||
printf("fuCK\n");
|
|
||||||
if (!err) {
|
|
||||||
Storage::to_lower(super.Type(), supertype);
|
|
||||||
installed_subtypes_info &info = fSupertypesMap[supertype];
|
|
||||||
printf("fuCK\n");
|
|
||||||
delete info.cached_message;
|
|
||||||
printf("fuCK\n");
|
|
||||||
info.cached_message = NULL;
|
|
||||||
printf("fuCK\n");
|
|
||||||
info.subtypes.erase(lowertype);
|
|
||||||
}
|
|
||||||
printf("fuCK\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildInstalledTypesList()
|
|
||||||
//! Builds an initial installed types list and (optionally) an installed types BMessage
|
|
||||||
status_t
|
|
||||||
MimeDatabaseBackend::BuildInstalledTypesList(BMessage **types)
|
|
||||||
{
|
|
||||||
BMessage *msg;
|
|
||||||
if (types) {
|
|
||||||
*types = new BMessage;
|
|
||||||
msg = *types;
|
|
||||||
} else
|
} else
|
||||||
msg = NULL;
|
err = B_OK;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSupertype
|
||||||
|
/*! \brief Adds the given supertype to the supertype map.
|
||||||
|
\return
|
||||||
|
- B_OK: success, even if the supertype already existed in the map
|
||||||
|
- "error code": failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::AddSupertype(const char *super, std::map<std::string, Supertype>::iterator &i)
|
||||||
|
{
|
||||||
|
status_t err = super ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err) {
|
||||||
|
i = fSupertypes.find(super);
|
||||||
|
if (i == fSupertypes.end()) {
|
||||||
|
Supertype &supertype = fSupertypes[super];
|
||||||
|
supertype.SetName(super);
|
||||||
|
if (fCachedMessage)
|
||||||
|
err = fCachedMessage->AddString(kTypesField, super);
|
||||||
|
if (!err && fCachedSupertypesMessage)
|
||||||
|
err = fCachedSupertypesMessage->AddString(kSupertypesField, super);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSubtype
|
||||||
|
/*! \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
|
||||||
|
- B_OK: success
|
||||||
|
- B_NAME_IN_USE: The subtype already exists in the subtype list
|
||||||
|
- "error code": failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::AddSubtype(const char *super, const char *sub)
|
||||||
|
{
|
||||||
|
status_t err = super && sub ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err) {
|
||||||
|
std::map<std::string, Supertype>::iterator i;
|
||||||
|
err = AddSupertype(super, i);
|
||||||
|
if (!err)
|
||||||
|
err = AddSubtype(i->second, sub);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSubtype
|
||||||
|
/*! \brief Adds the given subtype to the given supertype's lists of installed types.
|
||||||
|
|
||||||
|
\param super The supertype object
|
||||||
|
\param sub The subtype (subtype only; no "supertype/subtype" types please)
|
||||||
|
\return
|
||||||
|
- B_OK: success
|
||||||
|
- B_NAME_IN_USE: The subtype already exists in the subtype list
|
||||||
|
- "error code": failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::AddSubtype(Supertype &super, const char *sub)
|
||||||
|
{
|
||||||
|
status_t err = sub ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err)
|
||||||
|
err = super.AddSubtype(sub);
|
||||||
|
if (!err && fCachedMessage) {
|
||||||
|
char type[B_PATH_NAME_LENGTH+1];
|
||||||
|
sprintf(type, "%s/%s", super.GetName(), sub);
|
||||||
|
err = fCachedMessage->AddString("types", type);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSupertype
|
||||||
|
/*! \brief Removes the given supertype and any corresponding subtypes.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::RemoveSupertype(const char *super)
|
||||||
|
{
|
||||||
|
status_t err = super ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err)
|
||||||
|
err = fSupertypes.erase(super) == 1 ? B_OK : B_NAME_NOT_FOUND;
|
||||||
|
if (!err)
|
||||||
|
ClearCachedMessages();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSubtype
|
||||||
|
/*! \brief Removes the given subtype from the given supertype.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::RemoveSubtype(const char *super, const char *sub)
|
||||||
|
{
|
||||||
|
status_t err = super && sub ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err) {
|
||||||
|
std::map<std::string, Supertype>::iterator i = fSupertypes.find(super);
|
||||||
|
if (i != fSupertypes.end()) {
|
||||||
|
err = i->second.RemoveSubtype(sub);
|
||||||
|
if (!err)
|
||||||
|
ClearCachedMessages();
|
||||||
|
} else
|
||||||
|
err = B_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unset
|
||||||
|
// Clears any cached messages and empties the supertype map
|
||||||
|
void
|
||||||
|
InstalledTypes::Unset()
|
||||||
|
{
|
||||||
|
ClearCachedMessages();
|
||||||
|
fSupertypes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearCachedMessages
|
||||||
|
//! Frees any cached messages and sets their pointers to NULL
|
||||||
|
void
|
||||||
|
InstalledTypes::ClearCachedMessages()
|
||||||
|
{
|
||||||
|
delete fCachedSupertypesMessage;
|
||||||
|
delete fCachedMessage;
|
||||||
|
fCachedSupertypesMessage = NULL;
|
||||||
|
fCachedMessage = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildInstalledTypesList
|
||||||
|
/*! \brief Reads through the database and builds a complete set of installed types lists.
|
||||||
|
|
||||||
|
An initial set of cached messages are also created.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::BuildInstalledTypesList()
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
Unset();
|
||||||
|
|
||||||
|
// Create empty "cached messages" so proper messages
|
||||||
|
// will be built up as we add new types
|
||||||
|
try {
|
||||||
|
fCachedMessage = new BMessage();
|
||||||
|
fCachedSupertypesMessage = new BMessage();
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
err = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
BDirectory root;
|
BDirectory root;
|
||||||
status_t err = root.SetTo(MimeDatabase::kDatabaseDir.c_str());
|
if (!err)
|
||||||
|
err = root.SetTo(kDatabaseDir.c_str());
|
||||||
if (!err) {
|
if (!err) {
|
||||||
root.Rewind();
|
root.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -223,12 +391,12 @@ MimeDatabaseBackend::BuildInstalledTypesList(BMessage **types)
|
|||||||
// 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
|
||||||
fInstalledTypes.insert(supertype);
|
std::map<std::string, Supertype>::iterator i;
|
||||||
fSupertypesMap[supertype] = installed_subtypes_info();
|
if (AddSupertype(supertype, i) != B_OK)
|
||||||
installed_subtypes_info &info = fSupertypesMap[supertype];
|
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding supertype '%s': 0x%lx\n",
|
||||||
if (msg)
|
supertype, err));
|
||||||
msg->AddString("types", 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
|
||||||
@@ -246,167 +414,90 @@ MimeDatabaseBackend::BuildInstalledTypesList(BMessage **types)
|
|||||||
} else {
|
} else {
|
||||||
// Get the subtype's name
|
// Get the subtype's name
|
||||||
char subtype[B_PATH_NAME_LENGTH+1];
|
char subtype[B_PATH_NAME_LENGTH+1];
|
||||||
char mimetype[B_PATH_NAME_LENGTH+1];
|
|
||||||
if (subEntry.GetName(subtype) == B_OK) {
|
if (subEntry.GetName(subtype) == B_OK) {
|
||||||
BPrivate::Storage::to_lower(subtype);
|
BPrivate::Storage::to_lower(subtype);
|
||||||
sprintf(mimetype, "%s/%s", supertype, subtype);
|
|
||||||
|
|
||||||
// Add the subtype
|
// Add the subtype
|
||||||
if (BMimeType::IsValid(mimetype)) {
|
if (AddSubtype(supertypeRef, subtype) != B_OK) {
|
||||||
fInstalledTypes.insert(mimetype);
|
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList() -- Error adding subtype '%s/%s': 0x%lx\n",
|
||||||
info.subtypes.insert(mimetype);
|
supertype, subtype, err));
|
||||||
if (msg)
|
}
|
||||||
msg->AddString("types", mimetype);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DBG(OUT("MimeDatabaseBackend::BuildInstalledTypesList(): "
|
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList(): "
|
||||||
"Failed opening supertype directory '%s'\n",
|
"Failed opening supertype directory '%s'\n",
|
||||||
supertype));
|
supertype));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DBG(OUT("MimeDatabaseBackend::BuildInstalledTypesList(): "
|
DBG(OUT("Mime::InstalledTypes::BuildInstalledTypesList(): "
|
||||||
"Failed opening mime database directory '%s'\n",
|
"Failed opening mime database directory '%s'\n",
|
||||||
MimeDatabase::kDatabaseDir.c_str()));
|
kDatabaseDir.c_str()));
|
||||||
}
|
}
|
||||||
|
fHaveDoneFullBuild = true;
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateMessageWithTypes
|
||||||
|
/*! \brief Allocates a new BMessage into the BMessage pointer pointed to by \c result
|
||||||
|
and fills it with a complete list of installed types.
|
||||||
|
*/
|
||||||
status_t
|
status_t
|
||||||
MimeDatabaseBackend::BuildInstalledTypesMessage(BMessage **result)
|
InstalledTypes::CreateMessageWithTypes(BMessage **result) const
|
||||||
{
|
{
|
||||||
status_t err = result ? B_OK : B_BAD_VALUE;
|
status_t err = result ? B_OK : B_BAD_VALUE;
|
||||||
// Alloc the message
|
// Alloc the message
|
||||||
if (!err) {
|
if (!err) {
|
||||||
*result = new BMessage;
|
try {
|
||||||
if (!(*result))
|
*result = new BMessage();
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
err = B_NO_MEMORY;
|
err = B_NO_MEMORY;
|
||||||
}
|
|
||||||
// Fill with types
|
|
||||||
if (!err) {
|
|
||||||
BMessage &msg = **result;
|
|
||||||
std::set<std::string>::const_iterator i;
|
|
||||||
for (i = fInstalledTypes.begin(); i != fInstalledTypes.end(); i++)
|
|
||||||
msg.AddString("types", (*i).c_str());
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t
|
|
||||||
MimeDatabaseBackend::BuildInstalledTypesMessage(const std::set<std::string> &set, BMessage **result)
|
|
||||||
{
|
|
||||||
status_t err = result ? B_OK : B_BAD_VALUE;
|
|
||||||
// Alloc the message
|
|
||||||
if (!err) {
|
|
||||||
*result = new BMessage;
|
|
||||||
if (!(*result))
|
|
||||||
err = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// Fill with types
|
|
||||||
if (!err) {
|
|
||||||
BMessage &msg = **result;
|
|
||||||
std::set<std::string>::const_iterator i;
|
|
||||||
for (i = set.begin(); i != set.end(); i++)
|
|
||||||
msg.AddString("types", (*i).c_str());
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t
|
|
||||||
MimeDatabaseBackend::BuildInstalledSupertypesMessage(const std::map<std::string, installed_subtypes_info> &map, BMessage **result)
|
|
||||||
{
|
|
||||||
status_t err = result ? B_OK : B_BAD_VALUE;
|
|
||||||
// Alloc the message
|
|
||||||
if (!err) {
|
|
||||||
*result = new BMessage;
|
|
||||||
if (!(*result))
|
|
||||||
err = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// Fill with types
|
|
||||||
if (!err) {
|
|
||||||
BMessage &msg = **result;
|
|
||||||
std::map<std::string, installed_subtypes_info>::const_iterator i;
|
|
||||||
for (i = map.begin(); i != map.end(); i++)
|
|
||||||
msg.AddString("super_types", (i->first).c_str());
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
MimeDatabaseBackend::BuildInstalledTypesList(const char *supertype, BMessage **types)
|
|
||||||
{
|
|
||||||
return B_ERROR;
|
|
||||||
// I'm not going to work on this function anymore until we
|
|
||||||
// get to optimization, as BuildInstalledTypesList(Bmessage**)
|
|
||||||
// handles this already (just not as efficiently if we only
|
|
||||||
// want to build the types for a single supertype). I have
|
|
||||||
// no idea if this function works, as I've never tried it.
|
|
||||||
|
|
||||||
BMessage *msg;
|
|
||||||
if (types) {
|
|
||||||
*types = new BMessage;
|
|
||||||
msg = *types;
|
|
||||||
} else
|
|
||||||
msg = NULL;
|
|
||||||
|
|
||||||
status_t err = supertype && BMimeType::IsValid(supertype) ? B_OK : B_BAD_VALUE;
|
|
||||||
|
|
||||||
// Check that this entry is both a directory and a valid MIME string
|
|
||||||
if (!err)
|
|
||||||
{
|
|
||||||
// Make sure our string is all lowercase
|
|
||||||
BPrivate::Storage::to_lower(supertype);
|
|
||||||
|
|
||||||
// Clear any previous subtype info struct
|
|
||||||
fSupertypesMap[supertype] = installed_subtypes_info();
|
|
||||||
installed_subtypes_info &info = fSupertypesMap[supertype];
|
|
||||||
|
|
||||||
// Iterate through the supertype directory and add
|
|
||||||
// all of its subtypes
|
|
||||||
BDirectory super;
|
|
||||||
if (super.SetTo((MimeDatabase::kDatabaseDir + supertype).c_str()) == B_OK) {
|
|
||||||
super.Rewind();
|
|
||||||
while (true) {
|
|
||||||
BEntry entry;
|
|
||||||
err = super.GetNextEntry(&entry);
|
|
||||||
if (err) {
|
|
||||||
// If we've come to the end of list, it's not an error
|
|
||||||
if (err == B_ENTRY_NOT_FOUND)
|
|
||||||
err = B_OK;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// Get the subtype's name
|
|
||||||
char subtype[B_PATH_NAME_LENGTH+1];
|
|
||||||
char mimetype[B_PATH_NAME_LENGTH+1];
|
|
||||||
if (entry.GetName(subtype) == B_OK) {
|
|
||||||
BPrivate::Storage::to_lower(subtype);
|
|
||||||
sprintf(mimetype, "%s/%s", supertype, subtype);
|
|
||||||
|
|
||||||
// Add the subtype
|
|
||||||
if (BMimeType::IsValid(mimetype)) {
|
|
||||||
fInstalledTypes.insert(mimetype);
|
|
||||||
info.subtypes.insert(mimetype);
|
|
||||||
if (msg)
|
|
||||||
msg->AddString("types", mimetype);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DBG(OUT("MimeDatabaseBackend::BuildInstalledTypesList(): "
|
|
||||||
"Failed opening supertype directory '%s'\n",
|
|
||||||
supertype));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Fill with types
|
||||||
|
if (!err) {
|
||||||
|
BMessage &msg = **result;
|
||||||
|
std::map<std::string, Supertype>::const_iterator i;
|
||||||
|
for (i = fSupertypes.begin(); i != fSupertypes.end() && !err; i++) {
|
||||||
|
err = msg.AddString(kTypesField, i->first.c_str());
|
||||||
|
if (!err)
|
||||||
|
err = i->second.FillMessageWithTypes(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
// CreateMessageWithSupertypes
|
||||||
|
/*! \brief Allocates a new BMessage into the BMessage pointer pointed to by \c result
|
||||||
|
and fills it with a complete list of installed supertypes.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
InstalledTypes::CreateMessageWithSupertypes(BMessage **result) const
|
||||||
|
{
|
||||||
|
status_t err = result ? B_OK : B_BAD_VALUE;
|
||||||
|
// Alloc the message
|
||||||
|
if (!err) {
|
||||||
|
try {
|
||||||
|
*result = new BMessage();
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
err = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fill with types
|
||||||
|
if (!err) {
|
||||||
|
BMessage &msg = **result;
|
||||||
|
std::map<std::string, Supertype>::const_iterator i;
|
||||||
|
for (i = fSupertypes.begin(); i != fSupertypes.end() && !err; i++) {
|
||||||
|
err = msg.AddString(kSupertypesField, i->first.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|||||||
@@ -1,12 +1,20 @@
|
|||||||
// mime/Supertype.cpp
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file Supertype.cpp
|
||||||
|
Supertype class implementation
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mime/Supertype.h"
|
#include "mime/Supertype.h"
|
||||||
|
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
|
#include <mime/database_support.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#define DBG(x) x
|
#define DBG(x) x
|
||||||
//#define DBG(x)
|
//#define DBG(x)
|
||||||
#define OUT printf
|
#define OUT printf
|
||||||
@@ -15,17 +23,145 @@ namespace BPrivate {
|
|||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class Supertype
|
||||||
|
\brief Installed types information for a single supertype
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
//! Constructs a new Supertype object
|
||||||
Supertype::Supertype(const char *super)
|
Supertype::Supertype(const char *super)
|
||||||
: fCachedMessage(NULL)
|
: fCachedMessage(NULL)
|
||||||
, fType(super)
|
, fName(super ? super : "")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
//! Destroys the Supertype object
|
||||||
Supertype::~Supertype()
|
Supertype::~Supertype()
|
||||||
{
|
{
|
||||||
delete fCachedMessage;
|
delete fCachedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetInstalledSubtypes
|
||||||
|
/*! \brief Returns a list of the installeds subtypes for this supertype
|
||||||
|
in the pre-allocated \c BMessage pointed to by \c types.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
Supertype::GetInstalledSubtypes(BMessage *types)
|
||||||
|
{
|
||||||
|
status_t err = types ? B_OK : B_BAD_VALUE;
|
||||||
|
// See if we need to fill up a new message
|
||||||
|
if (!err && !fCachedMessage) {
|
||||||
|
err = CreateMessageWithTypes(&fCachedMessage);
|
||||||
|
}
|
||||||
|
// If we get this far, there's a cached message waiting
|
||||||
|
if (!err) {
|
||||||
|
*types = *fCachedMessage;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSubtype
|
||||||
|
/*! \brief Adds the given subtype to the subtype list and the cached message,
|
||||||
|
if one exists.
|
||||||
|
\param sub The subtype to add (do not include the supertype)
|
||||||
|
\return
|
||||||
|
- B_OK: success
|
||||||
|
- B_NAME_IN_USE: The subtype already exists in the subtype list
|
||||||
|
- "error code": failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
Supertype::AddSubtype(const char *sub)
|
||||||
|
{
|
||||||
|
status_t err = sub ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err)
|
||||||
|
err = fSubtypes.insert(sub).second ? B_OK : B_NAME_IN_USE;
|
||||||
|
if (!err && fCachedMessage) {
|
||||||
|
char type[B_PATH_NAME_LENGTH+1];
|
||||||
|
sprintf(type, "%s/%s", fName.c_str(), sub);
|
||||||
|
err = fCachedMessage->AddString("types", type);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveSubtype
|
||||||
|
/*! \brief Removes the given subtype from the subtype list and invalidates the
|
||||||
|
cached message, if one exists.
|
||||||
|
\param sub The subtype to remove (do not include the supertype)
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
Supertype::RemoveSubtype(const char *sub)
|
||||||
|
{
|
||||||
|
status_t err = sub ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err)
|
||||||
|
err = fSubtypes.erase(sub) == 1 ? B_OK : B_NAME_NOT_FOUND;
|
||||||
|
if (!err && fCachedMessage) {
|
||||||
|
delete fCachedMessage;
|
||||||
|
fCachedMessage = NULL;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName
|
||||||
|
//! Sets the supertype's name
|
||||||
|
void
|
||||||
|
Supertype::SetName(const char *super)
|
||||||
|
{
|
||||||
|
if (super)
|
||||||
|
fName = super;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName
|
||||||
|
//! Returns the supertype's name
|
||||||
|
const char*
|
||||||
|
Supertype::GetName()
|
||||||
|
{
|
||||||
|
return fName.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillMessageWithTypes
|
||||||
|
//! Adds the supertype's subtypes to the given message
|
||||||
|
/*! Each subtype is added as another item in the message's \c Mime::kTypesField
|
||||||
|
field. The complete type ("supertype/subtype") is added. The supertype itself
|
||||||
|
is not added to the message.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
Supertype::FillMessageWithTypes(BMessage &msg) const
|
||||||
|
{
|
||||||
|
status_t err = B_OK;
|
||||||
|
std::set<std::string>::const_iterator i;
|
||||||
|
for (i = fSubtypes.begin(); i != fSubtypes.end() && !err; i++) {
|
||||||
|
char type[B_PATH_NAME_LENGTH+1];
|
||||||
|
sprintf(type, "%s/%s", fName.c_str(), (*i).c_str());
|
||||||
|
err = msg.AddString(kTypesField, type);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateMessageWithTypes
|
||||||
|
/*! \brief Allocates a new BMessage into the BMessage pointer pointed to by \c result
|
||||||
|
and fills it with the supertype's subtypes.
|
||||||
|
|
||||||
|
See \c Supertype::FillMessageWithTypes() for more information.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
Supertype::CreateMessageWithTypes(BMessage **result) const
|
||||||
|
{
|
||||||
|
status_t err = result ? B_OK : B_BAD_VALUE;
|
||||||
|
// Alloc the message
|
||||||
|
if (!err) {
|
||||||
|
try {
|
||||||
|
*result = new BMessage();
|
||||||
|
} catch (std::bad_alloc) {
|
||||||
|
err = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fill with types
|
||||||
|
if (!err)
|
||||||
|
err = FillMessageWithTypes(**result);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// mime/Database.cpp
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file database_access.cpp
|
||||||
|
Mime database atomic read functions
|
||||||
|
*/
|
||||||
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
@@ -202,10 +209,9 @@ get_icon_for_type(const char *type, const char *fileType, BBitmap *icon,
|
|||||||
attr_info info;
|
attr_info info;
|
||||||
ssize_t err;
|
ssize_t err;
|
||||||
BNode node;
|
BNode node;
|
||||||
uint32 attrType;
|
uint32 attrType = 0;
|
||||||
size_t attrSize;
|
ssize_t attrSize = 0;
|
||||||
BRect bounds;
|
BRect bounds;
|
||||||
char *buffer;
|
|
||||||
|
|
||||||
err = type && icon ? B_OK : B_BAD_VALUE;
|
err = type && icon ? B_OK : B_BAD_VALUE;
|
||||||
|
|
||||||
@@ -249,7 +255,6 @@ get_icon_for_type(const char *type, const char *fileType, BBitmap *icon,
|
|||||||
if (!err) {
|
if (!err) {
|
||||||
bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
ssize_t read;
|
|
||||||
if (otherColorSpace) {
|
if (otherColorSpace) {
|
||||||
// other color space than stored in attribute
|
// other color space than stored in attribute
|
||||||
buffer = new(nothrow) char[attrSize];
|
buffer = new(nothrow) char[attrSize];
|
||||||
@@ -376,7 +381,7 @@ get_icon_data(const BBitmap *icon, icon_size which, void **data, int32 *dataSize
|
|||||||
// Set each pixel individually, since SetBits() for B_RGB32 takes
|
// Set each pixel individually, since SetBits() for B_RGB32 takes
|
||||||
// 24-bit rgb pixel data...
|
// 24-bit rgb pixel data...
|
||||||
char *bgra = (char*)icon->Bits();
|
char *bgra = (char*)icon->Bits();
|
||||||
for (uint32 i = 0; i*4+3 < icon->BitsLength(); bgra += 4, i++) {
|
for (int32 i = 0; i*4+3 < icon->BitsLength(); bgra += 4, i++) {
|
||||||
char rgb[3];
|
char rgb[3];
|
||||||
rgb[0] = bgra[2]; // red
|
rgb[0] = bgra[2]; // red
|
||||||
rgb[1] = bgra[1]; // green
|
rgb[1] = bgra[1]; // green
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
// database_support.cpp
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file database_support.cpp
|
||||||
|
Private mime database functions and constants
|
||||||
|
*/
|
||||||
|
|
||||||
#include <DataIO.h>
|
#include <DataIO.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
@@ -68,6 +75,9 @@ const int32 kPreferredAppType = 'MSIG';
|
|||||||
const int32 kSnifferRuleType = B_STRING_TYPE;
|
const int32 kSnifferRuleType = B_STRING_TYPE;
|
||||||
const int32 kSupportedTypesType = B_MESSAGE_TYPE;
|
const int32 kSupportedTypesType = B_MESSAGE_TYPE;
|
||||||
|
|
||||||
|
// Message fields
|
||||||
|
const char *kTypesField = "types";
|
||||||
|
const char *kSupertypesField = "super_types";
|
||||||
|
|
||||||
|
|
||||||
// type_to_filename
|
// type_to_filename
|
||||||
@@ -119,7 +129,7 @@ open_or_create_type(const char *type, BNode *result, bool *didCreate)
|
|||||||
// Figure out what type of node we need to create
|
// Figure out what type of node we need to create
|
||||||
// + Supertype == directory
|
// + Supertype == directory
|
||||||
// + Non-supertype == file
|
// + Non-supertype == file
|
||||||
int32 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(kDatabaseDir.c_str());
|
||||||
@@ -237,7 +247,7 @@ write_mime_attr(const char *type, const char *attr, const void *data,
|
|||||||
if (bytes < B_OK)
|
if (bytes < B_OK)
|
||||||
err = bytes;
|
err = bytes;
|
||||||
else
|
else
|
||||||
err = (bytes != len ? B_FILE_ERROR : B_OK);
|
err = (bytes != (ssize_t)len ? B_FILE_ERROR : B_OK);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -270,7 +280,7 @@ write_mime_attr_message(const char *type, const char *attr, const BMessage *msg,
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = node.WriteAttr(attr, B_MESSAGE_TYPE, 0, data.Buffer(), data.BufferLength());
|
err = node.WriteAttr(attr, B_MESSAGE_TYPE, 0, data.Buffer(), data.BufferLength());
|
||||||
if (err >= 0)
|
if (err >= 0)
|
||||||
err = err == data.BufferLength() ? B_OK : B_FILE_ERROR;
|
err = err == (ssize_t)data.BufferLength() ? B_OK : B_FILE_ERROR;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user