1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/bindings/MozMap.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,132 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/** 1.11 + * Class for representing MozMap arguments. This is an nsTHashtable 1.12 + * under the hood, but we don't want to leak that implementation 1.13 + * detail. 1.14 + */ 1.15 + 1.16 +#ifndef mozilla_dom_MozMap_h 1.17 +#define mozilla_dom_MozMap_h 1.18 + 1.19 +#include "nsTHashtable.h" 1.20 +#include "nsHashKeys.h" 1.21 +#include "nsStringGlue.h" 1.22 +#include "nsTArray.h" 1.23 +#include "mozilla/Move.h" 1.24 + 1.25 +namespace mozilla { 1.26 +namespace dom { 1.27 + 1.28 +namespace binding_detail { 1.29 +template<typename DataType> 1.30 +class MozMapEntry : public nsStringHashKey 1.31 +{ 1.32 +public: 1.33 + MozMapEntry(const nsAString* aKeyTypePointer) 1.34 + : nsStringHashKey(aKeyTypePointer) 1.35 + { 1.36 + } 1.37 + 1.38 + // Move constructor so we can do MozMaps of MozMaps. 1.39 + MozMapEntry(MozMapEntry<DataType>&& aOther) 1.40 + : nsStringHashKey(aOther), 1.41 + mData(Move(aOther.mData)) 1.42 + { 1.43 + } 1.44 + 1.45 + DataType mData; 1.46 +}; 1.47 +} // namespace binding_detail 1.48 + 1.49 +template<typename DataType> 1.50 +class MozMap : protected nsTHashtable<binding_detail::MozMapEntry<DataType>> 1.51 +{ 1.52 +public: 1.53 + typedef typename binding_detail::MozMapEntry<DataType> EntryType; 1.54 + typedef nsTHashtable<EntryType> Base; 1.55 + typedef MozMap<DataType> SelfType; 1.56 + 1.57 + MozMap() 1.58 + { 1.59 + } 1.60 + 1.61 + // Move constructor so we can do MozMap of MozMap. 1.62 + MozMap(SelfType&& aOther) : 1.63 + Base(Move(aOther)) 1.64 + { 1.65 + } 1.66 + 1.67 + // The return value is only safe to use until an AddEntry call. 1.68 + const DataType& Get(const nsAString& aKey) const 1.69 + { 1.70 + const EntryType* ent = this->GetEntry(aKey); 1.71 + MOZ_ASSERT(ent, "Why are you using a key we didn't claim to have?"); 1.72 + return ent->mData; 1.73 + } 1.74 + 1.75 + // The return value is only safe to use until an AddEntry call. 1.76 + const DataType* GetIfExists(const nsAString& aKey) const 1.77 + { 1.78 + const EntryType* ent = this->GetEntry(aKey); 1.79 + if (!ent) { 1.80 + return nullptr; 1.81 + } 1.82 + return &ent->mData; 1.83 + } 1.84 + 1.85 + void GetKeys(nsTArray<nsString>& aKeys) const { 1.86 + // Sadly, EnumerateEntries is not a const method 1.87 + const_cast<SelfType*>(this)->EnumerateEntries(KeyEnumerator, &aKeys); 1.88 + } 1.89 + 1.90 + // XXXbz we expose this generic enumerator for tracing. Otherwise we'd end up 1.91 + // with a dependency on BindingUtils.h here for the SequenceTracer bits. 1.92 + typedef PLDHashOperator (* Enumerator)(DataType* aValue, void* aClosure); 1.93 + void EnumerateValues(Enumerator aEnumerator, void *aClosure) 1.94 + { 1.95 + ValueEnumClosure args = { aEnumerator, aClosure }; 1.96 + this->EnumerateEntries(ValueEnumerator, &args); 1.97 + } 1.98 + 1.99 + DataType* AddEntry(const nsAString& aKey) NS_WARN_UNUSED_RESULT 1.100 + { 1.101 + // XXXbz can't just use fallible_t() because our superclass has a 1.102 + // private typedef by that name. 1.103 + EntryType* ent = this->PutEntry(aKey, mozilla::fallible_t()); 1.104 + if (!ent) { 1.105 + return nullptr; 1.106 + } 1.107 + return &ent->mData; 1.108 + } 1.109 + 1.110 +private: 1.111 + static PLDHashOperator 1.112 + KeyEnumerator(EntryType* aEntry, void* aClosure) 1.113 + { 1.114 + nsTArray<nsString>& keys = *static_cast<nsTArray<nsString>*>(aClosure); 1.115 + keys.AppendElement(aEntry->GetKey()); 1.116 + return PL_DHASH_NEXT; 1.117 + } 1.118 + 1.119 + struct ValueEnumClosure { 1.120 + Enumerator mEnumerator; 1.121 + void* mClosure; 1.122 + }; 1.123 + 1.124 + static PLDHashOperator 1.125 + ValueEnumerator(EntryType* aEntry, void* aClosure) 1.126 + { 1.127 + ValueEnumClosure* enumClosure = static_cast<ValueEnumClosure*>(aClosure); 1.128 + return enumClosure->mEnumerator(&aEntry->mData, enumClosure->mClosure); 1.129 + } 1.130 +}; 1.131 + 1.132 +} // namespace dom 1.133 +} // namespace mozilla 1.134 + 1.135 +#endif // mozilla_dom_MozMap_h