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:
Ingo Weinhold 2013-05-11 23:31:36 +02:00
parent 1848fdc329
commit d07c930c1e
55 changed files with 980 additions and 302 deletions

View File

@ -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

View File

@ -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;
}; };

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
} }

View File

@ -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)

View File

@ -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);
}; };

View File

@ -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);
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -19,10 +19,10 @@ PackageLeafNode::~PackageLeafNode()
} }
const char* String
PackageLeafNode::SymlinkPath() const PackageLeafNode::SymlinkPath() const
{ {
return NULL; return String();
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
}; };

View File

@ -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;

View File

@ -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;
}; };

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View 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;
}

View 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

View File

@ -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;
}

View File

@ -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

View File

@ -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")

View 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

View 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));
}

View 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

View File

@ -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) {

View File

@ -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;
}; };

View File

@ -16,7 +16,7 @@ OldNodeAttributes::~OldNodeAttributes()
void* void*
OldNodeAttributes::IndexCookieForAttribute(const char* name) const OldNodeAttributes::IndexCookieForAttribute(const StringKey& name) const
{ {
return NULL; return NULL;
} }

View File

@ -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;
}; };

View File

@ -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);

View File

@ -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);

View File

@ -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);