michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim:cindent:ts=2:et:sw=2: michael@0: * michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. michael@0: * michael@0: * This Original Code has been modified by IBM Corporation. Modifications made by IBM michael@0: * described herein are Copyright (c) International Business Machines Corporation, 2000. michael@0: * Modifications to Mozilla code or documentation identified per MPL Section 3.3 michael@0: * michael@0: * Date Modified by Description of modification michael@0: * 04/20/2000 IBM Corp. OS/2 VisualAge build. michael@0: */ michael@0: michael@0: /** michael@0: * nsPropertyTable allows a set of arbitrary key/value pairs to be stored michael@0: * for any number of nodes, in a global hashtable rather than on the nodes michael@0: * themselves. Nodes can be any type of object; the hashtable keys are michael@0: * nsIAtom pointers, and the values are void pointers. michael@0: */ michael@0: michael@0: #ifndef nsPropertyTable_h_ michael@0: #define nsPropertyTable_h_ michael@0: michael@0: #include "mozilla/MemoryReporting.h" michael@0: #include "nscore.h" michael@0: michael@0: class nsIAtom; michael@0: michael@0: typedef void michael@0: (*NSPropertyFunc)(void *aObject, michael@0: nsIAtom *aPropertyName, michael@0: void *aPropertyValue, michael@0: void *aData); michael@0: michael@0: /** michael@0: * Callback type for property destructors. |aObject| is the object michael@0: * the property is being removed for, |aPropertyName| is the property michael@0: * being removed, |aPropertyValue| is the value of the property, and |aData| michael@0: * is the opaque destructor data that was passed to SetProperty(). michael@0: **/ michael@0: typedef NSPropertyFunc NSPropertyDtorFunc; michael@0: class nsINode; michael@0: class nsIFrame; michael@0: michael@0: class nsPropertyOwner michael@0: { michael@0: public: michael@0: nsPropertyOwner(const nsPropertyOwner& aOther) : mObject(aOther.mObject) {} michael@0: michael@0: // These are the types of objects that can own properties. No object should michael@0: // inherit more then one of these classes. michael@0: // To add support for more types just add to this list. michael@0: nsPropertyOwner(const nsINode* aObject) : mObject(aObject) {} michael@0: nsPropertyOwner(const nsIFrame* aObject) : mObject(aObject) {} michael@0: michael@0: operator const void*() { return mObject; } michael@0: const void* get() { return mObject; } michael@0: michael@0: private: michael@0: const void* mObject; michael@0: }; michael@0: michael@0: class nsPropertyTable michael@0: { michael@0: public: michael@0: /** michael@0: * Get the value of the property |aPropertyName| for node |aObject|. michael@0: * |aResult|, if supplied, is filled in with a return status code. michael@0: **/ michael@0: void* GetProperty(nsPropertyOwner aObject, michael@0: nsIAtom *aPropertyName, michael@0: nsresult *aResult = nullptr) michael@0: { michael@0: return GetPropertyInternal(aObject, aPropertyName, false, aResult); michael@0: } michael@0: michael@0: /** michael@0: * Set the value of the property |aPropertyName| to michael@0: * |aPropertyValue| for node |aObject|. |aDtor| is a destructor for the michael@0: * property value to be called if the property is removed. It can be null michael@0: * if no destructor is required. |aDtorData| is an optional pointer to an michael@0: * opaque context to be passed to the property destructor. Note that the michael@0: * destructor is global for each property name regardless of node; it is an michael@0: * error to set a given property with a different destructor than was used michael@0: * before (this will return NS_ERROR_INVALID_ARG). If aOldValue is non-null michael@0: * it will contain the old value after the function returns (the destructor michael@0: * for the old value will not be run in that case). If |aTransfer| is true michael@0: * the property will be transfered to the new table when the property table michael@0: * for |aObject| changes (currently the tables for nodes are owned by their michael@0: * ownerDocument, so if the ownerDocument for a node changes, its property michael@0: * table changes too). If |aTransfer| is false the property will just be michael@0: * deleted instead. michael@0: */ michael@0: NS_HIDDEN_(nsresult) SetProperty(nsPropertyOwner aObject, michael@0: nsIAtom *aPropertyName, michael@0: void *aPropertyValue, michael@0: NSPropertyDtorFunc aDtor, michael@0: void *aDtorData, michael@0: bool aTransfer = false, michael@0: void **aOldValue = nullptr) michael@0: { michael@0: return SetPropertyInternal(aObject, aPropertyName, aPropertyValue, michael@0: aDtor, aDtorData, aTransfer, aOldValue); michael@0: } michael@0: michael@0: /** michael@0: * Delete the property |aPropertyName| in the global category for object michael@0: * |aObject|. The property's destructor function will be called. michael@0: */ michael@0: NS_HIDDEN_(nsresult) DeleteProperty(nsPropertyOwner aObject, michael@0: nsIAtom *aPropertyName); michael@0: michael@0: /** michael@0: * Unset the property |aPropertyName| in the global category for object michael@0: * |aObject|, but do not call the property's destructor function. The michael@0: * property value is returned. michael@0: */ michael@0: void* UnsetProperty(nsPropertyOwner aObject, michael@0: nsIAtom *aPropertyName, michael@0: nsresult *aStatus = nullptr) michael@0: { michael@0: return GetPropertyInternal(aObject, aPropertyName, true, aStatus); michael@0: } michael@0: michael@0: /** michael@0: * Deletes all of the properties for object |aObject|, calling the michael@0: * destructor function for each property. michael@0: */ michael@0: NS_HIDDEN_(void) DeleteAllPropertiesFor(nsPropertyOwner aObject); michael@0: michael@0: /** michael@0: * Transfers all properties for object |aObject| that were set with the michael@0: * |aTransfer| argument as true to |aTable|. Deletes the other properties michael@0: * for object |aObject|, calling the destructor function for each property. michael@0: * If transfering a property fails, this deletes all the properties for michael@0: * object |aObject|. michael@0: */ michael@0: NS_HIDDEN_(nsresult) michael@0: TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject, michael@0: nsPropertyTable *aOtherTable); michael@0: michael@0: /** michael@0: * Enumerate the properties for object |aObject|. michael@0: * For every property |aCallback| will be called with as arguments |aObject|, michael@0: * the property name, the property value and |aData|. michael@0: */ michael@0: NS_HIDDEN_(void) Enumerate(nsPropertyOwner aObject, michael@0: NSPropertyFunc aCallback, void *aData); michael@0: michael@0: /** michael@0: * Enumerate all the properties. michael@0: * For every property |aCallback| will be called with arguments the owner, michael@0: * the property name, the property value and |aData|. michael@0: */ michael@0: NS_HIDDEN_(void) EnumerateAll(NSPropertyFunc aCallback, void *aData); michael@0: michael@0: /** michael@0: * Deletes all of the properties for all objects in the property michael@0: * table, calling the destructor function for each property. michael@0: */ michael@0: NS_HIDDEN_(void) DeleteAllProperties(); michael@0: michael@0: nsPropertyTable() : mPropertyList(nullptr) {} michael@0: ~nsPropertyTable() { michael@0: DeleteAllProperties(); michael@0: } michael@0: michael@0: /** michael@0: * Function useable as destructor function for property data that is michael@0: * XPCOM objects. The function will call NS_IF_RELASE on the value michael@0: * to destroy it. michael@0: */ michael@0: static void SupportsDtorFunc(void *aObject, nsIAtom *aPropertyName, michael@0: void *aPropertyValue, void *aData); michael@0: michael@0: class PropertyList; michael@0: michael@0: size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; michael@0: michael@0: private: michael@0: NS_HIDDEN_(void) DestroyPropertyList(); michael@0: NS_HIDDEN_(PropertyList*) GetPropertyListFor(nsIAtom *aPropertyName) const; michael@0: NS_HIDDEN_(void*) GetPropertyInternal(nsPropertyOwner aObject, michael@0: nsIAtom *aPropertyName, michael@0: bool aRemove, michael@0: nsresult *aStatus); michael@0: NS_HIDDEN_(nsresult) SetPropertyInternal(nsPropertyOwner aObject, michael@0: nsIAtom *aPropertyName, michael@0: void *aPropertyValue, michael@0: NSPropertyDtorFunc aDtor, michael@0: void *aDtorData, michael@0: bool aTransfer, michael@0: void **aOldValue); michael@0: michael@0: PropertyList *mPropertyList; michael@0: }; michael@0: #endif