michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ 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 file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_quota_patternmatcher_h__ michael@0: #define mozilla_dom_quota_patternmatcher_h__ michael@0: michael@0: #include "mozilla/dom/quota/QuotaCommon.h" michael@0: michael@0: #include "ArrayCluster.h" michael@0: #include "Utilities.h" michael@0: michael@0: BEGIN_QUOTA_NAMESPACE michael@0: michael@0: template > michael@0: class StorageMatcher : public ValueType michael@0: { michael@0: typedef StorageMatcher SelfType; michael@0: michael@0: struct Closure michael@0: { michael@0: Closure(SelfType& aSelf) michael@0: : mSelf(aSelf), mPattern(EmptyCString()), mIndexes(nullptr) michael@0: { } michael@0: michael@0: Closure(SelfType& aSelf, const nsACString& aPattern) michael@0: : mSelf(aSelf), mPattern(aPattern), mIndexes(nullptr) michael@0: { } michael@0: michael@0: Closure(SelfType& aSelf, const nsTArray* aIndexes) michael@0: : mSelf(aSelf), mPattern(EmptyCString()), mIndexes(aIndexes) michael@0: { } michael@0: michael@0: Closure(SelfType& aSelf, const nsACString& aPattern, michael@0: const nsTArray* aIndexes) michael@0: : mSelf(aSelf), mPattern(aPattern), mIndexes(aIndexes) michael@0: { } michael@0: michael@0: SelfType& mSelf; michael@0: const nsACString& mPattern; michael@0: const nsTArray* mIndexes; michael@0: }; michael@0: michael@0: public: michael@0: template michael@0: void michael@0: Find(const nsBaseHashtable& aHashtable, michael@0: const nsACString& aPattern) michael@0: { michael@0: SelfType::Clear(); michael@0: michael@0: Closure closure(*this, aPattern); michael@0: aHashtable.EnumerateRead(SelfType::MatchPattern, &closure); michael@0: } michael@0: michael@0: template michael@0: void michael@0: Find(const nsBaseHashtable& aHashtable, michael@0: const nsTArray* aIndexes) michael@0: { michael@0: SelfType::Clear(); michael@0: michael@0: Closure closure(*this, aIndexes); michael@0: aHashtable.EnumerateRead(SelfType::MatchIndexes, &closure); michael@0: } michael@0: michael@0: template michael@0: void michael@0: Find(const nsBaseHashtable& aHashtable, michael@0: uint32_t aIndex) michael@0: { michael@0: nsAutoTArray indexes; michael@0: indexes.AppendElement(aIndex); michael@0: michael@0: Find(aHashtable, &indexes); michael@0: } michael@0: michael@0: template michael@0: void michael@0: Find(const nsBaseHashtable& aHashtable, michael@0: const nsACString& aPattern, michael@0: const nsTArray* aIndexes) michael@0: { michael@0: SelfType::Clear(); michael@0: michael@0: Closure closure(*this, aPattern, aIndexes); michael@0: aHashtable.EnumerateRead(SelfType::MatchPatternAndIndexes, &closure); michael@0: } michael@0: michael@0: template michael@0: void michael@0: Find(const nsBaseHashtable& aHashtable, michael@0: const nsACString& aPattern, michael@0: uint32_t aIndex) michael@0: { michael@0: nsAutoTArray indexes; michael@0: indexes.AppendElement(aIndex); michael@0: michael@0: Find(aHashtable, aPattern, &indexes); michael@0: } michael@0: michael@0: template michael@0: void michael@0: Find(const nsBaseHashtable& aHashtable) michael@0: { michael@0: SelfType::Clear(); michael@0: michael@0: Closure closure(*this); michael@0: aHashtable.EnumerateRead(SelfType::MatchAll, &closure); michael@0: } michael@0: michael@0: private: michael@0: static PLDHashOperator michael@0: MatchPattern(const nsACString& aKey, michael@0: BaseType* aValue, michael@0: void* aUserArg) michael@0: { michael@0: MOZ_ASSERT(!aKey.IsEmpty(), "Empty key!"); michael@0: MOZ_ASSERT(aValue, "Null pointer!"); michael@0: MOZ_ASSERT(aUserArg, "Null pointer!"); michael@0: michael@0: Closure* closure = static_cast(aUserArg); michael@0: michael@0: if (PatternMatchesOrigin(closure->mPattern, aKey)) { michael@0: aValue->AppendElementsTo(closure->mSelf); michael@0: } michael@0: michael@0: return PL_DHASH_NEXT; michael@0: } michael@0: michael@0: static PLDHashOperator michael@0: MatchIndexes(const nsACString& aKey, michael@0: BaseType* aValue, michael@0: void* aUserArg) michael@0: { michael@0: MOZ_ASSERT(!aKey.IsEmpty(), "Empty key!"); michael@0: MOZ_ASSERT(aValue, "Null pointer!"); michael@0: MOZ_ASSERT(aUserArg, "Null pointer!"); michael@0: michael@0: Closure* closure = static_cast(aUserArg); michael@0: michael@0: for (uint32_t index = 0; index < closure->mIndexes->Length(); index++) { michael@0: aValue->AppendElementsTo(closure->mIndexes->ElementAt(index), michael@0: closure->mSelf); michael@0: } michael@0: michael@0: return PL_DHASH_NEXT; michael@0: } michael@0: michael@0: static PLDHashOperator michael@0: MatchPatternAndIndexes(const nsACString& aKey, michael@0: BaseType* aValue, michael@0: void* aUserArg) michael@0: { michael@0: MOZ_ASSERT(!aKey.IsEmpty(), "Empty key!"); michael@0: MOZ_ASSERT(aValue, "Null pointer!"); michael@0: MOZ_ASSERT(aUserArg, "Null pointer!"); michael@0: michael@0: Closure* closure = static_cast(aUserArg); michael@0: michael@0: if (PatternMatchesOrigin(closure->mPattern, aKey)) { michael@0: for (uint32_t index = 0; index < closure->mIndexes->Length(); index++) { michael@0: aValue->AppendElementsTo(closure->mIndexes->ElementAt(index), michael@0: closure->mSelf); michael@0: } michael@0: } michael@0: michael@0: return PL_DHASH_NEXT; michael@0: } michael@0: michael@0: static PLDHashOperator michael@0: MatchAll(const nsACString& aKey, michael@0: BaseType* aValue, michael@0: void* aUserArg) michael@0: { michael@0: MOZ_ASSERT(!aKey.IsEmpty(), "Empty key!"); michael@0: MOZ_ASSERT(aValue, "Null pointer!"); michael@0: MOZ_ASSERT(aUserArg, "Null pointer!"); michael@0: michael@0: Closure* closure = static_cast(aUserArg); michael@0: aValue->AppendElementsTo(closure->mSelf); michael@0: michael@0: return PL_DHASH_NEXT; michael@0: } michael@0: }; michael@0: michael@0: END_QUOTA_NAMESPACE michael@0: michael@0: #endif // mozilla_dom_quota_patternmatcher_h__