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