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 #ifndef NS_SVGATTRTEAROFFTABLE_H_
8 #define NS_SVGATTRTEAROFFTABLE_H_
9
10 #include "nsDataHashtable.h"
11 #include "nsDebug.h"
12 #include "nsHashKeys.h"
13
14 /**
15 * Global hashmap to associate internal SVG data types (e.g. nsSVGLength2) with
16 * DOM tear-off objects (e.g. nsIDOMSVGLength). This allows us to always return
17 * the same object for subsequent requests for DOM objects.
18 *
19 * We don't keep an owning reference to the tear-off objects so they are
20 * responsible for removing themselves from this table when they die.
21 */
22 template<class SimpleType, class TearoffType>
23 class nsSVGAttrTearoffTable
24 {
25 public:
26 #ifdef DEBUG
~nsSVGAttrTearoffTable()27 ~nsSVGAttrTearoffTable()
28 {
29 MOZ_ASSERT(!mTable, "Tear-off objects remain in hashtable at shutdown.");
30 }
31 #endif
32
33 TearoffType* GetTearoff(SimpleType* aSimple);
34
35 void AddTearoff(SimpleType* aSimple, TearoffType* aTearoff);
36
37 void RemoveTearoff(SimpleType* aSimple);
38
39 private:
40 typedef nsPtrHashKey<SimpleType> SimpleTypePtrKey;
41 typedef nsDataHashtable<SimpleTypePtrKey, TearoffType* > TearoffTable;
42
43 TearoffTable* mTable;
44 };
45
46 template<class SimpleType, class TearoffType>
47 TearoffType*
GetTearoff(SimpleType * aSimple)48 nsSVGAttrTearoffTable<SimpleType, TearoffType>::GetTearoff(SimpleType* aSimple)
49 {
50 if (!mTable)
51 return nullptr;
52
53 TearoffType *tearoff = nullptr;
54
55 #ifdef DEBUG
56 bool found =
57 #endif
58 mTable->Get(aSimple, &tearoff);
59 MOZ_ASSERT(!found || tearoff,
60 "null pointer stored in attribute tear-off map");
61
62 return tearoff;
63 }
64
65 template<class SimpleType, class TearoffType>
66 void
AddTearoff(SimpleType * aSimple,TearoffType * aTearoff)67 nsSVGAttrTearoffTable<SimpleType, TearoffType>::AddTearoff(SimpleType* aSimple,
68 TearoffType* aTearoff)
69 {
70 if (!mTable) {
71 mTable = new TearoffTable;
72 }
73
74 // We shouldn't be adding a tear-off if there already is one. If that happens,
75 // something is wrong.
76 if (mTable->Get(aSimple, nullptr)) {
77 MOZ_ASSERT(false, "There is already a tear-off for this object.");
78 return;
79 }
80
81 mTable->Put(aSimple, aTearoff);
82 }
83
84 template<class SimpleType, class TearoffType>
85 void
RemoveTearoff(SimpleType * aSimple)86 nsSVGAttrTearoffTable<SimpleType, TearoffType>::RemoveTearoff(
87 SimpleType* aSimple)
88 {
89 if (!mTable) {
90 // Perhaps something happened in between creating the SimpleType object and
91 // registering it
92 return;
93 }
94
95 mTable->Remove(aSimple);
96 if (mTable->Count() == 0) {
97 delete mTable;
98 mTable = nullptr;
99 }
100 }
101
102 #endif // NS_SVGATTRTEAROFFTABLE_H_
103