Refactor MIME DB access
* Add class DatabaseLocation. It contains a list of the MIME DB
directory paths plus methods to access type files.
* Move all low-level MIME DB access functions from
database_{support,access} to DatabaseLocation. All code that formerly
used those now requires a DatabaseLocation object. In BMimeType and in
the registrar the default object is used, but the low-level classes
can now be reused with different locations.
* Move get_icon_data() from database_access to database_support and
delete the former, which is now empty.
This commit is contained in:
@@ -21,12 +21,15 @@ namespace BPrivate {
|
|||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation;
|
||||||
class MimeSniffer;
|
class MimeSniffer;
|
||||||
|
|
||||||
|
|
||||||
class AssociatedTypes {
|
class AssociatedTypes {
|
||||||
public:
|
public:
|
||||||
AssociatedTypes(MimeSniffer* mimeSniffer);
|
AssociatedTypes(DatabaseLocation* databaseLocation,
|
||||||
|
MimeSniffer* mimeSniffer);
|
||||||
~AssociatedTypes();
|
~AssociatedTypes();
|
||||||
|
|
||||||
status_t GetAssociatedTypes(const char *extension, BMessage *types);
|
status_t GetAssociatedTypes(const char *extension, BMessage *types);
|
||||||
@@ -50,8 +53,9 @@ private:
|
|||||||
std::map<std::string, std::set<std::string> > fAssociatedTypes; // file extension => set of associated mime types
|
std::map<std::string, std::set<std::string> > fAssociatedTypes; // file extension => set of associated mime types
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MimeSniffer* fMimeSniffer;
|
DatabaseLocation* fDatabaseLocation;
|
||||||
bool fHaveDoneFullBuild;
|
MimeSniffer* fMimeSniffer;
|
||||||
|
bool fHaveDoneFullBuild;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include <StorageDefs.h>
|
#include <StorageDefs.h>
|
||||||
|
|
||||||
#include <mime/AssociatedTypes.h>
|
#include <mime/AssociatedTypes.h>
|
||||||
#include <mime/database_access.h>
|
|
||||||
#include <mime/InstalledTypes.h>
|
#include <mime/InstalledTypes.h>
|
||||||
#include <mime/SnifferRules.h>
|
#include <mime/SnifferRules.h>
|
||||||
#include <mime/SupportingApps.h>
|
#include <mime/SupportingApps.h>
|
||||||
@@ -36,8 +35,11 @@ namespace BPrivate {
|
|||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation;
|
||||||
class MimeSniffer;
|
class MimeSniffer;
|
||||||
|
|
||||||
|
|
||||||
// types of mime update functions that may be run asynchronously
|
// types of mime update functions that may be run asynchronously
|
||||||
typedef enum {
|
typedef enum {
|
||||||
B_REG_UPDATE_MIME_INFO,
|
B_REG_UPDATE_MIME_INFO,
|
||||||
@@ -49,16 +51,18 @@ class Database {
|
|||||||
class NotificationListener;
|
class NotificationListener;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Database(MimeSniffer* mimeSniffer,
|
Database(DatabaseLocation* databaseLocation, MimeSniffer* mimeSniffer,
|
||||||
NotificationListener* notificationListener);
|
NotificationListener* notificationListener);
|
||||||
~Database();
|
~Database();
|
||||||
|
|
||||||
status_t InitCheck() const;
|
status_t InitCheck() const;
|
||||||
|
|
||||||
|
DatabaseLocation* Location() const { return fLocation; }
|
||||||
|
|
||||||
// Type management
|
// Type management
|
||||||
status_t Install(const char *type);
|
status_t Install(const char *type);
|
||||||
status_t Delete(const char *type);
|
status_t Delete(const char *type);
|
||||||
|
|
||||||
// Set()
|
// Set()
|
||||||
status_t SetAppHint(const char *type, const entry_ref *ref);
|
status_t SetAppHint(const char *type, const entry_ref *ref);
|
||||||
status_t SetAttrInfo(const char *type, const BMessage *info);
|
status_t SetAttrInfo(const char *type, const BMessage *info);
|
||||||
@@ -142,6 +146,7 @@ class Database {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
status_t fStatus;
|
status_t fStatus;
|
||||||
|
DatabaseLocation* fLocation;
|
||||||
NotificationListener* fNotificationListener;
|
NotificationListener* fNotificationListener;
|
||||||
std::set<BMessenger> fMonitorMessengers;
|
std::set<BMessenger> fMonitorMessengers;
|
||||||
AssociatedTypes fAssociatedTypes;
|
AssociatedTypes fAssociatedTypes;
|
||||||
|
|||||||
@@ -17,12 +17,16 @@ namespace Storage {
|
|||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation;
|
||||||
|
|
||||||
|
|
||||||
class DatabaseDirectory : public BMergedDirectory {
|
class DatabaseDirectory : public BMergedDirectory {
|
||||||
public:
|
public:
|
||||||
DatabaseDirectory();
|
DatabaseDirectory();
|
||||||
virtual ~DatabaseDirectory();
|
virtual ~DatabaseDirectory();
|
||||||
|
|
||||||
status_t Init(const char* superType = NULL);
|
status_t Init(DatabaseLocation* databaseLocation,
|
||||||
|
const char* superType = NULL);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool ShallPreferFirstEntry(const entry_ref& entry1,
|
virtual bool ShallPreferFirstEntry(const entry_ref& entry1,
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Ingo Weinhold <[email protected]>
|
||||||
|
*/
|
||||||
|
#ifndef _MIME_DATABASE_LOCATION_H
|
||||||
|
#define _MIME_DATABASE_LOCATION_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Mime.h>
|
||||||
|
#include <StringList.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
namespace Storage {
|
||||||
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation {
|
||||||
|
public:
|
||||||
|
DatabaseLocation();
|
||||||
|
~DatabaseLocation();
|
||||||
|
|
||||||
|
bool AddDirectory(const BString& directory);
|
||||||
|
|
||||||
|
// paths
|
||||||
|
|
||||||
|
const BStringList& Directories() const
|
||||||
|
{ return fDirectories; }
|
||||||
|
BString WritableDirectory() const
|
||||||
|
{ return fDirectories.StringAt(0); }
|
||||||
|
|
||||||
|
BString WritablePathForType(const char* type) const
|
||||||
|
{ return _TypeToFilename(type, 0); }
|
||||||
|
|
||||||
|
// opening type nodes
|
||||||
|
|
||||||
|
status_t OpenType(const char* type, BNode& _node) const;
|
||||||
|
status_t OpenOrCreateType(const char* type,
|
||||||
|
BNode& _node, bool* _didCreate = NULL)
|
||||||
|
const;
|
||||||
|
|
||||||
|
// generic type attributes access
|
||||||
|
|
||||||
|
ssize_t ReadAttribute(const char* type,
|
||||||
|
const char* attribute, void* data,
|
||||||
|
size_t length, type_code datatype) const;
|
||||||
|
status_t ReadMessageAttribute(const char* type,
|
||||||
|
const char* attribute, BMessage& _message)
|
||||||
|
const;
|
||||||
|
status_t ReadStringAttribute(const char* type,
|
||||||
|
const char* attribute, BString& _string)
|
||||||
|
const;
|
||||||
|
|
||||||
|
status_t WriteAttribute(const char* type,
|
||||||
|
const char* attribute, const void* data,
|
||||||
|
size_t length, type_code datatype,
|
||||||
|
bool* _didCreate) const;
|
||||||
|
status_t WriteMessageAttribute(const char* type,
|
||||||
|
const char* attribute,
|
||||||
|
const BMessage& message, bool* _didCreate)
|
||||||
|
const;
|
||||||
|
|
||||||
|
status_t DeleteAttribute(const char* type,
|
||||||
|
const char* attribute) const;
|
||||||
|
|
||||||
|
// type attribute convenience getters
|
||||||
|
|
||||||
|
status_t GetAppHint(const char* type, entry_ref& _ref);
|
||||||
|
status_t GetAttributesInfo(const char* type,
|
||||||
|
BMessage& _info);
|
||||||
|
status_t GetShortDescription(const char* type,
|
||||||
|
char* description);
|
||||||
|
status_t GetLongDescription(const char* type,
|
||||||
|
char* description);
|
||||||
|
status_t GetFileExtensions(const char* type,
|
||||||
|
BMessage& _extensions);
|
||||||
|
status_t GetIcon(const char* type, BBitmap& _icon,
|
||||||
|
icon_size size);
|
||||||
|
status_t GetIcon(const char* type, uint8*& _data,
|
||||||
|
size_t& _size);
|
||||||
|
status_t GetIconForType(const char* type,
|
||||||
|
const char* fileType, BBitmap& _icon,
|
||||||
|
icon_size which);
|
||||||
|
status_t GetIconForType(const char* type,
|
||||||
|
const char* fileType, uint8*& _data,
|
||||||
|
size_t& _size);
|
||||||
|
status_t GetPreferredApp(const char* type,
|
||||||
|
char* signature, app_verb verb);
|
||||||
|
status_t GetSnifferRule(const char* type,
|
||||||
|
BString& _result);
|
||||||
|
status_t GetSupportedTypes(const char* type,
|
||||||
|
BMessage& _types);
|
||||||
|
|
||||||
|
bool IsInstalled(const char* type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BString _TypeToFilename(const char* type, int32 index)
|
||||||
|
const;
|
||||||
|
status_t _OpenType(const char* type, BNode& _node,
|
||||||
|
int32& _index) const;
|
||||||
|
status_t _CreateTypeNode(const char* type, BNode& _node)
|
||||||
|
const;
|
||||||
|
status_t _CopyTypeNode(BNode& source, const char* type,
|
||||||
|
BNode& _target) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BStringList fDirectories;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Mime
|
||||||
|
} // namespace Storage
|
||||||
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _MIME_DATABASE_LOCATION_H
|
||||||
@@ -25,9 +25,13 @@ namespace BPrivate {
|
|||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation;
|
||||||
|
|
||||||
|
|
||||||
class InstalledTypes {
|
class InstalledTypes {
|
||||||
public:
|
public:
|
||||||
InstalledTypes();
|
InstalledTypes(DatabaseLocation* databaseLocation);
|
||||||
~InstalledTypes();
|
~InstalledTypes();
|
||||||
|
|
||||||
status_t GetInstalledTypes(BMessage *types);
|
status_t GetInstalledTypes(BMessage *types);
|
||||||
@@ -55,6 +59,8 @@ class InstalledTypes {
|
|||||||
|
|
||||||
status_t _BuildInstalledTypesList();
|
status_t _BuildInstalledTypesList();
|
||||||
|
|
||||||
|
private:
|
||||||
|
DatabaseLocation* fDatabaseLocation;
|
||||||
std::map<std::string, Supertype> fSupertypes;
|
std::map<std::string, Supertype> fSupertypes;
|
||||||
BMessage *fCachedMessage;
|
BMessage *fCachedMessage;
|
||||||
BMessage *fCachedSupertypesMessage;
|
BMessage *fCachedSupertypesMessage;
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ namespace Sniffer {
|
|||||||
|
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation;
|
||||||
class MimeSniffer;
|
class MimeSniffer;
|
||||||
|
|
||||||
|
|
||||||
class SnifferRules {
|
class SnifferRules {
|
||||||
public:
|
public:
|
||||||
SnifferRules(MimeSniffer* mimeSniffer);
|
SnifferRules(DatabaseLocation* databaseLocation, MimeSniffer* mimeSniffer);
|
||||||
~SnifferRules();
|
~SnifferRules();
|
||||||
|
|
||||||
status_t GuessMimeType(const entry_ref *ref, BString *type);
|
status_t GuessMimeType(const entry_ref *ref, BString *type);
|
||||||
@@ -59,9 +61,10 @@ private:
|
|||||||
std::list<sniffer_rule> fRuleList;
|
std::list<sniffer_rule> fRuleList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MimeSniffer* fMimeSniffer;
|
DatabaseLocation* fDatabaseLocation;
|
||||||
ssize_t fMaxBytesNeeded;
|
MimeSniffer* fMimeSniffer;
|
||||||
bool fHaveDoneFullBuild;
|
ssize_t fMaxBytesNeeded;
|
||||||
|
bool fHaveDoneFullBuild;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
|
|||||||
@@ -22,11 +22,15 @@ namespace BPrivate {
|
|||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
class DatabaseLocation;
|
||||||
|
|
||||||
|
|
||||||
class SupportingApps {
|
class SupportingApps {
|
||||||
public:
|
public:
|
||||||
SupportingApps();
|
SupportingApps(DatabaseLocation* databaseLocation);
|
||||||
~SupportingApps();
|
~SupportingApps();
|
||||||
|
|
||||||
status_t GetSupportingApps(const char *type, BMessage *apps);
|
status_t GetSupportingApps(const char *type, BMessage *apps);
|
||||||
|
|
||||||
status_t SetSupportedTypes(const char *app, const BMessage *types, bool fullSync);
|
status_t SetSupportedTypes(const char *app, const BMessage *types, bool fullSync);
|
||||||
@@ -41,6 +45,9 @@ private:
|
|||||||
std::map<std::string, std::set<std::string> > fSupportingApps; // mime type => set of supporting apps
|
std::map<std::string, std::set<std::string> > fSupportingApps; // mime type => set of supporting apps
|
||||||
std::map<std::string, std::set<std::string> > fStrandedTypes; // app sig => set of no longer supported types for whom the
|
std::map<std::string, std::set<std::string> > fStrandedTypes; // app sig => set of no longer supported types for whom the
|
||||||
// given app is still listed as a supporting app
|
// given app is still listed as a supporting app
|
||||||
|
|
||||||
|
private:
|
||||||
|
DatabaseLocation* fDatabaseLocation;
|
||||||
bool fHaveDoneFullBuild;
|
bool fHaveDoneFullBuild;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
/*!
|
|
||||||
\file database_access.h
|
|
||||||
Mime database atomic read functions and miscellany declarations
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _MIME_DATABASE_ACCESS_H
|
|
||||||
#define _MIME_DATABASE_ACCESS_H
|
|
||||||
|
|
||||||
#include <Mime.h>
|
|
||||||
|
|
||||||
class BNode;
|
|
||||||
class BBitmap;
|
|
||||||
class BMessage;
|
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
namespace Storage {
|
|
||||||
namespace Mime {
|
|
||||||
|
|
||||||
// Get() functions
|
|
||||||
status_t get_app_hint(const char *type, entry_ref *ref);
|
|
||||||
status_t get_attr_info(const char *type, BMessage *info);
|
|
||||||
status_t get_short_description(const char *type, char *description);
|
|
||||||
status_t get_long_description(const char *type, char *description);
|
|
||||||
status_t get_file_extensions(const char *type, BMessage *extensions);
|
|
||||||
status_t get_icon(const char *type, BBitmap *icon, icon_size size);
|
|
||||||
status_t get_icon(const char *type, uint8** data, size_t* size);
|
|
||||||
status_t get_icon_for_type(const char *type, const char *fileType,
|
|
||||||
BBitmap *icon, icon_size which);
|
|
||||||
status_t get_icon_for_type(const char *type, const char *fileType,
|
|
||||||
uint8** data, size_t* size);
|
|
||||||
status_t get_preferred_app(const char *type, char *signature, app_verb verb);
|
|
||||||
status_t get_sniffer_rule(const char *type, BString *result);
|
|
||||||
status_t get_supported_types(const char *type, BMessage *types);
|
|
||||||
|
|
||||||
bool is_installed(const char *type);
|
|
||||||
|
|
||||||
// Called by BMimeType to get properly formatted icon data ready
|
|
||||||
// to be shipped off to SetIcon*() and written to the database
|
|
||||||
status_t get_icon_data(const BBitmap *icon, icon_size size, void **data, int32 *dataSize);
|
|
||||||
|
|
||||||
} // namespace Mime
|
|
||||||
} // namespace Storage
|
|
||||||
} // namespace BPrivate
|
|
||||||
|
|
||||||
#endif // _MIME_DATABASE_H
|
|
||||||
@@ -1,27 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007, Haiku, Inc. All Rights Reserved.
|
* Copyright 2002-2013, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _MIME_DATABASE_SUPPORT_H
|
#ifndef _MIME_DATABASE_SUPPORT_H
|
||||||
#define _MIME_DATABASE_SUPPORT_H
|
#define _MIME_DATABASE_SUPPORT_H
|
||||||
|
|
||||||
|
|
||||||
#include <StorageDefs.h>
|
#include <Mime.h>
|
||||||
#include <String.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
class BNode;
|
class BBitmap;
|
||||||
class BMessage;
|
|
||||||
class BStringList;
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Mime {
|
namespace Mime {
|
||||||
|
|
||||||
// Database directory
|
|
||||||
const BStringList& get_database_directories();
|
class DatabaseLocation;
|
||||||
BString get_writable_database_directory();
|
|
||||||
|
|
||||||
// Attribute Prefixes
|
// Attribute Prefixes
|
||||||
extern const char *kMiniIconAttrPrefix;
|
extern const char *kMiniIconAttrPrefix;
|
||||||
@@ -75,24 +73,18 @@ extern const char *kMetaMimeType;
|
|||||||
// Error codes (to be used only by BPrivate::Storage::Mime members)
|
// Error codes (to be used only by BPrivate::Storage::Mime members)
|
||||||
extern const status_t kMimeGuessFailureError;
|
extern const status_t kMimeGuessFailureError;
|
||||||
|
|
||||||
BString type_to_writable_filename(const char *type);
|
|
||||||
|
|
||||||
status_t open_type(const char *type, BNode *result);
|
DatabaseLocation* default_database_location();
|
||||||
status_t open_or_create_type(const char *type, BNode *result, bool *didCreate);
|
|
||||||
|
|
||||||
ssize_t read_mime_attr(const char *type, const char *attr, void *data,
|
// Called by BMimeType to get properly formatted icon data ready
|
||||||
size_t len, type_code datatype);
|
// to be shipped off to SetIcon*() and written to the database
|
||||||
status_t read_mime_attr_message(const char *type, const char *attr, BMessage *msg);
|
status_t get_icon_data(const BBitmap *icon, icon_size size, void **data,
|
||||||
status_t read_mime_attr_string(const char *type, const char *attr, BString *str);
|
int32 *dataSize);
|
||||||
status_t write_mime_attr(const char *type, const char *attr, const void *data,
|
|
||||||
size_t len, type_code datatype, bool *didCreate);
|
|
||||||
status_t write_mime_attr_message(const char *type, const char *attr,
|
|
||||||
const BMessage *msg, bool *didCreate);
|
|
||||||
|
|
||||||
status_t delete_attribute(const char *type, const char *attr);
|
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
} // namespace BPrivate
|
} // namespace BPrivate
|
||||||
|
|
||||||
|
|
||||||
#endif // _MIME_DATABASE_SUPPORT_H
|
#endif // _MIME_DATABASE_SUPPORT_H
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
#include <IconUtils.h>
|
#include <IconUtils.h>
|
||||||
#include <Mime.h>
|
#include <Mime.h>
|
||||||
#include <MimeType.h>
|
#include <MimeType.h>
|
||||||
#include <mime/database_access.h>
|
|
||||||
#include <Node.h>
|
#include <Node.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <RegistrarDefs.h>
|
#include <RegistrarDefs.h>
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
#include "MimeType.h"
|
#include "MimeType.h"
|
||||||
|
|
||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <mime/database_access.h>
|
#include <mime/database_support.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
#include <sniffer/Rule.h>
|
#include <sniffer/Rule.h>
|
||||||
#include <sniffer/Parser.h>
|
#include <sniffer/Parser.h>
|
||||||
|
|
||||||
@@ -176,7 +177,8 @@ BMimeType::IsSupertypeOnly() const
|
|||||||
bool
|
bool
|
||||||
BMimeType::IsInstalled() const
|
BMimeType::IsInstalled() const
|
||||||
{
|
{
|
||||||
return InitCheck() == B_OK && is_installed(Type());
|
return InitCheck() == B_OK
|
||||||
|
&& default_database_location()->IsInstalled(Type());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -307,9 +309,12 @@ BMimeType::Delete()
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetIcon(BBitmap *icon, icon_size size) const
|
BMimeType::GetIcon(BBitmap *icon, icon_size size) const
|
||||||
{
|
{
|
||||||
|
if (icon == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err)
|
||||||
err = get_icon(Type(), icon, size);
|
err = default_database_location()->GetIcon(Type(), *icon, size);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -319,9 +324,12 @@ BMimeType::GetIcon(BBitmap *icon, icon_size size) const
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetIcon(uint8** data, size_t* size) const
|
BMimeType::GetIcon(uint8** data, size_t* size) const
|
||||||
{
|
{
|
||||||
|
if (data == NULL || size == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err)
|
||||||
err = get_icon(Type(), data, size);
|
err = default_database_location()->GetIcon(Type(), *data, *size);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -333,8 +341,10 @@ status_t
|
|||||||
BMimeType::GetPreferredApp(char *signature, app_verb verb) const
|
BMimeType::GetPreferredApp(char *signature, app_verb verb) const
|
||||||
{
|
{
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err) {
|
||||||
err = get_preferred_app(Type(), signature, verb);
|
err = default_database_location()->GetPreferredApp(Type(), signature,
|
||||||
|
verb);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -345,9 +355,12 @@ BMimeType::GetPreferredApp(char *signature, app_verb verb) const
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetAttrInfo(BMessage *info) const
|
BMimeType::GetAttrInfo(BMessage *info) const
|
||||||
{
|
{
|
||||||
|
if (info == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err)
|
||||||
err = get_attr_info(Type(), info);
|
err = default_database_location()->GetAttributesInfo(Type(), *info);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -358,9 +371,14 @@ BMimeType::GetAttrInfo(BMessage *info) const
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetFileExtensions(BMessage *extensions) const
|
BMimeType::GetFileExtensions(BMessage *extensions) const
|
||||||
{
|
{
|
||||||
|
if (extensions == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err) {
|
||||||
err = get_file_extensions(Type(), extensions);
|
err = default_database_location()->GetFileExtensions(Type(),
|
||||||
|
*extensions);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -371,8 +389,10 @@ status_t
|
|||||||
BMimeType::GetShortDescription(char *description) const
|
BMimeType::GetShortDescription(char *description) const
|
||||||
{
|
{
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err) {
|
||||||
err = get_short_description(Type(), description);
|
err = default_database_location()->GetShortDescription(Type(),
|
||||||
|
description);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -383,8 +403,10 @@ status_t
|
|||||||
BMimeType::GetLongDescription(char *description) const
|
BMimeType::GetLongDescription(char *description) const
|
||||||
{
|
{
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err) {
|
||||||
err = get_long_description(Type(), description);
|
err = default_database_location()->GetLongDescription(Type(),
|
||||||
|
description);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -703,9 +725,12 @@ BMimeType::IsValid(const char *string)
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetAppHint(entry_ref *ref) const
|
BMimeType::GetAppHint(entry_ref *ref) const
|
||||||
{
|
{
|
||||||
|
if (ref == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err)
|
||||||
err = get_app_hint(Type(), ref);
|
err = default_database_location()->GetAppHint(Type(), *ref);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,13 +770,18 @@ BMimeType::SetAppHint(const entry_ref *ref)
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetIconForType(const char *type, BBitmap *icon, icon_size which) const
|
BMimeType::GetIconForType(const char *type, BBitmap *icon, icon_size which) const
|
||||||
{
|
{
|
||||||
|
if (icon == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// If type is NULL, this function works just like GetIcon(), othewise,
|
// If type is NULL, this function works just like GetIcon(), othewise,
|
||||||
// we need to make sure the give type is valid.
|
// we need to make sure the give type is valid.
|
||||||
status_t err;
|
status_t err;
|
||||||
if (type) {
|
if (type) {
|
||||||
err = BMimeType::IsValid(type) ? B_OK : B_BAD_VALUE;
|
err = BMimeType::IsValid(type) ? B_OK : B_BAD_VALUE;
|
||||||
if (!err)
|
if (!err) {
|
||||||
err = get_icon_for_type(Type(), type, icon, which);
|
err = default_database_location()->GetIconForType(Type(), type,
|
||||||
|
*icon, which);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
err = GetIcon(icon, which);
|
err = GetIcon(icon, which);
|
||||||
|
|
||||||
@@ -764,6 +794,9 @@ BMimeType::GetIconForType(const char *type, BBitmap *icon, icon_size which) cons
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetIconForType(const char *type, uint8** _data, size_t* _size) const
|
BMimeType::GetIconForType(const char *type, uint8** _data, size_t* _size) const
|
||||||
{
|
{
|
||||||
|
if (_data == NULL || _size == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// If type is NULL, this function works just like GetIcon(), otherwise,
|
// If type is NULL, this function works just like GetIcon(), otherwise,
|
||||||
// we need to make sure the give type is valid.
|
// we need to make sure the give type is valid.
|
||||||
if (type == NULL)
|
if (type == NULL)
|
||||||
@@ -772,7 +805,8 @@ BMimeType::GetIconForType(const char *type, uint8** _data, size_t* _size) const
|
|||||||
if (!BMimeType::IsValid(type))
|
if (!BMimeType::IsValid(type))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return get_icon_for_type(Type(), type, _data, _size);
|
return default_database_location()->GetIconForType(Type(), type, *_data,
|
||||||
|
*_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -871,9 +905,12 @@ BMimeType::SetIconForType(const char* type, const uint8* data, size_t dataSize)
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetSnifferRule(BString *result) const
|
BMimeType::GetSnifferRule(BString *result) const
|
||||||
{
|
{
|
||||||
|
if (result == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err)
|
||||||
err = get_sniffer_rule(Type(), result);
|
err = default_database_location()->GetSnifferRule(Type(), *result);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -1096,9 +1133,12 @@ BMimeType::BMimeType(const BMimeType &)
|
|||||||
status_t
|
status_t
|
||||||
BMimeType::GetSupportedTypes(BMessage *types)
|
BMimeType::GetSupportedTypes(BMessage *types)
|
||||||
{
|
{
|
||||||
|
if (types == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t err = InitCheck();
|
status_t err = InitCheck();
|
||||||
if (!err)
|
if (!err)
|
||||||
err = get_supported_types(Type(), types);
|
err = default_database_location()->GetSupportedTypes(Type(), *types);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <mime/database_support.h>
|
#include <mime/database_support.h>
|
||||||
#include <mime/DatabaseDirectory.h>
|
#include <mime/DatabaseDirectory.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
#include <mime/MimeSniffer.h>
|
#include <mime/MimeSniffer.h>
|
||||||
#include <MimeType.h>
|
#include <MimeType.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
@@ -40,8 +41,10 @@ namespace Mime {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
//! Constructs a new AssociatedTypes object
|
//! Constructs a new AssociatedTypes object
|
||||||
AssociatedTypes::AssociatedTypes(MimeSniffer* mimeSniffer)
|
AssociatedTypes::AssociatedTypes(DatabaseLocation* databaseLocation,
|
||||||
|
MimeSniffer* mimeSniffer)
|
||||||
:
|
:
|
||||||
|
fDatabaseLocation(databaseLocation),
|
||||||
fMimeSniffer(mimeSniffer),
|
fMimeSniffer(mimeSniffer),
|
||||||
fHaveDoneFullBuild(false)
|
fHaveDoneFullBuild(false)
|
||||||
{
|
{
|
||||||
@@ -333,7 +336,7 @@ AssociatedTypes::BuildAssociatedTypesTable()
|
|||||||
fAssociatedTypes.clear();
|
fAssociatedTypes.clear();
|
||||||
|
|
||||||
DatabaseDirectory root;
|
DatabaseDirectory root;
|
||||||
status_t err = root.Init();
|
status_t err = root.Init(fDatabaseLocation);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
root.Rewind();
|
root.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -357,7 +360,7 @@ AssociatedTypes::BuildAssociatedTypesTable()
|
|||||||
// First, iterate through this supertype directory and process
|
// First, iterate through this supertype directory and process
|
||||||
// all of its subtypes
|
// all of its subtypes
|
||||||
DatabaseDirectory dir;
|
DatabaseDirectory dir;
|
||||||
if (dir.Init(supertype) == B_OK) {
|
if (dir.Init(fDatabaseLocation, supertype) == B_OK) {
|
||||||
dir.Rewind();
|
dir.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
BEntry subEntry;
|
BEntry subEntry;
|
||||||
@@ -424,7 +427,8 @@ AssociatedTypes::ProcessType(const char *type)
|
|||||||
if (!err) {
|
if (!err) {
|
||||||
// Read in the list of file extension types
|
// Read in the list of file extension types
|
||||||
BMessage msg;
|
BMessage msg;
|
||||||
if (read_mime_attr_message(type, kFileExtensionsAttr, &msg) == B_OK) {
|
if (fDatabaseLocation->ReadMessageAttribute(type, kFileExtensionsAttr,
|
||||||
|
msg) == B_OK) {
|
||||||
// Iterate through the file extesions, adding them to the list of
|
// Iterate through the file extesions, adding them to the list of
|
||||||
// file extensions for the mime type and adding the mime type
|
// file extensions for the mime type and adding the mime type
|
||||||
// to the list of associated types for each file extension
|
// to the list of associated types for each file extension
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
#include <TypeConstants.h>
|
#include <TypeConstants.h>
|
||||||
|
|
||||||
#include <AutoLocker.h>
|
#include <AutoLocker.h>
|
||||||
#include <mime/database_access.h>
|
|
||||||
#include <mime/database_support.h>
|
#include <mime/database_support.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
#include <storage_support.h>
|
#include <storage_support.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -64,18 +64,21 @@ Database::NotificationListener::~NotificationListener()
|
|||||||
// constructor
|
// constructor
|
||||||
/*! \brief Creates and initializes a Mime::Database object.
|
/*! \brief Creates and initializes a Mime::Database object.
|
||||||
*/
|
*/
|
||||||
Database::Database(MimeSniffer* mimeSniffer,
|
Database::Database(DatabaseLocation* databaseLocation, MimeSniffer* mimeSniffer,
|
||||||
NotificationListener* notificationListener)
|
NotificationListener* notificationListener)
|
||||||
:
|
:
|
||||||
fStatus(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
|
fLocation(databaseLocation),
|
||||||
fNotificationListener(notificationListener),
|
fNotificationListener(notificationListener),
|
||||||
fAssociatedTypes(mimeSniffer),
|
fAssociatedTypes(databaseLocation, mimeSniffer),
|
||||||
fSnifferRules(mimeSniffer),
|
fInstalledTypes(databaseLocation),
|
||||||
|
fSnifferRules(databaseLocation, mimeSniffer),
|
||||||
|
fSupportingApps(databaseLocation),
|
||||||
fDeferredInstallNotificationsLocker("deferred install notifications"),
|
fDeferredInstallNotificationsLocker("deferred install notifications"),
|
||||||
fDeferredInstallNotifications()
|
fDeferredInstallNotifications()
|
||||||
{
|
{
|
||||||
// make sure the user's MIME DB directory exists
|
// make sure the user's MIME DB directory exists
|
||||||
fStatus = create_directory(get_writable_database_directory(),
|
fStatus = create_directory(fLocation->WritableDirectory(),
|
||||||
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,14 +119,14 @@ Database::Install(const char *type)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
status_t err = entry.SetTo(type_to_writable_filename(type));
|
status_t err = entry.SetTo(fLocation->WritablePathForType(type));
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (entry.Exists())
|
if (entry.Exists())
|
||||||
err = B_FILE_EXISTS;
|
err = B_FILE_EXISTS;
|
||||||
else {
|
else {
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
BNode node;
|
BNode node;
|
||||||
err = open_or_create_type(type, &node, &didCreate);
|
err = fLocation->OpenOrCreateType(type, node, &didCreate);
|
||||||
if (!err && didCreate) {
|
if (!err && didCreate) {
|
||||||
fInstalledTypes.AddType(type);
|
fInstalledTypes.AddType(type);
|
||||||
_SendInstallNotification(type);
|
_SendInstallNotification(type);
|
||||||
@@ -148,7 +151,7 @@ Database::Delete(const char *type)
|
|||||||
|
|
||||||
// Open the type
|
// Open the type
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
status_t status = entry.SetTo(type_to_writable_filename(type));
|
status_t status = entry.SetTo(fLocation->WritablePathForType(type));
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
@@ -198,7 +201,7 @@ Database::_SetStringValue(const char *type, int32 what, const char* attribute,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
char oldValue[maxLength];
|
char oldValue[maxLength];
|
||||||
status_t status = read_mime_attr(type, attribute, oldValue,
|
status_t status = fLocation->ReadAttribute(type, attribute, oldValue,
|
||||||
maxLength, attributeType);
|
maxLength, attributeType);
|
||||||
if (status >= B_OK && !strcmp(value, oldValue)) {
|
if (status >= B_OK && !strcmp(value, oldValue)) {
|
||||||
// nothing has changed, no need to write back the data
|
// nothing has changed, no need to write back the data
|
||||||
@@ -206,7 +209,7 @@ Database::_SetStringValue(const char *type, int32 what, const char* attribute,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
status = write_mime_attr(type, attribute, value, length + 1,
|
status = fLocation->WriteAttribute(type, attribute, value, length + 1,
|
||||||
attributeType, &didCreate);
|
attributeType, &didCreate);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
@@ -267,7 +270,8 @@ Database::SetAttrInfo(const char *type, const BMessage *info)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
status_t status = write_mime_attr_message(type, kAttrInfoAttr, info, &didCreate);
|
status_t status = fLocation->WriteMessageAttribute(type, kAttrInfoAttr,
|
||||||
|
*info, &didCreate);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
if (didCreate)
|
if (didCreate)
|
||||||
_SendInstallNotification(type);
|
_SendInstallNotification(type);
|
||||||
@@ -334,8 +338,8 @@ Database::SetFileExtensions(const char *type, const BMessage *extensions)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
status_t status = write_mime_attr_message(type, kFileExtensionsAttr,
|
status_t status = fLocation->WriteMessageAttribute(type,
|
||||||
extensions, &didCreate);
|
kFileExtensionsAttr, *extensions, &didCreate);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
if (didCreate) {
|
if (didCreate) {
|
||||||
@@ -439,7 +443,7 @@ Database::SetIconForType(const char *type, const char *fileType,
|
|||||||
BNode node;
|
BNode node;
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
|
|
||||||
status_t err = open_or_create_type(type, &node, &didCreate);
|
status_t err = fLocation->OpenOrCreateType(type, node, &didCreate);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -500,7 +504,7 @@ Database::SetIconForType(const char *type, const char *fileType,
|
|||||||
BNode node;
|
BNode node;
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
|
|
||||||
status_t err = open_or_create_type(type, &node, &didCreate);
|
status_t err = fLocation->OpenOrCreateType(type, node, &didCreate);
|
||||||
if (err != B_OK)
|
if (err != B_OK)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -556,8 +560,8 @@ Database::SetSnifferRule(const char *type, const char *rule)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
status_t status = write_mime_attr(type, kSnifferRuleAttr, rule, strlen(rule) + 1,
|
status_t status = fLocation->WriteAttribute(type, kSnifferRuleAttr, rule,
|
||||||
kSnifferRuleType, &didCreate);
|
strlen(rule) + 1, kSnifferRuleType, &didCreate);
|
||||||
|
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = fSnifferRules.SetSnifferRule(type, rule);
|
status = fSnifferRules.SetSnifferRule(type, rule);
|
||||||
@@ -597,7 +601,7 @@ Database::SetSupportedTypes(const char *type, const BMessage *types, bool fullSy
|
|||||||
// Install the types
|
// Install the types
|
||||||
const char *supportedType;
|
const char *supportedType;
|
||||||
for (int32 i = 0; types->FindString("types", i, &supportedType) == B_OK; i++) {
|
for (int32 i = 0; types->FindString("types", i, &supportedType) == B_OK; i++) {
|
||||||
if (!is_installed(supportedType)) {
|
if (!fLocation->IsInstalled(supportedType)) {
|
||||||
if (Install(supportedType) != B_OK)
|
if (Install(supportedType) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -610,8 +614,8 @@ Database::SetSupportedTypes(const char *type, const BMessage *types, bool fullSy
|
|||||||
|
|
||||||
// Write the attr
|
// Write the attr
|
||||||
bool didCreate = false;
|
bool didCreate = false;
|
||||||
status_t status = write_mime_attr_message(type, kSupportedTypesAttr, types,
|
status_t status = fLocation->WriteMessageAttribute(type,
|
||||||
&didCreate);
|
kSupportedTypesAttr, *types, &didCreate);
|
||||||
|
|
||||||
// Notify the monitor if we created the type when we opened it
|
// Notify the monitor if we created the type when we opened it
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
@@ -976,7 +980,7 @@ Database::StopWatching(BMessenger target)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteAppHint(const char *type)
|
Database::DeleteAppHint(const char *type)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kAppHintAttr);
|
status_t status = fLocation->DeleteAttribute(type, kAppHintAttr);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
_SendMonitorUpdate(B_APP_HINT_CHANGED, type, B_META_MIME_DELETED);
|
_SendMonitorUpdate(B_APP_HINT_CHANGED, type, B_META_MIME_DELETED);
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
else if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -998,7 +1002,7 @@ Database::DeleteAppHint(const char *type)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteAttrInfo(const char *type)
|
Database::DeleteAttrInfo(const char *type)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kAttrInfoAttr);
|
status_t status = fLocation->DeleteAttribute(type, kAttrInfoAttr);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
_SendMonitorUpdate(B_ATTR_INFO_CHANGED, type, B_META_MIME_DELETED);
|
_SendMonitorUpdate(B_ATTR_INFO_CHANGED, type, B_META_MIME_DELETED);
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
else if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -1020,7 +1024,7 @@ Database::DeleteAttrInfo(const char *type)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteShortDescription(const char *type)
|
Database::DeleteShortDescription(const char *type)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kShortDescriptionAttr);
|
status_t status = fLocation->DeleteAttribute(type, kShortDescriptionAttr);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
_SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type, B_META_MIME_DELETED);
|
_SendMonitorUpdate(B_SHORT_DESCRIPTION_CHANGED, type, B_META_MIME_DELETED);
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
else if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -1042,7 +1046,7 @@ Database::DeleteShortDescription(const char *type)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteLongDescription(const char *type)
|
Database::DeleteLongDescription(const char *type)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kLongDescriptionAttr);
|
status_t status = fLocation->DeleteAttribute(type, kLongDescriptionAttr);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
_SendMonitorUpdate(B_LONG_DESCRIPTION_CHANGED, type, B_META_MIME_DELETED);
|
_SendMonitorUpdate(B_LONG_DESCRIPTION_CHANGED, type, B_META_MIME_DELETED);
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
else if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -1064,7 +1068,7 @@ Database::DeleteLongDescription(const char *type)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteFileExtensions(const char *type)
|
Database::DeleteFileExtensions(const char *type)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kFileExtensionsAttr);
|
status_t status = fLocation->DeleteAttribute(type, kFileExtensionsAttr);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
_SendMonitorUpdate(B_FILE_EXTENSIONS_CHANGED, type, B_META_MIME_DELETED);
|
_SendMonitorUpdate(B_FILE_EXTENSIONS_CHANGED, type, B_META_MIME_DELETED);
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
else if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -1088,7 +1092,7 @@ status_t
|
|||||||
Database::DeleteIcon(const char *type, icon_size which)
|
Database::DeleteIcon(const char *type, icon_size which)
|
||||||
{
|
{
|
||||||
const char *attr = which == B_MINI_ICON ? kMiniIconAttr : kLargeIconAttr;
|
const char *attr = which == B_MINI_ICON ? kMiniIconAttr : kLargeIconAttr;
|
||||||
status_t status = delete_attribute(type, attr);
|
status_t status = fLocation->DeleteAttribute(type, attr);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
_SendMonitorUpdate(B_ICON_CHANGED, type, which, B_META_MIME_DELETED);
|
_SendMonitorUpdate(B_ICON_CHANGED, type, which, B_META_MIME_DELETED);
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
else if (status == B_ENTRY_NOT_FOUND)
|
||||||
@@ -1111,7 +1115,7 @@ status_t
|
|||||||
Database::DeleteIcon(const char *type)
|
Database::DeleteIcon(const char *type)
|
||||||
{
|
{
|
||||||
// TODO: extra notification for vector icon (uses B_LARGE_ICON now)
|
// TODO: extra notification for vector icon (uses B_LARGE_ICON now)
|
||||||
status_t status = delete_attribute(type, kIconAttr);
|
status_t status = fLocation->DeleteAttribute(type, kIconAttr);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
_SendMonitorUpdate(B_ICON_CHANGED, type, B_LARGE_ICON,
|
_SendMonitorUpdate(B_ICON_CHANGED, type, B_LARGE_ICON,
|
||||||
B_META_MIME_DELETED);
|
B_META_MIME_DELETED);
|
||||||
@@ -1146,7 +1150,7 @@ Database::DeleteIconForType(const char *type, const char *fileType, icon_size wh
|
|||||||
std::string attr = (which == B_MINI_ICON
|
std::string attr = (which == B_MINI_ICON
|
||||||
? kMiniIconAttrPrefix : kLargeIconAttrPrefix) + BPrivate::Storage::to_lower(fileType);
|
? kMiniIconAttrPrefix : kLargeIconAttrPrefix) + BPrivate::Storage::to_lower(fileType);
|
||||||
|
|
||||||
status_t status = delete_attribute(type, attr.c_str());
|
status_t status = fLocation->DeleteAttribute(type, attr.c_str());
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
_SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType,
|
_SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType,
|
||||||
which == B_LARGE_ICON, B_META_MIME_DELETED);
|
which == B_LARGE_ICON, B_META_MIME_DELETED);
|
||||||
@@ -1181,7 +1185,7 @@ Database::DeleteIconForType(const char *type, const char *fileType)
|
|||||||
|
|
||||||
// TODO: introduce extra notification for vector icons?
|
// TODO: introduce extra notification for vector icons?
|
||||||
// (uses B_LARGE_ICON now)
|
// (uses B_LARGE_ICON now)
|
||||||
status_t status = delete_attribute(type, attr.c_str());
|
status_t status = fLocation->DeleteAttribute(type, attr.c_str());
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
_SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType,
|
_SendMonitorUpdate(B_ICON_FOR_TYPE_CHANGED, type, fileType,
|
||||||
true, B_META_MIME_DELETED);
|
true, B_META_MIME_DELETED);
|
||||||
@@ -1209,7 +1213,7 @@ Database::DeletePreferredApp(const char *type, app_verb verb)
|
|||||||
|
|
||||||
switch (verb) {
|
switch (verb) {
|
||||||
case B_OPEN:
|
case B_OPEN:
|
||||||
status = delete_attribute(type, kPreferredAppAttr);
|
status = fLocation->DeleteAttribute(type, kPreferredAppAttr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1242,7 +1246,7 @@ Database::DeletePreferredApp(const char *type, app_verb verb)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteSnifferRule(const char *type)
|
Database::DeleteSnifferRule(const char *type)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kSnifferRuleAttr);
|
status_t status = fLocation->DeleteAttribute(type, kSnifferRuleAttr);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
status = fSnifferRules.DeleteSnifferRule(type);
|
status = fSnifferRules.DeleteSnifferRule(type);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
@@ -1274,7 +1278,7 @@ Database::DeleteSnifferRule(const char *type)
|
|||||||
status_t
|
status_t
|
||||||
Database::DeleteSupportedTypes(const char *type, bool fullSync)
|
Database::DeleteSupportedTypes(const char *type, bool fullSync)
|
||||||
{
|
{
|
||||||
status_t status = delete_attribute(type, kSupportedTypesAttr);
|
status_t status = fLocation->DeleteAttribute(type, kSupportedTypesAttr);
|
||||||
|
|
||||||
// Update the supporting apps database. If fullSync is specified,
|
// Update the supporting apps database. If fullSync is specified,
|
||||||
// do so even if the supported types attribute didn't exist, as
|
// do so even if the supported types attribute didn't exist, as
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <StringList.h>
|
#include <StringList.h>
|
||||||
|
|
||||||
#include <mime/database_support.h>
|
#include <mime/database_support.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -34,14 +35,14 @@ DatabaseDirectory::~DatabaseDirectory()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DatabaseDirectory::Init(const char* superType)
|
DatabaseDirectory::Init(DatabaseLocation* databaseLocation,
|
||||||
|
const char* superType)
|
||||||
{
|
{
|
||||||
status_t error = BMergedDirectory::Init();
|
status_t error = BMergedDirectory::Init();
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
const BStringList& directories
|
const BStringList& directories = databaseLocation->Directories();
|
||||||
= BPrivate::Storage::Mime::get_database_directories();
|
|
||||||
int32 count = directories.CountStrings();
|
int32 count = directories.CountStrings();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
BString directory = directories.StringAt(i);
|
BString directory = directories.StringAt(i);
|
||||||
|
|||||||
@@ -0,0 +1,909 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2013, Haiku, Inc. All Rights Reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Tyler Dauwalder
|
||||||
|
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <DataIO.h>
|
||||||
|
#include <Directory.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <fs_attr.h>
|
||||||
|
#include <IconUtils.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Node.h>
|
||||||
|
|
||||||
|
#include <AutoDeleter.h>
|
||||||
|
#include <mime/database_support.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BPrivate {
|
||||||
|
namespace Storage {
|
||||||
|
namespace Mime {
|
||||||
|
|
||||||
|
|
||||||
|
DatabaseLocation::DatabaseLocation()
|
||||||
|
:
|
||||||
|
fDirectories()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DatabaseLocation::~DatabaseLocation()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
DatabaseLocation::AddDirectory(const BString& directory)
|
||||||
|
{
|
||||||
|
return !directory.IsEmpty() && fDirectories.Add(directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Opens a BNode on the given type, failing if the type has no
|
||||||
|
corresponding file in the database.
|
||||||
|
\param type The MIME type to open.
|
||||||
|
\param _node Node opened on the given MIME type.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::OpenType(const char* type, BNode& _node) const
|
||||||
|
{
|
||||||
|
if (type == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
int32 index;
|
||||||
|
return _OpenType(type, _node, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Opens a BNode on the given type, creating a node of the
|
||||||
|
appropriate flavor if necessary.
|
||||||
|
All MIME types are converted to lowercase for use in the filesystem.
|
||||||
|
\param type The MIME type to open.
|
||||||
|
\param _node Node opened on the given MIME type.
|
||||||
|
\param _didCreate If not \c NULL, the variable the pointer refers to is
|
||||||
|
set to \c true, if the node has been newly create, to \c false
|
||||||
|
otherwise.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::OpenOrCreateType(const char* type, BNode& _node,
|
||||||
|
bool* _didCreate) const
|
||||||
|
{
|
||||||
|
if (_didCreate)
|
||||||
|
*_didCreate = false;
|
||||||
|
|
||||||
|
// See, if the type already exists.
|
||||||
|
int32 index;
|
||||||
|
status_t error = _OpenType(type, _node, index);
|
||||||
|
if (error == B_OK) {
|
||||||
|
if (index == 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
// The caller wants a editable node, but the node found is not in the
|
||||||
|
// user's settings directory. Copy the node.
|
||||||
|
BNode nodeToClone(_node);
|
||||||
|
if (nodeToClone.InitCheck() != B_OK)
|
||||||
|
return nodeToClone.InitCheck();
|
||||||
|
|
||||||
|
error = _CopyTypeNode(nodeToClone, type, _node);
|
||||||
|
if (error != B_OK) {
|
||||||
|
_node.Unset();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_didCreate != NULL)
|
||||||
|
*_didCreate = true;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// type doesn't exist yet -- create the respective node
|
||||||
|
error = _CreateTypeNode(type, _node);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// write the type attribute
|
||||||
|
error = _node.WriteAttr(kTypeAttr, B_STRING_TYPE, 0, type,
|
||||||
|
strlen(type) + 1);
|
||||||
|
if (error != B_OK) {
|
||||||
|
_node.Unset();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_didCreate != NULL)
|
||||||
|
*_didCreate = true;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Reads up to \c len bytes of the given data from the given attribute
|
||||||
|
for the given MIME type.
|
||||||
|
|
||||||
|
If no entry for the given type exists in the database, the function fails,
|
||||||
|
and the contents of \c data are undefined.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param attribute The attribute name
|
||||||
|
\param data Pointer to a memory buffer into which the data should be copied
|
||||||
|
\param length The maximum number of bytes to read
|
||||||
|
\param datatype The expected data type
|
||||||
|
\return If successful, the number of bytes read is returned, otherwise, an
|
||||||
|
error code is returned.
|
||||||
|
*/
|
||||||
|
ssize_t
|
||||||
|
DatabaseLocation::ReadAttribute(const char* type, const char* attribute,
|
||||||
|
void* data, size_t length, type_code datatype) const
|
||||||
|
{
|
||||||
|
if (type == NULL || attribute == NULL || data == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BNode node;
|
||||||
|
status_t error = OpenType(type, node);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return node.ReadAttr(attribute, datatype, 0, data, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Reads a flattened BMessage from the given attribute of the given
|
||||||
|
MIME type.
|
||||||
|
|
||||||
|
If no entry for the given type exists in the database, or if the data
|
||||||
|
stored in the attribute is not a flattened BMessage, the function fails
|
||||||
|
and the contents of \c msg are undefined.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param attribute The attribute name
|
||||||
|
\param data Reference to a pre-allocated BMessage into which the attribute
|
||||||
|
data is unflattened.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::ReadMessageAttribute(const char* type, const char* attribute,
|
||||||
|
BMessage& _message) const
|
||||||
|
{
|
||||||
|
if (type == NULL || attribute == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BNode node;
|
||||||
|
attr_info info;
|
||||||
|
|
||||||
|
status_t error = OpenType(type, node);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
error = node.GetAttrInfo(attribute, &info);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (info.type != B_MESSAGE_TYPE)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
void* buffer = malloc(info.size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
MemoryDeleter bufferDeleter(buffer);
|
||||||
|
|
||||||
|
ssize_t bytesRead = node.ReadAttr(attribute, B_MESSAGE_TYPE, 0, buffer,
|
||||||
|
info.size);
|
||||||
|
if (bytesRead != info.size)
|
||||||
|
return bytesRead < 0 ? (status_t)bytesRead : (status_t)B_FILE_ERROR;
|
||||||
|
|
||||||
|
return _message.Unflatten((const char*)buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Reads a BString from the given attribute of the given
|
||||||
|
MIME type.
|
||||||
|
|
||||||
|
If no entry for the given type exists in the database, the function fails
|
||||||
|
and the contents of \c str are undefined.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param attribute The attribute name
|
||||||
|
\param _string Reference to a pre-allocated BString into which the attribute
|
||||||
|
data stored.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::ReadStringAttribute(const char* type, const char* attribute,
|
||||||
|
BString& _string) const
|
||||||
|
{
|
||||||
|
if (type == NULL || attribute == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BNode node;
|
||||||
|
status_t error = OpenType(type, node);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return node.ReadAttrString(attribute, &_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Writes \c len bytes of the given data to the given attribute
|
||||||
|
for the given MIME type.
|
||||||
|
|
||||||
|
If no entry for the given type exists in the database, it is created.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param attribute The attribute name
|
||||||
|
\param data Pointer to the data to write
|
||||||
|
\param length The number of bytes to write
|
||||||
|
\param datatype The data type of the given data
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::WriteAttribute(const char* type, const char* attribute,
|
||||||
|
const void* data, size_t length, type_code datatype, bool* _didCreate) const
|
||||||
|
{
|
||||||
|
if (type == NULL || attribute == NULL || data == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BNode node;
|
||||||
|
status_t error = OpenOrCreateType(type, node, _didCreate);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ssize_t bytesWritten = node.WriteAttr(attribute, datatype, 0, data, length);
|
||||||
|
if (bytesWritten < 0)
|
||||||
|
return bytesWritten;
|
||||||
|
return bytesWritten == (ssize_t)length ? B_OK : B_FILE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Flattens the given \c BMessage and writes it to the given attribute
|
||||||
|
of the given MIME type.
|
||||||
|
|
||||||
|
If no entry for the given type exists in the database, it is created.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param attribute The attribute name
|
||||||
|
\param message The BMessage to flatten and write
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::WriteMessageAttribute(const char* type, const char* attribute,
|
||||||
|
const BMessage& message, bool* _didCreate) const
|
||||||
|
{
|
||||||
|
BMallocIO data;
|
||||||
|
status_t error = data.SetSize(message.FlattenedSize());
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
ssize_t bytes;
|
||||||
|
error = message.Flatten(&data, &bytes);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return WriteAttribute(type, attribute, data.Buffer(), data.BufferLength(),
|
||||||
|
B_MESSAGE_TYPE, _didCreate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Deletes the given attribute for the given type
|
||||||
|
/*!
|
||||||
|
\param type The mime type
|
||||||
|
\param attribute The attribute name
|
||||||
|
\return
|
||||||
|
- B_OK: success
|
||||||
|
- B_ENTRY_NOT_FOUND: no such type or attribute
|
||||||
|
- "error code": failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::DeleteAttribute(const char* type, const char* attribute) const
|
||||||
|
{
|
||||||
|
if (type == NULL || attribute == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
BNode node;
|
||||||
|
int32 index;
|
||||||
|
status_t error = _OpenType(type, node, index);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (index != 0)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
return node.RemoveAttr(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches the application hint for the given MIME type.
|
||||||
|
|
||||||
|
The entry_ref pointed to by \c ref must be pre-allocated.
|
||||||
|
|
||||||
|
\param type The MIME type of interest
|
||||||
|
\param _ref Reference to a pre-allocated \c entry_ref struct into
|
||||||
|
which the location of the hint application is copied.
|
||||||
|
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No app hint exists for the given type
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetAppHint(const char* type, entry_ref& _ref)
|
||||||
|
{
|
||||||
|
if (type == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
char path[B_PATH_NAME_LENGTH];
|
||||||
|
BEntry entry;
|
||||||
|
ssize_t status = ReadAttribute(type, kAppHintAttr, path, B_PATH_NAME_LENGTH,
|
||||||
|
kAppHintType);
|
||||||
|
|
||||||
|
if (status >= B_OK)
|
||||||
|
status = entry.SetTo(path);
|
||||||
|
if (status == B_OK)
|
||||||
|
status = entry.GetRef(&_ref);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches from the MIME database a BMessage describing the attributes
|
||||||
|
typically associated with files of the given MIME type
|
||||||
|
|
||||||
|
The attribute information is returned in a pre-allocated BMessage pointed to
|
||||||
|
by the \c info parameter (note that the any prior contents of the message
|
||||||
|
will be destroyed). Please see BMimeType::SetAttrInfo() for a description
|
||||||
|
of the expected format of such a message.
|
||||||
|
|
||||||
|
\param _info Reference to a pre-allocated BMessage into which information
|
||||||
|
about the MIME type's associated file attributes is stored.
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetAttributesInfo(const char* type, BMessage& _info)
|
||||||
|
{
|
||||||
|
status_t err = ReadMessageAttribute(type, kAttrInfoAttr, _info);
|
||||||
|
if (err == B_ENTRY_NOT_FOUND) {
|
||||||
|
// return an empty message
|
||||||
|
_info.MakeEmpty();
|
||||||
|
err = B_OK;
|
||||||
|
}
|
||||||
|
if (err == B_OK) {
|
||||||
|
_info.what = 233;
|
||||||
|
// Don't know why, but that's what R5 does.
|
||||||
|
err = _info.AddString("type", type);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches the short description for the given MIME type.
|
||||||
|
|
||||||
|
The string pointed to by \c description must be long enough to
|
||||||
|
hold the short description; a length of \c B_MIME_TYPE_LENGTH is
|
||||||
|
recommended.
|
||||||
|
|
||||||
|
\param type The MIME type of interest
|
||||||
|
\param description Pointer to a pre-allocated string into which the short
|
||||||
|
description is copied. If the function fails, the contents of the string
|
||||||
|
are undefined.
|
||||||
|
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No short description exists for the given type
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetShortDescription(const char* type, char* description)
|
||||||
|
{
|
||||||
|
ssize_t err = ReadAttribute(type, kShortDescriptionAttr, description,
|
||||||
|
B_MIME_TYPE_LENGTH, kShortDescriptionType);
|
||||||
|
return err >= 0 ? B_OK : err ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Fetches the long description for the given MIME type.
|
||||||
|
/*! The string pointed to by \c description must be long enough to
|
||||||
|
hold the long description; a length of \c B_MIME_TYPE_LENGTH is
|
||||||
|
recommended.
|
||||||
|
|
||||||
|
\param type The MIME type of interest
|
||||||
|
\param description Pointer to a pre-allocated string into which the long
|
||||||
|
description is copied. If the function fails, the contents of the string
|
||||||
|
are undefined.
|
||||||
|
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No long description exists for the given type
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetLongDescription(const char* type, char* description)
|
||||||
|
{
|
||||||
|
ssize_t err = ReadAttribute(type, kLongDescriptionAttr, description,
|
||||||
|
B_MIME_TYPE_LENGTH, kLongDescriptionType);
|
||||||
|
return err >= 0 ? B_OK : err ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches a BMessage describing the MIME type's associated filename
|
||||||
|
extensions
|
||||||
|
|
||||||
|
The list of extensions is returned in a pre-allocated BMessage pointed to
|
||||||
|
by the \c extensions parameter (note that the any prior contents of the
|
||||||
|
message will be destroyed). Please see BMimeType::GetFileExtensions() for
|
||||||
|
a description of the message format.
|
||||||
|
|
||||||
|
\param extensions Reference to a pre-allocated BMessage into which the MIME
|
||||||
|
type's associated file extensions will be stored.
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetFileExtensions(const char* type, BMessage& _extensions)
|
||||||
|
{
|
||||||
|
status_t err = ReadMessageAttribute(type, kFileExtensionsAttr, _extensions);
|
||||||
|
if (err == B_ENTRY_NOT_FOUND) {
|
||||||
|
// return an empty message
|
||||||
|
_extensions.MakeEmpty();
|
||||||
|
err = B_OK;
|
||||||
|
}
|
||||||
|
if (err == B_OK) {
|
||||||
|
_extensions.what = 234; // Don't know why, but that's what R5 does.
|
||||||
|
err = _extensions.AddString("type", type);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches the icon of given size associated with the given MIME type
|
||||||
|
|
||||||
|
The bitmap pointed to by \c icon must be of the proper size (\c 32x32
|
||||||
|
for \c B_LARGE_ICON, \c 16x16 for \c B_MINI_ICON) and color depth
|
||||||
|
(\c B_CMAP8).
|
||||||
|
|
||||||
|
\param type The mime type
|
||||||
|
\param icon Reference to a pre-allocated bitmap of proper dimensions and
|
||||||
|
color depth
|
||||||
|
\param size The size icon you're interested in (\c B_LARGE_ICON or
|
||||||
|
\c B_MINI_ICON)
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetIcon(const char* type, BBitmap& _icon, icon_size size)
|
||||||
|
{
|
||||||
|
return GetIconForType(type, NULL, _icon, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Fetches the vector icon associated with the given MIME type
|
||||||
|
/** \param type The mime type
|
||||||
|
\param _data Reference via which the allocated icon data is returned. You
|
||||||
|
need to free the buffer once you're done with it.
|
||||||
|
\param _size Reference via which the size of the icon data is returned.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetIcon(const char* type, uint8*& _data, size_t& _size)
|
||||||
|
{
|
||||||
|
return GetIconForType(type, NULL, _data, _size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches the large or mini icon used by an application of this type
|
||||||
|
for files of the given type.
|
||||||
|
|
||||||
|
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 calling
|
||||||
|
\c GetIconForType() on a non-application type will likely return
|
||||||
|
\c B_ENTRY_NOT_FOUND.
|
||||||
|
|
||||||
|
The icon is copied into the \c BBitmap pointed to by \c icon. The bitmap
|
||||||
|
must be the proper size: \c 32x32 for the large icon, \c 16x16 for the mini
|
||||||
|
icon.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param fileType Pointer to a pre-allocated string containing the MIME type
|
||||||
|
whose custom icon you wish to fetch. If NULL, works just like
|
||||||
|
GetIcon().
|
||||||
|
\param icon Reference to a pre-allocated \c BBitmap of proper size and
|
||||||
|
colorspace into which the icon is copied.
|
||||||
|
\param icon_size Value that specifies which icon to return. Currently
|
||||||
|
\c B_LARGE_ICON and \c B_MINI_ICON are supported.
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No icon of the given size exists for the given type
|
||||||
|
- "error code": Failure
|
||||||
|
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetIconForType(const char* type, const char* fileType,
|
||||||
|
BBitmap& _icon, icon_size which)
|
||||||
|
{
|
||||||
|
if (type == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// open the node for the given type
|
||||||
|
BNode node;
|
||||||
|
ssize_t err = OpenType(type, node);
|
||||||
|
if (err < B_OK)
|
||||||
|
return (status_t)err;
|
||||||
|
|
||||||
|
// construct our attribute name
|
||||||
|
BString vectorIconAttrName;
|
||||||
|
BString smallIconAttrName;
|
||||||
|
BString largeIconAttrName;
|
||||||
|
|
||||||
|
if (fileType) {
|
||||||
|
BString lowerCaseFileType(fileType);
|
||||||
|
lowerCaseFileType.ToLower();
|
||||||
|
|
||||||
|
vectorIconAttrName << kIconAttrPrefix << lowerCaseFileType;
|
||||||
|
smallIconAttrName << kMiniIconAttrPrefix << lowerCaseFileType;
|
||||||
|
largeIconAttrName << kLargeIconAttrPrefix << lowerCaseFileType;
|
||||||
|
} else {
|
||||||
|
vectorIconAttrName = kIconAttr;
|
||||||
|
smallIconAttrName = kMiniIconAttr;
|
||||||
|
largeIconAttrName = kLargeIconAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BIconUtils::GetIcon(&node, vectorIconAttrName, smallIconAttrName,
|
||||||
|
largeIconAttrName, which, &_icon);
|
||||||
|
|
||||||
|
// ssize_t err = type && icon ? B_OK : B_BAD_VALUE;
|
||||||
|
//
|
||||||
|
// // Figure out what kind of data we *should* find
|
||||||
|
// uint32 attrType = 0;
|
||||||
|
// ssize_t attrSize = 0;
|
||||||
|
// BRect bounds;
|
||||||
|
//
|
||||||
|
// if (!err) {
|
||||||
|
// switch (which) {
|
||||||
|
// case B_MINI_ICON:
|
||||||
|
// bounds.Set(0, 0, 15, 15);
|
||||||
|
// attrType = kMiniIconType;
|
||||||
|
// attrSize = 16 * 16;
|
||||||
|
// break;
|
||||||
|
// case B_LARGE_ICON:
|
||||||
|
// bounds.Set(0, 0, 31, 31);
|
||||||
|
// attrType = kLargeIconType;
|
||||||
|
// attrSize = 32 * 32;
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// err = B_BAD_VALUE;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// // Construct our attribute name
|
||||||
|
// std::string attr;
|
||||||
|
// if (fileType) {
|
||||||
|
// attr = (which == B_MINI_ICON
|
||||||
|
// ? kMiniIconAttrPrefix
|
||||||
|
// : kLargeIconAttrPrefix)
|
||||||
|
// + BPrivate::Storage::to_lower(fileType);
|
||||||
|
// } else {
|
||||||
|
// attr = (which == B_MINI_ICON) ? kMiniIconAttr : kLargeIconAttr;
|
||||||
|
// }
|
||||||
|
// // Check the icon and attribute to see if they match
|
||||||
|
// if (!err) {
|
||||||
|
// err = (icon->InitCheck() == B_OK
|
||||||
|
// && icon->Bounds() == bounds) ? B_OK : B_BAD_VALUE;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// BNode node;
|
||||||
|
// if (!err)
|
||||||
|
// err = open_type(type, &node);
|
||||||
|
//
|
||||||
|
// attr_info info;
|
||||||
|
// if (!err)
|
||||||
|
// err = node.GetAttrInfo(attr.c_str(), &info);
|
||||||
|
//
|
||||||
|
// if (!err)
|
||||||
|
// err = (attrType == info.type && attrSize == info.size) ? B_OK : B_BAD_VALUE;
|
||||||
|
// // read the attribute
|
||||||
|
// if (!err) {
|
||||||
|
// bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
||||||
|
// char *buffer = NULL;
|
||||||
|
// if (otherColorSpace) {
|
||||||
|
// // other color space than stored in attribute
|
||||||
|
// buffer = new(std::nothrow) char[attrSize];
|
||||||
|
// if (!buffer)
|
||||||
|
// err = B_NO_MEMORY;
|
||||||
|
// if (!err)
|
||||||
|
// err = node.ReadAttr(attr.c_str(), attrType, 0, buffer, attrSize);
|
||||||
|
// } else {
|
||||||
|
// // same color space, just read direct
|
||||||
|
// err = node.ReadAttr(attr.c_str(), attrType, 0, icon->Bits(), attrSize);
|
||||||
|
// }
|
||||||
|
// if (err >= 0)
|
||||||
|
// err = (err == attrSize) ? (status_t)B_OK : (status_t)B_FILE_ERROR;
|
||||||
|
// if (otherColorSpace) {
|
||||||
|
// if (!err) {
|
||||||
|
// err = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
|
||||||
|
// 0, B_CMAP8);
|
||||||
|
// }
|
||||||
|
// delete[] buffer;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches the vector icon used by an application of this type for files
|
||||||
|
of the given type.
|
||||||
|
|
||||||
|
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 calling
|
||||||
|
\c GetIconForType() on a non-application type will likely return
|
||||||
|
\c B_ENTRY_NOT_FOUND.
|
||||||
|
|
||||||
|
The icon data is allocated and returned in \a _data.
|
||||||
|
|
||||||
|
\param type The MIME type
|
||||||
|
\param fileType Reference to a pre-allocated string containing the MIME type
|
||||||
|
whose custom icon you wish to fetch. If NULL, works just like GetIcon().
|
||||||
|
\param _data Reference via which the icon data is returned on success.
|
||||||
|
\param _size Reference via which the size of the icon data is returned.
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No vector icon exists for the given type
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetIconForType(const char* type, const char* fileType,
|
||||||
|
uint8*& _data, size_t& _size)
|
||||||
|
{
|
||||||
|
if (type == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// open the node for the given type
|
||||||
|
BNode node;
|
||||||
|
ssize_t err = OpenType(type, node);
|
||||||
|
if (err < B_OK)
|
||||||
|
return (status_t)err;
|
||||||
|
|
||||||
|
// construct our attribute name
|
||||||
|
BString iconAttrName;
|
||||||
|
|
||||||
|
if (fileType)
|
||||||
|
iconAttrName << kIconAttrPrefix << BString(fileType).ToLower();
|
||||||
|
else
|
||||||
|
iconAttrName = kIconAttr;
|
||||||
|
|
||||||
|
// get info about attribute for that name
|
||||||
|
attr_info info;
|
||||||
|
if (!err)
|
||||||
|
err = node.GetAttrInfo(iconAttrName, &info);
|
||||||
|
|
||||||
|
// validate attribute type
|
||||||
|
if (!err)
|
||||||
|
err = (info.type == B_VECTOR_ICON_TYPE) ? B_OK : B_BAD_VALUE;
|
||||||
|
|
||||||
|
// allocate a buffer and read the attribute data into it
|
||||||
|
if (!err) {
|
||||||
|
uint8* buffer = new(std::nothrow) uint8[info.size];
|
||||||
|
if (!buffer)
|
||||||
|
err = B_NO_MEMORY;
|
||||||
|
if (!err) {
|
||||||
|
err = node.ReadAttr(iconAttrName, B_VECTOR_ICON_TYPE, 0, buffer,
|
||||||
|
info.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err >= 0)
|
||||||
|
err = (err == info.size) ? (ssize_t)B_OK : (ssize_t)B_FILE_ERROR;
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
// success, set data pointer and size
|
||||||
|
_data = buffer;
|
||||||
|
_size = info.size;
|
||||||
|
} else {
|
||||||
|
delete[] buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches signature of the MIME type's preferred application for the
|
||||||
|
given action.
|
||||||
|
|
||||||
|
The string pointed to by \c signature must be long enough to
|
||||||
|
hold the short description; a length of \c B_MIME_TYPE_LENGTH is
|
||||||
|
recommended.
|
||||||
|
|
||||||
|
Currently, the only supported app verb is \c B_OPEN.
|
||||||
|
|
||||||
|
\param type The MIME type of interest
|
||||||
|
\param description Pointer to a pre-allocated string into which the
|
||||||
|
preferred application's signature is copied. If the function fails,
|
||||||
|
the contents of the string are undefined.
|
||||||
|
\param verb \c The action of interest
|
||||||
|
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No such preferred application exists
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetPreferredApp(const char* type, char* signature,
|
||||||
|
app_verb verb)
|
||||||
|
{
|
||||||
|
// Since B_OPEN is the currently the only app_verb, it is essentially
|
||||||
|
// ignored
|
||||||
|
ssize_t err = ReadAttribute(type, kPreferredAppAttr, signature,
|
||||||
|
B_MIME_TYPE_LENGTH, kPreferredAppType);
|
||||||
|
return err >= 0 ? B_OK : err ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*! \brief Fetches the sniffer rule for the given MIME type.
|
||||||
|
\param type The MIME type of interest
|
||||||
|
\param _result Pointer to a pre-allocated BString into which the type's
|
||||||
|
sniffer rule is copied.
|
||||||
|
\return
|
||||||
|
- \c B_OK: Success
|
||||||
|
- \c B_ENTRY_NOT_FOUND: No such preferred application exists
|
||||||
|
- "error code": Failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetSnifferRule(const char* type, BString& _result)
|
||||||
|
{
|
||||||
|
return ReadStringAttribute(type, kSnifferRuleAttr, _result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::GetSupportedTypes(const char* type, BMessage& _types)
|
||||||
|
{
|
||||||
|
status_t err = ReadMessageAttribute(type, kSupportedTypesAttr, _types);
|
||||||
|
if (err == B_ENTRY_NOT_FOUND) {
|
||||||
|
// return an empty message
|
||||||
|
_types.MakeEmpty();
|
||||||
|
err = B_OK;
|
||||||
|
}
|
||||||
|
if (err == B_OK) {
|
||||||
|
_types.what = 0;
|
||||||
|
err = _types.AddString("type", type);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Checks if the given MIME type is present in the database
|
||||||
|
bool
|
||||||
|
DatabaseLocation::IsInstalled(const char* type)
|
||||||
|
{
|
||||||
|
BNode node;
|
||||||
|
return OpenType(type, node) == B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BString
|
||||||
|
DatabaseLocation::_TypeToFilename(const char* type, int32 index) const
|
||||||
|
{
|
||||||
|
BString path = fDirectories.StringAt(index);
|
||||||
|
return path << '/' << BString(type).ToLower();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::_OpenType(const char* type, BNode& _node, int32& _index) const
|
||||||
|
{
|
||||||
|
int32 count = fDirectories.CountStrings();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
status_t error = _node.SetTo(_TypeToFilename(type, i));
|
||||||
|
attr_info attrInfo;
|
||||||
|
if (error == B_OK && _node.GetAttrInfo(kTypeAttr, &attrInfo) == B_OK) {
|
||||||
|
_index = i;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::_CreateTypeNode(const char* type, BNode& _node) const
|
||||||
|
{
|
||||||
|
const char* slash = strchr(type, '/');
|
||||||
|
BString superTypeName;
|
||||||
|
if (slash != NULL)
|
||||||
|
superTypeName.SetTo(type, slash - type);
|
||||||
|
else
|
||||||
|
superTypeName = type;
|
||||||
|
superTypeName.ToLower();
|
||||||
|
|
||||||
|
// open/create the directory for the supertype
|
||||||
|
BDirectory parent(WritableDirectory());
|
||||||
|
status_t error = parent.InitCheck();
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
BDirectory superTypeDirectory;
|
||||||
|
if (BEntry(&parent, superTypeName).Exists())
|
||||||
|
error = superTypeDirectory.SetTo(&parent, superTypeName);
|
||||||
|
else
|
||||||
|
error = parent.CreateDirectory(superTypeName, &superTypeDirectory);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// create the subtype
|
||||||
|
BFile subTypeFile;
|
||||||
|
if (slash != NULL) {
|
||||||
|
error = superTypeDirectory.CreateFile(BString(slash + 1).ToLower(),
|
||||||
|
&subTypeFile);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assign the result
|
||||||
|
if (slash != NULL)
|
||||||
|
_node = subTypeFile;
|
||||||
|
else
|
||||||
|
_node = superTypeDirectory;
|
||||||
|
return _node.InitCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
DatabaseLocation::_CopyTypeNode(BNode& source, const char* type, BNode& _target)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
status_t error = _CreateTypeNode(type, _target);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// copy the attributes
|
||||||
|
MemoryDeleter bufferDeleter;
|
||||||
|
size_t bufferSize = 0;
|
||||||
|
|
||||||
|
source.RewindAttrs();
|
||||||
|
char attribute[B_ATTR_NAME_LENGTH];
|
||||||
|
while (source.GetNextAttrName(attribute) == B_OK) {
|
||||||
|
attr_info info;
|
||||||
|
error = source.GetAttrInfo(attribute, &info);
|
||||||
|
if (error != B_OK) {
|
||||||
|
syslog(LOG_ERR, "Failed to get info for attribute \"%s\" of MIME "
|
||||||
|
"type \"%s\": %s", attribute, type, strerror(error));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// resize our buffer, if necessary
|
||||||
|
if (info.size > bufferSize) {
|
||||||
|
bufferDeleter.SetTo(malloc(info.size));
|
||||||
|
if (bufferDeleter.Get() == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
bufferSize = info.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t bytesRead = source.ReadAttr(attribute, info.type, 0,
|
||||||
|
bufferDeleter.Get(), info.size);
|
||||||
|
if (bytesRead != info.size) {
|
||||||
|
syslog(LOG_ERR, "Failed to read attribute \"%s\" of MIME "
|
||||||
|
"type \"%s\": %s", attribute, type,
|
||||||
|
bytesRead < 0 ? strerror(bytesRead) : "short read");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t bytesWritten = _target.WriteAttr(attribute, info.type, 0,
|
||||||
|
bufferDeleter.Get(), info.size);
|
||||||
|
if (bytesWritten < 0) {
|
||||||
|
syslog(LOG_ERR, "Failed to write attribute \"%s\" of MIME "
|
||||||
|
"type \"%s\": %s", attribute, type,
|
||||||
|
bytesWritten < 0 ? strerror(bytesWritten) : "short write");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Mime
|
||||||
|
} // namespace Storage
|
||||||
|
} // namespace BPrivate
|
||||||
@@ -40,8 +40,9 @@ namespace Mime {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//! Constructs a new InstalledTypes object
|
//! Constructs a new InstalledTypes object
|
||||||
InstalledTypes::InstalledTypes()
|
InstalledTypes::InstalledTypes(DatabaseLocation* databaseLocation)
|
||||||
:
|
:
|
||||||
|
fDatabaseLocation(databaseLocation),
|
||||||
fCachedMessage(NULL),
|
fCachedMessage(NULL),
|
||||||
fCachedSupertypesMessage(NULL),
|
fCachedSupertypesMessage(NULL),
|
||||||
fHaveDoneFullBuild(false)
|
fHaveDoneFullBuild(false)
|
||||||
@@ -385,7 +386,7 @@ InstalledTypes::_BuildInstalledTypesList()
|
|||||||
|
|
||||||
DatabaseDirectory root;
|
DatabaseDirectory root;
|
||||||
if (!err)
|
if (!err)
|
||||||
err = root.Init();
|
err = root.Init(fDatabaseLocation);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
root.Rewind();
|
root.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -417,7 +418,7 @@ InstalledTypes::_BuildInstalledTypesList()
|
|||||||
// Now iterate through this supertype directory and add
|
// Now iterate through this supertype directory and add
|
||||||
// all of its subtypes
|
// all of its subtypes
|
||||||
DatabaseDirectory dir;
|
DatabaseDirectory dir;
|
||||||
if (dir.Init(supertype) == B_OK) {
|
if (dir.Init(fDatabaseLocation, supertype) == B_OK) {
|
||||||
dir.Rewind();
|
dir.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
BEntry subEntry;
|
BEntry subEntry;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ StaticLibrary libstorage_kit_mime.a :
|
|||||||
AssociatedTypes.cpp
|
AssociatedTypes.cpp
|
||||||
Database.cpp
|
Database.cpp
|
||||||
DatabaseDirectory.cpp
|
DatabaseDirectory.cpp
|
||||||
database_access.cpp
|
DatabaseLocation.cpp
|
||||||
database_support.cpp
|
database_support.cpp
|
||||||
InstalledTypes.cpp
|
InstalledTypes.cpp
|
||||||
MimeSniffer.cpp
|
MimeSniffer.cpp
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <MimeType.h>
|
#include <MimeType.h>
|
||||||
#include <mime/database_support.h>
|
#include <mime/database_support.h>
|
||||||
#include <mime/DatabaseDirectory.h>
|
#include <mime/DatabaseDirectory.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
#include <mime/MimeSniffer.h>
|
#include <mime/MimeSniffer.h>
|
||||||
#include <sniffer/Parser.h>
|
#include <sniffer/Parser.h>
|
||||||
#include <sniffer/Rule.h>
|
#include <sniffer/Rule.h>
|
||||||
@@ -112,8 +113,10 @@ bool operator<(SnifferRules::sniffer_rule &left, SnifferRules::sniffer_rule &rig
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
//! Constructs a new SnifferRules object
|
//! Constructs a new SnifferRules object
|
||||||
SnifferRules::SnifferRules(MimeSniffer* mimeSniffer)
|
SnifferRules::SnifferRules(DatabaseLocation* databaseLocation,
|
||||||
|
MimeSniffer* mimeSniffer)
|
||||||
:
|
:
|
||||||
|
fDatabaseLocation(databaseLocation),
|
||||||
fMimeSniffer(mimeSniffer),
|
fMimeSniffer(mimeSniffer),
|
||||||
fMaxBytesNeeded(0),
|
fMaxBytesNeeded(0),
|
||||||
fHaveDoneFullBuild(false)
|
fHaveDoneFullBuild(false)
|
||||||
@@ -338,7 +341,7 @@ SnifferRules::BuildRuleList()
|
|||||||
ssize_t bytesNeeded = 0;
|
ssize_t bytesNeeded = 0;
|
||||||
DatabaseDirectory root;
|
DatabaseDirectory root;
|
||||||
|
|
||||||
status_t err = root.Init();
|
status_t err = root.Init(fDatabaseLocation);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
root.Rewind();
|
root.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -362,7 +365,7 @@ SnifferRules::BuildRuleList()
|
|||||||
// First, iterate through this supertype directory and process
|
// First, iterate through this supertype directory and process
|
||||||
// all of its subtypes
|
// all of its subtypes
|
||||||
DatabaseDirectory dir;
|
DatabaseDirectory dir;
|
||||||
if (dir.Init(supertype) == B_OK) {
|
if (dir.Init(fDatabaseLocation, supertype) == B_OK) {
|
||||||
dir.Rewind();
|
dir.Rewind();
|
||||||
while (true) {
|
while (true) {
|
||||||
BEntry subEntry;
|
BEntry subEntry;
|
||||||
@@ -562,8 +565,10 @@ SnifferRules::ProcessType(const char *type, ssize_t *bytesNeeded)
|
|||||||
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 = fDatabaseLocation->ReadStringAttribute(type, kSnifferRuleAttr,
|
||||||
|
str);
|
||||||
|
}
|
||||||
// Parse the rule
|
// Parse the rule
|
||||||
if (!err) {
|
if (!err) {
|
||||||
err = Sniffer::parse(str.String(), rule.rule, &errorMsg);
|
err = Sniffer::parse(str.String(), rule.rule, &errorMsg);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <mime/database_support.h>
|
#include <mime/database_support.h>
|
||||||
#include <mime/DatabaseDirectory.h>
|
#include <mime/DatabaseDirectory.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
#include <storage_support.h>
|
#include <storage_support.h>
|
||||||
|
|
||||||
|
|
||||||
@@ -42,8 +43,10 @@ namespace Mime {
|
|||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
//! Constructs a new SupportingApps object
|
//! Constructs a new SupportingApps object
|
||||||
SupportingApps::SupportingApps()
|
SupportingApps::SupportingApps(DatabaseLocation* databaseLocation)
|
||||||
: fHaveDoneFullBuild(false)
|
:
|
||||||
|
fDatabaseLocation(databaseLocation),
|
||||||
|
fHaveDoneFullBuild(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +269,7 @@ SupportingApps::BuildSupportingAppsTable()
|
|||||||
fStrandedTypes.clear();
|
fStrandedTypes.clear();
|
||||||
|
|
||||||
DatabaseDirectory dir;
|
DatabaseDirectory dir;
|
||||||
status_t status = dir.Init("application");
|
status_t status = dir.Init(fDatabaseLocation, "application");
|
||||||
|
|
||||||
// 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) {
|
||||||
@@ -290,8 +293,8 @@ SupportingApps::BuildSupportingAppsTable()
|
|||||||
&appSignature) >= B_OK) {
|
&appSignature) >= B_OK) {
|
||||||
// Read in the list of supported types
|
// Read in the list of supported types
|
||||||
BMessage msg;
|
BMessage msg;
|
||||||
if (read_mime_attr_message(appSignature.String(), kSupportedTypesAttr,
|
if (fDatabaseLocation->ReadMessageAttribute(appSignature,
|
||||||
&msg) == B_OK) {
|
kSupportedTypesAttr, msg) == B_OK) {
|
||||||
// Iterate through the supported types, adding them to the list of
|
// Iterate through the supported types, adding them to the list of
|
||||||
// supported types for the application and adding the application's
|
// supported types for the application and adding the application's
|
||||||
// signature to the list of supporting apps for each type
|
// signature to the list of supporting apps for each type
|
||||||
|
|||||||
@@ -1,585 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2002-2007, Haiku.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Tyler Dauwalder
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\file database_access.cpp
|
|
||||||
Mime database atomic read functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <mime/database_access.h>
|
|
||||||
|
|
||||||
#include <Bitmap.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <Directory.h>
|
|
||||||
#include <IconUtils.h>
|
|
||||||
#include <Message.h>
|
|
||||||
#include <mime/database_support.h>
|
|
||||||
#include <Node.h>
|
|
||||||
#include <Path.h>
|
|
||||||
#include <RegistrarDefs.h>
|
|
||||||
#include <String.h>
|
|
||||||
#include <storage_support.h>
|
|
||||||
|
|
||||||
#include <fs_attr.h> // For struct attr_info
|
|
||||||
#include <iostream>
|
|
||||||
#include <new> // For new(nothrow)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
|
|
||||||
#define DBG(x) x
|
|
||||||
//#define DBG(x)
|
|
||||||
#define OUT printf
|
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
namespace Storage {
|
|
||||||
namespace Mime {
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches the application hint for the given MIME type.
|
|
||||||
|
|
||||||
The entry_ref pointed to by \c ref must be pre-allocated.
|
|
||||||
|
|
||||||
\param type The MIME type of interest
|
|
||||||
\param ref Pointer to a pre-allocated \c entry_ref struct into
|
|
||||||
which the location of the hint application is copied.
|
|
||||||
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No app hint exists for the given type
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_app_hint(const char *type, entry_ref *ref)
|
|
||||||
{
|
|
||||||
if (type == NULL || ref == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
char path[B_PATH_NAME_LENGTH];
|
|
||||||
BEntry entry;
|
|
||||||
ssize_t status = read_mime_attr(type, kAppHintAttr, path,
|
|
||||||
B_PATH_NAME_LENGTH, kAppHintType);
|
|
||||||
|
|
||||||
if (status >= B_OK)
|
|
||||||
status = entry.SetTo(path);
|
|
||||||
if (status == B_OK)
|
|
||||||
status = entry.GetRef(ref);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches from the MIME database a BMessage describing the attributes
|
|
||||||
typically associated with files of the given MIME type
|
|
||||||
|
|
||||||
The attribute information is returned in a pre-allocated BMessage pointed to by
|
|
||||||
the \c info parameter (note that the any prior contents of the message
|
|
||||||
will be destroyed). Please see BMimeType::SetAttrInfo() for a description
|
|
||||||
of the expected format of such a message.
|
|
||||||
|
|
||||||
\param info Pointer to a pre-allocated BMessage into which information about
|
|
||||||
the MIME type's associated file attributes is stored.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_attr_info(const char *type, BMessage *info)
|
|
||||||
{
|
|
||||||
status_t err = read_mime_attr_message(type, kAttrInfoAttr, info);
|
|
||||||
if (err == B_ENTRY_NOT_FOUND) {
|
|
||||||
// return an empty message
|
|
||||||
info->MakeEmpty();
|
|
||||||
err = B_OK;
|
|
||||||
}
|
|
||||||
if (err == B_OK) {
|
|
||||||
info->what = 233;
|
|
||||||
// Don't know why, but that's what R5 does.
|
|
||||||
err = info->AddString("type", type);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches the short description for the given MIME type.
|
|
||||||
|
|
||||||
The string pointed to by \c description must be long enough to
|
|
||||||
hold the short description; a length of \c B_MIME_TYPE_LENGTH is
|
|
||||||
recommended.
|
|
||||||
|
|
||||||
\param type The MIME type of interest
|
|
||||||
\param description Pointer to a pre-allocated string into which the short
|
|
||||||
description is copied. If the function fails, the contents
|
|
||||||
of the string are undefined.
|
|
||||||
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No short description exists for the given type
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_short_description(const char *type, char *description)
|
|
||||||
{
|
|
||||||
/// DBG(OUT("Mime::Database::get_short_description()\n"));
|
|
||||||
ssize_t err = read_mime_attr(type, kShortDescriptionAttr, description,
|
|
||||||
B_MIME_TYPE_LENGTH, kShortDescriptionType);
|
|
||||||
return err >= 0 ? B_OK : err ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_long_description
|
|
||||||
//! Fetches the long description for the given MIME type.
|
|
||||||
/*! The string pointed to by \c description must be long enough to
|
|
||||||
hold the long description; a length of \c B_MIME_TYPE_LENGTH is
|
|
||||||
recommended.
|
|
||||||
|
|
||||||
\param type The MIME type of interest
|
|
||||||
\param description Pointer to a pre-allocated string into which the long
|
|
||||||
description is copied. If the function fails, the contents
|
|
||||||
of the string are undefined.
|
|
||||||
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No long description exists for the given type
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_long_description(const char *type, char *description)
|
|
||||||
{
|
|
||||||
// DBG(OUT("Mime::Database::get_long_description()\n"));
|
|
||||||
ssize_t err = read_mime_attr(type, kLongDescriptionAttr, description,
|
|
||||||
B_MIME_TYPE_LENGTH, kLongDescriptionType);
|
|
||||||
return err >= 0 ? B_OK : err ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches a BMessage describing the MIME type's associated filename
|
|
||||||
extensions
|
|
||||||
|
|
||||||
The list of extensions is returned in a pre-allocated BMessage pointed to
|
|
||||||
by the \c extensions parameter (note that the any prior contents of the
|
|
||||||
message will be destroyed). Please see BMimeType::GetFileExtensions() for
|
|
||||||
a description of the message format.
|
|
||||||
|
|
||||||
\param extensions Pointer to a pre-allocated BMessage into which the MIME
|
|
||||||
type's associated file extensions will be stored.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_file_extensions(const char *type, BMessage *extensions)
|
|
||||||
{
|
|
||||||
status_t err = read_mime_attr_message(type, kFileExtensionsAttr, extensions);
|
|
||||||
if (err == B_ENTRY_NOT_FOUND) {
|
|
||||||
// return an empty message
|
|
||||||
extensions->MakeEmpty();
|
|
||||||
err = B_OK;
|
|
||||||
}
|
|
||||||
if (err == B_OK) {
|
|
||||||
extensions->what = 234; // Don't know why, but that's what R5 does.
|
|
||||||
err = extensions->AddString("type", type);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches the icon of given size associated with the given MIME type
|
|
||||||
|
|
||||||
The bitmap pointed to by \c icon must be of the proper size (\c 32x32
|
|
||||||
for \c B_LARGE_ICON, \c 16x16 for \c B_MINI_ICON) and color depth
|
|
||||||
(\c B_CMAP8).
|
|
||||||
|
|
||||||
\param type The mime type
|
|
||||||
\param icon Pointer to a pre-allocated bitmap of proper dimensions and color depth
|
|
||||||
\param size The size icon you're interested in (\c B_LARGE_ICON or \c B_MINI_ICON)
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_icon(const char *type, BBitmap *icon, icon_size which)
|
|
||||||
{
|
|
||||||
return get_icon_for_type(type, NULL, icon, which);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_icon
|
|
||||||
//! Fetches the vector icon associated with the given MIME type
|
|
||||||
/* \param type The mime type
|
|
||||||
\param data Pointer in which the allocated icon data is returned. You need to
|
|
||||||
free the buffer once you're done with it.
|
|
||||||
\param size Pointer in which the size of the icon data is returned.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_icon(const char *type, uint8** data, size_t* size)
|
|
||||||
{
|
|
||||||
return get_icon_for_type(type, NULL, data, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_icon_for_type
|
|
||||||
/*! \brief Fetches the large or mini icon used by an application of this type for files of the
|
|
||||||
given type.
|
|
||||||
|
|
||||||
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 calling \c get_icon_for_type()
|
|
||||||
on a non-application type will likely return \c B_ENTRY_NOT_FOUND.
|
|
||||||
|
|
||||||
The icon is copied into the \c BBitmap pointed to by \c icon. The bitmap must
|
|
||||||
be the proper size: \c 32x32 for the large icon, \c 16x16 for the mini icon.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param fileType Pointer to a pre-allocated string containing the MIME type whose
|
|
||||||
custom icon you wish to fetch. If NULL, works just like get_icon().
|
|
||||||
\param icon Pointer to a pre-allocated \c BBitmap of proper size and colorspace into
|
|
||||||
which the icon is copied.
|
|
||||||
\param icon_size Value that specifies which icon to return. Currently \c B_LARGE_ICON
|
|
||||||
and \c B_MINI_ICON are supported.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No icon of the given size exists for the given type
|
|
||||||
- "error code": Failure
|
|
||||||
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_icon_for_type(const char* type, const char* fileType, BBitmap* icon,
|
|
||||||
icon_size which)
|
|
||||||
{
|
|
||||||
if (!type || !icon)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// open the node for the given type
|
|
||||||
BNode node;
|
|
||||||
ssize_t err = open_type(type, &node);
|
|
||||||
if (err < B_OK)
|
|
||||||
return (status_t)err;
|
|
||||||
|
|
||||||
// construct our attribute name
|
|
||||||
std::string vectorIconAttrName;
|
|
||||||
std::string smallIconAttrName;
|
|
||||||
std::string largeIconAttrName;
|
|
||||||
|
|
||||||
if (fileType) {
|
|
||||||
std::string lowerCaseFileType = BPrivate::Storage::to_lower(fileType);
|
|
||||||
|
|
||||||
vectorIconAttrName = kIconAttrPrefix + lowerCaseFileType;
|
|
||||||
smallIconAttrName = kMiniIconAttrPrefix + lowerCaseFileType;
|
|
||||||
largeIconAttrName = kLargeIconAttrPrefix + lowerCaseFileType;
|
|
||||||
} else {
|
|
||||||
vectorIconAttrName = kIconAttr;
|
|
||||||
smallIconAttrName = kMiniIconAttr;
|
|
||||||
largeIconAttrName = kLargeIconAttr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BIconUtils::GetIcon(&node, vectorIconAttrName.c_str(),
|
|
||||||
smallIconAttrName.c_str(), largeIconAttrName.c_str(),
|
|
||||||
which, icon);
|
|
||||||
|
|
||||||
|
|
||||||
// ssize_t err = type && icon ? B_OK : B_BAD_VALUE;
|
|
||||||
//
|
|
||||||
// // Figure out what kind of data we *should* find
|
|
||||||
// uint32 attrType = 0;
|
|
||||||
// ssize_t attrSize = 0;
|
|
||||||
// BRect bounds;
|
|
||||||
//
|
|
||||||
// if (!err) {
|
|
||||||
// switch (which) {
|
|
||||||
// case B_MINI_ICON:
|
|
||||||
// bounds.Set(0, 0, 15, 15);
|
|
||||||
// attrType = kMiniIconType;
|
|
||||||
// attrSize = 16 * 16;
|
|
||||||
// break;
|
|
||||||
// case B_LARGE_ICON:
|
|
||||||
// bounds.Set(0, 0, 31, 31);
|
|
||||||
// attrType = kLargeIconType;
|
|
||||||
// attrSize = 32 * 32;
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// err = B_BAD_VALUE;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // Construct our attribute name
|
|
||||||
// std::string attr;
|
|
||||||
// if (fileType) {
|
|
||||||
// attr = (which == B_MINI_ICON
|
|
||||||
// ? kMiniIconAttrPrefix
|
|
||||||
// : kLargeIconAttrPrefix)
|
|
||||||
// + BPrivate::Storage::to_lower(fileType);
|
|
||||||
// } else {
|
|
||||||
// attr = (which == B_MINI_ICON) ? kMiniIconAttr : kLargeIconAttr;
|
|
||||||
// }
|
|
||||||
// // Check the icon and attribute to see if they match
|
|
||||||
// if (!err) {
|
|
||||||
// err = (icon->InitCheck() == B_OK
|
|
||||||
// && icon->Bounds() == bounds) ? B_OK : B_BAD_VALUE;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// BNode node;
|
|
||||||
// if (!err)
|
|
||||||
// err = open_type(type, &node);
|
|
||||||
//
|
|
||||||
// attr_info info;
|
|
||||||
// if (!err)
|
|
||||||
// err = node.GetAttrInfo(attr.c_str(), &info);
|
|
||||||
//
|
|
||||||
// if (!err)
|
|
||||||
// err = (attrType == info.type && attrSize == info.size) ? B_OK : B_BAD_VALUE;
|
|
||||||
// // read the attribute
|
|
||||||
// if (!err) {
|
|
||||||
// bool otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
|
||||||
// char *buffer = NULL;
|
|
||||||
// if (otherColorSpace) {
|
|
||||||
// // other color space than stored in attribute
|
|
||||||
// buffer = new(std::nothrow) char[attrSize];
|
|
||||||
// if (!buffer)
|
|
||||||
// err = B_NO_MEMORY;
|
|
||||||
// if (!err)
|
|
||||||
// err = node.ReadAttr(attr.c_str(), attrType, 0, buffer, attrSize);
|
|
||||||
// } else {
|
|
||||||
// // same color space, just read direct
|
|
||||||
// err = node.ReadAttr(attr.c_str(), attrType, 0, icon->Bits(), attrSize);
|
|
||||||
// }
|
|
||||||
// if (err >= 0)
|
|
||||||
// err = (err == attrSize) ? (status_t)B_OK : (status_t)B_FILE_ERROR;
|
|
||||||
// if (otherColorSpace) {
|
|
||||||
// if (!err) {
|
|
||||||
// err = icon->ImportBits(buffer, attrSize, B_ANY_BYTES_PER_ROW,
|
|
||||||
// 0, B_CMAP8);
|
|
||||||
// }
|
|
||||||
// delete[] buffer;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_icon_for_type
|
|
||||||
/*! \brief Fetches the vector icon used by an application of this type for files of the
|
|
||||||
given type.
|
|
||||||
|
|
||||||
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 calling \c get_icon_for_type()
|
|
||||||
on a non-application type will likely return \c B_ENTRY_NOT_FOUND.
|
|
||||||
|
|
||||||
The icon data is allocated and returned in \a data.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param fileType Pointer to a pre-allocated string containing the MIME type whose
|
|
||||||
custom icon you wish to fetch. If NULL, works just like get_icon().
|
|
||||||
\param data Pointer in which the icon data is returned on success.
|
|
||||||
\param size Pointer in which the size of the icon data is returned.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No vector icon exists for the given type
|
|
||||||
- "error code": Failure
|
|
||||||
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_icon_for_type(const char* type, const char* fileType, uint8** data,
|
|
||||||
size_t* size)
|
|
||||||
{
|
|
||||||
if (!type || !data || !size)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// open the node for the given type
|
|
||||||
BNode node;
|
|
||||||
ssize_t err = open_type(type, &node);
|
|
||||||
if (err < B_OK)
|
|
||||||
return (status_t)err;
|
|
||||||
|
|
||||||
// construct our attribute name
|
|
||||||
std::string iconAttrName;
|
|
||||||
|
|
||||||
if (fileType)
|
|
||||||
iconAttrName = kIconAttrPrefix + BPrivate::Storage::to_lower(fileType);
|
|
||||||
else
|
|
||||||
iconAttrName = kIconAttr;
|
|
||||||
|
|
||||||
// get info about attribute for that name
|
|
||||||
attr_info info;
|
|
||||||
if (!err)
|
|
||||||
err = node.GetAttrInfo(iconAttrName.c_str(), &info);
|
|
||||||
|
|
||||||
// validate attribute type
|
|
||||||
if (!err)
|
|
||||||
err = (info.type == B_VECTOR_ICON_TYPE) ? B_OK : B_BAD_VALUE;
|
|
||||||
|
|
||||||
// allocate a buffer and read the attribute data into it
|
|
||||||
if (!err) {
|
|
||||||
uint8* buffer = new(std::nothrow) uint8[info.size];
|
|
||||||
if (!buffer)
|
|
||||||
err = B_NO_MEMORY;
|
|
||||||
if (!err) {
|
|
||||||
err = node.ReadAttr(iconAttrName.c_str(), B_VECTOR_ICON_TYPE,
|
|
||||||
0, buffer, info.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err >= 0)
|
|
||||||
err = (err == info.size) ? (ssize_t)B_OK : (ssize_t)B_FILE_ERROR;
|
|
||||||
|
|
||||||
if (!err) {
|
|
||||||
// success, set data pointer and size
|
|
||||||
*data = buffer;
|
|
||||||
*size = info.size;
|
|
||||||
} else {
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches signature of the MIME type's preferred application for the
|
|
||||||
given action.
|
|
||||||
|
|
||||||
The string pointed to by \c signature must be long enough to
|
|
||||||
hold the short description; a length of \c B_MIME_TYPE_LENGTH is
|
|
||||||
recommended.
|
|
||||||
|
|
||||||
Currently, the only supported app verb is \c B_OPEN.
|
|
||||||
|
|
||||||
\param type The MIME type of interest
|
|
||||||
\param description Pointer to a pre-allocated string into which the
|
|
||||||
preferred application's signature is copied. If the function fails,
|
|
||||||
the contents of the string are undefined.
|
|
||||||
\param verb \c The action of interest
|
|
||||||
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No such preferred application exists
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_preferred_app(const char *type, char *signature, app_verb verb = B_OPEN)
|
|
||||||
{
|
|
||||||
// Since B_OPEN is the currently the only app_verb, it is essentially ignored
|
|
||||||
ssize_t err = read_mime_attr(type, kPreferredAppAttr, signature,
|
|
||||||
B_MIME_TYPE_LENGTH, kPreferredAppType);
|
|
||||||
return err >= 0 ? B_OK : err ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Fetches the sniffer rule for the given MIME type.
|
|
||||||
\param type The MIME type of interest
|
|
||||||
\param result Pointer to a pre-allocated BString into which the type's
|
|
||||||
sniffer rule is copied.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Success
|
|
||||||
- \c B_ENTRY_NOT_FOUND: No such preferred application exists
|
|
||||||
- "error code": Failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_sniffer_rule(const char *type, BString *result)
|
|
||||||
{
|
|
||||||
return read_mime_attr_string(type, kSnifferRuleAttr, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
get_supported_types(const char *type, BMessage *types)
|
|
||||||
{
|
|
||||||
status_t err = read_mime_attr_message(type, kSupportedTypesAttr, types);
|
|
||||||
if (err == B_ENTRY_NOT_FOUND) {
|
|
||||||
// return an empty message
|
|
||||||
types->MakeEmpty();
|
|
||||||
err = B_OK;
|
|
||||||
}
|
|
||||||
if (err == B_OK) {
|
|
||||||
types->what = 0;
|
|
||||||
err = types->AddString("type", type);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Checks if the given MIME type is present in the database
|
|
||||||
bool
|
|
||||||
is_installed(const char *type)
|
|
||||||
{
|
|
||||||
BNode node;
|
|
||||||
return open_type(type, &node) == B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Returns properly formatted raw bitmap data, ready to be shipped off
|
|
||||||
to the hacked up 4-parameter version of Database::SetIcon()
|
|
||||||
|
|
||||||
This function exists as something of a hack until an OBOS::BBitmap
|
|
||||||
implementation is available. It takes the given bitmap, converts it to the
|
|
||||||
B_CMAP8 color space if necessary and able, and returns said bitmap data in
|
|
||||||
a newly allocated array pointed to by the pointer that's pointed to by
|
|
||||||
\c data. The length of the array is stored in the integer pointed to by
|
|
||||||
\c dataSize. The array is allocated with \c new[], and it's your
|
|
||||||
responsibility to \c delete[] it when you're finished.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
get_icon_data(const BBitmap *icon, icon_size which, void **data,
|
|
||||||
int32 *dataSize)
|
|
||||||
{
|
|
||||||
if (icon == NULL || data == NULL || dataSize == 0
|
|
||||||
|| icon->InitCheck() != B_OK)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
BRect bounds;
|
|
||||||
BBitmap *icon8 = NULL;
|
|
||||||
void *srcData = NULL;
|
|
||||||
bool otherColorSpace = false;
|
|
||||||
|
|
||||||
// Figure out what kind of data we *should* have
|
|
||||||
switch (which) {
|
|
||||||
case B_MINI_ICON:
|
|
||||||
bounds.Set(0, 0, 15, 15);
|
|
||||||
break;
|
|
||||||
case B_LARGE_ICON:
|
|
||||||
bounds.Set(0, 0, 31, 31);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the icon
|
|
||||||
status_t err = icon->Bounds() == bounds ? B_OK : B_BAD_VALUE;
|
|
||||||
|
|
||||||
// Convert to B_CMAP8 if necessary
|
|
||||||
if (!err) {
|
|
||||||
otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
|
||||||
if (otherColorSpace) {
|
|
||||||
icon8 = new(std::nothrow) BBitmap(bounds, B_BITMAP_NO_SERVER_LINK,
|
|
||||||
B_CMAP8);
|
|
||||||
if (!icon8)
|
|
||||||
err = B_NO_MEMORY;
|
|
||||||
if (!err)
|
|
||||||
err = icon8->ImportBits(icon);
|
|
||||||
if (!err) {
|
|
||||||
srcData = icon8->Bits();
|
|
||||||
*dataSize = icon8->BitsLength();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
srcData = icon->Bits();
|
|
||||||
*dataSize = icon->BitsLength();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alloc a new data buffer
|
|
||||||
if (!err) {
|
|
||||||
*data = new(std::nothrow) char[*dataSize];
|
|
||||||
if (!*data)
|
|
||||||
err = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy the data into it.
|
|
||||||
if (!err)
|
|
||||||
memcpy(*data, srcData, *dataSize);
|
|
||||||
if (otherColorSpace)
|
|
||||||
delete icon8;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Mime
|
|
||||||
} // namespace Storage
|
|
||||||
} // namespace BPrivate
|
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006, Haiku.
|
* Copyright 2002-2013, Haiku.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@@ -7,37 +7,16 @@
|
|||||||
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
* Ingo Weinhold <ingo_weinhold@gmx.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
|
||||||
\file database_support.cpp
|
|
||||||
Private mime database functions and constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <AppMisc.h>
|
#include <mime/database_support.h>
|
||||||
#include <DataIO.h>
|
|
||||||
#include <Directory.h>
|
#include <pthread.h>
|
||||||
#include <File.h>
|
|
||||||
|
#include <Bitmap.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
#include <Entry.h>
|
|
||||||
#include <Message.h>
|
|
||||||
#include <Node.h>
|
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <storage_support.h>
|
|
||||||
#include <StringList.h>
|
|
||||||
#include <TypeConstants.h>
|
|
||||||
|
|
||||||
#include <fs_attr.h> // For struct attr_info
|
#include <mime/DatabaseLocation.h>
|
||||||
#include <new> // For new(nothrow)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
|
|
||||||
#include <AutoDeleter.h>
|
|
||||||
|
|
||||||
#include "mime/database_support.h"
|
|
||||||
|
|
||||||
//#define DBG(x) x
|
|
||||||
#define DBG(x)
|
|
||||||
#define OUT printf
|
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -109,12 +88,12 @@ static const directory_which kBaseDirectoryConstants[] = {
|
|||||||
B_SYSTEM_DATA_DIRECTORY
|
B_SYSTEM_DATA_DIRECTORY
|
||||||
};
|
};
|
||||||
|
|
||||||
static pthread_once_t sDatabaseDirectoryInitOnce = PTHREAD_ONCE_INIT;
|
static pthread_once_t sDefaultDatabaseLocationInitOnce = PTHREAD_ONCE_INIT;
|
||||||
static BStringList sDatabaseDirectories;
|
static DatabaseLocation sDefaultDatabaseLocation;
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_database_directories()
|
init_default_database_location()
|
||||||
{
|
{
|
||||||
for (size_t i = 0;
|
for (size_t i = 0;
|
||||||
i < sizeof(kBaseDirectoryConstants)
|
i < sizeof(kBaseDirectoryConstants)
|
||||||
@@ -129,410 +108,94 @@ init_database_directories()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
directoryPath += "/mime_db";
|
directoryPath += "/mime_db";
|
||||||
sDatabaseDirectories.Add(directoryPath);
|
sDefaultDatabaseLocation.AddDirectory(directoryPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const BStringList&
|
DatabaseLocation*
|
||||||
get_database_directories()
|
default_database_location()
|
||||||
{
|
{
|
||||||
pthread_once(&sDatabaseDirectoryInitOnce, &init_database_directories);
|
pthread_once(&sDefaultDatabaseLocationInitOnce,
|
||||||
return sDatabaseDirectories;
|
&init_default_database_location);
|
||||||
|
return &sDefaultDatabaseLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BString
|
/*! \brief Returns properly formatted raw bitmap data, ready to be shipped off
|
||||||
get_writable_database_directory()
|
to the hacked up 4-parameter version of Database::SetIcon()
|
||||||
{
|
|
||||||
return get_database_directories().StringAt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
This function exists as something of a hack until an OBOS::BBitmap
|
||||||
static BString
|
implementation is available. It takes the given bitmap, converts it to the
|
||||||
type_to_filename(const char* type, int32 index)
|
B_CMAP8 color space if necessary and able, and returns said bitmap data in
|
||||||
{
|
a newly allocated array pointed to by the pointer that's pointed to by
|
||||||
BString path = get_database_directories().StringAt(index);
|
\c data. The length of the array is stored in the integer pointed to by
|
||||||
return path << '/' << BPrivate::Storage::to_lower(type).c_str();
|
\c dataSize. The array is allocated with \c new[], and it's your
|
||||||
}
|
responsibility to \c delete[] it when you're finished.
|
||||||
|
|
||||||
|
|
||||||
/*! Converts the given MIME type to an absolute path in the user writeable MIME
|
|
||||||
database directory.
|
|
||||||
*/
|
|
||||||
BString
|
|
||||||
type_to_writable_filename(const char* type)
|
|
||||||
{
|
|
||||||
return type_to_filename(type, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
open_type(const char* type, BNode* _node, int32& _index)
|
|
||||||
{
|
|
||||||
const BStringList& directories = get_database_directories();
|
|
||||||
int32 count = directories.CountStrings();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
status_t error = _node->SetTo(type_to_filename(type, i));
|
|
||||||
attr_info attrInfo;
|
|
||||||
if (error == B_OK && _node->GetAttrInfo(kTypeAttr, &attrInfo) == B_OK) {
|
|
||||||
_index = i;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
create_type_node(const char* type, BNode& _result)
|
|
||||||
{
|
|
||||||
const char* slash = strchr(type, '/');
|
|
||||||
BString superTypeName;
|
|
||||||
if (slash != NULL)
|
|
||||||
superTypeName.SetTo(type, slash - type);
|
|
||||||
else
|
|
||||||
superTypeName = type;
|
|
||||||
superTypeName.ToLower();
|
|
||||||
|
|
||||||
// open/create the directory for the supertype
|
|
||||||
BDirectory parent(get_writable_database_directory());
|
|
||||||
status_t error = parent.InitCheck();
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
BDirectory superTypeDirectory;
|
|
||||||
if (BEntry(&parent, superTypeName).Exists())
|
|
||||||
error = superTypeDirectory.SetTo(&parent, superTypeName);
|
|
||||||
else
|
|
||||||
error = parent.CreateDirectory(superTypeName, &superTypeDirectory);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// create the subtype
|
|
||||||
BFile subTypeFile;
|
|
||||||
if (slash != NULL) {
|
|
||||||
error = superTypeDirectory.CreateFile(BString(slash + 1).ToLower(),
|
|
||||||
&subTypeFile);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// assign the result
|
|
||||||
if (slash != NULL)
|
|
||||||
_result = subTypeFile;
|
|
||||||
else
|
|
||||||
_result = superTypeDirectory;
|
|
||||||
return _result.InitCheck();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
copy_type_node(BNode& source, const char* type, BNode& _target)
|
|
||||||
{
|
|
||||||
status_t error = create_type_node(type, _target);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// copy the attributes
|
|
||||||
MemoryDeleter bufferDeleter;
|
|
||||||
size_t bufferSize = 0;
|
|
||||||
|
|
||||||
source.RewindAttrs();
|
|
||||||
char attribute[B_ATTR_NAME_LENGTH];
|
|
||||||
while (source.GetNextAttrName(attribute) == B_OK) {
|
|
||||||
attr_info info;
|
|
||||||
error = source.GetAttrInfo(attribute, &info);
|
|
||||||
if (error != B_OK) {
|
|
||||||
syslog(LOG_ERR, "Failed to get info for attribute \"%s\" of MIME "
|
|
||||||
"type \"%s\": %s", attribute, type, strerror(error));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resize our buffer, if necessary
|
|
||||||
if (info.size > bufferSize) {
|
|
||||||
bufferDeleter.SetTo(malloc(info.size));
|
|
||||||
if (bufferDeleter.Get() == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
bufferSize = info.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t bytesRead = source.ReadAttr(attribute, info.type, 0,
|
|
||||||
bufferDeleter.Get(), info.size);
|
|
||||||
if (bytesRead != info.size) {
|
|
||||||
syslog(LOG_ERR, "Failed to read attribute \"%s\" of MIME "
|
|
||||||
"type \"%s\": %s", attribute, type,
|
|
||||||
bytesRead < 0 ? strerror(bytesRead) : "short read");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t bytesWritten = _target.WriteAttr(attribute, info.type, 0,
|
|
||||||
bufferDeleter.Get(), info.size);
|
|
||||||
if (bytesWritten < 0) {
|
|
||||||
syslog(LOG_ERR, "Failed to write attribute \"%s\" of MIME "
|
|
||||||
"type \"%s\": %s", attribute, type,
|
|
||||||
bytesWritten < 0 ? strerror(bytesWritten) : "short write");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// open_type
|
|
||||||
/*! \brief Opens a BNode on the given type, failing if the type has no
|
|
||||||
corresponding file in the database.
|
|
||||||
\param type The MIME type to open
|
|
||||||
\param result Pointer to a pre-allocated BNode into which
|
|
||||||
is opened on the given MIME type
|
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
open_type(const char *type, BNode *result)
|
get_icon_data(const BBitmap *icon, icon_size which, void **data,
|
||||||
|
int32 *dataSize)
|
||||||
{
|
{
|
||||||
if (type == NULL || result == NULL)
|
if (icon == NULL || data == NULL || dataSize == 0
|
||||||
|
|| icon->InitCheck() != B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
int32 index;
|
BRect bounds;
|
||||||
return open_type(type, result, index);
|
BBitmap *icon8 = NULL;
|
||||||
}
|
void *srcData = NULL;
|
||||||
|
bool otherColorSpace = false;
|
||||||
|
|
||||||
// open_or_create_type
|
// Figure out what kind of data we *should* have
|
||||||
/*! \brief Opens a BNode on the given type, creating a node of the
|
switch (which) {
|
||||||
appropriate flavor if necessary.
|
case B_MINI_ICON:
|
||||||
|
bounds.Set(0, 0, 15, 15);
|
||||||
All MIME types are converted to lowercase for use in the filesystem.
|
break;
|
||||||
\param type The MIME type to open
|
case B_LARGE_ICON:
|
||||||
\param result Pointer to a pre-allocated BNode into which
|
bounds.Set(0, 0, 31, 31);
|
||||||
is opened on the given MIME type
|
break;
|
||||||
*/
|
default:
|
||||||
status_t
|
return B_BAD_VALUE;
|
||||||
open_or_create_type(const char *type, BNode *result, bool *didCreate)
|
|
||||||
{
|
|
||||||
if (didCreate)
|
|
||||||
*didCreate = false;
|
|
||||||
|
|
||||||
// See, if the type already exists.
|
|
||||||
int32 index;
|
|
||||||
status_t error = open_type(type, result, index);
|
|
||||||
if (error == B_OK) {
|
|
||||||
if (index == 0)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
// The caller wants a editable node, but the node found is not in the
|
|
||||||
// user's settings directory. Copy the node.
|
|
||||||
BNode nodeToClone(*result);
|
|
||||||
if (nodeToClone.InitCheck() != B_OK)
|
|
||||||
return nodeToClone.InitCheck();
|
|
||||||
|
|
||||||
error = copy_type_node(nodeToClone, type, *result);
|
|
||||||
if (error != B_OK) {
|
|
||||||
result->Unset();
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (didCreate != NULL)
|
|
||||||
*didCreate = true;
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// type doesn't exist yet -- create the respective node
|
// Check the icon
|
||||||
error = create_type_node(type, *result);
|
status_t err = icon->Bounds() == bounds ? B_OK : B_BAD_VALUE;
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// write the type attribute
|
// Convert to B_CMAP8 if necessary
|
||||||
error = result->WriteAttr(kTypeAttr, B_STRING_TYPE, 0, type,
|
|
||||||
strlen(type) + 1);
|
|
||||||
if (error != B_OK) {
|
|
||||||
result->Unset();
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (didCreate != NULL)
|
|
||||||
*didCreate = true;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read_mime_attr
|
|
||||||
/*! \brief Reads up to \c len bytes of the given data from the given attribute
|
|
||||||
for the given MIME type.
|
|
||||||
|
|
||||||
If no entry for the given type exists in the database, the function fails,
|
|
||||||
and the contents of \c data are undefined.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param attr The attribute name
|
|
||||||
\param data Pointer to a memory buffer into which the data should be copied
|
|
||||||
\param len The maximum number of bytes to read
|
|
||||||
\param datatype The expected data type
|
|
||||||
\return If successful, the number of bytes read is returned, otherwise, an
|
|
||||||
error code is returned.
|
|
||||||
*/
|
|
||||||
ssize_t
|
|
||||||
read_mime_attr(const char *type, const char *attr, void *data,
|
|
||||||
size_t len, type_code datatype)
|
|
||||||
{
|
|
||||||
BNode node;
|
|
||||||
ssize_t err = (type && attr && data ? B_OK : B_BAD_VALUE);
|
|
||||||
if (!err)
|
|
||||||
err = open_type(type, &node);
|
|
||||||
if (!err)
|
|
||||||
err = node.ReadAttr(attr, datatype, 0, data, len);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// read_mime_attr_message
|
|
||||||
/*! \brief Reads a flattened BMessage from the given attribute of the given
|
|
||||||
MIME type.
|
|
||||||
|
|
||||||
If no entry for the given type exists in the database, or if the data
|
|
||||||
stored in the attribute is not a flattened BMessage, the function fails
|
|
||||||
and the contents of \c msg are undefined.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param attr The attribute name
|
|
||||||
\param data Pointer to a pre-allocated BMessage into which the attribute
|
|
||||||
data is unflattened.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
read_mime_attr_message(const char *type, const char *attr, BMessage *msg)
|
|
||||||
{
|
|
||||||
BNode node;
|
|
||||||
attr_info info;
|
|
||||||
char *buffer = NULL;
|
|
||||||
ssize_t err = (type && attr && msg ? B_OK : B_BAD_VALUE);
|
|
||||||
if (!err)
|
|
||||||
err = open_type(type, &node);
|
|
||||||
if (!err)
|
|
||||||
err = node.GetAttrInfo(attr, &info);
|
|
||||||
if (!err)
|
|
||||||
err = info.type == B_MESSAGE_TYPE ? B_OK : B_BAD_VALUE;
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
buffer = new(std::nothrow) char[info.size];
|
otherColorSpace = (icon->ColorSpace() != B_CMAP8);
|
||||||
if (!buffer)
|
if (otherColorSpace) {
|
||||||
|
icon8 = new(std::nothrow) BBitmap(bounds, B_BITMAP_NO_SERVER_LINK,
|
||||||
|
B_CMAP8);
|
||||||
|
if (!icon8)
|
||||||
|
err = B_NO_MEMORY;
|
||||||
|
if (!err)
|
||||||
|
err = icon8->ImportBits(icon);
|
||||||
|
if (!err) {
|
||||||
|
srcData = icon8->Bits();
|
||||||
|
*dataSize = icon8->BitsLength();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
srcData = icon->Bits();
|
||||||
|
*dataSize = icon->BitsLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alloc a new data buffer
|
||||||
|
if (!err) {
|
||||||
|
*data = new(std::nothrow) char[*dataSize];
|
||||||
|
if (!*data)
|
||||||
err = B_NO_MEMORY;
|
err = B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the data into it.
|
||||||
if (!err)
|
if (!err)
|
||||||
err = node.ReadAttr(attr, B_MESSAGE_TYPE, 0, buffer, info.size);
|
memcpy(*data, srcData, *dataSize);
|
||||||
if (err >= 0)
|
if (otherColorSpace)
|
||||||
err = err == info.size ? (status_t)B_OK : (status_t)B_FILE_ERROR;
|
delete icon8;
|
||||||
if (!err)
|
|
||||||
err = msg->Unflatten(buffer);
|
|
||||||
delete [] buffer;
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read_mime_attr_string
|
|
||||||
/*! \brief Reads a BString from the given attribute of the given
|
|
||||||
MIME type.
|
|
||||||
|
|
||||||
If no entry for the given type exists in the database, the function fails
|
|
||||||
and the contents of \c str are undefined.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param attr The attribute name
|
|
||||||
\param str Pointer to a pre-allocated BString into which the attribute
|
|
||||||
data stored.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
read_mime_attr_string(const char *type, const char *attr, BString *str)
|
|
||||||
{
|
|
||||||
BNode node;
|
|
||||||
status_t err = (type && attr && str ? B_OK : B_BAD_VALUE);
|
|
||||||
if (!err)
|
|
||||||
err = open_type(type, &node);
|
|
||||||
if (!err)
|
|
||||||
err = node.ReadAttrString(attr, str);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write_mime_attr
|
|
||||||
/*! \brief Writes \c len bytes of the given data to the given attribute
|
|
||||||
for the given MIME type.
|
|
||||||
|
|
||||||
If no entry for the given type exists in the database, it is created.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param attr The attribute name
|
|
||||||
\param data Pointer to the data to write
|
|
||||||
\param len The number of bytes to write
|
|
||||||
\param datatype The data type of the given data
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
write_mime_attr(const char *type, const char *attr, const void *data,
|
|
||||||
size_t len, type_code datatype, bool *didCreate)
|
|
||||||
{
|
|
||||||
BNode node;
|
|
||||||
status_t err = (type && attr && data ? B_OK : B_BAD_VALUE);
|
|
||||||
if (!err)
|
|
||||||
err = open_or_create_type(type, &node, didCreate);
|
|
||||||
if (!err) {
|
|
||||||
ssize_t bytes = node.WriteAttr(attr, datatype, 0, data, len);
|
|
||||||
if (bytes < B_OK)
|
|
||||||
err = bytes;
|
|
||||||
else
|
|
||||||
err = (bytes != (ssize_t)len ? (status_t)B_FILE_ERROR : (status_t)B_OK);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// write_mime_attr_message
|
|
||||||
/*! \brief Flattens the given \c BMessage and writes it to the given attribute
|
|
||||||
of the given MIME type.
|
|
||||||
|
|
||||||
If no entry for the given type exists in the database, it is created.
|
|
||||||
|
|
||||||
\param type The MIME type
|
|
||||||
\param attr The attribute name
|
|
||||||
\param msg The BMessage to flatten and write
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
write_mime_attr_message(const char *type, const char *attr, const BMessage *msg, bool *didCreate)
|
|
||||||
{
|
|
||||||
BNode node;
|
|
||||||
BMallocIO data;
|
|
||||||
ssize_t bytes;
|
|
||||||
ssize_t err = (type && attr && msg ? B_OK : B_BAD_VALUE);
|
|
||||||
if (!err)
|
|
||||||
err = data.SetSize(msg->FlattenedSize());
|
|
||||||
if (!err)
|
|
||||||
err = msg->Flatten(&data, &bytes);
|
|
||||||
if (!err)
|
|
||||||
err = bytes == msg->FlattenedSize() ? B_OK : B_ERROR;
|
|
||||||
if (!err)
|
|
||||||
err = open_or_create_type(type, &node, didCreate);
|
|
||||||
if (!err)
|
|
||||||
err = node.WriteAttr(attr, B_MESSAGE_TYPE, 0, data.Buffer(), data.BufferLength());
|
|
||||||
if (err >= 0)
|
|
||||||
err = err == (ssize_t)data.BufferLength() ? (ssize_t)B_OK : (ssize_t)B_FILE_ERROR;
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete_attribute
|
|
||||||
//! Deletes the given attribute for the given type
|
|
||||||
/*!
|
|
||||||
\param type The mime type
|
|
||||||
\param attr The attribute name
|
|
||||||
\return
|
|
||||||
- B_OK: success
|
|
||||||
- B_ENTRY_NOT_FOUND: no such type or attribute
|
|
||||||
- "error code": failure
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
delete_attribute(const char *type, const char *attr)
|
|
||||||
{
|
|
||||||
status_t err = type ? B_OK : B_BAD_VALUE;
|
|
||||||
BNode node;
|
|
||||||
if (!err)
|
|
||||||
err = open_type(type, &node);
|
|
||||||
if (!err)
|
|
||||||
err = node.RemoveAttr(attr);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Mime
|
} // namespace Mime
|
||||||
} // namespace Storage
|
} // namespace Storage
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <TypeConstants.h>
|
#include <TypeConstants.h>
|
||||||
|
|
||||||
|
#include <mime/database_support.h>
|
||||||
|
|
||||||
#include "CreateAppMetaMimeThread.h"
|
#include "CreateAppMetaMimeThread.h"
|
||||||
#include "MessageDeliverer.h"
|
#include "MessageDeliverer.h"
|
||||||
#include "MimeSnifferAddonManager.h"
|
#include "MimeSnifferAddonManager.h"
|
||||||
@@ -56,7 +58,8 @@ init_mime_sniffer_add_on_manager()
|
|||||||
MIMEManager::MIMEManager()
|
MIMEManager::MIMEManager()
|
||||||
:
|
:
|
||||||
BLooper("main_mime"),
|
BLooper("main_mime"),
|
||||||
fDatabase(init_mime_sniffer_add_on_manager(), this),
|
fDatabase(BPrivate::Storage::Mime::default_database_location(),
|
||||||
|
init_mime_sniffer_add_on_manager(), this),
|
||||||
fThreadManager()
|
fThreadManager()
|
||||||
{
|
{
|
||||||
AddHandler(&fThreadManager);
|
AddHandler(&fThreadManager);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <mime/Database.h>
|
#include <mime/Database.h>
|
||||||
#include <mime/database_support.h>
|
#include <mime/database_support.h>
|
||||||
|
#include <mime/DatabaseLocation.h>
|
||||||
|
|
||||||
|
|
||||||
namespace BPrivate {
|
namespace BPrivate {
|
||||||
@@ -83,7 +84,7 @@ CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
|
|||||||
mime.Install();
|
mime.Install();
|
||||||
|
|
||||||
BNode typeNode;
|
BNode typeNode;
|
||||||
status = open_type(signature, &typeNode);
|
status = fDatabase->Location()->OpenType(signature, typeNode);
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user