diff --git a/src/add-ons/kernel/file_systems/packagefs/Jamfile b/src/add-ons/kernel/file_systems/packagefs/Jamfile index 203e8507d7..7a4833ebea 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Jamfile +++ b/src/add-ons/kernel/file_systems/packagefs/Jamfile @@ -53,6 +53,9 @@ HAIKU_PACKAGE_FS_SOURCES = Resolvable.cpp ResolvableFamily.cpp SizeIndex.cpp + String.cpp + StringConstants.cpp + StringPool.cpp UnpackingAttributeCookie.cpp UnpackingAttributeDirectoryCookie.cpp UnpackingDirectory.cpp diff --git a/src/add-ons/kernel/file_systems/packagefs/indices/AttributeIndexer.h b/src/add-ons/kernel/file_systems/packagefs/indices/AttributeIndexer.h index f332b29f69..ccd5dbc438 100644 --- a/src/add-ons/kernel/file_systems/packagefs/indices/AttributeIndexer.h +++ b/src/add-ons/kernel/file_systems/packagefs/indices/AttributeIndexer.h @@ -8,6 +8,8 @@ #include +#include "String.h" + class AttributeIndex; class AttributeIndexTreeValue; @@ -28,12 +30,12 @@ public: AttributeIndexTreeValue* Cookie() const { return fCookie; } - const char* IndexName() const + const String& IndexName() const { return fIndexName; } private: AttributeIndex* fIndex; - const char* fIndexName; + const String& fIndexName; uint32 fIndexType; AttributeIndexTreeValue* fCookie; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/indices/Index.cpp b/src/add-ons/kernel/file_systems/packagefs/indices/Index.cpp index 8b4ec21477..efdf4dab9c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/indices/Index.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/indices/Index.cpp @@ -18,7 +18,7 @@ Index::Index() : fVolume(NULL), - fName(NULL), + fName(), fType(0), fKeyLength(0), fFixedKeyLength(true) @@ -28,7 +28,6 @@ Index::Index() Index::~Index() { - free(fName); } @@ -36,8 +35,7 @@ status_t Index::Init(Volume* volume, const char* name, uint32 type, bool fixedKeyLength, size_t keyLength) { - fName = strdup(name); - if (fName == NULL) + if (!fName.SetTo(name)) return B_NO_MEMORY; fVolume = volume; diff --git a/src/add-ons/kernel/file_systems/packagefs/indices/Index.h b/src/add-ons/kernel/file_systems/packagefs/indices/Index.h index 751eaeadf0..7f82ee6f4e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/indices/Index.h +++ b/src/add-ons/kernel/file_systems/packagefs/indices/Index.h @@ -13,6 +13,9 @@ #include #include +#include "String.h" +#include "StringKey.h" + class AbstractIndexIterator; class IndexIterator; @@ -34,7 +37,7 @@ public: Volume* GetVolume() const { return fVolume; } - const char* Name() const { return fName; } + const String& Name() const { return fName; } uint32 Type() const { return fType; } bool HasFixedKeyLength() const { return fFixedKeyLength; } @@ -64,7 +67,7 @@ protected: protected: Index* fHashLink; Volume* fVolume; - char* fName; + String fName; uint32 fType; size_t fKeyLength; bool fFixedKeyLength; @@ -98,22 +101,22 @@ private: struct IndexHashDefinition { - typedef const char* KeyType; + typedef StringKey KeyType; 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 { - 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 diff --git a/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp b/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp index 2f5d39c632..b92c1ea230 100644 --- a/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp @@ -84,7 +84,7 @@ struct Query::QueryPolicy { 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; } @@ -181,7 +181,8 @@ struct Query::QueryPolicy { { // TODO: Creating a cookie is quite a bit of overhead. 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) return error; diff --git a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp index 77f833e662..260ea197a4 100644 --- a/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp @@ -24,6 +24,8 @@ #include "GlobalFactory.h" #include "Query.h" #include "PackageFSRoot.h" +#include "StringConstants.h" +#include "StringPool.h" #include "Utils.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 NodeReadLocker dirLocker(dir); - Node* node = dynamic_cast(dir)->FindChild(entryName); + String entryNameString; + Node* node = dynamic_cast(dir)->FindChild(StringKey(entryName)); if (node == NULL) return B_ENTRY_NOT_FOUND; BReference nodeReference(node); @@ -792,7 +795,7 @@ packagefs_open_attr(fs_volume* fsVolume, fs_vnode* fsNode, const char* name, return error; AttributeCookie* cookie; - error = node->OpenAttribute(name, openMode, cookie); + error = node->OpenAttribute(StringKey(name), openMode, cookie); if (error != B_OK) 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); - Index* index = volume->FindIndex(name); + Index* index = volume->FindIndex(StringKey(name)); if (index == NULL) return B_ENTRY_NOT_FOUND; @@ -1093,9 +1096,25 @@ packagefs_std_ops(int32 op, ...) init_debugging(); 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) { ERROR("Failed to init GlobalFactory\n"); + StringConstants::Cleanup(); + StringPool::Cleanup(); exit_debugging(); return error; } @@ -1104,6 +1123,8 @@ packagefs_std_ops(int32 op, ...) if (error != B_OK) { ERROR("Failed to init PackageFSRoot\n"); GlobalFactory::DeleteDefault(); + StringConstants::Cleanup(); + StringPool::Cleanup(); exit_debugging(); return error; } @@ -1116,6 +1137,8 @@ packagefs_std_ops(int32 op, ...) PRINT("package_std_ops(): B_MODULE_UNINIT\n"); PackageFSRoot::GlobalUninit(); GlobalFactory::DeleteDefault(); + StringConstants::Cleanup(); + StringPool::Cleanup(); exit_debugging(); return B_OK; } diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.cpp index fac17f9c25..37fdad00bf 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.cpp @@ -16,11 +16,7 @@ #include "AttributeCookie.h" #include "DebugSupport.h" #include "Package.h" - - -static const char* const kAttributeNames[AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT] = { - "SYS:PACKAGE" -}; +#include "StringConstants.h" class AutoPackageAttributeCookie : public AttributeCookie { @@ -81,11 +77,11 @@ private: /*static*/ bool -AutoPackageAttributes::AttributeForName(const char* name, +AutoPackageAttributes::AttributeForName(const StringKey& name, AutoPackageAttribute& _attribute) { 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; return true; } @@ -95,12 +91,11 @@ AutoPackageAttributes::AttributeForName(const char* name, } -/*static*/ const char* +/*static*/ const String& AutoPackageAttributes::NameForAttribute(AutoPackageAttribute attribute) { - if (attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) - return kAttributeNames[attribute]; - return NULL; + ASSERT(attribute >= 0 && attribute < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT); + return StringConstants::Get().kAutoPackageAttributeNames[attribute]; } @@ -124,7 +119,7 @@ AutoPackageAttributes::GetAttributeValue(const Package* package, /*static*/ status_t -AutoPackageAttributes::OpenCookie(Package* package, const char* name, +AutoPackageAttributes::OpenCookie(Package* package, const StringKey& name, int openMode, AttributeCookie*& _cookie) { if (package == NULL) diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.h b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.h index cbb4d05818..b1a75bf8b4 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/AutoPackageAttributes.h @@ -8,6 +8,8 @@ #include +#include "StringKey.h" + class AttributeCookie; class Package; @@ -22,16 +24,17 @@ enum AutoPackageAttribute { struct AutoPackageAttributes { - static bool AttributeForName(const char* name, + static bool AttributeForName(const StringKey& name, AutoPackageAttribute& _attribute); - static const char* NameForAttribute( + static const String& NameForAttribute( AutoPackageAttribute attribute); static const void* GetAttributeValue(const Package* package, AutoPackageAttribute attribute, off_t& _size, uint32& _type); - static status_t OpenCookie(Package* package, const char* name, - int openMode, AttributeCookie*& _cookie); + static status_t OpenCookie(Package* package, + const StringKey& name, int openMode, + AttributeCookie*& _cookie); }; diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.cpp index 0ac01c5f8a..72a1c0a4f2 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.cpp @@ -31,9 +31,9 @@ Directory::~Directory() 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) return error; @@ -104,7 +104,7 @@ Directory::RemoveChild(Node* node) Node* -Directory::FindChild(const char* name) +Directory::FindChild(const StringKey& name) { return fChildTable.Lookup(name); } diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.h b/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.h index c117d1ec08..402bf45587 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.h @@ -27,8 +27,7 @@ public: Directory(ino_t id); virtual ~Directory(); - virtual status_t Init(Directory* parent, const char* name, - uint32 flags); + virtual status_t Init(Directory* parent, const String& name); virtual mode_t Mode() const; virtual off_t FileSize() const; @@ -41,7 +40,7 @@ public: void AddChild(Node* node); void RemoveChild(Node* node); - Node* FindChild(const char* name); + Node* FindChild(const StringKey& name); inline Node* FirstChild() const; inline Node* NextChild(Node* node) const; diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/Node.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/Node.cpp index d5e3bb1627..aec69b5db0 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/Node.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/Node.cpp @@ -17,7 +17,7 @@ Node::Node(ino_t id) : fID(id), fParent(NULL), - fName(NULL), + fName(), fFlags(0) { rw_lock_init(&fLock, "packagefs node"); @@ -26,29 +26,16 @@ Node::Node(ino_t id) Node::~Node() { - if ((fFlags & NODE_FLAG_OWNS_NAME) != 0) - free(fName); - rw_lock_destroy(&fLock); } status_t -Node::Init(Directory* parent, const char* name, uint32 flags) +Node::Init(Directory* parent, const String& name) { fParent = parent; - fFlags = flags; - - if ((flags & NODE_FLAG_CONST_NAME) != 0 - || (flags & NODE_FLAG_KEEP_NAME) != 0) { - fName = const_cast(name); - } else { - fName = strdup(name); - if (fName == NULL) - RETURN_ERROR(B_NO_MEMORY); - fFlags |= NODE_FLAG_OWNS_NAME; - } - + fName = name; + fFlags = 0; return B_OK; } @@ -110,7 +97,8 @@ Node::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie) 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; } @@ -124,7 +112,7 @@ Node::IndexAttribute(AttributeIndexer* indexer) void* -Node::IndexCookieForAttribute(const char* name) const +Node::IndexCookieForAttribute(const StringKey& name) const { return NULL; } diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h b/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h index 50c05381f1..3924fb0048 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/Node.h @@ -16,6 +16,9 @@ #include #include +#include "String.h" +#include "StringKey.h" + class AttributeCookie; class AttributeDirectoryCookie; @@ -26,14 +29,7 @@ class PackageNode; // node flags enum { - NODE_FLAG_KEEP_NAME = 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, + NODE_FLAG_KNOWN_TO_VFS = 0x01 // internal flag }; @@ -50,17 +46,14 @@ public: ino_t ID() const { return fID; } Directory* Parent() const { return fParent; } - const char* Name() const { return fName; } + const String& Name() const { return fName; } Node*& NameHashTableNext() { return fNameHashTableNext; } Node*& IDHashTableNext() { return fIDHashTableNext; } - virtual status_t Init(Directory* parent, const char* name, - uint32 flags); - // If specified to keep the name, it does - // so also on error. + virtual status_t Init(Directory* parent, const String& name); virtual status_t VFSInit(dev_t deviceID); // base class version must be called on @@ -87,17 +80,18 @@ public: virtual status_t OpenAttributeDirectory( AttributeDirectoryCookie*& _cookie); - virtual status_t OpenAttribute(const char* name, int openMode, - AttributeCookie*& _cookie); + virtual status_t OpenAttribute(const StringKey& name, + int openMode, AttributeCookie*& _cookie); virtual status_t IndexAttribute(AttributeIndexer* indexer); - virtual void* IndexCookieForAttribute(const char* name) const; + virtual void* IndexCookieForAttribute(const StringKey& name) + const; protected: rw_lock fLock; ino_t fID; Directory* fParent; - char* fName; + String fName; Node* fNameHashTableNext; Node* fIDHashTableNext; uint32 fFlags; @@ -143,22 +137,22 @@ Node::IsKnownToVFS() const struct NodeNameHashDefinition { - typedef const char* KeyType; - typedef Node ValueType; + typedef StringKey KeyType; + 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 { - 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 diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.cpp index 173a1daf6a..81ea4536d7 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.cpp @@ -36,7 +36,7 @@ OldUnpackingNodeAttributes::FileSize() const void* -OldUnpackingNodeAttributes::IndexCookieForAttribute(const char* name) const +OldUnpackingNodeAttributes::IndexCookieForAttribute(const StringKey& name) const { return fPackageNode != NULL ? fPackageNode->IndexCookieForAttribute(name) : NULL; diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.h b/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.h index c9f348360b..f26f9a139c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/OldUnpackingNodeAttributes.h @@ -19,7 +19,8 @@ public: virtual timespec ModifiedTime() const; virtual off_t FileSize() const; - virtual void* IndexCookieForAttribute(const char* name) const; + virtual void* IndexCookieForAttribute(const StringKey& name) + const; private: PackageNode* fPackageNode; diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp index 714bb7d780..8809199fae 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.cpp @@ -80,7 +80,7 @@ UnpackingAttributeCookie::~UnpackingAttributeCookie() /*static*/ status_t -UnpackingAttributeCookie::Open(PackageNode* packageNode, const char* name, +UnpackingAttributeCookie::Open(PackageNode* packageNode, const StringKey& name, int openMode, AttributeCookie*& _cookie) { if (packageNode == NULL) diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.h b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.h index 8a20257efa..a3ae60bc2c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeCookie.h @@ -7,6 +7,7 @@ #include "AttributeCookie.h" +#include "StringKey.h" class AttributeIndexer; @@ -23,8 +24,9 @@ public: int openMode); virtual ~UnpackingAttributeCookie(); - static status_t Open(PackageNode* packageNode, const char* name, - int openMode, AttributeCookie*& _cookie); + static status_t Open(PackageNode* packageNode, + const StringKey& name, int openMode, + AttributeCookie*& _cookie); virtual status_t ReadAttribute(off_t offset, void* buffer, size_t* bufferSize); diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp index ab2d3db30f..9d757b224e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingAttributeDirectoryCookie.cpp @@ -75,12 +75,10 @@ UnpackingAttributeDirectoryCookie::Read(dev_t volumeID, ino_t nodeID, } // get the attribute name - const char* name; - if (fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT) { - name = AutoPackageAttributes::NameForAttribute( - (AutoPackageAttribute)fState); - } else - name = fAttribute->Name(); + const String& name = fState < AUTO_PACKAGE_ATTRIBUTE_ENUM_COUNT + ? AutoPackageAttributes::NameForAttribute( + (AutoPackageAttribute)fState) + : fAttribute->Name(); // fill in the entry name -- checks whether the entry fits into the // buffer diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.cpp index ee67354819..22410b9d16 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.cpp @@ -170,7 +170,7 @@ UnpackingDirectory::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie) status_t -UnpackingDirectory::OpenAttribute(const char* name, int openMode, +UnpackingDirectory::OpenAttribute(const StringKey& name, int openMode, AttributeCookie*& _cookie) { return UnpackingAttributeCookie::Open(fPackageDirectories.Head(), name, @@ -187,7 +187,7 @@ UnpackingDirectory::IndexAttribute(AttributeIndexer* indexer) void* -UnpackingDirectory::IndexCookieForAttribute(const char* name) const +UnpackingDirectory::IndexCookieForAttribute(const StringKey& name) const { if (PackageDirectory* packageDirectory = fPackageDirectories.Head()) return packageDirectory->IndexCookieForAttribute(name); diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.h b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.h index baad89b1d5..4cebf6da8c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingDirectory.h @@ -36,11 +36,12 @@ public: virtual status_t OpenAttributeDirectory( AttributeDirectoryCookie*& _cookie); - virtual status_t OpenAttribute(const char* name, int openMode, - AttributeCookie*& _cookie); + virtual status_t OpenAttribute(const StringKey& name, + int openMode, AttributeCookie*& _cookie); virtual status_t IndexAttribute(AttributeIndexer* indexer); - virtual void* IndexCookieForAttribute(const char* name) const; + virtual void* IndexCookieForAttribute(const StringKey& name) + const; private: PackageDirectoryList fPackageDirectories; diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.cpp b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.cpp index bb68b71db9..51f80bb784 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.cpp @@ -216,7 +216,7 @@ UnpackingLeafNode::CloneTransferPackageNodes(ino_t id, UnpackingNode*& _newNode) if (clone == NULL) return B_NO_MEMORY; - status_t error = clone->Init(Parent(), Name(), 0); + status_t error = clone->Init(Parent(), Name()); if (error != B_OK) { delete clone; return error; @@ -260,8 +260,8 @@ UnpackingLeafNode::ReadSymlink(void* buffer, size_t* bufferSize) if (packageNode == NULL) return B_BAD_VALUE; - const char* linkPath = packageNode->SymlinkPath(); - if (linkPath == NULL) { + const String& linkPath = packageNode->SymlinkPath(); + if (linkPath[0] == '\0') { *bufferSize = 0; return B_OK; } @@ -283,7 +283,7 @@ UnpackingLeafNode::OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie) status_t -UnpackingLeafNode::OpenAttribute(const char* name, int openMode, +UnpackingLeafNode::OpenAttribute(const StringKey& name, int openMode, AttributeCookie*& _cookie) { return UnpackingAttributeCookie::Open(_ActivePackageNode(), name, openMode, @@ -300,7 +300,7 @@ UnpackingLeafNode::IndexAttribute(AttributeIndexer* indexer) void* -UnpackingLeafNode::IndexCookieForAttribute(const char* name) const +UnpackingLeafNode::IndexCookieForAttribute(const StringKey& name) const { if (PackageLeafNode* packageNode = _ActivePackageNode()) return packageNode->IndexCookieForAttribute(name); diff --git a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.h b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.h index e3bb4f175c..914e9a4903 100644 --- a/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/nodes/UnpackingLeafNode.h @@ -48,11 +48,12 @@ public: virtual status_t OpenAttributeDirectory( AttributeDirectoryCookie*& _cookie); - virtual status_t OpenAttribute(const char* name, int openMode, - AttributeCookie*& _cookie); + virtual status_t OpenAttribute(const StringKey& name, + int openMode, AttributeCookie*& _cookie); virtual status_t IndexAttribute(AttributeIndexer* indexer); - virtual void* IndexCookieForAttribute(const char* name) const; + virtual void* IndexCookieForAttribute(const StringKey& name) + const; private: inline PackageLeafNode* _ActivePackageNode() const; diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp index ee04cc662e..bddb40980e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.cpp @@ -88,8 +88,6 @@ struct Package::LoaderContentHandler : BPackageContentHandler { RETURN_ERROR(B_BAD_DATA); } - status_t error; - // get the file mode -- filter out write permissions 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()); } else if (S_ISLNK(mode)) { // symlink + String path; + if (!path.SetTo(entry->SymlinkPath())) + RETURN_ERROR(B_NO_MEMORY); + PackageSymlink* symlink = new(std::nothrow) PackageSymlink( fPackage, mode); if (symlink == NULL) RETURN_ERROR(B_NO_MEMORY); - error = symlink->SetSymlinkPath(entry->SymlinkPath()); - if (error != B_OK) { - delete symlink; - return error; - } - + symlink->SetSymlinkPath(path); node = symlink; } else if (S_ISDIR(mode)) { // directory @@ -122,7 +119,11 @@ struct Package::LoaderContentHandler : BPackageContentHandler { RETURN_ERROR(B_NO_MEMORY); BReference 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) RETURN_ERROR(error); @@ -147,17 +148,16 @@ struct Package::LoaderContentHandler : BPackageContentHandler { PackageNode* node = (PackageNode*)entry->UserToken(); + String name; + if (!name.SetTo(attribute->Name())) + RETURN_ERROR(B_NO_MEMORY); + PackageNodeAttribute* nodeAttribute = new(std::nothrow) PackageNodeAttribute(attribute->Type(), attribute->Data()); if (nodeAttribute == NULL) RETURN_ERROR(B_NO_MEMORY) - status_t error = nodeAttribute->Init(attribute->Name()); - if (error != B_OK) { - delete nodeAttribute; - RETURN_ERROR(error); - } - + nodeAttribute->Init(name); node->AddAttribute(nodeAttribute); return B_OK; @@ -173,10 +173,22 @@ struct Package::LoaderContentHandler : BPackageContentHandler { { switch (value.attributeID) { 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: - 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: { @@ -303,9 +315,9 @@ private: Package::Package(::Volume* volume, dev_t deviceID, ino_t nodeID) : fVolume(volume), - fFileName(NULL), - fName(NULL), - fInstallPath(NULL), + fFileName(), + fName(), + fInstallPath(), fVersion(NULL), fArchitecture(B_PACKAGE_ARCHITECTURE_ENUM_COUNT), fLinkDirectory(NULL), @@ -329,9 +341,6 @@ Package::~Package() while (Dependency* dependency = fDependencies.RemoveHead()) delete dependency; - free(fFileName); - free(fName); - free(fInstallPath); delete fVersion; mutex_destroy(&fLock); @@ -341,8 +350,7 @@ Package::~Package() status_t Package::Init(const char* fileName) { - fFileName = strdup(fileName); - if (fFileName == NULL) + if (!fFileName.SetTo(fileName)) RETURN_ERROR(B_NO_MEMORY); return B_OK; @@ -379,31 +387,17 @@ Package::Load() } -status_t -Package::SetName(const char* name) +void +Package::SetName(const String& name) { - if (fName != NULL) - free(fName); - - fName = strdup(name); - if (fName == NULL) - RETURN_ERROR(B_NO_MEMORY); - - return B_OK; + fName = name; } -status_t -Package::SetInstallPath(const char* installPath) +void +Package::SetInstallPath(const String& installPath) { - if (fInstallPath != NULL) - free(fInstallPath); - - fInstallPath = strdup(installPath); - if (fInstallPath == NULL) - RETURN_ERROR(B_NO_MEMORY); - - return B_OK; + fInstallPath = installPath; } @@ -463,14 +457,14 @@ Package::Open() // open the file fFD = openat(fVolume->PackagesDirectoryFD(), fFileName, O_RDONLY); if (fFD < 0) { - ERROR("Failed to open package file \"%s\"\n", fFileName); + ERROR("Failed to open package file \"%s\"\n", fFileName.Data()); return errno; } // stat it to verify that it's still the same file struct stat st; 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); fFD = -1; return errno; diff --git a/src/add-ons/kernel/file_systems/packagefs/package/Package.h b/src/add-ons/kernel/file_systems/packagefs/package/Package.h index b8495b5e5d..ffe3ab9471 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/Package.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/Package.h @@ -19,6 +19,7 @@ #include "Dependency.h" #include "PackageNode.h" #include "Resolvable.h" +#include "String.h" using BPackageKit::BPackageArchitecture; @@ -40,18 +41,18 @@ public: status_t Load(); ::Volume* Volume() const { return fVolume; } - const char* FileName() const { return fFileName; } + const String& FileName() const { return fFileName; } - status_t SetName(const char* name); - const char* Name() const { return fName; } + void SetName(const String& name); + const String& Name() const { return fName; } dev_t DeviceID() const { return fDeviceID; } ino_t NodeID() const { return fNodeID; } - status_t SetInstallPath(const char* installPath); - const char* InstallPath() const { return fInstallPath; } + void SetInstallPath(const String& installPath); + const String& InstallPath() const { return fInstallPath; } void SetVersion(::Version* version); // takes over object ownership @@ -94,9 +95,9 @@ private: private: mutex fLock; ::Volume* fVolume; - char* fFileName; - char* fName; - char* fInstallPath; + String fFileName; + String fName; + String fInstallPath; ::Version* fVersion; BPackageArchitecture fArchitecture; PackageLinkDirectory* fLinkDirectory; @@ -145,7 +146,7 @@ struct PackageFileNameHashDefinition { size_t Hash(const Package* value) const { - return HashKey(value->FileName()); + return value->FileName().Hash(); } bool Compare(const char* key, const Package* value) const diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.cpp index 94a680432a..f87645f4a7 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.cpp @@ -19,10 +19,10 @@ PackageLeafNode::~PackageLeafNode() } -const char* +String PackageLeafNode::SymlinkPath() const { - return NULL; + return String(); } diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.h index b5fca3e0e2..0a5561622e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageLeafNode.h @@ -19,7 +19,7 @@ public: PackageLeafNode(Package* package, mode_t mode); virtual ~PackageLeafNode(); - virtual const char* SymlinkPath() const; + virtual String SymlinkPath() const; virtual status_t Read(off_t offset, void* buffer, size_t* bufferSize); diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.cpp index 06eb88110a..1888da39d8 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.cpp @@ -17,7 +17,7 @@ PackageNode::PackageNode(Package* package, mode_t mode) : fPackage(package), fParent(NULL), - fName(NULL), + fName(), fMode(mode), fUserID(0), fGroupID(0) @@ -29,19 +29,14 @@ PackageNode::~PackageNode() { while (PackageNodeAttribute* attribute = fAttributes.RemoveHead()) delete attribute; - - free(fName); } status_t -PackageNode::Init(PackageDirectory* parent, const char* name) +PackageNode::Init(PackageDirectory* parent, const String& name) { fParent = parent; - fName = strdup(name); - if (fName == NULL) - RETURN_ERROR(B_NO_MEMORY); - + fName = name; return B_OK; } @@ -83,11 +78,11 @@ PackageNode::RemoveAttribute(PackageNodeAttribute* attribute) PackageNodeAttribute* -PackageNode::FindAttribute(const char* name) const +PackageNode::FindAttribute(const StringKey& name) const { for (PackageNodeAttributeList::ConstIterator it = fAttributes.GetIterator(); PackageNodeAttribute* attribute = it.Next();) { - if (strcmp(attribute->Name(), name) == 0) + if (name == attribute->Name()) return attribute; } diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.h index 8f9ed2f048..c2a68153e2 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNode.h @@ -14,6 +14,7 @@ #include "IndexedAttributeOwner.h" #include "PackageNodeAttribute.h" +#include "StringKey.h" class AttributeIndexer; @@ -34,10 +35,10 @@ public: // must otherwise make sure the package // still exists. PackageDirectory* Parent() const { return fParent; } - const char* Name() const { return fName; } + const String& Name() const { return fName; } virtual status_t Init(PackageDirectory* parent, - const char* name); + const String& name); virtual status_t VFSInit(dev_t deviceID, ino_t nodeID); virtual void VFSUninit(); @@ -65,11 +66,12 @@ public: const PackageNodeAttributeList& Attributes() const { return fAttributes; } - PackageNodeAttribute* FindAttribute(const char* name) const; + PackageNodeAttribute* FindAttribute(const StringKey& name) const; virtual void UnsetIndexCookie(void* attributeCookie); - inline void* IndexCookieForAttribute(const char* name) const; + inline void* IndexCookieForAttribute(const StringKey& name) + const; protected: void NonVirtualVFSUninit() @@ -80,7 +82,7 @@ protected: protected: Package* fPackage; PackageDirectory* fParent; - char* fName; + String fName; mode_t fMode; uid_t fUserID; gid_t fGroupID; @@ -90,7 +92,7 @@ protected: void* -PackageNode::IndexCookieForAttribute(const char* name) const +PackageNode::IndexCookieForAttribute(const StringKey& name) const { PackageNodeAttribute* attribute = FindAttribute(name); return attribute != NULL ? attribute->IndexCookie() : NULL; diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp index cd80d831ac..63cda955b8 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.cpp @@ -14,7 +14,7 @@ PackageNodeAttribute::PackageNodeAttribute(uint32 type, const BPackageData& data) : fData(data), - fName(NULL), + fName(), fIndexCookie(NULL), fType(type) { @@ -23,13 +23,11 @@ PackageNodeAttribute::PackageNodeAttribute(uint32 type, PackageNodeAttribute::~PackageNodeAttribute() { - free(fName); } -status_t -PackageNodeAttribute::Init(const char* name) +void +PackageNodeAttribute::Init(const String& name) { - fName = strdup(name); - return fName != NULL ? B_OK : B_NO_MEMORY; + fName = name; } diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h index 361dd81647..f467af8b29 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageNodeAttribute.h @@ -10,6 +10,8 @@ #include +#include "String.h" + using BPackageKit::BHPKG::BPackageData; @@ -23,11 +25,11 @@ public: const BPackageData& data); ~PackageNodeAttribute(); - const char* Name() const { return fName; } + const String& Name() const { return fName; } uint32 Type() const { return fType; } const BPackageData& Data() const { return fData; } - status_t Init(const char* name); + void Init(const String& name); void SetIndexCookie(void* cookie) { fIndexCookie = cookie; } @@ -36,7 +38,7 @@ public: protected: BPackageData fData; - char* fName; + String fName; void* fIndexCookie; uint32 fType; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.cpp b/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.cpp index 8f9961aa56..1ae619305f 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.cpp @@ -13,29 +13,24 @@ PackageSymlink::PackageSymlink(Package* package, mode_t mode) : PackageLeafNode(package, mode), - fSymlinkPath(NULL) + fSymlinkPath() { } PackageSymlink::~PackageSymlink() { - free(fSymlinkPath); } -status_t -PackageSymlink::SetSymlinkPath(const char* path) +void +PackageSymlink::SetSymlinkPath(const String& path) { - if (path == NULL) - return B_OK; - - fSymlinkPath = strdup(path); - return fSymlinkPath != NULL ? B_OK : B_NO_MEMORY; + fSymlinkPath = path; } -const char* +String PackageSymlink::SymlinkPath() const { return fSymlinkPath; diff --git a/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.h b/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.h index 65940c7856..2dd775266c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.h +++ b/src/add-ons/kernel/file_systems/packagefs/package/PackageSymlink.h @@ -14,12 +14,12 @@ public: PackageSymlink(Package* package, mode_t mode); virtual ~PackageSymlink(); - status_t SetSymlinkPath(const char* path); + void SetSymlinkPath(const String& path); - virtual const char* SymlinkPath() const; + virtual String SymlinkPath() const; private: - char* fSymlinkPath; + String fSymlinkPath; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.cpp index 24e505bbf7..cb96ee9a0c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.cpp @@ -14,15 +14,12 @@ #include "DebugSupport.h" #include "PackageLinksListener.h" +#include "StringConstants.h" #include "Utils.h" #include "Version.h" #include "Volume.h" -static const char* const kSelfLinkName = ".self"; -static const char* const kSettingsLinkName = ".settings"; - - PackageLinkDirectory::PackageLinkDirectory() : Directory(0), @@ -63,6 +60,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) char* name = (char*)malloc(size); if (name == NULL) return B_NO_MEMORY; + MemoryDeleter nameDeleter(name); memcpy(name, package->Name(), nameLength + 1); if (version != NULL) { @@ -70,8 +68,12 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) version->ToString(name + nameLength + 1, size - nameLength - 1); } + String nameString; + if (!nameString.SetTo(name)) + return B_NO_MEMORY; + // init the directory/node - status_t error = Init(parent, name, NODE_FLAG_KEEP_NAME); + status_t error = Init(parent, nameString); if (error != B_OK) RETURN_ERROR(error); @@ -83,9 +85,9 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) 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 status_t error = _CreateOrUpdateLink(fSelfLink, package, - Link::TYPE_INSTALLATION_LOCATION, kSelfLinkName, listener); + Link::TYPE_INSTALLATION_LOCATION, StringConstants::Get().kSelfLinkName, + listener); if (error != B_OK) RETURN_ERROR(error); error = _CreateOrUpdateLink(fSettingsLink, package, Link::TYPE_SETTINGS, - kSettingsLinkName, listener); + StringConstants::Get().kSettingsLinkName, listener); if (error != B_OK) RETURN_ERROR(error); @@ -219,7 +222,7 @@ PackageLinkDirectory::_UpdateDependencies(PackageLinksListener* listener) if (link == NULL) 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) { delete link; RETURN_ERROR(error); @@ -256,14 +259,14 @@ PackageLinkDirectory::_RemoveLink(Link* link, PackageLinksListener* listener) status_t 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) { link = new(std::nothrow) Link(package, type); if (link == NULL) 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) RETURN_ERROR(error); diff --git a/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.h b/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.h index c0af9ab3ef..2bdf2c59eb 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkDirectory.h @@ -20,8 +20,7 @@ public: virtual ~PackageLinkDirectory(); status_t Init(Directory* parent, Package* package); - virtual status_t Init(Directory* parent, const char* name, - uint32 flags); + virtual status_t Init(Directory* parent, const String& name); virtual timespec ModifiedTime() const; @@ -60,7 +59,7 @@ private: status_t _CreateOrUpdateLink(Link*& link, Package* package, Link::Type type, - const char* name, + const String& name, PackageLinksListener* listener); void _RemoveLink(Link* link, PackageLinksListener* listener); diff --git a/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkSymlink.cpp b/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkSymlink.cpp index ad4cdebd13..ec287cfe6e 100644 --- a/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkSymlink.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/package_links/PackageLinkSymlink.cpp @@ -98,7 +98,7 @@ PackageLinkSymlink::Update(Package* package, PackageLinksListener* listener) if (package != NULL) { fLinkPath = package->InstallPath(); - if (fLinkPath != NULL) { + if (fLinkPath[0] != '\0') { if (fType == TYPE_SETTINGS) fLinkPath = ".self/settings"; } else { diff --git a/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.cpp b/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.cpp index c4c34a4132..30f02dfc23 100644 --- a/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.cpp @@ -17,7 +17,7 @@ Dependency::Dependency(::Package* package) fPackage(package), fFamily(NULL), fResolvable(NULL), - fName(NULL), + fName(), fVersion(NULL), fVersionOperator(B_PACKAGE_RESOLVABLE_OP_EQUAL) { @@ -26,7 +26,6 @@ Dependency::Dependency(::Package* package) Dependency::~Dependency() { - free(fName); delete fVersion; } @@ -34,8 +33,7 @@ Dependency::~Dependency() status_t Dependency::Init(const char* name) { - fName = strdup(name); - if (fName == NULL) + if (!fName.SetTo(name)) return B_NO_MEMORY; return B_OK; diff --git a/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.h b/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.h index bab31c2d5b..4997110b24 100644 --- a/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.h +++ b/src/add-ons/kernel/file_systems/packagefs/resolvables/Dependency.h @@ -12,6 +12,8 @@ #include +#include "String.h" + class DependencyFamily; class Package; @@ -52,13 +54,13 @@ public: bool ResolvableCompatibleVersionMatches( Version* resolvableVersion) const; - const char* Name() const { return fName; } + const String& Name() const { return fName; } private: ::Package* fPackage; DependencyFamily* fFamily; ::Resolvable* fResolvable; - char* fName; + String fName; Version* fVersion; BPackageResolvableOperator fVersionOperator; diff --git a/src/add-ons/kernel/file_systems/packagefs/resolvables/DependencyFamily.h b/src/add-ons/kernel/file_systems/packagefs/resolvables/DependencyFamily.h index fa9daf1d0b..25cd4595da 100644 --- a/src/add-ons/kernel/file_systems/packagefs/resolvables/DependencyFamily.h +++ b/src/add-ons/kernel/file_systems/packagefs/resolvables/DependencyFamily.h @@ -20,7 +20,7 @@ public: void AddDependenciesToList( ResolvableDependencyList& list) const; - const char* Name() const; + String Name() const; bool IsLastDependency(Dependency* dependency) const; @@ -58,11 +58,11 @@ DependencyFamily::AddDependenciesToList(ResolvableDependencyList& list) const } -inline const char* +inline String DependencyFamily::Name() const { 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 { - typedef const char* KeyType; + typedef String KeyType; 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 { - 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 diff --git a/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.cpp b/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.cpp index 43a7414d0f..b8daec8499 100644 --- a/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.cpp @@ -15,7 +15,7 @@ Resolvable::Resolvable(::Package* package) : fPackage(package), fFamily(NULL), - fName(NULL), + fName(), fVersion(NULL), fCompatibleVersion(NULL) { @@ -24,7 +24,6 @@ Resolvable::Resolvable(::Package* package) Resolvable::~Resolvable() { - free(fName); delete fVersion; delete fCompatibleVersion; } @@ -37,8 +36,7 @@ Resolvable::Init(const char* name, ::Version* version, fVersion = version; fCompatibleVersion = compatibleVersion; - fName = strdup(name); - if (fName == NULL) + if (!fName.SetTo(name)) return B_NO_MEMORY; return B_OK; diff --git a/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.h b/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.h index 87d4509f61..298737a817 100644 --- a/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.h +++ b/src/add-ons/kernel/file_systems/packagefs/resolvables/Resolvable.h @@ -37,7 +37,7 @@ public: ResolvableFamily* Family() const { return fFamily; } - const char* Name() const { return fName; } + const String& Name() const { return fName; } ::Version* Version() const { return fVersion; } ::Version* CompatibleVersion() const { return fCompatibleVersion; } @@ -50,7 +50,7 @@ public: private: ::Package* fPackage; ResolvableFamily* fFamily; - char* fName; + String fName; ::Version* fVersion; ::Version* fCompatibleVersion; ResolvableDependencyList fDependencies; diff --git a/src/add-ons/kernel/file_systems/packagefs/resolvables/ResolvableFamily.h b/src/add-ons/kernel/file_systems/packagefs/resolvables/ResolvableFamily.h index 7d0a87fcbc..d5d8d643c0 100644 --- a/src/add-ons/kernel/file_systems/packagefs/resolvables/ResolvableFamily.h +++ b/src/add-ons/kernel/file_systems/packagefs/resolvables/ResolvableFamily.h @@ -23,7 +23,7 @@ public: bool ResolveDependency(Dependency* dependency); - const char* Name() const; + String Name() const; bool IsLastResolvable(Resolvable* resolvable) const; @@ -35,11 +35,11 @@ private: }; -inline const char* +inline String ResolvableFamily::Name() const { 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 { - typedef const char* KeyType; + typedef String KeyType; 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 { - 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 diff --git a/src/add-ons/kernel/file_systems/packagefs/util/String.cpp b/src/add-ons/kernel/file_systems/packagefs/util/String.cpp new file mode 100644 index 0000000000..785abeb3bf --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/String.cpp @@ -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; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/util/String.h b/src/add-ons/kernel/file_systems/packagefs/util/String.h new file mode 100644 index 0000000000..3025e972df --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/String.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/packagefs/util/StringConstants.cpp b/src/add-ons/kernel/file_systems/packagefs/util/StringConstants.cpp new file mode 100644 index 0000000000..04de05eac8 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/StringConstants.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include "StringConstants.h" + +#include + + +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; +} diff --git a/src/add-ons/kernel/file_systems/packagefs/util/StringConstants.h b/src/add-ons/kernel/file_systems/packagefs/util/StringConstants.h new file mode 100644 index 0000000000..129856c830 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/StringConstants.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/packagefs/util/StringConstantsPrivate.h b/src/add-ons/kernel/file_systems/packagefs/util/StringConstantsPrivate.h new file mode 100644 index 0000000000..a50b21c682 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/StringConstantsPrivate.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") diff --git a/src/add-ons/kernel/file_systems/packagefs/util/StringKey.h b/src/add-ons/kernel/file_systems/packagefs/util/StringKey.h new file mode 100644 index 0000000000..209aa0c96b --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/StringKey.h @@ -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 diff --git a/src/add-ons/kernel/file_systems/packagefs/util/StringPool.cpp b/src/add-ons/kernel/file_systems/packagefs/util/StringPool.cpp new file mode 100644 index 0000000000..d67019f914 --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/StringPool.cpp @@ -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)); +} diff --git a/src/add-ons/kernel/file_systems/packagefs/util/StringPool.h b/src/add-ons/kernel/file_systems/packagefs/util/StringPool.h new file mode 100644 index 0000000000..2a97b2aace --- /dev/null +++ b/src/add-ons/kernel/file_systems/packagefs/util/StringPool.h @@ -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 + +#include +#include + +#include + +#include +#include +#include + + +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 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 diff --git a/src/add-ons/kernel/file_systems/packagefs/util/Version.cpp b/src/add-ons/kernel/file_systems/packagefs/util/Version.cpp index 849453f595..ed4542a587 100644 --- a/src/add-ons/kernel/file_systems/packagefs/util/Version.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/util/Version.cpp @@ -22,11 +22,11 @@ static const char* const kVersionPartPlaceholder = "_"; static int -compare_version_part(const char* a, const char* b) +compare_version_part(const String& a, const String& b) { - if (a == NULL) - return b != NULL ? -1 : 0; - if (b == NULL) + if (a.IsEmpty()) + return b.IsEmpty() ? 0 : -1; + if (b.IsEmpty()) return 1; return BPrivate::NaturalCompare(a, b); @@ -35,10 +35,10 @@ compare_version_part(const char* a, const char* b) Version::Version() : - fMajor(NULL), - fMinor(NULL), - fMicro(NULL), - fPreRelease(NULL), + fMajor(), + fMinor(), + fMicro(), + fPreRelease(), fRevision(0) { } @@ -46,10 +46,6 @@ 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) { if (major != NULL) { - fMajor = strdup(major); - if (fMajor == NULL) + if (!fMajor.SetTo(major)) return B_NO_MEMORY; } if (minor != NULL) { - fMinor = strdup(minor); - if (fMinor == NULL) + if (!fMinor.SetTo(minor)) return B_NO_MEMORY; } if (micro != NULL) { - fMicro = strdup(micro); - if (fMicro == NULL) + if (!fMicro.SetTo(micro)) return B_NO_MEMORY; } if (preRelease != NULL) { - fPreRelease = strdup(preRelease); - if (fPreRelease == NULL) + if (!fPreRelease.SetTo(preRelease)) 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 // non-empty string (e.g. "R1" is newer than "R1-rc2"). So we catch the // empty string cases first. - if (fPreRelease == NULL) { - if (other.fPreRelease != NULL) + if (fPreRelease.IsEmpty()) { + if (!other.fPreRelease.IsEmpty()) return 1; - } else if (other.fPreRelease == NULL) { + } else if (other.fPreRelease.IsEmpty()) { return -1; } else { // both are non-null -- compare normally @@ -180,27 +172,27 @@ Version::ToString(char* buffer, size_t bufferSize) const const char* minor = fMinor; const char* micro = fMicro; - if (micro != NULL && minor == NULL) + if (micro[0] != '\0' && minor[0] == '\0') minor = kVersionPartPlaceholder; - if (minor != NULL && major == NULL) + if (minor[0] != '\0' && major[0] == '\0') major = kVersionPartPlaceholder; size_t size = strlcpy(buffer, major, bufferSize); - if (minor != NULL) { + if (minor[0] != '\0') { size_t offset = std::min(bufferSize, size); size += snprintf(buffer + offset, bufferSize - offset, ".%s", minor); } - if (micro != NULL) { + if (micro[0] != '\0') { size_t offset = std::min(bufferSize, size); size += snprintf(buffer + offset, bufferSize - offset, ".%s", micro); } - if (fPreRelease != NULL) { + if (fPreRelease[0] != '\0') { size_t offset = std::min(bufferSize, size); size += snprintf(buffer + offset, bufferSize - offset, "~%s", - fPreRelease); + fPreRelease.Data()); } if (fRevision != 0) { diff --git a/src/add-ons/kernel/file_systems/packagefs/util/Version.h b/src/add-ons/kernel/file_systems/packagefs/util/Version.h index 8ce58af21f..30a798ae2d 100644 --- a/src/add-ons/kernel/file_systems/packagefs/util/Version.h +++ b/src/add-ons/kernel/file_systems/packagefs/util/Version.h @@ -9,6 +9,8 @@ #include #include +#include "String.h" + using namespace BPackageKit; @@ -35,10 +37,10 @@ public: // been (excluding the terminating null) private: - char* fMajor; - char* fMinor; - char* fMicro; - char* fPreRelease; + String fMajor; + String fMinor; + String fMicro; + String fPreRelease; uint32 fRevision; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.cpp index d38064ed32..18b4b29a6b 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.cpp @@ -16,7 +16,7 @@ OldNodeAttributes::~OldNodeAttributes() void* -OldNodeAttributes::IndexCookieForAttribute(const char* name) const +OldNodeAttributes::IndexCookieForAttribute(const StringKey& name) const { return NULL; } diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.h b/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.h index 1d583acb4b..89e3dc00c6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.h +++ b/src/add-ons/kernel/file_systems/packagefs/volume/NodeListener.h @@ -11,6 +11,8 @@ #include #include +#include "StringKey.h" + class Node; @@ -24,7 +26,8 @@ public: virtual timespec ModifiedTime() const = 0; virtual off_t FileSize() const = 0; - virtual void* IndexCookieForAttribute(const char* name) const; + virtual void* IndexCookieForAttribute(const StringKey& name) + const; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/PackageFSRoot.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/PackageFSRoot.cpp index 74ee53b90c..268bbb5b62 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/PackageFSRoot.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/PackageFSRoot.cpp @@ -12,6 +12,7 @@ #include "DebugSupport.h" #include "PackageLinksDirectory.h" +#include "StringConstants.h" //#define TRACE_DEPENDENCIES_ENABLED @@ -22,9 +23,6 @@ #endif -static const char* const kPackageLinksDirectoryName = "package-links"; - - mutex PackageFSRoot::sRootListLock = MUTEX_INITIALIZER("packagefs root list"); PackageFSRoot::RootList PackageFSRoot::sRootList; @@ -71,7 +69,7 @@ PackageFSRoot::Init() return B_NO_MEMORY; status_t error = fPackageLinksDirectory->Init(NULL, - kPackageLinksDirectoryName, 0); + StringConstants::Get().kPackageLinksDirectoryName); if (error != B_OK) RETURN_ERROR(error); @@ -243,7 +241,7 @@ PackageFSRoot::_RemoveVolume(Volume* volume) status_t PackageFSRoot::_AddPackage(Package* package) { - TRACE_DEPENDENCIES("adding package \"%s\"\n", package->Name()); + TRACE_DEPENDENCIES("adding package \"%s\"\n", package->Name().Data()); ResolvableDependencyList dependenciesToUpdate; @@ -306,7 +304,7 @@ PackageFSRoot::_AddPackage(Package* package) void PackageFSRoot::_RemovePackage(Package* package) { - TRACE_DEPENDENCIES("removing package \"%s\"\n", package->Name()); + TRACE_DEPENDENCIES("removing package \"%s\"\n", package->Name().Data()); fPackageLinksDirectory->RemovePackage(package); diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp index 6f9f788442..f04fd504e5 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.cpp @@ -485,12 +485,16 @@ Volume::Mount(const char* parameterString) } } + String volumeNameString; + if (!volumeNameString.SetTo(volumeName)) + RETURN_ERROR(B_NO_MEMORY); + // create the root node fRootDirectory = new(std::nothrow) ::RootDirectory(kRootDirectoryID, st.st_mtim); if (fRootDirectory == NULL) RETURN_ERROR(B_NO_MEMORY); - fRootDirectory->Init(NULL, volumeName, 0); + fRootDirectory->Init(NULL, volumeNameString); fNodes.Insert(fRootDirectory); fRootDirectory->AcquireReference(); // one reference for the table @@ -529,6 +533,8 @@ Volume::Mount(const char* parameterString) if (error != B_OK) RETURN_ERROR(error); + StringPool::DumpUsageStatistics(); + return B_OK; } @@ -1318,7 +1324,7 @@ Volume::_RemovePackageNode(Directory* directory, PackageNode* packageNode, 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* unpackingNode; @@ -1335,7 +1341,7 @@ Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name, Node* node = unpackingNode->GetNode(); BReference nodeReference(node, true); - status_t error = node->Init(parent, name, 0); + status_t error = node->Init(parent, name); if (error != B_OK) RETURN_ERROR(error); @@ -1541,7 +1547,7 @@ INFORM("Volume::_ChangeActivation(): %" B_PRId32 " new packages, %" B_PRId32 " o oldPackageReferences[oldPackageIndex++].SetTo(package); _RemovePackageContent(package, NULL, true); _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 // first. The reactivation case may make that problematic, since two packages @@ -1560,7 +1566,7 @@ INFORM("package \"%s\" deactivated\n", package->FileName()); _RemovePackage(package); 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. @@ -1579,7 +1585,7 @@ INFORM("package \"%s\" activated\n", package->FileName()); // nothing we can do here ERROR("Volume::_ChangeActivation(): failed to roll back " "deactivation of package \"%s\" after error\n", - package->FileName()); + package->FileName().Data()); _RemovePackage(package); } } @@ -1619,7 +1625,11 @@ Volume::_CreateShineThroughDirectory(Directory* parent, const char* name, RETURN_ERROR(B_NO_MEMORY); BReference 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) RETURN_ERROR(error); diff --git a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h index 525a979ff3..2e34a70f79 100644 --- a/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h +++ b/src/add-ons/kernel/file_systems/packagefs/volume/Volume.h @@ -85,7 +85,7 @@ public: const void* oldKey, size_t oldLength, const void* newKey, size_t newLength); - Index* FindIndex(const char* name) const + Index* FindIndex(const StringKey& name) const { return fIndices.Lookup(name); } IndexDirIterator GetIndexDirIterator() const { return fIndices.GetIterator(); } @@ -139,7 +139,7 @@ private: bool notify); status_t _CreateUnpackingNode(mode_t mode, - Directory* parent, const char* name, + Directory* parent, const String& name, UnpackingNode*& _node); // does *not* return a reference void _RemoveNode(Node* node);