diff --git a/mozilla/xpcom/ds/nsHashtable.cpp b/mozilla/xpcom/ds/nsHashtable.cpp index 4b9d57f3785..1f78ee299b7 100644 --- a/mozilla/xpcom/ds/nsHashtable.cpp +++ b/mozilla/xpcom/ds/nsHashtable.cpp @@ -454,3 +454,68 @@ nsSupportsHashtable::Reset() } //////////////////////////////////////////////////////////////////////////////// +// nsOpaqueKey: Where keys are opaque byte array blobs +// + +// Note opaque keys are not copied by this constructor. If you want a private +// copy in each hash key, you must create one and pass it in to this function. +nsOpaqueKey::nsOpaqueKey(const char *aOpaqueKey, PRUint32 aKeyLength) +{ + mOpaqueKey = aOpaqueKey; + mKeyLength = aKeyLength; +} + +nsOpaqueKey::~nsOpaqueKey(void) +{ +} + +PRUint32 +nsOpaqueKey::HashValue(void) const +{ + PRUint32 h, i, k; + + h = 0; + + // Same hashing technique as for java.lang.String.hashCode() + if (mKeyLength <= 15) { + // A short key; Use a dense sampling to compute the hash code + for (i = 0; i < mKeyLength; i++) + h += 37 * mOpaqueKey[i]; + } else { + // A long key; Use a sparse sampling to compute the hash code + k = mKeyLength >> 3; + for (i = 0; i < mKeyLength; i += k) + h += 39 * mOpaqueKey[i]; + } + return h; +} + +PRBool +nsOpaqueKey::Equals(const nsHashKey* aKey) const +{ + nsOpaqueKey *otherKey = (nsOpaqueKey*)aKey; + if (mKeyLength != otherKey->mKeyLength) + return PR_FALSE; + return !(PRBool)memcmp(otherKey->mOpaqueKey, mOpaqueKey, mKeyLength); +} + +nsHashKey* +nsOpaqueKey::Clone() const +{ + return new nsOpaqueKey(mOpaqueKey, mKeyLength); +} + +PRUint32 +nsOpaqueKey::GetKeyLength() const +{ + return mKeyLength; +} + +const char* +nsOpaqueKey::GetKey() const +{ + return mOpaqueKey; +} + +//////////////////////////////////////////////////////////////////////////////// + diff --git a/mozilla/xpcom/ds/nsHashtable.h b/mozilla/xpcom/ds/nsHashtable.h index 468aecf96dd..37cce188ece 100644 --- a/mozilla/xpcom/ds/nsHashtable.h +++ b/mozilla/xpcom/ds/nsHashtable.h @@ -218,5 +218,31 @@ public: const nsString& GetString() const; }; +//////////////////////////////////////////////////////////////////////////////// +// nsOpaqueKey: Where keys are opaque byte-array blobs + +#include "nsString.h" + +class NS_COM nsOpaqueKey : public nsHashKey { +protected: + const char* mOpaqueKey; // Byte array of opaque data + PRUint32 mKeyLength; // Length, in bytes, of mOpaqueKey + +public: + // Note opaque keys are not copied by this constructor. If you want a private + // copy in each hash key, you must create one and pass it in to this function. + nsOpaqueKey(const char* aOpaqueKey, PRUint32 aKeyLength); + + ~nsOpaqueKey(void); + + PRUint32 HashValue(void) const; + PRBool Equals(const nsHashKey* aKey) const; + nsHashKey* Clone() const; + + // For when the owner of the hashtable wants to peek at the actual + // opaque array in the key. No copy is made, so be careful. + const char* GetKey() const; + PRUint32 GetKeyLength() const; +}; #endif diff --git a/mozilla/xpcom/ds/nsHashtableEnumerator.cpp b/mozilla/xpcom/ds/nsHashtableEnumerator.cpp index 6de5df09634..69721112bd7 100644 --- a/mozilla/xpcom/ds/nsHashtableEnumerator.cpp +++ b/mozilla/xpcom/ds/nsHashtableEnumerator.cpp @@ -63,7 +63,7 @@ struct nsHashEnumClosure void *Data; }; -nsresult +extern "C" NS_COM nsresult NS_NewHashtableEnumerator (nsHashtable *aHash, NS_HASH_ENUMERATOR_CONVERTER aConverter, void *aData, nsIEnumerator **retval) @@ -185,14 +185,13 @@ nsHashtableEnumerator::Last () NS_IMETHODIMP nsHashtableEnumerator::Prev () { - if (!mElements || (mCount == 0) || (mCurrent == 0)) + if (!mElements || (mCount == 0) || (mCurrent == 0)) { + mDoneFlag = PR_TRUE; return NS_ERROR_FAILURE; + } mCurrent--; - if (mCurrent == 0) - mDoneFlag = PR_TRUE; - else - mDoneFlag = PR_FALSE; + mDoneFlag = PR_FALSE; return NS_OK; @@ -201,17 +200,15 @@ nsHashtableEnumerator::Prev () NS_IMETHODIMP nsHashtableEnumerator::Next () { - if (!mElements || (mCount == 0) || (mCurrent == mCount - 1)) + if (!mElements || (mCount == 0) || (mCurrent == mCount - 1)) { + mDoneFlag = PR_TRUE; return NS_ERROR_FAILURE; + } mCurrent++; - if (mCurrent == mCount - 1) - mDoneFlag = PR_TRUE; - else - mDoneFlag = PR_FALSE; + mDoneFlag = PR_FALSE; return NS_OK; - } NS_IMETHODIMP @@ -244,8 +241,7 @@ nsHashtableEnumerator::IsDone () { if ((!mElements) || (mCount == 0) || (mDoneFlag)) - return NS_ERROR_FAILURE; - - return NS_OK; + return NS_OK; + return NS_COMFALSE; } diff --git a/mozilla/xpcom/ds/nsHashtableEnumerator.h b/mozilla/xpcom/ds/nsHashtableEnumerator.h index 599c909f56e..61b407c618e 100644 --- a/mozilla/xpcom/ds/nsHashtableEnumerator.h +++ b/mozilla/xpcom/ds/nsHashtableEnumerator.h @@ -37,7 +37,7 @@ typedef NS_CALLBACK(NS_HASH_ENUMERATOR_CONVERTER) (nsHashKey *key, void *data, void *convert_data, nsISupports **retval); -extern nsresult +extern "C" NS_COM nsresult NS_NewHashtableEnumerator (nsHashtable *aHash, NS_HASH_ENUMERATOR_CONVERTER aConverter, void *aData, nsIEnumerator **retval);