packagefs: Share string instances globally
Introduce a class String which refers to shared private data that is registered in a global hash table (in class StringPool) and use the class consequently. This eliminates duplicate allocations for the same string and also speeds up tests for equality. There's quite a bit overhead for the management structures (apparently even more than for the string data itself), but due to almost all strings being used multiple times this still almost halves the memory usage for string data.
This commit is contained in:
parent
1848fdc329
commit
d07c930c1e
@ -53,6 +53,9 @@ HAIKU_PACKAGE_FS_SOURCES =
|
|||||||
Resolvable.cpp
|
Resolvable.cpp
|
||||||
ResolvableFamily.cpp
|
ResolvableFamily.cpp
|
||||||
SizeIndex.cpp
|
SizeIndex.cpp
|
||||||
|
String.cpp
|
||||||
|
StringConstants.cpp
|
||||||
|
StringPool.cpp
|
||||||
UnpackingAttributeCookie.cpp
|
UnpackingAttributeCookie.cpp
|
||||||
UnpackingAttributeDirectoryCookie.cpp
|
UnpackingAttributeDirectoryCookie.cpp
|
||||||
UnpackingDirectory.cpp
|
UnpackingDirectory.cpp
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
class AttributeIndex;
|
class AttributeIndex;
|
||||||
class AttributeIndexTreeValue;
|
class AttributeIndexTreeValue;
|
||||||
@ -28,12 +30,12 @@ public:
|
|||||||
AttributeIndexTreeValue* Cookie() const
|
AttributeIndexTreeValue* Cookie() const
|
||||||
{ return fCookie; }
|
{ return fCookie; }
|
||||||
|
|
||||||
const char* IndexName() const
|
const String& IndexName() const
|
||||||
{ return fIndexName; }
|
{ return fIndexName; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AttributeIndex* fIndex;
|
AttributeIndex* fIndex;
|
||||||
const char* fIndexName;
|
const String& fIndexName;
|
||||||
uint32 fIndexType;
|
uint32 fIndexType;
|
||||||
AttributeIndexTreeValue* fCookie;
|
AttributeIndexTreeValue* fCookie;
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
Index::Index()
|
Index::Index()
|
||||||
:
|
:
|
||||||
fVolume(NULL),
|
fVolume(NULL),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fType(0),
|
fType(0),
|
||||||
fKeyLength(0),
|
fKeyLength(0),
|
||||||
fFixedKeyLength(true)
|
fFixedKeyLength(true)
|
||||||
@ -28,7 +28,6 @@ Index::Index()
|
|||||||
|
|
||||||
Index::~Index()
|
Index::~Index()
|
||||||
{
|
{
|
||||||
free(fName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -36,8 +35,7 @@ status_t
|
|||||||
Index::Init(Volume* volume, const char* name, uint32 type, bool fixedKeyLength,
|
Index::Init(Volume* volume, const char* name, uint32 type, bool fixedKeyLength,
|
||||||
size_t keyLength)
|
size_t keyLength)
|
||||||
{
|
{
|
||||||
fName = strdup(name);
|
if (!fName.SetTo(name))
|
||||||
if (fName == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
fVolume = volume;
|
fVolume = volume;
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#include <util/khash.h>
|
#include <util/khash.h>
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
#include "StringKey.h"
|
||||||
|
|
||||||
|
|
||||||
class AbstractIndexIterator;
|
class AbstractIndexIterator;
|
||||||
class IndexIterator;
|
class IndexIterator;
|
||||||
@ -34,7 +37,7 @@ public:
|
|||||||
|
|
||||||
Volume* GetVolume() const { return fVolume; }
|
Volume* GetVolume() const { return fVolume; }
|
||||||
|
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
uint32 Type() const { return fType; }
|
uint32 Type() const { return fType; }
|
||||||
bool HasFixedKeyLength() const
|
bool HasFixedKeyLength() const
|
||||||
{ return fFixedKeyLength; }
|
{ return fFixedKeyLength; }
|
||||||
@ -64,7 +67,7 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
Index* fHashLink;
|
Index* fHashLink;
|
||||||
Volume* fVolume;
|
Volume* fVolume;
|
||||||
char* fName;
|
String fName;
|
||||||
uint32 fType;
|
uint32 fType;
|
||||||
size_t fKeyLength;
|
size_t fKeyLength;
|
||||||
bool fFixedKeyLength;
|
bool fFixedKeyLength;
|
||||||
@ -98,22 +101,22 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
struct IndexHashDefinition {
|
struct IndexHashDefinition {
|
||||||
typedef const char* KeyType;
|
typedef StringKey KeyType;
|
||||||
typedef Index ValueType;
|
typedef Index ValueType;
|
||||||
|
|
||||||
size_t HashKey(const char* key) const
|
size_t HashKey(const StringKey& key) const
|
||||||
{
|
{
|
||||||
return key != NULL ? hash_hash_string(key) : 0;
|
return key.Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Hash(const Index* value) const
|
size_t Hash(const Index* value) const
|
||||||
{
|
{
|
||||||
return HashKey(value->Name());
|
return value->Name().Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compare(const char* key, const Index* value) const
|
bool Compare(const StringKey& key, const Index* value) const
|
||||||
{
|
{
|
||||||
return strcmp(value->Name(), key) == 0;
|
return key == value->Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
Index*& GetLink(Index* value) const
|
Index*& GetLink(Index* value) const
|
||||||
|
@ -84,7 +84,7 @@ struct Query::QueryPolicy {
|
|||||||
|
|
||||||
static status_t IndexSetTo(Index& index, const char* attribute)
|
static status_t IndexSetTo(Index& index, const char* attribute)
|
||||||
{
|
{
|
||||||
index.index = index.query->fVolume->FindIndex(attribute);
|
index.index = index.query->fVolume->FindIndex(StringKey(attribute));
|
||||||
return index.index != NULL ? B_OK : B_ENTRY_NOT_FOUND;
|
return index.index != NULL ? B_OK : B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +181,8 @@ struct Query::QueryPolicy {
|
|||||||
{
|
{
|
||||||
// TODO: Creating a cookie is quite a bit of overhead.
|
// TODO: Creating a cookie is quite a bit of overhead.
|
||||||
AttributeCookie* cookie;
|
AttributeCookie* cookie;
|
||||||
status_t error = node->OpenAttribute(attribute, O_RDONLY, cookie);
|
status_t error = node->OpenAttribute(StringKey(attribute), O_RDONLY,
|
||||||
|
cookie);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#include "GlobalFactory.h"
|
#include "GlobalFactory.h"
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
#include "PackageFSRoot.h"
|
#include "PackageFSRoot.h"
|
||||||
|
#include "StringConstants.h"
|
||||||
|
#include "StringPool.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
@ -181,7 +183,8 @@ packagefs_lookup(fs_volume* fsVolume, fs_vnode* fsDir, const char* entryName,
|
|||||||
|
|
||||||
// resolve normal entries -- look up the node
|
// resolve normal entries -- look up the node
|
||||||
NodeReadLocker dirLocker(dir);
|
NodeReadLocker dirLocker(dir);
|
||||||
Node* node = dynamic_cast<Directory*>(dir)->FindChild(entryName);
|
String entryNameString;
|
||||||
|
Node* node = dynamic_cast<Directory*>(dir)->FindChild(StringKey(entryName));
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
BReference<Node> nodeReference(node);
|
BReference<Node> nodeReference(node);
|
||||||
@ -792,7 +795,7 @@ packagefs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name,
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
AttributeCookie* cookie;
|
AttributeCookie* cookie;
|
||||||
error = node->OpenAttribute(name, openMode, cookie);
|
error = node->OpenAttribute(StringKey(name), openMode, cookie);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@ -976,7 +979,7 @@ packagefs_read_index_stat(fs_volume* fsVolume, const char* name,
|
|||||||
|
|
||||||
FUNCTION("volume: %p, name: \"%s\", stat: %p\n", volume, name, stat);
|
FUNCTION("volume: %p, name: \"%s\", stat: %p\n", volume, name, stat);
|
||||||
|
|
||||||
Index* index = volume->FindIndex(name);
|
Index* index = volume->FindIndex(StringKey(name));
|
||||||
if (index == NULL)
|
if (index == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
@ -1093,9 +1096,25 @@ packagefs_std_ops(int32 op, ...)
|
|||||||
init_debugging();
|
init_debugging();
|
||||||
PRINT("package_std_ops(): B_MODULE_INIT\n");
|
PRINT("package_std_ops(): B_MODULE_INIT\n");
|
||||||
|
|
||||||
status_t error = GlobalFactory::CreateDefault();
|
status_t error = StringPool::Init();
|
||||||
|
if (error != B_OK) {
|
||||||
|
ERROR("Failed to init StringPool\n");
|
||||||
|
exit_debugging();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringConstants::Init()) {
|
||||||
|
ERROR("Failed to init string constants\n");
|
||||||
|
StringPool::Cleanup();
|
||||||
|
exit_debugging();
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = GlobalFactory::CreateDefault();
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
ERROR("Failed to init GlobalFactory\n");
|
ERROR("Failed to init GlobalFactory\n");
|
||||||
|
StringConstants::Cleanup();
|
||||||
|
StringPool::Cleanup();
|
||||||
exit_debugging();
|
exit_debugging();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1104,6 +1123,8 @@ packagefs_std_ops(int32 op, ...)
|
|||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
ERROR("Failed to init PackageFSRoot\n");
|
ERROR("Failed to init PackageFSRoot\n");
|
||||||
GlobalFactory::DeleteDefault();
|
GlobalFactory::DeleteDefault();
|
||||||
|
StringConstants::Cleanup();
|
||||||
|
StringPool::Cleanup();
|
||||||
exit_debugging();
|
exit_debugging();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -1116,6 +1137,8 @@ packagefs_std_ops(int32 op, ...)
|
|||||||
PRINT("package_std_ops(): B_MODULE_UNINIT\n");
|
PRINT("package_std_ops(): B_MODULE_UNINIT\n");
|
||||||
PackageFSRoot::GlobalUninit();
|
PackageFSRoot::GlobalUninit();
|
||||||
GlobalFactory::DeleteDefault();
|
GlobalFactory::DeleteDefault();
|
||||||
|
StringConstants::Cleanup();
|
||||||
|
StringPool::Cleanup();
|
||||||
exit_debugging();
|
exit_debugging();
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,7 @@
|
|||||||
#include "AttributeCookie.h"
|
#include "AttributeCookie.h"
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "Package.h"
|
#include "Package.h"
|
||||||
|
#include "StringConstants.h"
|
||||||
|
|
||||||
static const char* const kAttributeNames[AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT] = {
|
|
||||||
"SYS:PACKAGE"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class AutoPackageAttributeCookie : public AttributeCookie {
|
class AutoPackageAttributeCookie : public AttributeCookie {
|
||||||
@ -81,11 +77,11 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
AutoPackageAttributes::AttributeForName(const char* name,
|
AutoPackageAttributes::AttributeForName(const StringKey& name,
|
||||||
AutoPackageAttribute& _attribute)
|
AutoPackageAttribute& _attribute)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT; i++) {
|
for (int i = 0; i < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT; i++) {
|
||||||
if (strcmp(name, kAttributeNames[i]) == 0) {
|
if (name == StringConstants::Get().kAutoPackageAttributeNames[i]) {
|
||||||
_attribute = (AutoPackageAttribute)i;
|
_attribute = (AutoPackageAttribute)i;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -95,12 +91,11 @@ AutoPackageAttributes::AttributeForName(const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*static*/ const char*
|
/*static*/ const String&
|
||||||
AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute)
|
AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute)
|
||||||
{
|
{
|
||||||
if (attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT)
|
ASSERT(attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT);
|
||||||
return kAttributeNames[attribute];
|
return StringConstants::Get().kAutoPackageAttributeNames[attribute];
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -124,7 +119,7 @@ AutoPackageAttributes::GetAttributeValue(const Package* package,
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
AutoPackageAttributes::OpenCookie(Package* package, const char* name,
|
AutoPackageAttributes::OpenCookie(Package* package, const StringKey& name,
|
||||||
int openMode, AttributeCookie*& _cookie)
|
int openMode, AttributeCookie*& _cookie)
|
||||||
{
|
{
|
||||||
if (package == NULL)
|
if (package == NULL)
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "StringKey.h"
|
||||||
|
|
||||||
|
|
||||||
class AttributeCookie;
|
class AttributeCookie;
|
||||||
class Package;
|
class Package;
|
||||||
@ -22,16 +24,17 @@ enum AutoPackageAttribute {
|
|||||||
|
|
||||||
|
|
||||||
struct AutoPackageAttributes {
|
struct AutoPackageAttributes {
|
||||||
static bool AttributeForName(const char* name,
|
static bool AttributeForName(const StringKey& name,
|
||||||
AutoPackageAttribute& _attribute);
|
AutoPackageAttribute& _attribute);
|
||||||
static const char* NameForAttribute(
|
static const String& NameForAttribute(
|
||||||
AutoPackageAttribute attribute);
|
AutoPackageAttribute attribute);
|
||||||
static const void* GetAttributeValue(const Package* package,
|
static const void* GetAttributeValue(const Package* package,
|
||||||
AutoPackageAttribute attribute,
|
AutoPackageAttribute attribute,
|
||||||
off_t& _size, uint32& _type);
|
off_t& _size, uint32& _type);
|
||||||
|
|
||||||
static status_t OpenCookie(Package* package, const char* name,
|
static status_t OpenCookie(Package* package,
|
||||||
int openMode, AttributeCookie*& _cookie);
|
const StringKey& name, int openMode,
|
||||||
|
AttributeCookie*& _cookie);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,9 +31,9 @@ Directory::~Directory()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Directory::Init(Directory* parent, const char* name, uint32 flags)
|
Directory::Init(Directory* parent, const String& name)
|
||||||
{
|
{
|
||||||
status_t error = Node::Init(parent, name, flags);
|
status_t error = Node::Init(parent, name);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ Directory::RemoveChild(Node* node)
|
|||||||
|
|
||||||
|
|
||||||
Node*
|
Node*
|
||||||
Directory::FindChild(const char* name)
|
Directory::FindChild(const StringKey& name)
|
||||||
{
|
{
|
||||||
return fChildTable.Lookup(name);
|
return fChildTable.Lookup(name);
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,7 @@ public:
|
|||||||
Directory(ino_t id);
|
Directory(ino_t id);
|
||||||
virtual ~Directory();
|
virtual ~Directory();
|
||||||
|
|
||||||
virtual status_t Init(Directory* parent, const char* name,
|
virtual status_t Init(Directory* parent, const String& name);
|
||||||
uint32 flags);
|
|
||||||
|
|
||||||
virtual mode_t Mode() const;
|
virtual mode_t Mode() const;
|
||||||
virtual off_t FileSize() const;
|
virtual off_t FileSize() const;
|
||||||
@ -41,7 +40,7 @@ public:
|
|||||||
|
|
||||||
void AddChild(Node* node);
|
void AddChild(Node* node);
|
||||||
void RemoveChild(Node* node);
|
void RemoveChild(Node* node);
|
||||||
Node* FindChild(const char* name);
|
Node* FindChild(const StringKey& name);
|
||||||
|
|
||||||
inline Node* FirstChild() const;
|
inline Node* FirstChild() const;
|
||||||
inline Node* NextChild(Node* node) const;
|
inline Node* NextChild(Node* node) const;
|
||||||
|
@ -17,7 +17,7 @@ Node::Node(ino_t id)
|
|||||||
:
|
:
|
||||||
fID(id),
|
fID(id),
|
||||||
fParent(NULL),
|
fParent(NULL),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fFlags(0)
|
fFlags(0)
|
||||||
{
|
{
|
||||||
rw_lock_init(&fLock, "packagefs node");
|
rw_lock_init(&fLock, "packagefs node");
|
||||||
@ -26,29 +26,16 @@ Node::Node(ino_t id)
|
|||||||
|
|
||||||
Node::~Node()
|
Node::~Node()
|
||||||
{
|
{
|
||||||
if ((fFlags & NODE_FLAG_OWNS_NAME) != 0)
|
|
||||||
free(fName);
|
|
||||||
|
|
||||||
rw_lock_destroy(&fLock);
|
rw_lock_destroy(&fLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Node::Init(Directory* parent, const char* name, uint32 flags)
|
Node::Init(Directory* parent, const String& name)
|
||||||
{
|
{
|
||||||
fParent = parent;
|
fParent = parent;
|
||||||
fFlags = flags;
|
fName = name;
|
||||||
|
fFlags = 0;
|
||||||
if ((flags & NODE_FLAG_CONST_NAME) != 0
|
|
||||||
|| (flags & NODE_FLAG_KEEP_NAME) != 0) {
|
|
||||||
fName = const_cast<char*>(name);
|
|
||||||
} else {
|
|
||||||
fName = strdup(name);
|
|
||||||
if (fName == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
fFlags |= NODE_FLAG_OWNS_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +97,8 @@ Node::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Node::OpenAttribute(const char* name, int openMode, AttributeCookie*& _cookie)
|
Node::OpenAttribute(const StringKey& name, int openMode,
|
||||||
|
AttributeCookie*& _cookie)
|
||||||
{
|
{
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -124,7 +112,7 @@ Node::IndexAttribute(AttributeIndexer* indexer)
|
|||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
Node::IndexCookieForAttribute(const char* name) const
|
Node::IndexCookieForAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
#include <util/khash.h>
|
#include <util/khash.h>
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
#include "StringKey.h"
|
||||||
|
|
||||||
|
|
||||||
class AttributeCookie;
|
class AttributeCookie;
|
||||||
class AttributeDirectoryCookie;
|
class AttributeDirectoryCookie;
|
||||||
@ -26,14 +29,7 @@ class PackageNode;
|
|||||||
|
|
||||||
// node flags
|
// node flags
|
||||||
enum {
|
enum {
|
||||||
NODE_FLAG_KEEP_NAME = 0x01,
|
NODE_FLAG_KNOWN_TO_VFS = 0x01
|
||||||
// Init(): Take over ownership of the given name (i.e. free in
|
|
||||||
// destructor).
|
|
||||||
NODE_FLAG_CONST_NAME = 0x02,
|
|
||||||
// Init(): The given name is a constant that won't go away during the
|
|
||||||
// lifetime of the object. No need to copy.
|
|
||||||
NODE_FLAG_OWNS_NAME = NODE_FLAG_KEEP_NAME,
|
|
||||||
NODE_FLAG_KNOWN_TO_VFS = 0x04,
|
|
||||||
// internal flag
|
// internal flag
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -50,17 +46,14 @@ public:
|
|||||||
|
|
||||||
ino_t ID() const { return fID; }
|
ino_t ID() const { return fID; }
|
||||||
Directory* Parent() const { return fParent; }
|
Directory* Parent() const { return fParent; }
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
|
|
||||||
Node*& NameHashTableNext()
|
Node*& NameHashTableNext()
|
||||||
{ return fNameHashTableNext; }
|
{ return fNameHashTableNext; }
|
||||||
Node*& IDHashTableNext()
|
Node*& IDHashTableNext()
|
||||||
{ return fIDHashTableNext; }
|
{ return fIDHashTableNext; }
|
||||||
|
|
||||||
virtual status_t Init(Directory* parent, const char* name,
|
virtual status_t Init(Directory* parent, const String& name);
|
||||||
uint32 flags);
|
|
||||||
// If specified to keep the name, it does
|
|
||||||
// so also on error.
|
|
||||||
|
|
||||||
virtual status_t VFSInit(dev_t deviceID);
|
virtual status_t VFSInit(dev_t deviceID);
|
||||||
// base class version must be called on
|
// base class version must be called on
|
||||||
@ -87,17 +80,18 @@ public:
|
|||||||
|
|
||||||
virtual status_t OpenAttributeDirectory(
|
virtual status_t OpenAttributeDirectory(
|
||||||
AttributeDirectoryCookie*& _cookie);
|
AttributeDirectoryCookie*& _cookie);
|
||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const StringKey& name,
|
||||||
AttributeCookie*& _cookie);
|
int openMode, AttributeCookie*& _cookie);
|
||||||
|
|
||||||
virtual status_t IndexAttribute(AttributeIndexer* indexer);
|
virtual status_t IndexAttribute(AttributeIndexer* indexer);
|
||||||
virtual void* IndexCookieForAttribute(const char* name) const;
|
virtual void* IndexCookieForAttribute(const StringKey& name)
|
||||||
|
const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
rw_lock fLock;
|
rw_lock fLock;
|
||||||
ino_t fID;
|
ino_t fID;
|
||||||
Directory* fParent;
|
Directory* fParent;
|
||||||
char* fName;
|
String fName;
|
||||||
Node* fNameHashTableNext;
|
Node* fNameHashTableNext;
|
||||||
Node* fIDHashTableNext;
|
Node* fIDHashTableNext;
|
||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
@ -143,22 +137,22 @@ Node::IsKnownToVFS() const
|
|||||||
|
|
||||||
|
|
||||||
struct NodeNameHashDefinition {
|
struct NodeNameHashDefinition {
|
||||||
typedef const char* KeyType;
|
typedef StringKey KeyType;
|
||||||
typedef Node ValueType;
|
typedef Node ValueType;
|
||||||
|
|
||||||
size_t HashKey(const char* key) const
|
size_t HashKey(const StringKey& key) const
|
||||||
{
|
{
|
||||||
return hash_hash_string(key);
|
return key.Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Hash(const Node* value) const
|
size_t Hash(const Node* value) const
|
||||||
{
|
{
|
||||||
return HashKey(value->Name());
|
return value->Name().Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compare(const char* key, const Node* value) const
|
bool Compare(const StringKey& key, const Node* value) const
|
||||||
{
|
{
|
||||||
return strcmp(value->Name(), key) == 0;
|
return key == value->Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
Node*& GetLink(Node* value) const
|
Node*& GetLink(Node* value) const
|
||||||
|
@ -36,7 +36,7 @@ OldUnpackingNodeAttributes::FileSize() const
|
|||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
OldUnpackingNodeAttributes::IndexCookieForAttribute(const char* name) const
|
OldUnpackingNodeAttributes::IndexCookieForAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
return fPackageNode != NULL
|
return fPackageNode != NULL
|
||||||
? fPackageNode->IndexCookieForAttribute(name) : NULL;
|
? fPackageNode->IndexCookieForAttribute(name) : NULL;
|
||||||
|
@ -19,7 +19,8 @@ public:
|
|||||||
|
|
||||||
virtual timespec ModifiedTime() const;
|
virtual timespec ModifiedTime() const;
|
||||||
virtual off_t FileSize() const;
|
virtual off_t FileSize() const;
|
||||||
virtual void* IndexCookieForAttribute(const char* name) const;
|
virtual void* IndexCookieForAttribute(const StringKey& name)
|
||||||
|
const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PackageNode* fPackageNode;
|
PackageNode* fPackageNode;
|
||||||
|
@ -80,7 +80,7 @@ UnpackingAttributeCookie::~UnpackingAttributeCookie()
|
|||||||
|
|
||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
UnpackingAttributeCookie::Open(PackageNode* packageNode, const char* name,
|
UnpackingAttributeCookie::Open(PackageNode* packageNode, const StringKey& name,
|
||||||
int openMode, AttributeCookie*& _cookie)
|
int openMode, AttributeCookie*& _cookie)
|
||||||
{
|
{
|
||||||
if (packageNode == NULL)
|
if (packageNode == NULL)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "AttributeCookie.h"
|
#include "AttributeCookie.h"
|
||||||
|
#include "StringKey.h"
|
||||||
|
|
||||||
|
|
||||||
class AttributeIndexer;
|
class AttributeIndexer;
|
||||||
@ -23,8 +24,9 @@ public:
|
|||||||
int openMode);
|
int openMode);
|
||||||
virtual ~UnpackingAttributeCookie();
|
virtual ~UnpackingAttributeCookie();
|
||||||
|
|
||||||
static status_t Open(PackageNode* packageNode, const char* name,
|
static status_t Open(PackageNode* packageNode,
|
||||||
int openMode, AttributeCookie*& _cookie);
|
const StringKey& name, int openMode,
|
||||||
|
AttributeCookie*& _cookie);
|
||||||
|
|
||||||
virtual status_t ReadAttribute(off_t offset, void* buffer,
|
virtual status_t ReadAttribute(off_t offset, void* buffer,
|
||||||
size_t* bufferSize);
|
size_t* bufferSize);
|
||||||
|
@ -75,12 +75,10 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the attribute name
|
// get the attribute name
|
||||||
const char* name;
|
const String& name = fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT
|
||||||
if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) {
|
? AutoPackageAttributes::NameForAttribute(
|
||||||
name = AutoPackageAttributes::NameForAttribute(
|
(AutoPackageAttribute)fState)
|
||||||
(AutoPackageAttribute)fState);
|
: fAttribute->Name();
|
||||||
} else
|
|
||||||
name = fAttribute->Name();
|
|
||||||
|
|
||||||
// fill in the entry name -- checks whether the entry fits into the
|
// fill in the entry name -- checks whether the entry fits into the
|
||||||
// buffer
|
// buffer
|
||||||
|
@ -170,7 +170,7 @@ UnpackingDirectory::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UnpackingDirectory::OpenAttribute(const char* name, int openMode,
|
UnpackingDirectory::OpenAttribute(const StringKey& name, int openMode,
|
||||||
AttributeCookie*& _cookie)
|
AttributeCookie*& _cookie)
|
||||||
{
|
{
|
||||||
return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name,
|
return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name,
|
||||||
@ -187,7 +187,7 @@ UnpackingDirectory::IndexAttribute(AttributeIndexer* indexer)
|
|||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
UnpackingDirectory::IndexCookieForAttribute(const char* name) const
|
UnpackingDirectory::IndexCookieForAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
|
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
|
||||||
return packageDirectory->IndexCookieForAttribute(name);
|
return packageDirectory->IndexCookieForAttribute(name);
|
||||||
|
@ -36,11 +36,12 @@ public:
|
|||||||
|
|
||||||
virtual status_t OpenAttributeDirectory(
|
virtual status_t OpenAttributeDirectory(
|
||||||
AttributeDirectoryCookie*& _cookie);
|
AttributeDirectoryCookie*& _cookie);
|
||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const StringKey& name,
|
||||||
AttributeCookie*& _cookie);
|
int openMode, AttributeCookie*& _cookie);
|
||||||
|
|
||||||
virtual status_t IndexAttribute(AttributeIndexer* indexer);
|
virtual status_t IndexAttribute(AttributeIndexer* indexer);
|
||||||
virtual void* IndexCookieForAttribute(const char* name) const;
|
virtual void* IndexCookieForAttribute(const StringKey& name)
|
||||||
|
const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PackageDirectoryList fPackageDirectories;
|
PackageDirectoryList fPackageDirectories;
|
||||||
|
@ -216,7 +216,7 @@ UnpackingLeafNode::CloneTransferPackageNodes(ino_t id, UnpackingNode*& _newNode)
|
|||||||
if (clone == NULL)
|
if (clone == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = clone->Init(Parent(), Name(), 0);
|
status_t error = clone->Init(Parent(), Name());
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
delete clone;
|
delete clone;
|
||||||
return error;
|
return error;
|
||||||
@ -260,8 +260,8 @@ UnpackingLeafNode::ReadSymlink(void* buffer, size_t* bufferSize)
|
|||||||
if (packageNode == NULL)
|
if (packageNode == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
const char* linkPath = packageNode->SymlinkPath();
|
const String& linkPath = packageNode->SymlinkPath();
|
||||||
if (linkPath == NULL) {
|
if (linkPath[0] == '\0') {
|
||||||
*bufferSize = 0;
|
*bufferSize = 0;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@ -283,7 +283,7 @@ UnpackingLeafNode::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
UnpackingLeafNode::OpenAttribute(const char* name, int openMode,
|
UnpackingLeafNode::OpenAttribute(const StringKey& name, int openMode,
|
||||||
AttributeCookie*& _cookie)
|
AttributeCookie*& _cookie)
|
||||||
{
|
{
|
||||||
return UnpackingAttributeCookie::Open(_ActivePackageNode(), name, openMode,
|
return UnpackingAttributeCookie::Open(_ActivePackageNode(), name, openMode,
|
||||||
@ -300,7 +300,7 @@ UnpackingLeafNode::IndexAttribute(AttributeIndexer* indexer)
|
|||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
UnpackingLeafNode::IndexCookieForAttribute(const char* name) const
|
UnpackingLeafNode::IndexCookieForAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
if (PackageLeafNode* packageNode = _ActivePackageNode())
|
if (PackageLeafNode* packageNode = _ActivePackageNode())
|
||||||
return packageNode->IndexCookieForAttribute(name);
|
return packageNode->IndexCookieForAttribute(name);
|
||||||
|
@ -48,11 +48,12 @@ public:
|
|||||||
|
|
||||||
virtual status_t OpenAttributeDirectory(
|
virtual status_t OpenAttributeDirectory(
|
||||||
AttributeDirectoryCookie*& _cookie);
|
AttributeDirectoryCookie*& _cookie);
|
||||||
virtual status_t OpenAttribute(const char* name, int openMode,
|
virtual status_t OpenAttribute(const StringKey& name,
|
||||||
AttributeCookie*& _cookie);
|
int openMode, AttributeCookie*& _cookie);
|
||||||
|
|
||||||
virtual status_t IndexAttribute(AttributeIndexer* indexer);
|
virtual status_t IndexAttribute(AttributeIndexer* indexer);
|
||||||
virtual void* IndexCookieForAttribute(const char* name) const;
|
virtual void* IndexCookieForAttribute(const StringKey& name)
|
||||||
|
const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline PackageLeafNode* _ActivePackageNode() const;
|
inline PackageLeafNode* _ActivePackageNode() const;
|
||||||
|
@ -88,8 +88,6 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
RETURN_ERROR(B_BAD_DATA);
|
RETURN_ERROR(B_BAD_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t error;
|
|
||||||
|
|
||||||
// get the file mode -- filter out write permissions
|
// get the file mode -- filter out write permissions
|
||||||
mode_t mode = entry->Mode() & ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH);
|
mode_t mode = entry->Mode() & ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||||
|
|
||||||
@ -100,17 +98,16 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
node = new(std::nothrow) PackageFile(fPackage, mode, entry->Data());
|
node = new(std::nothrow) PackageFile(fPackage, mode, entry->Data());
|
||||||
} else if (S_ISLNK(mode)) {
|
} else if (S_ISLNK(mode)) {
|
||||||
// symlink
|
// symlink
|
||||||
|
String path;
|
||||||
|
if (!path.SetTo(entry->SymlinkPath()))
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
PackageSymlink* symlink = new(std::nothrow) PackageSymlink(
|
PackageSymlink* symlink = new(std::nothrow) PackageSymlink(
|
||||||
fPackage, mode);
|
fPackage, mode);
|
||||||
if (symlink == NULL)
|
if (symlink == NULL)
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
error = symlink->SetSymlinkPath(entry->SymlinkPath());
|
symlink->SetSymlinkPath(path);
|
||||||
if (error != B_OK) {
|
|
||||||
delete symlink;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
node = symlink;
|
node = symlink;
|
||||||
} else if (S_ISDIR(mode)) {
|
} else if (S_ISDIR(mode)) {
|
||||||
// directory
|
// directory
|
||||||
@ -122,7 +119,11 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
BReference<PackageNode> nodeReference(node, true);
|
BReference<PackageNode> nodeReference(node, true);
|
||||||
|
|
||||||
error = node->Init(parentDir, entry->Name());
|
String entryName;
|
||||||
|
if (!entryName.SetTo(entry->Name()))
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
|
status_t error = node->Init(parentDir, entryName);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
@ -147,17 +148,16 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
|
|
||||||
PackageNode* node = (PackageNode*)entry->UserToken();
|
PackageNode* node = (PackageNode*)entry->UserToken();
|
||||||
|
|
||||||
|
String name;
|
||||||
|
if (!name.SetTo(attribute->Name()))
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
PackageNodeAttribute* nodeAttribute = new(std::nothrow)
|
PackageNodeAttribute* nodeAttribute = new(std::nothrow)
|
||||||
PackageNodeAttribute(attribute->Type(), attribute->Data());
|
PackageNodeAttribute(attribute->Type(), attribute->Data());
|
||||||
if (nodeAttribute == NULL)
|
if (nodeAttribute == NULL)
|
||||||
RETURN_ERROR(B_NO_MEMORY)
|
RETURN_ERROR(B_NO_MEMORY)
|
||||||
|
|
||||||
status_t error = nodeAttribute->Init(attribute->Name());
|
nodeAttribute->Init(name);
|
||||||
if (error != B_OK) {
|
|
||||||
delete nodeAttribute;
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
node->AddAttribute(nodeAttribute);
|
node->AddAttribute(nodeAttribute);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -173,10 +173,22 @@ struct Package::LoaderContentHandler : BPackageContentHandler {
|
|||||||
{
|
{
|
||||||
switch (value.attributeID) {
|
switch (value.attributeID) {
|
||||||
case B_PACKAGE_INFO_NAME:
|
case B_PACKAGE_INFO_NAME:
|
||||||
return fPackage->SetName(value.string);
|
{
|
||||||
|
String name;
|
||||||
|
if (!name.SetTo(value.string))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
fPackage->SetName(name);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
case B_PACKAGE_INFO_INSTALL_PATH:
|
case B_PACKAGE_INFO_INSTALL_PATH:
|
||||||
return fPackage->SetInstallPath(value.string);
|
{
|
||||||
|
String path;
|
||||||
|
if (!path.SetTo(value.string))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
fPackage->SetInstallPath(path);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
case B_PACKAGE_INFO_VERSION:
|
case B_PACKAGE_INFO_VERSION:
|
||||||
{
|
{
|
||||||
@ -303,9 +315,9 @@ private:
|
|||||||
Package::Package(::Volume* volume, dev_t deviceID, ino_t nodeID)
|
Package::Package(::Volume* volume, dev_t deviceID, ino_t nodeID)
|
||||||
:
|
:
|
||||||
fVolume(volume),
|
fVolume(volume),
|
||||||
fFileName(NULL),
|
fFileName(),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fInstallPath(NULL),
|
fInstallPath(),
|
||||||
fVersion(NULL),
|
fVersion(NULL),
|
||||||
fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT),
|
fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT),
|
||||||
fLinkDirectory(NULL),
|
fLinkDirectory(NULL),
|
||||||
@ -329,9 +341,6 @@ Package::~Package()
|
|||||||
while (Dependency* dependency = fDependencies.RemoveHead())
|
while (Dependency* dependency = fDependencies.RemoveHead())
|
||||||
delete dependency;
|
delete dependency;
|
||||||
|
|
||||||
free(fFileName);
|
|
||||||
free(fName);
|
|
||||||
free(fInstallPath);
|
|
||||||
delete fVersion;
|
delete fVersion;
|
||||||
|
|
||||||
mutex_destroy(&fLock);
|
mutex_destroy(&fLock);
|
||||||
@ -341,8 +350,7 @@ Package::~Package()
|
|||||||
status_t
|
status_t
|
||||||
Package::Init(const char* fileName)
|
Package::Init(const char* fileName)
|
||||||
{
|
{
|
||||||
fFileName = strdup(fileName);
|
if (!fFileName.SetTo(fileName))
|
||||||
if (fFileName == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -379,31 +387,17 @@ Package::Load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
Package::SetName(const char* name)
|
Package::SetName(const String& name)
|
||||||
{
|
{
|
||||||
if (fName != NULL)
|
fName = name;
|
||||||
free(fName);
|
|
||||||
|
|
||||||
fName = strdup(name);
|
|
||||||
if (fName == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
Package::SetInstallPath(const char* installPath)
|
Package::SetInstallPath(const String& installPath)
|
||||||
{
|
{
|
||||||
if (fInstallPath != NULL)
|
fInstallPath = installPath;
|
||||||
free(fInstallPath);
|
|
||||||
|
|
||||||
fInstallPath = strdup(installPath);
|
|
||||||
if (fInstallPath == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -463,14 +457,14 @@ Package::Open()
|
|||||||
// open the file
|
// open the file
|
||||||
fFD = openat(fVolume->PackagesDirectoryFD(), fFileName, O_RDONLY);
|
fFD = openat(fVolume->PackagesDirectoryFD(), fFileName, O_RDONLY);
|
||||||
if (fFD < 0) {
|
if (fFD < 0) {
|
||||||
ERROR("Failed to open package file \"%s\"\n", fFileName);
|
ERROR("Failed to open package file \"%s\"\n", fFileName.Data());
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stat it to verify that it's still the same file
|
// stat it to verify that it's still the same file
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (fstat(fFD, &st) < 0) {
|
if (fstat(fFD, &st) < 0) {
|
||||||
ERROR("Failed to stat package file \"%s\"\n", fFileName);
|
ERROR("Failed to stat package file \"%s\"\n", fFileName.Data());
|
||||||
close(fFD);
|
close(fFD);
|
||||||
fFD = -1;
|
fFD = -1;
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "Dependency.h"
|
#include "Dependency.h"
|
||||||
#include "PackageNode.h"
|
#include "PackageNode.h"
|
||||||
#include "Resolvable.h"
|
#include "Resolvable.h"
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
using BPackageKit::BPackageArchitecture;
|
using BPackageKit::BPackageArchitecture;
|
||||||
@ -40,18 +41,18 @@ public:
|
|||||||
status_t Load();
|
status_t Load();
|
||||||
|
|
||||||
::Volume* Volume() const { return fVolume; }
|
::Volume* Volume() const { return fVolume; }
|
||||||
const char* FileName() const { return fFileName; }
|
const String& FileName() const { return fFileName; }
|
||||||
|
|
||||||
status_t SetName(const char* name);
|
void SetName(const String& name);
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
|
|
||||||
dev_t DeviceID() const
|
dev_t DeviceID() const
|
||||||
{ return fDeviceID; }
|
{ return fDeviceID; }
|
||||||
ino_t NodeID() const
|
ino_t NodeID() const
|
||||||
{ return fNodeID; }
|
{ return fNodeID; }
|
||||||
|
|
||||||
status_t SetInstallPath(const char* installPath);
|
void SetInstallPath(const String& installPath);
|
||||||
const char* InstallPath() const { return fInstallPath; }
|
const String& InstallPath() const { return fInstallPath; }
|
||||||
|
|
||||||
void SetVersion(::Version* version);
|
void SetVersion(::Version* version);
|
||||||
// takes over object ownership
|
// takes over object ownership
|
||||||
@ -94,9 +95,9 @@ private:
|
|||||||
private:
|
private:
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
::Volume* fVolume;
|
::Volume* fVolume;
|
||||||
char* fFileName;
|
String fFileName;
|
||||||
char* fName;
|
String fName;
|
||||||
char* fInstallPath;
|
String fInstallPath;
|
||||||
::Version* fVersion;
|
::Version* fVersion;
|
||||||
BPackageArchitecture fArchitecture;
|
BPackageArchitecture fArchitecture;
|
||||||
PackageLinkDirectory* fLinkDirectory;
|
PackageLinkDirectory* fLinkDirectory;
|
||||||
@ -145,7 +146,7 @@ struct PackageFileNameHashDefinition {
|
|||||||
|
|
||||||
size_t Hash(const Package* value) const
|
size_t Hash(const Package* value) const
|
||||||
{
|
{
|
||||||
return HashKey(value->FileName());
|
return value->FileName().Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compare(const char* key, const Package* value) const
|
bool Compare(const char* key, const Package* value) const
|
||||||
|
@ -19,10 +19,10 @@ PackageLeafNode::~PackageLeafNode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
String
|
||||||
PackageLeafNode::SymlinkPath() const
|
PackageLeafNode::SymlinkPath() const
|
||||||
{
|
{
|
||||||
return NULL;
|
return String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ public:
|
|||||||
PackageLeafNode(Package* package, mode_t mode);
|
PackageLeafNode(Package* package, mode_t mode);
|
||||||
virtual ~PackageLeafNode();
|
virtual ~PackageLeafNode();
|
||||||
|
|
||||||
virtual const char* SymlinkPath() const;
|
virtual String SymlinkPath() const;
|
||||||
|
|
||||||
virtual status_t Read(off_t offset, void* buffer,
|
virtual status_t Read(off_t offset, void* buffer,
|
||||||
size_t* bufferSize);
|
size_t* bufferSize);
|
||||||
|
@ -17,7 +17,7 @@ PackageNode::PackageNode(Package* package, mode_t mode)
|
|||||||
:
|
:
|
||||||
fPackage(package),
|
fPackage(package),
|
||||||
fParent(NULL),
|
fParent(NULL),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fMode(mode),
|
fMode(mode),
|
||||||
fUserID(0),
|
fUserID(0),
|
||||||
fGroupID(0)
|
fGroupID(0)
|
||||||
@ -29,19 +29,14 @@ PackageNode::~PackageNode()
|
|||||||
{
|
{
|
||||||
while (PackageNodeAttribute* attribute = fAttributes.RemoveHead())
|
while (PackageNodeAttribute* attribute = fAttributes.RemoveHead())
|
||||||
delete attribute;
|
delete attribute;
|
||||||
|
|
||||||
free(fName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageNode::Init(PackageDirectory* parent, const char* name)
|
PackageNode::Init(PackageDirectory* parent, const String& name)
|
||||||
{
|
{
|
||||||
fParent = parent;
|
fParent = parent;
|
||||||
fName = strdup(name);
|
fName = name;
|
||||||
if (fName == NULL)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,11 +78,11 @@ PackageNode::RemoveAttribute(PackageNodeAttribute* attribute)
|
|||||||
|
|
||||||
|
|
||||||
PackageNodeAttribute*
|
PackageNodeAttribute*
|
||||||
PackageNode::FindAttribute(const char* name) const
|
PackageNode::FindAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
for (PackageNodeAttributeList::ConstIterator it = fAttributes.GetIterator();
|
for (PackageNodeAttributeList::ConstIterator it = fAttributes.GetIterator();
|
||||||
PackageNodeAttribute* attribute = it.Next();) {
|
PackageNodeAttribute* attribute = it.Next();) {
|
||||||
if (strcmp(attribute->Name(), name) == 0)
|
if (name == attribute->Name())
|
||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include "IndexedAttributeOwner.h"
|
#include "IndexedAttributeOwner.h"
|
||||||
#include "PackageNodeAttribute.h"
|
#include "PackageNodeAttribute.h"
|
||||||
|
#include "StringKey.h"
|
||||||
|
|
||||||
|
|
||||||
class AttributeIndexer;
|
class AttributeIndexer;
|
||||||
@ -34,10 +35,10 @@ public:
|
|||||||
// must otherwise make sure the package
|
// must otherwise make sure the package
|
||||||
// still exists.
|
// still exists.
|
||||||
PackageDirectory* Parent() const { return fParent; }
|
PackageDirectory* Parent() const { return fParent; }
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
|
|
||||||
virtual status_t Init(PackageDirectory* parent,
|
virtual status_t Init(PackageDirectory* parent,
|
||||||
const char* name);
|
const String& name);
|
||||||
|
|
||||||
virtual status_t VFSInit(dev_t deviceID, ino_t nodeID);
|
virtual status_t VFSInit(dev_t deviceID, ino_t nodeID);
|
||||||
virtual void VFSUninit();
|
virtual void VFSUninit();
|
||||||
@ -65,11 +66,12 @@ public:
|
|||||||
const PackageNodeAttributeList& Attributes() const
|
const PackageNodeAttributeList& Attributes() const
|
||||||
{ return fAttributes; }
|
{ return fAttributes; }
|
||||||
|
|
||||||
PackageNodeAttribute* FindAttribute(const char* name) const;
|
PackageNodeAttribute* FindAttribute(const StringKey& name) const;
|
||||||
|
|
||||||
virtual void UnsetIndexCookie(void* attributeCookie);
|
virtual void UnsetIndexCookie(void* attributeCookie);
|
||||||
|
|
||||||
inline void* IndexCookieForAttribute(const char* name) const;
|
inline void* IndexCookieForAttribute(const StringKey& name)
|
||||||
|
const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void NonVirtualVFSUninit()
|
void NonVirtualVFSUninit()
|
||||||
@ -80,7 +82,7 @@ protected:
|
|||||||
protected:
|
protected:
|
||||||
Package* fPackage;
|
Package* fPackage;
|
||||||
PackageDirectory* fParent;
|
PackageDirectory* fParent;
|
||||||
char* fName;
|
String fName;
|
||||||
mode_t fMode;
|
mode_t fMode;
|
||||||
uid_t fUserID;
|
uid_t fUserID;
|
||||||
gid_t fGroupID;
|
gid_t fGroupID;
|
||||||
@ -90,7 +92,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
PackageNode::IndexCookieForAttribute(const char* name) const
|
PackageNode::IndexCookieForAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
PackageNodeAttribute* attribute = FindAttribute(name);
|
PackageNodeAttribute* attribute = FindAttribute(name);
|
||||||
return attribute != NULL ? attribute->IndexCookie() : NULL;
|
return attribute != NULL ? attribute->IndexCookie() : NULL;
|
||||||
|
@ -14,7 +14,7 @@ PackageNodeAttribute::PackageNodeAttribute(uint32 type,
|
|||||||
const BPackageData& data)
|
const BPackageData& data)
|
||||||
:
|
:
|
||||||
fData(data),
|
fData(data),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fIndexCookie(NULL),
|
fIndexCookie(NULL),
|
||||||
fType(type)
|
fType(type)
|
||||||
{
|
{
|
||||||
@ -23,13 +23,11 @@ PackageNodeAttribute::PackageNodeAttribute(uint32 type,
|
|||||||
|
|
||||||
PackageNodeAttribute::~PackageNodeAttribute()
|
PackageNodeAttribute::~PackageNodeAttribute()
|
||||||
{
|
{
|
||||||
free(fName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
PackageNodeAttribute::Init(const char* name)
|
PackageNodeAttribute::Init(const String& name)
|
||||||
{
|
{
|
||||||
fName = strdup(name);
|
fName = name;
|
||||||
return fName != NULL ? B_OK : B_NO_MEMORY;
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <package/hpkg/PackageData.h>
|
#include <package/hpkg/PackageData.h>
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
using BPackageKit::BHPKG::BPackageData;
|
using BPackageKit::BHPKG::BPackageData;
|
||||||
|
|
||||||
@ -23,11 +25,11 @@ public:
|
|||||||
const BPackageData& data);
|
const BPackageData& data);
|
||||||
~PackageNodeAttribute();
|
~PackageNodeAttribute();
|
||||||
|
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
uint32 Type() const { return fType; }
|
uint32 Type() const { return fType; }
|
||||||
const BPackageData& Data() const { return fData; }
|
const BPackageData& Data() const { return fData; }
|
||||||
|
|
||||||
status_t Init(const char* name);
|
void Init(const String& name);
|
||||||
|
|
||||||
void SetIndexCookie(void* cookie)
|
void SetIndexCookie(void* cookie)
|
||||||
{ fIndexCookie = cookie; }
|
{ fIndexCookie = cookie; }
|
||||||
@ -36,7 +38,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
BPackageData fData;
|
BPackageData fData;
|
||||||
char* fName;
|
String fName;
|
||||||
void* fIndexCookie;
|
void* fIndexCookie;
|
||||||
uint32 fType;
|
uint32 fType;
|
||||||
};
|
};
|
||||||
|
@ -13,29 +13,24 @@
|
|||||||
PackageSymlink::PackageSymlink(Package* package, mode_t mode)
|
PackageSymlink::PackageSymlink(Package* package, mode_t mode)
|
||||||
:
|
:
|
||||||
PackageLeafNode(package, mode),
|
PackageLeafNode(package, mode),
|
||||||
fSymlinkPath(NULL)
|
fSymlinkPath()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PackageSymlink::~PackageSymlink()
|
PackageSymlink::~PackageSymlink()
|
||||||
{
|
{
|
||||||
free(fSymlinkPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
PackageSymlink::SetSymlinkPath(const char* path)
|
PackageSymlink::SetSymlinkPath(const String& path)
|
||||||
{
|
{
|
||||||
if (path == NULL)
|
fSymlinkPath = path;
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
fSymlinkPath = strdup(path);
|
|
||||||
return fSymlinkPath != NULL ? B_OK : B_NO_MEMORY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char*
|
String
|
||||||
PackageSymlink::SymlinkPath() const
|
PackageSymlink::SymlinkPath() const
|
||||||
{
|
{
|
||||||
return fSymlinkPath;
|
return fSymlinkPath;
|
||||||
|
@ -14,12 +14,12 @@ public:
|
|||||||
PackageSymlink(Package* package, mode_t mode);
|
PackageSymlink(Package* package, mode_t mode);
|
||||||
virtual ~PackageSymlink();
|
virtual ~PackageSymlink();
|
||||||
|
|
||||||
status_t SetSymlinkPath(const char* path);
|
void SetSymlinkPath(const String& path);
|
||||||
|
|
||||||
virtual const char* SymlinkPath() const;
|
virtual String SymlinkPath() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* fSymlinkPath;
|
String fSymlinkPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,15 +14,12 @@
|
|||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "PackageLinksListener.h"
|
#include "PackageLinksListener.h"
|
||||||
|
#include "StringConstants.h"
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
static const char* const kSelfLinkName = ".self";
|
|
||||||
static const char* const kSettingsLinkName = ".settings";
|
|
||||||
|
|
||||||
|
|
||||||
PackageLinkDirectory::PackageLinkDirectory()
|
PackageLinkDirectory::PackageLinkDirectory()
|
||||||
:
|
:
|
||||||
Directory(0),
|
Directory(0),
|
||||||
@ -63,6 +60,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
|
|||||||
char* name = (char*)malloc(size);
|
char* name = (char*)malloc(size);
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
MemoryDeleter nameDeleter(name);
|
||||||
|
|
||||||
memcpy(name, package->Name(), nameLength + 1);
|
memcpy(name, package->Name(), nameLength + 1);
|
||||||
if (version != NULL) {
|
if (version != NULL) {
|
||||||
@ -70,8 +68,12 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
|
|||||||
version->ToString(name + nameLength + 1, size - nameLength - 1);
|
version->ToString(name + nameLength + 1, size - nameLength - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String nameString;
|
||||||
|
if (!nameString.SetTo(name))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
// init the directory/node
|
// init the directory/node
|
||||||
status_t error = Init(parent, name, NODE_FLAG_KEEP_NAME);
|
status_t error = Init(parent, nameString);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
@ -83,9 +85,9 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageLinkDirectory::Init(Directory* parent, const char* name, uint32 flags)
|
PackageLinkDirectory::Init(Directory* parent, const String& name)
|
||||||
{
|
{
|
||||||
return Directory::Init(parent, name, flags);
|
return Directory::Init(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,12 +178,13 @@ PackageLinkDirectory::_Update(PackageLinksListener* listener)
|
|||||||
|
|
||||||
// create/update self and settings link
|
// create/update self and settings link
|
||||||
status_t error = _CreateOrUpdateLink(fSelfLink, package,
|
status_t error = _CreateOrUpdateLink(fSelfLink, package,
|
||||||
Link::TYPE_INSTALLATION_LOCATION, kSelfLinkName, listener);
|
Link::TYPE_INSTALLATION_LOCATION, StringConstants::Get().kSelfLinkName,
|
||||||
|
listener);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
error = _CreateOrUpdateLink(fSettingsLink, package, Link::TYPE_SETTINGS,
|
error = _CreateOrUpdateLink(fSettingsLink, package, Link::TYPE_SETTINGS,
|
||||||
kSettingsLinkName, listener);
|
StringConstants::Get().kSettingsLinkName, listener);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
@ -219,7 +222,7 @@ PackageLinkDirectory::_UpdateDependencies(PackageLinksListener* listener)
|
|||||||
if (link == NULL)
|
if (link == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = link->Init(this, dependency->Name(), 0);
|
status_t error = link->Init(this, dependency->Name());
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
delete link;
|
delete link;
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
@ -256,14 +259,14 @@ PackageLinkDirectory::_RemoveLink(Link* link, PackageLinksListener* listener)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
PackageLinkDirectory::_CreateOrUpdateLink(Link*& link, Package* package,
|
PackageLinkDirectory::_CreateOrUpdateLink(Link*& link, Package* package,
|
||||||
Link::Type type, const char* name, PackageLinksListener* listener)
|
Link::Type type, const String& name, PackageLinksListener* listener)
|
||||||
{
|
{
|
||||||
if (link == NULL) {
|
if (link == NULL) {
|
||||||
link = new(std::nothrow) Link(package, type);
|
link = new(std::nothrow) Link(package, type);
|
||||||
if (link == NULL)
|
if (link == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = link->Init(this, name, NODE_FLAG_CONST_NAME);
|
status_t error = link->Init(this, name);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ public:
|
|||||||
virtual ~PackageLinkDirectory();
|
virtual ~PackageLinkDirectory();
|
||||||
|
|
||||||
status_t Init(Directory* parent, Package* package);
|
status_t Init(Directory* parent, Package* package);
|
||||||
virtual status_t Init(Directory* parent, const char* name,
|
virtual status_t Init(Directory* parent, const String& name);
|
||||||
uint32 flags);
|
|
||||||
|
|
||||||
virtual timespec ModifiedTime() const;
|
virtual timespec ModifiedTime() const;
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ private:
|
|||||||
|
|
||||||
status_t _CreateOrUpdateLink(Link*& link,
|
status_t _CreateOrUpdateLink(Link*& link,
|
||||||
Package* package, Link::Type type,
|
Package* package, Link::Type type,
|
||||||
const char* name,
|
const String& name,
|
||||||
PackageLinksListener* listener);
|
PackageLinksListener* listener);
|
||||||
void _RemoveLink(Link* link,
|
void _RemoveLink(Link* link,
|
||||||
PackageLinksListener* listener);
|
PackageLinksListener* listener);
|
||||||
|
@ -98,7 +98,7 @@ PackageLinkSymlink::Update(Package* package, PackageLinksListener* listener)
|
|||||||
|
|
||||||
if (package != NULL) {
|
if (package != NULL) {
|
||||||
fLinkPath = package->InstallPath();
|
fLinkPath = package->InstallPath();
|
||||||
if (fLinkPath != NULL) {
|
if (fLinkPath[0] != '\0') {
|
||||||
if (fType == TYPE_SETTINGS)
|
if (fType == TYPE_SETTINGS)
|
||||||
fLinkPath = ".self/settings";
|
fLinkPath = ".self/settings";
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,7 +17,7 @@ Dependency::Dependency(::Package* package)
|
|||||||
fPackage(package),
|
fPackage(package),
|
||||||
fFamily(NULL),
|
fFamily(NULL),
|
||||||
fResolvable(NULL),
|
fResolvable(NULL),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fVersion(NULL),
|
fVersion(NULL),
|
||||||
fVersionOperator(B_PACKAGE_RESOLVABLE_OP_EQUAL)
|
fVersionOperator(B_PACKAGE_RESOLVABLE_OP_EQUAL)
|
||||||
{
|
{
|
||||||
@ -26,7 +26,6 @@ Dependency::Dependency(::Package* package)
|
|||||||
|
|
||||||
Dependency::~Dependency()
|
Dependency::~Dependency()
|
||||||
{
|
{
|
||||||
free(fName);
|
|
||||||
delete fVersion;
|
delete fVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +33,7 @@ Dependency::~Dependency()
|
|||||||
status_t
|
status_t
|
||||||
Dependency::Init(const char* name)
|
Dependency::Init(const char* name)
|
||||||
{
|
{
|
||||||
fName = strdup(name);
|
if (!fName.SetTo(name))
|
||||||
if (fName == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
class DependencyFamily;
|
class DependencyFamily;
|
||||||
class Package;
|
class Package;
|
||||||
@ -52,13 +54,13 @@ public:
|
|||||||
bool ResolvableCompatibleVersionMatches(
|
bool ResolvableCompatibleVersionMatches(
|
||||||
Version* resolvableVersion) const;
|
Version* resolvableVersion) const;
|
||||||
|
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Package* fPackage;
|
::Package* fPackage;
|
||||||
DependencyFamily* fFamily;
|
DependencyFamily* fFamily;
|
||||||
::Resolvable* fResolvable;
|
::Resolvable* fResolvable;
|
||||||
char* fName;
|
String fName;
|
||||||
Version* fVersion;
|
Version* fVersion;
|
||||||
BPackageResolvableOperator fVersionOperator;
|
BPackageResolvableOperator fVersionOperator;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public:
|
|||||||
void AddDependenciesToList(
|
void AddDependenciesToList(
|
||||||
ResolvableDependencyList& list) const;
|
ResolvableDependencyList& list) const;
|
||||||
|
|
||||||
const char* Name() const;
|
String Name() const;
|
||||||
|
|
||||||
bool IsLastDependency(Dependency* dependency) const;
|
bool IsLastDependency(Dependency* dependency) const;
|
||||||
|
|
||||||
@ -58,11 +58,11 @@ DependencyFamily::AddDependenciesToList(ResolvableDependencyList& list) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const char*
|
inline String
|
||||||
DependencyFamily::Name() const
|
DependencyFamily::Name() const
|
||||||
{
|
{
|
||||||
Dependency* head = fDependencies.Head();
|
Dependency* head = fDependencies.Head();
|
||||||
return head != NULL ? head->Name() : NULL;
|
return head != NULL ? head->Name() : String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -78,22 +78,22 @@ DependencyFamily::IsLastDependency(Dependency* dependency) const
|
|||||||
|
|
||||||
|
|
||||||
struct DependencyFamilyHashDefinition {
|
struct DependencyFamilyHashDefinition {
|
||||||
typedef const char* KeyType;
|
typedef String KeyType;
|
||||||
typedef DependencyFamily ValueType;
|
typedef DependencyFamily ValueType;
|
||||||
|
|
||||||
size_t HashKey(const char* key) const
|
size_t HashKey(const String& key) const
|
||||||
{
|
{
|
||||||
return key != NULL ? hash_hash_string(key) : 0;
|
return key.Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Hash(const DependencyFamily* value) const
|
size_t Hash(const DependencyFamily* value) const
|
||||||
{
|
{
|
||||||
return HashKey(value->Name());
|
return value->Name().Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compare(const char* key, const DependencyFamily* value) const
|
bool Compare(const String& key, const DependencyFamily* value) const
|
||||||
{
|
{
|
||||||
return strcmp(value->Name(), key) == 0;
|
return key == value->Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
DependencyFamily*& GetLink(DependencyFamily* value) const
|
DependencyFamily*& GetLink(DependencyFamily* value) const
|
||||||
|
@ -15,7 +15,7 @@ Resolvable::Resolvable(::Package* package)
|
|||||||
:
|
:
|
||||||
fPackage(package),
|
fPackage(package),
|
||||||
fFamily(NULL),
|
fFamily(NULL),
|
||||||
fName(NULL),
|
fName(),
|
||||||
fVersion(NULL),
|
fVersion(NULL),
|
||||||
fCompatibleVersion(NULL)
|
fCompatibleVersion(NULL)
|
||||||
{
|
{
|
||||||
@ -24,7 +24,6 @@ Resolvable::Resolvable(::Package* package)
|
|||||||
|
|
||||||
Resolvable::~Resolvable()
|
Resolvable::~Resolvable()
|
||||||
{
|
{
|
||||||
free(fName);
|
|
||||||
delete fVersion;
|
delete fVersion;
|
||||||
delete fCompatibleVersion;
|
delete fCompatibleVersion;
|
||||||
}
|
}
|
||||||
@ -37,8 +36,7 @@ Resolvable::Init(const char* name, ::Version* version,
|
|||||||
fVersion = version;
|
fVersion = version;
|
||||||
fCompatibleVersion = compatibleVersion;
|
fCompatibleVersion = compatibleVersion;
|
||||||
|
|
||||||
fName = strdup(name);
|
if (!fName.SetTo(name))
|
||||||
if (fName == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
@ -37,7 +37,7 @@ public:
|
|||||||
ResolvableFamily* Family() const
|
ResolvableFamily* Family() const
|
||||||
{ return fFamily; }
|
{ return fFamily; }
|
||||||
|
|
||||||
const char* Name() const { return fName; }
|
const String& Name() const { return fName; }
|
||||||
::Version* Version() const { return fVersion; }
|
::Version* Version() const { return fVersion; }
|
||||||
::Version* CompatibleVersion() const
|
::Version* CompatibleVersion() const
|
||||||
{ return fCompatibleVersion; }
|
{ return fCompatibleVersion; }
|
||||||
@ -50,7 +50,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
::Package* fPackage;
|
::Package* fPackage;
|
||||||
ResolvableFamily* fFamily;
|
ResolvableFamily* fFamily;
|
||||||
char* fName;
|
String fName;
|
||||||
::Version* fVersion;
|
::Version* fVersion;
|
||||||
::Version* fCompatibleVersion;
|
::Version* fCompatibleVersion;
|
||||||
ResolvableDependencyList fDependencies;
|
ResolvableDependencyList fDependencies;
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
|
|
||||||
bool ResolveDependency(Dependency* dependency);
|
bool ResolveDependency(Dependency* dependency);
|
||||||
|
|
||||||
const char* Name() const;
|
String Name() const;
|
||||||
|
|
||||||
bool IsLastResolvable(Resolvable* resolvable) const;
|
bool IsLastResolvable(Resolvable* resolvable) const;
|
||||||
|
|
||||||
@ -35,11 +35,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inline const char*
|
inline String
|
||||||
ResolvableFamily::Name() const
|
ResolvableFamily::Name() const
|
||||||
{
|
{
|
||||||
Resolvable* head = fResolvables.Head();
|
Resolvable* head = fResolvables.Head();
|
||||||
return head != NULL ? head->Name() : NULL;
|
return head != NULL ? head->Name() : String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,22 +55,22 @@ ResolvableFamily::IsLastResolvable(Resolvable* resolvable) const
|
|||||||
|
|
||||||
|
|
||||||
struct ResolvableFamilyHashDefinition {
|
struct ResolvableFamilyHashDefinition {
|
||||||
typedef const char* KeyType;
|
typedef String KeyType;
|
||||||
typedef ResolvableFamily ValueType;
|
typedef ResolvableFamily ValueType;
|
||||||
|
|
||||||
size_t HashKey(const char* key) const
|
size_t HashKey(const String& key) const
|
||||||
{
|
{
|
||||||
return key != NULL ? hash_hash_string(key) : 0;
|
return key.Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Hash(const ResolvableFamily* value) const
|
size_t Hash(const ResolvableFamily* value) const
|
||||||
{
|
{
|
||||||
return HashKey(value->Name());
|
return value->Name().Hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Compare(const char* key, const ResolvableFamily* value) const
|
bool Compare(const String& key, const ResolvableFamily* value) const
|
||||||
{
|
{
|
||||||
return strcmp(value->Name(), key) == 0;
|
return key == value->Name();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolvableFamily*& GetLink(ResolvableFamily* value) const
|
ResolvableFamily*& GetLink(ResolvableFamily* value) const
|
||||||
|
34
src/add-ons/kernel/file_systems/packagefs/util/String.cpp
Normal file
34
src/add-ons/kernel/file_systems/packagefs/util/String.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
String::SetToExactLength(const char* string, size_t length)
|
||||||
|
{
|
||||||
|
StringData* data = StringPool::Get(string, length);
|
||||||
|
if (data == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
fData->ReleaseReference();
|
||||||
|
fData = data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String&
|
||||||
|
String::operator=(const String& other)
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
fData->ReleaseReference();
|
||||||
|
fData = other.fData;
|
||||||
|
fData->AcquireReference();
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
120
src/add-ons/kernel/file_systems/packagefs/util/String.h
Normal file
120
src/add-ons/kernel/file_systems/packagefs/util/String.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef STRING_H
|
||||||
|
#define STRING_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "StringPool.h"
|
||||||
|
|
||||||
|
|
||||||
|
class String {
|
||||||
|
public:
|
||||||
|
String();
|
||||||
|
String(const String& other);
|
||||||
|
~String();
|
||||||
|
|
||||||
|
bool SetTo(const char* string);
|
||||||
|
bool SetTo(const char* string, size_t maxLength);
|
||||||
|
bool SetToExactLength(const char* string,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
const char* Data() const;
|
||||||
|
uint32 Hash() const;
|
||||||
|
|
||||||
|
bool IsEmpty() const;
|
||||||
|
|
||||||
|
String& operator=(const String& other);
|
||||||
|
|
||||||
|
bool operator==(const String& other) const;
|
||||||
|
bool operator!=(const String& other) const;
|
||||||
|
|
||||||
|
operator const char*() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringData* fData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
String::String()
|
||||||
|
:
|
||||||
|
fData(StringData::GetEmpty())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
String::String(const String& other)
|
||||||
|
:
|
||||||
|
fData(other.fData)
|
||||||
|
{
|
||||||
|
fData->AcquireReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
String::~String()
|
||||||
|
{
|
||||||
|
fData->ReleaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
String::SetTo(const char* string)
|
||||||
|
{
|
||||||
|
return SetToExactLength(string, strlen(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
String::SetTo(const char* string, size_t maxLength)
|
||||||
|
{
|
||||||
|
return SetToExactLength(string, strnlen(string, maxLength));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const char*
|
||||||
|
String::Data() const
|
||||||
|
{
|
||||||
|
return fData->String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint32
|
||||||
|
String::Hash() const
|
||||||
|
{
|
||||||
|
return fData->Hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
String::IsEmpty() const
|
||||||
|
{
|
||||||
|
return fData == StringData::Empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
String::operator==(const String& other) const
|
||||||
|
{
|
||||||
|
return fData == other.fData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
String::operator!=(const String& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
String::operator const char*() const
|
||||||
|
{
|
||||||
|
return fData->String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STRING_H
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "StringConstants.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
|
||||||
|
StringConstants StringConstants::sDefaultInstance;
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ bool
|
||||||
|
StringConstants::Init()
|
||||||
|
{
|
||||||
|
new(&sDefaultInstance) StringConstants;
|
||||||
|
if (!sDefaultInstance._Init()) {
|
||||||
|
sDefaultInstance.Cleanup();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void
|
||||||
|
StringConstants::Cleanup()
|
||||||
|
{
|
||||||
|
sDefaultInstance.~StringConstants();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
StringConstants::_Init()
|
||||||
|
{
|
||||||
|
// generate the member variable initializations
|
||||||
|
#define DEFINE_STRING_CONSTANT(name, value) \
|
||||||
|
if (!name.SetTo(value)) \
|
||||||
|
return false;
|
||||||
|
#define DEFINE_STRING_ARRAY_CONSTANT(name, size, ...) \
|
||||||
|
{ \
|
||||||
|
const char* const _values[size] = { __VA_ARGS__ }; \
|
||||||
|
for (size_t i = 0; i < sizeof(_values) / sizeof(_values[0]); \
|
||||||
|
i++) { \
|
||||||
|
if (!name[i].SetTo(_values[i])) \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "StringConstantsPrivate.h"
|
||||||
|
|
||||||
|
#undef DEFINE_STRING_CONSTANT
|
||||||
|
#undef DEFINE_STRING_ARRAY_CONSTANT
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef STRING_CONSTANTS_H
|
||||||
|
#define STRING_CONSTANTS_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "AutoPackageAttributes.h"
|
||||||
|
// for the kAutoPackageAttributeNames array size
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
|
class StringConstants {
|
||||||
|
public:
|
||||||
|
// generate the member variable declarations
|
||||||
|
#define DEFINE_STRING_CONSTANT(name, value) \
|
||||||
|
String name;
|
||||||
|
#define DEFINE_STRING_ARRAY_CONSTANT(name, size, ...) \
|
||||||
|
String name[size];
|
||||||
|
|
||||||
|
#include "StringConstantsPrivate.h"
|
||||||
|
|
||||||
|
#undef DEFINE_STRING_CONSTANT
|
||||||
|
#undef DEFINE_STRING_ARRAY_CONSTANT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static bool Init();
|
||||||
|
static void Cleanup();
|
||||||
|
|
||||||
|
static const StringConstants& Get()
|
||||||
|
{ return sDefaultInstance; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _Init();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static StringConstants sDefaultInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STRING_CONSTANTS_H
|
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// This file is included in StringConstants.h and StringConstants.cpp with the
|
||||||
|
// macros DEFINE_STRING[_ARRAY]_CONSTANT() defined to generate the member
|
||||||
|
// variable declarations respectively the initializations.
|
||||||
|
|
||||||
|
|
||||||
|
DEFINE_STRING_CONSTANT(kPackageLinksDirectoryName, "package-links")
|
||||||
|
DEFINE_STRING_CONSTANT(kSelfLinkName, ".self")
|
||||||
|
DEFINE_STRING_CONSTANT(kSettingsLinkName, ".settings")
|
||||||
|
|
||||||
|
DEFINE_STRING_ARRAY_CONSTANT(kAutoPackageAttributeNames,
|
||||||
|
AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT,
|
||||||
|
"SYS:PACKAGE")
|
56
src/add-ons/kernel/file_systems/packagefs/util/StringKey.h
Normal file
56
src/add-ons/kernel/file_systems/packagefs/util/StringKey.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef STRING_KEY_H
|
||||||
|
#define STRING_KEY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
|
class StringKey {
|
||||||
|
public:
|
||||||
|
StringKey(const ::String& string)
|
||||||
|
:
|
||||||
|
fString(string.Data()),
|
||||||
|
fHash(string.Hash())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit StringKey(const char* string)
|
||||||
|
:
|
||||||
|
fString(string),
|
||||||
|
fHash(hash_hash_string(string))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* String() const
|
||||||
|
{
|
||||||
|
return fString;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Hash() const
|
||||||
|
{
|
||||||
|
return fHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const ::String& other) const
|
||||||
|
{
|
||||||
|
if (fHash != other.Hash())
|
||||||
|
return false;
|
||||||
|
return fString == other.Data() || strcmp(fString, other.Data()) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const ::String& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* fString;
|
||||||
|
uint32 fHash;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STRING_KEY_H
|
154
src/add-ons/kernel/file_systems/packagefs/util/StringPool.cpp
Normal file
154
src/add-ons/kernel/file_systems/packagefs/util/StringPool.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "StringPool.h"
|
||||||
|
|
||||||
|
#include "DebugSupport.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const size_t kInitialStringTableSize = 128;
|
||||||
|
|
||||||
|
static char sStringsBuffer[sizeof(StringDataHash)];
|
||||||
|
|
||||||
|
StringData StringData::fEmptyString(StringDataKey("", 0));
|
||||||
|
|
||||||
|
mutex StringPool::sLock;
|
||||||
|
StringDataHash* StringPool::sStrings;
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - StringData
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void
|
||||||
|
StringData::Init()
|
||||||
|
{
|
||||||
|
new(&fEmptyString) StringData(StringDataKey("", 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - StringPool
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ status_t
|
||||||
|
StringPool::Init()
|
||||||
|
{
|
||||||
|
sStrings = new(sStringsBuffer) StringDataHash;
|
||||||
|
status_t error = sStrings->Init(kInitialStringTableSize);
|
||||||
|
if (error != B_OK) {
|
||||||
|
sStrings->~StringDataHash();
|
||||||
|
sStrings = NULL;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_init(&sLock, "string pool");
|
||||||
|
|
||||||
|
StringData::Init();
|
||||||
|
sStrings->Insert(StringData::Empty());
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void
|
||||||
|
StringPool::Cleanup()
|
||||||
|
{
|
||||||
|
sStrings->Remove(StringData::Empty());
|
||||||
|
|
||||||
|
sStrings->~StringDataHash();
|
||||||
|
sStrings = NULL;
|
||||||
|
|
||||||
|
mutex_destroy(&sLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ inline StringData*
|
||||||
|
StringPool::_GetLocked(const StringDataKey& key)
|
||||||
|
{
|
||||||
|
if (StringData* string = sStrings->Lookup(key)) {
|
||||||
|
if (!string->AcquireReference())
|
||||||
|
return string;
|
||||||
|
|
||||||
|
// The object was fully dereferenced and will be deleted. Remove it
|
||||||
|
// from the hash table, so it isn't in the way.
|
||||||
|
sStrings->Remove(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ StringData*
|
||||||
|
StringPool::Get(const char* string, size_t length)
|
||||||
|
{
|
||||||
|
MutexLocker locker(sLock);
|
||||||
|
StringDataKey key(string, length);
|
||||||
|
StringData* data = _GetLocked(key);
|
||||||
|
if (data != NULL)
|
||||||
|
return data;
|
||||||
|
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
StringData* newString = StringData::Create(key);
|
||||||
|
if (newString == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
locker.Lock();
|
||||||
|
|
||||||
|
data = _GetLocked(key);
|
||||||
|
if (data != NULL) {
|
||||||
|
locker.Unlock();
|
||||||
|
newString->Delete();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
sStrings->Insert(newString);
|
||||||
|
return newString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void
|
||||||
|
StringPool::LastReferenceReleased(StringData* data)
|
||||||
|
{
|
||||||
|
MutexLocker locker(sLock);
|
||||||
|
sStrings->Remove(data);
|
||||||
|
locker.Unlock();
|
||||||
|
data->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ void
|
||||||
|
StringPool::DumpUsageStatistics()
|
||||||
|
{
|
||||||
|
size_t unsharedStringCount = 0;
|
||||||
|
size_t totalReferenceCount = 0;
|
||||||
|
size_t totalStringSize = 0;
|
||||||
|
size_t totalStringSizeWithDuplicates = 0;
|
||||||
|
|
||||||
|
MutexLocker locker(sLock);
|
||||||
|
for (StringDataHash::Iterator it = sStrings->GetIterator(); it.HasNext();) {
|
||||||
|
StringData* data = it.Next();
|
||||||
|
int32 referenceCount = data->CountReferences();
|
||||||
|
totalReferenceCount += referenceCount;
|
||||||
|
if (referenceCount == 1)
|
||||||
|
unsharedStringCount++;
|
||||||
|
|
||||||
|
size_t stringSize = strlen(data->String() + 1);
|
||||||
|
totalStringSize += stringSize;
|
||||||
|
totalStringSizeWithDuplicates += stringSize * referenceCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t stringCount = sStrings->CountElements();
|
||||||
|
size_t overhead = stringCount * (sizeof(StringData) - 1);
|
||||||
|
|
||||||
|
INFORM("StringPool usage:\n");
|
||||||
|
INFORM(" total unique strings: %8zu, %8zu bytes, overhead: %zu bytes\n",
|
||||||
|
stringCount, totalStringSize, overhead);
|
||||||
|
INFORM(" total strings with dups: %8zu, %8zu bytes\n", totalReferenceCount,
|
||||||
|
totalStringSizeWithDuplicates);
|
||||||
|
INFORM(" unshared strings: %8zu\n", unsharedStringCount);
|
||||||
|
INFORM(" bytes saved: %8zd\n",
|
||||||
|
(ssize_t)(totalStringSizeWithDuplicates - totalStringSize - overhead));
|
||||||
|
}
|
192
src/add-ons/kernel/file_systems/packagefs/util/StringPool.h
Normal file
192
src/add-ons/kernel/file_systems/packagefs/util/StringPool.h
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef STRING_POOL_H
|
||||||
|
#define STRING_POOL_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include <util/AutoLock.h>
|
||||||
|
#include <util/khash.h>
|
||||||
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
|
||||||
|
class StringData;
|
||||||
|
|
||||||
|
|
||||||
|
class StringDataKey {
|
||||||
|
public:
|
||||||
|
StringDataKey(const char* string, size_t length)
|
||||||
|
:
|
||||||
|
fString(string),
|
||||||
|
fLength(length),
|
||||||
|
fHash(hash_hash_string_part(string, length))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* String() const
|
||||||
|
{
|
||||||
|
return fString;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Length() const
|
||||||
|
{
|
||||||
|
return fLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Hash() const
|
||||||
|
{
|
||||||
|
return fHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* fString;
|
||||||
|
size_t fLength;
|
||||||
|
uint32 fHash;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct StringDataHashDefinition;
|
||||||
|
typedef BOpenHashTable<StringDataHashDefinition> StringDataHash;
|
||||||
|
|
||||||
|
|
||||||
|
class StringPool {
|
||||||
|
public:
|
||||||
|
static status_t Init();
|
||||||
|
static void Cleanup();
|
||||||
|
|
||||||
|
static StringData* Get(const char* string, size_t length);
|
||||||
|
static void LastReferenceReleased(StringData* data);
|
||||||
|
|
||||||
|
static void DumpUsageStatistics();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static StringData* _GetLocked(const StringDataKey& key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static mutex sLock;
|
||||||
|
static StringDataHash* sStrings;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class StringData {
|
||||||
|
public:
|
||||||
|
static void Init();
|
||||||
|
|
||||||
|
static StringData* Create(const StringDataKey& key)
|
||||||
|
{
|
||||||
|
void* data = malloc(sizeof(StringData) + key.Length());
|
||||||
|
if (data == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return new(data) StringData(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringData* Empty()
|
||||||
|
{
|
||||||
|
return &fEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringData* GetEmpty()
|
||||||
|
{
|
||||||
|
fEmptyString.AcquireReference();
|
||||||
|
return &fEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Delete()
|
||||||
|
{
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AcquireReference()
|
||||||
|
{
|
||||||
|
return atomic_add(&fReferenceCount, 1) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReleaseReference()
|
||||||
|
{
|
||||||
|
if (atomic_add(&fReferenceCount, -1) == 1)
|
||||||
|
StringPool::LastReferenceReleased(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// debugging only
|
||||||
|
int32 CountReferences() const
|
||||||
|
{
|
||||||
|
return fReferenceCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* String() const
|
||||||
|
{
|
||||||
|
return fString;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Hash() const
|
||||||
|
{
|
||||||
|
return fHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringData*& HashNext()
|
||||||
|
{
|
||||||
|
return fHashNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
StringData(const StringDataKey& key)
|
||||||
|
:
|
||||||
|
fReferenceCount(1),
|
||||||
|
fHash(key.Hash())
|
||||||
|
{
|
||||||
|
memcpy(fString, key.String(), key.Length());
|
||||||
|
fString[key.Length()] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
~StringData()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static StringData fEmptyString;
|
||||||
|
|
||||||
|
StringData* fHashNext;
|
||||||
|
int32 fReferenceCount;
|
||||||
|
uint32 fHash;
|
||||||
|
char fString[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct StringDataHashDefinition {
|
||||||
|
typedef StringDataKey KeyType;
|
||||||
|
typedef StringData ValueType;
|
||||||
|
|
||||||
|
size_t HashKey(const StringDataKey& key) const
|
||||||
|
{
|
||||||
|
return key.Hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Hash(const StringData* value) const
|
||||||
|
{
|
||||||
|
return value->Hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compare(const StringDataKey& key, const StringData* value) const
|
||||||
|
{
|
||||||
|
return key.Hash() == value->Hash()
|
||||||
|
&& strncmp(value->String(), key.String(), key.Length()) == 0
|
||||||
|
&& value->String()[key.Length()] == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
StringData*& GetLink(StringData* value) const
|
||||||
|
{
|
||||||
|
return value->HashNext();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STRING_POOL_H
|
@ -22,11 +22,11 @@ static const char* const kVersionPartPlaceholder = "_";
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_version_part(const char* a, const char* b)
|
compare_version_part(const String& a, const String& b)
|
||||||
{
|
{
|
||||||
if (a == NULL)
|
if (a.IsEmpty())
|
||||||
return b != NULL ? -1 : 0;
|
return b.IsEmpty() ? 0 : -1;
|
||||||
if (b == NULL)
|
if (b.IsEmpty())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return BPrivate::NaturalCompare(a, b);
|
return BPrivate::NaturalCompare(a, b);
|
||||||
@ -35,10 +35,10 @@ compare_version_part(const char* a, const char* b)
|
|||||||
|
|
||||||
Version::Version()
|
Version::Version()
|
||||||
:
|
:
|
||||||
fMajor(NULL),
|
fMajor(),
|
||||||
fMinor(NULL),
|
fMinor(),
|
||||||
fMicro(NULL),
|
fMicro(),
|
||||||
fPreRelease(NULL),
|
fPreRelease(),
|
||||||
fRevision(0)
|
fRevision(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -46,10 +46,6 @@ Version::Version()
|
|||||||
|
|
||||||
Version::~Version()
|
Version::~Version()
|
||||||
{
|
{
|
||||||
free(fMajor);
|
|
||||||
free(fMinor);
|
|
||||||
free(fMicro);
|
|
||||||
free(fPreRelease);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -58,26 +54,22 @@ Version::Init(const char* major, const char* minor, const char* micro,
|
|||||||
const char* preRelease, uint32 revision)
|
const char* preRelease, uint32 revision)
|
||||||
{
|
{
|
||||||
if (major != NULL) {
|
if (major != NULL) {
|
||||||
fMajor = strdup(major);
|
if (!fMajor.SetTo(major))
|
||||||
if (fMajor == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minor != NULL) {
|
if (minor != NULL) {
|
||||||
fMinor = strdup(minor);
|
if (!fMinor.SetTo(minor))
|
||||||
if (fMinor == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (micro != NULL) {
|
if (micro != NULL) {
|
||||||
fMicro = strdup(micro);
|
if (!fMicro.SetTo(micro))
|
||||||
if (fMicro == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preRelease != NULL) {
|
if (preRelease != NULL) {
|
||||||
fPreRelease = strdup(preRelease);
|
if (!fPreRelease.SetTo(preRelease))
|
||||||
if (fPreRelease == NULL)
|
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,10 +116,10 @@ Version::Compare(const Version& other) const
|
|||||||
// The pre-version works differently: The empty string is greater than any
|
// The pre-version works differently: The empty string is greater than any
|
||||||
// non-empty string (e.g. "R1" is newer than "R1-rc2"). So we catch the
|
// non-empty string (e.g. "R1" is newer than "R1-rc2"). So we catch the
|
||||||
// empty string cases first.
|
// empty string cases first.
|
||||||
if (fPreRelease == NULL) {
|
if (fPreRelease.IsEmpty()) {
|
||||||
if (other.fPreRelease != NULL)
|
if (!other.fPreRelease.IsEmpty())
|
||||||
return 1;
|
return 1;
|
||||||
} else if (other.fPreRelease == NULL) {
|
} else if (other.fPreRelease.IsEmpty()) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
// both are non-null -- compare normally
|
// both are non-null -- compare normally
|
||||||
@ -180,27 +172,27 @@ Version::ToString(char* buffer, size_t bufferSize) const
|
|||||||
const char* minor = fMinor;
|
const char* minor = fMinor;
|
||||||
const char* micro = fMicro;
|
const char* micro = fMicro;
|
||||||
|
|
||||||
if (micro != NULL && minor == NULL)
|
if (micro[0] != '\0' && minor[0] == '\0')
|
||||||
minor = kVersionPartPlaceholder;
|
minor = kVersionPartPlaceholder;
|
||||||
if (minor != NULL && major == NULL)
|
if (minor[0] != '\0' && major[0] == '\0')
|
||||||
major = kVersionPartPlaceholder;
|
major = kVersionPartPlaceholder;
|
||||||
|
|
||||||
size_t size = strlcpy(buffer, major, bufferSize);
|
size_t size = strlcpy(buffer, major, bufferSize);
|
||||||
|
|
||||||
if (minor != NULL) {
|
if (minor[0] != '\0') {
|
||||||
size_t offset = std::min(bufferSize, size);
|
size_t offset = std::min(bufferSize, size);
|
||||||
size += snprintf(buffer + offset, bufferSize - offset, ".%s", minor);
|
size += snprintf(buffer + offset, bufferSize - offset, ".%s", minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (micro != NULL) {
|
if (micro[0] != '\0') {
|
||||||
size_t offset = std::min(bufferSize, size);
|
size_t offset = std::min(bufferSize, size);
|
||||||
size += snprintf(buffer + offset, bufferSize - offset, ".%s", micro);
|
size += snprintf(buffer + offset, bufferSize - offset, ".%s", micro);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fPreRelease != NULL) {
|
if (fPreRelease[0] != '\0') {
|
||||||
size_t offset = std::min(bufferSize, size);
|
size_t offset = std::min(bufferSize, size);
|
||||||
size += snprintf(buffer + offset, bufferSize - offset, "~%s",
|
size += snprintf(buffer + offset, bufferSize - offset, "~%s",
|
||||||
fPreRelease);
|
fPreRelease.Data());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fRevision != 0) {
|
if (fRevision != 0) {
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <package/PackageResolvableOperator.h>
|
#include <package/PackageResolvableOperator.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace BPackageKit;
|
using namespace BPackageKit;
|
||||||
|
|
||||||
@ -35,10 +37,10 @@ public:
|
|||||||
// been (excluding the terminating null)
|
// been (excluding the terminating null)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* fMajor;
|
String fMajor;
|
||||||
char* fMinor;
|
String fMinor;
|
||||||
char* fMicro;
|
String fMicro;
|
||||||
char* fPreRelease;
|
String fPreRelease;
|
||||||
uint32 fRevision;
|
uint32 fRevision;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ OldNodeAttributes::~OldNodeAttributes()
|
|||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
OldNodeAttributes::IndexCookieForAttribute(const char* name) const
|
OldNodeAttributes::IndexCookieForAttribute(const StringKey& name) const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
|
#include "StringKey.h"
|
||||||
|
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
@ -24,7 +26,8 @@ public:
|
|||||||
|
|
||||||
virtual timespec ModifiedTime() const = 0;
|
virtual timespec ModifiedTime() const = 0;
|
||||||
virtual off_t FileSize() const = 0;
|
virtual off_t FileSize() const = 0;
|
||||||
virtual void* IndexCookieForAttribute(const char* name) const;
|
virtual void* IndexCookieForAttribute(const StringKey& name)
|
||||||
|
const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "DebugSupport.h"
|
#include "DebugSupport.h"
|
||||||
#include "PackageLinksDirectory.h"
|
#include "PackageLinksDirectory.h"
|
||||||
|
#include "StringConstants.h"
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_DEPENDENCIES_ENABLED
|
//#define TRACE_DEPENDENCIES_ENABLED
|
||||||
@ -22,9 +23,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const char* const kPackageLinksDirectoryName = "package-links";
|
|
||||||
|
|
||||||
|
|
||||||
mutex PackageFSRoot::sRootListLock = MUTEX_INITIALIZER("packagefs root list");
|
mutex PackageFSRoot::sRootListLock = MUTEX_INITIALIZER("packagefs root list");
|
||||||
PackageFSRoot::RootList PackageFSRoot::sRootList;
|
PackageFSRoot::RootList PackageFSRoot::sRootList;
|
||||||
|
|
||||||
@ -71,7 +69,7 @@ PackageFSRoot::Init()
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = fPackageLinksDirectory->Init(NULL,
|
status_t error = fPackageLinksDirectory->Init(NULL,
|
||||||
kPackageLinksDirectoryName, 0);
|
StringConstants::Get().kPackageLinksDirectoryName);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
@ -243,7 +241,7 @@ PackageFSRoot::_RemoveVolume(Volume* volume)
|
|||||||
status_t
|
status_t
|
||||||
PackageFSRoot::_AddPackage(Package* package)
|
PackageFSRoot::_AddPackage(Package* package)
|
||||||
{
|
{
|
||||||
TRACE_DEPENDENCIES("adding package \"%s\"\n", package->Name());
|
TRACE_DEPENDENCIES("adding package \"%s\"\n", package->Name().Data());
|
||||||
|
|
||||||
ResolvableDependencyList dependenciesToUpdate;
|
ResolvableDependencyList dependenciesToUpdate;
|
||||||
|
|
||||||
@ -306,7 +304,7 @@ PackageFSRoot::_AddPackage(Package* package)
|
|||||||
void
|
void
|
||||||
PackageFSRoot::_RemovePackage(Package* package)
|
PackageFSRoot::_RemovePackage(Package* package)
|
||||||
{
|
{
|
||||||
TRACE_DEPENDENCIES("removing package \"%s\"\n", package->Name());
|
TRACE_DEPENDENCIES("removing package \"%s\"\n", package->Name().Data());
|
||||||
|
|
||||||
fPackageLinksDirectory->RemovePackage(package);
|
fPackageLinksDirectory->RemovePackage(package);
|
||||||
|
|
||||||
|
@ -485,12 +485,16 @@ Volume::Mount(const char* parameterString)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String volumeNameString;
|
||||||
|
if (!volumeNameString.SetTo(volumeName))
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
// create the root node
|
// create the root node
|
||||||
fRootDirectory
|
fRootDirectory
|
||||||
= new(std::nothrow) ::RootDirectory(kRootDirectoryID, st.st_mtim);
|
= new(std::nothrow) ::RootDirectory(kRootDirectoryID, st.st_mtim);
|
||||||
if (fRootDirectory == NULL)
|
if (fRootDirectory == NULL)
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
fRootDirectory->Init(NULL, volumeName, 0);
|
fRootDirectory->Init(NULL, volumeNameString);
|
||||||
fNodes.Insert(fRootDirectory);
|
fNodes.Insert(fRootDirectory);
|
||||||
fRootDirectory->AcquireReference();
|
fRootDirectory->AcquireReference();
|
||||||
// one reference for the table
|
// one reference for the table
|
||||||
@ -529,6 +533,8 @@ Volume::Mount(const char* parameterString)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
StringPool::DumpUsageStatistics();
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1318,7 +1324,7 @@ Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode,
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name,
|
Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const String& name,
|
||||||
UnpackingNode*& _node)
|
UnpackingNode*& _node)
|
||||||
{
|
{
|
||||||
UnpackingNode* unpackingNode;
|
UnpackingNode* unpackingNode;
|
||||||
@ -1335,7 +1341,7 @@ Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name,
|
|||||||
Node* node = unpackingNode->GetNode();
|
Node* node = unpackingNode->GetNode();
|
||||||
BReference<Node> nodeReference(node, true);
|
BReference<Node> nodeReference(node, true);
|
||||||
|
|
||||||
status_t error = node->Init(parent, name, 0);
|
status_t error = node->Init(parent, name);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
@ -1541,7 +1547,7 @@ INFORM("Volume::_ChangeActivation(): %" B_PRId32 " new packages, %" B_PRId32 " o
|
|||||||
oldPackageReferences[oldPackageIndex++].SetTo(package);
|
oldPackageReferences[oldPackageIndex++].SetTo(package);
|
||||||
_RemovePackageContent(package, NULL, true);
|
_RemovePackageContent(package, NULL, true);
|
||||||
_RemovePackage(package);
|
_RemovePackage(package);
|
||||||
INFORM("package \"%s\" deactivated\n", package->FileName());
|
INFORM("package \"%s\" deactivated\n", package->FileName().Data());
|
||||||
}
|
}
|
||||||
// TODO: Since package removal cannot fail, consider adding the new packages
|
// TODO: Since package removal cannot fail, consider adding the new packages
|
||||||
// first. The reactivation case may make that problematic, since two packages
|
// first. The reactivation case may make that problematic, since two packages
|
||||||
@ -1560,7 +1566,7 @@ INFORM("package \"%s\" deactivated\n", package->FileName());
|
|||||||
_RemovePackage(package);
|
_RemovePackage(package);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
INFORM("package \"%s\" activated\n", package->FileName());
|
INFORM("package \"%s\" activated\n", package->FileName().Data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to roll back the changes, if an error occurred.
|
// Try to roll back the changes, if an error occurred.
|
||||||
@ -1579,7 +1585,7 @@ INFORM("package \"%s\" activated\n", package->FileName());
|
|||||||
// nothing we can do here
|
// nothing we can do here
|
||||||
ERROR("Volume::_ChangeActivation(): failed to roll back "
|
ERROR("Volume::_ChangeActivation(): failed to roll back "
|
||||||
"deactivation of package \"%s\" after error\n",
|
"deactivation of package \"%s\" after error\n",
|
||||||
package->FileName());
|
package->FileName().Data());
|
||||||
_RemovePackage(package);
|
_RemovePackage(package);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1619,7 +1625,11 @@ Volume::_CreateShineThroughDirectory(Directory* parent, const char* name,
|
|||||||
RETURN_ERROR(B_NO_MEMORY);
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
BReference<ShineThroughDirectory> directoryReference(directory, true);
|
BReference<ShineThroughDirectory> directoryReference(directory, true);
|
||||||
|
|
||||||
status_t error = directory->Init(parent, name, 0);
|
String nameString;
|
||||||
|
if (!nameString.SetTo(name))
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
|
||||||
|
status_t error = directory->Init(parent, nameString);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public:
|
|||||||
const void* oldKey, size_t oldLength,
|
const void* oldKey, size_t oldLength,
|
||||||
const void* newKey, size_t newLength);
|
const void* newKey, size_t newLength);
|
||||||
|
|
||||||
Index* FindIndex(const char* name) const
|
Index* FindIndex(const StringKey& name) const
|
||||||
{ return fIndices.Lookup(name); }
|
{ return fIndices.Lookup(name); }
|
||||||
IndexDirIterator GetIndexDirIterator() const
|
IndexDirIterator GetIndexDirIterator() const
|
||||||
{ return fIndices.GetIterator(); }
|
{ return fIndices.GetIterator(); }
|
||||||
@ -139,7 +139,7 @@ private:
|
|||||||
bool notify);
|
bool notify);
|
||||||
|
|
||||||
status_t _CreateUnpackingNode(mode_t mode,
|
status_t _CreateUnpackingNode(mode_t mode,
|
||||||
Directory* parent, const char* name,
|
Directory* parent, const String& name,
|
||||||
UnpackingNode*& _node);
|
UnpackingNode*& _node);
|
||||||
// does *not* return a reference
|
// does *not* return a reference
|
||||||
void _RemoveNode(Node* node);
|
void _RemoveNode(Node* node);
|
||||||
|
Loading…
Reference in New Issue
Block a user