michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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: michael@0: #ifndef nsCommandParams_h__ michael@0: #define nsCommandParams_h__ michael@0: michael@0: #include "nsString.h" michael@0: #include "nsICommandParams.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "pldhash.h" michael@0: michael@0: michael@0: michael@0: class nsCommandParams : public nsICommandParams michael@0: { michael@0: public: michael@0: michael@0: nsCommandParams(); michael@0: virtual ~nsCommandParams(); michael@0: michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSICOMMANDPARAMS michael@0: michael@0: nsresult Init(); michael@0: michael@0: protected: michael@0: michael@0: struct HashEntry : public PLDHashEntryHdr michael@0: { michael@0: nsCString mEntryName; michael@0: michael@0: uint8_t mEntryType; michael@0: union { michael@0: michael@0: bool mBoolean; michael@0: int32_t mLong; michael@0: double mDouble; michael@0: nsString* mString; michael@0: nsCString* mCString; michael@0: } mData; michael@0: michael@0: nsCOMPtr mISupports; michael@0: michael@0: HashEntry(uint8_t inType, const char * inEntryName) michael@0: : mEntryName(inEntryName) michael@0: , mEntryType(inType) michael@0: { michael@0: memset(&mData, 0, sizeof(mData)); michael@0: Reset(mEntryType); michael@0: } michael@0: michael@0: HashEntry(const HashEntry& inRHS) michael@0: : mEntryType(inRHS.mEntryType) michael@0: { michael@0: Reset(mEntryType); michael@0: switch (mEntryType) michael@0: { michael@0: case eBooleanType: mData.mBoolean = inRHS.mData.mBoolean; break; michael@0: case eLongType: mData.mLong = inRHS.mData.mLong; break; michael@0: case eDoubleType: mData.mDouble = inRHS.mData.mDouble; break; michael@0: case eWStringType: michael@0: NS_ASSERTION(inRHS.mData.mString, "Source entry has no string"); michael@0: mData.mString = new nsString(*inRHS.mData.mString); michael@0: break; michael@0: case eStringType: michael@0: NS_ASSERTION(inRHS.mData.mCString, "Source entry has no string"); michael@0: mData.mCString = new nsCString(*inRHS.mData.mCString); michael@0: break; michael@0: case eISupportsType: michael@0: mISupports = inRHS.mISupports.get(); // additional addref michael@0: break; michael@0: default: michael@0: NS_ERROR("Unknown type"); michael@0: } michael@0: } michael@0: michael@0: ~HashEntry() michael@0: { michael@0: if (mEntryType == eWStringType) michael@0: delete mData.mString; michael@0: else if (mEntryType == eStringType) michael@0: delete mData.mCString; michael@0: } michael@0: michael@0: void Reset(uint8_t inNewType) michael@0: { michael@0: switch (mEntryType) michael@0: { michael@0: case eNoType: break; michael@0: case eBooleanType: mData.mBoolean = false; break; michael@0: case eLongType: mData.mLong = 0; break; michael@0: case eDoubleType: mData.mDouble = 0.0; break; michael@0: case eWStringType: delete mData.mString; mData.mString = nullptr; break; michael@0: case eISupportsType: mISupports = nullptr; break; // clear the nsCOMPtr michael@0: case eStringType: delete mData.mCString; mData.mCString = nullptr; break; michael@0: default: michael@0: NS_ERROR("Unknown type"); michael@0: } michael@0: michael@0: mEntryType = inNewType; michael@0: } michael@0: michael@0: }; michael@0: michael@0: michael@0: HashEntry* GetNamedEntry(const char * name); michael@0: HashEntry* GetIndexedEntry(int32_t index); michael@0: uint32_t GetNumEntries(); michael@0: michael@0: nsresult GetOrMakeEntry(const char * name, uint8_t entryType, HashEntry*& outEntry); michael@0: michael@0: protected: michael@0: michael@0: static PLDHashNumber HashKey(PLDHashTable *table, const void *key); michael@0: michael@0: static bool HashMatchEntry(PLDHashTable *table, michael@0: const PLDHashEntryHdr *entry, const void *key); michael@0: michael@0: static void HashMoveEntry(PLDHashTable *table, const PLDHashEntryHdr *from, michael@0: PLDHashEntryHdr *to); michael@0: michael@0: static void HashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry); michael@0: michael@0: michael@0: protected: michael@0: michael@0: enum { michael@0: eNumEntriesUnknown = -1 michael@0: }; michael@0: michael@0: // this is going to have to use a pldhash, because we need to michael@0: // be able to iterate through entries, passing names back michael@0: // to the caller, which means that we need to store the names michael@0: // internally. michael@0: michael@0: PLDHashTable mValuesHash; michael@0: michael@0: // enumerator data michael@0: int32_t mCurEntry; michael@0: int32_t mNumEntries; // number of entries at start of enumeration (-1 indicates not known) michael@0: michael@0: static const PLDHashTableOps sHashOps; michael@0: }; michael@0: michael@0: michael@0: #endif // nsCommandParams_h__