dom/bindings/MozMap.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 /**
michael@0 8 * Class for representing MozMap arguments. This is an nsTHashtable
michael@0 9 * under the hood, but we don't want to leak that implementation
michael@0 10 * detail.
michael@0 11 */
michael@0 12
michael@0 13 #ifndef mozilla_dom_MozMap_h
michael@0 14 #define mozilla_dom_MozMap_h
michael@0 15
michael@0 16 #include "nsTHashtable.h"
michael@0 17 #include "nsHashKeys.h"
michael@0 18 #include "nsStringGlue.h"
michael@0 19 #include "nsTArray.h"
michael@0 20 #include "mozilla/Move.h"
michael@0 21
michael@0 22 namespace mozilla {
michael@0 23 namespace dom {
michael@0 24
michael@0 25 namespace binding_detail {
michael@0 26 template<typename DataType>
michael@0 27 class MozMapEntry : public nsStringHashKey
michael@0 28 {
michael@0 29 public:
michael@0 30 MozMapEntry(const nsAString* aKeyTypePointer)
michael@0 31 : nsStringHashKey(aKeyTypePointer)
michael@0 32 {
michael@0 33 }
michael@0 34
michael@0 35 // Move constructor so we can do MozMaps of MozMaps.
michael@0 36 MozMapEntry(MozMapEntry<DataType>&& aOther)
michael@0 37 : nsStringHashKey(aOther),
michael@0 38 mData(Move(aOther.mData))
michael@0 39 {
michael@0 40 }
michael@0 41
michael@0 42 DataType mData;
michael@0 43 };
michael@0 44 } // namespace binding_detail
michael@0 45
michael@0 46 template<typename DataType>
michael@0 47 class MozMap : protected nsTHashtable<binding_detail::MozMapEntry<DataType>>
michael@0 48 {
michael@0 49 public:
michael@0 50 typedef typename binding_detail::MozMapEntry<DataType> EntryType;
michael@0 51 typedef nsTHashtable<EntryType> Base;
michael@0 52 typedef MozMap<DataType> SelfType;
michael@0 53
michael@0 54 MozMap()
michael@0 55 {
michael@0 56 }
michael@0 57
michael@0 58 // Move constructor so we can do MozMap of MozMap.
michael@0 59 MozMap(SelfType&& aOther) :
michael@0 60 Base(Move(aOther))
michael@0 61 {
michael@0 62 }
michael@0 63
michael@0 64 // The return value is only safe to use until an AddEntry call.
michael@0 65 const DataType& Get(const nsAString& aKey) const
michael@0 66 {
michael@0 67 const EntryType* ent = this->GetEntry(aKey);
michael@0 68 MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?");
michael@0 69 return ent->mData;
michael@0 70 }
michael@0 71
michael@0 72 // The return value is only safe to use until an AddEntry call.
michael@0 73 const DataType* GetIfExists(const nsAString& aKey) const
michael@0 74 {
michael@0 75 const EntryType* ent = this->GetEntry(aKey);
michael@0 76 if (!ent) {
michael@0 77 return nullptr;
michael@0 78 }
michael@0 79 return &ent->mData;
michael@0 80 }
michael@0 81
michael@0 82 void GetKeys(nsTArray<nsString>& aKeys) const {
michael@0 83 // Sadly, EnumerateEntries is not a const method
michael@0 84 const_cast<SelfType*>(this)->EnumerateEntries(KeyEnumerator, &aKeys);
michael@0 85 }
michael@0 86
michael@0 87 // XXXbz we expose this generic enumerator for tracing. Otherwise we'd end up
michael@0 88 // with a dependency on BindingUtils.h here for the SequenceTracer bits.
michael@0 89 typedef PLDHashOperator (* Enumerator)(DataType* aValue, void* aClosure);
michael@0 90 void EnumerateValues(Enumerator aEnumerator, void *aClosure)
michael@0 91 {
michael@0 92 ValueEnumClosure args = { aEnumerator, aClosure };
michael@0 93 this->EnumerateEntries(ValueEnumerator, &args);
michael@0 94 }
michael@0 95
michael@0 96 DataType* AddEntry(const nsAString& aKey) NS_WARN_UNUSED_RESULT
michael@0 97 {
michael@0 98 // XXXbz can't just use fallible_t() because our superclass has a
michael@0 99 // private typedef by that name.
michael@0 100 EntryType* ent = this->PutEntry(aKey, mozilla::fallible_t());
michael@0 101 if (!ent) {
michael@0 102 return nullptr;
michael@0 103 }
michael@0 104 return &ent->mData;
michael@0 105 }
michael@0 106
michael@0 107 private:
michael@0 108 static PLDHashOperator
michael@0 109 KeyEnumerator(EntryType* aEntry, void* aClosure)
michael@0 110 {
michael@0 111 nsTArray<nsString>& keys = *static_cast<nsTArray<nsString>*>(aClosure);
michael@0 112 keys.AppendElement(aEntry->GetKey());
michael@0 113 return PL_DHASH_NEXT;
michael@0 114 }
michael@0 115
michael@0 116 struct ValueEnumClosure {
michael@0 117 Enumerator mEnumerator;
michael@0 118 void* mClosure;
michael@0 119 };
michael@0 120
michael@0 121 static PLDHashOperator
michael@0 122 ValueEnumerator(EntryType* aEntry, void* aClosure)
michael@0 123 {
michael@0 124 ValueEnumClosure* enumClosure = static_cast<ValueEnumClosure*>(aClosure);
michael@0 125 return enumClosure->mEnumerator(&aEntry->mData, enumClosure->mClosure);
michael@0 126 }
michael@0 127 };
michael@0 128
michael@0 129 } // namespace dom
michael@0 130 } // namespace mozilla
michael@0 131
michael@0 132 #endif // mozilla_dom_MozMap_h

mercurial