/work/obj-fuzz/dist/include/mozilla/gfx/UserData.h
Line | Count | Source (jump to first uncovered line) |
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 MOZILLA_GFX_USERDATA_H_ |
8 | | #define MOZILLA_GFX_USERDATA_H_ |
9 | | |
10 | | #include <stdlib.h> |
11 | | #include "Types.h" |
12 | | #include "mozilla/Assertions.h" |
13 | | |
14 | | namespace mozilla { |
15 | | namespace gfx { |
16 | | |
17 | | struct UserDataKey { |
18 | | int unused; |
19 | | }; |
20 | | |
21 | | /* this class is basically a clone of the user data concept from cairo */ |
22 | | class UserData |
23 | | { |
24 | | typedef void (*destroyFunc)(void *data); |
25 | | public: |
26 | | UserData() : count(0), entries(nullptr) {} |
27 | | |
28 | | /* Attaches untyped userData associated with key. destroy is called on destruction */ |
29 | | void Add(UserDataKey *key, void *userData, destroyFunc destroy) |
30 | | { |
31 | | for (int i=0; i<count; i++) { |
32 | | if (key == entries[i].key) { |
33 | | if (entries[i].destroy) { |
34 | | entries[i].destroy(entries[i].userData); |
35 | | } |
36 | | entries[i].userData = userData; |
37 | | entries[i].destroy = destroy; |
38 | | return; |
39 | | } |
40 | | } |
41 | | |
42 | | // We could keep entries in a std::vector instead of managing it by hand |
43 | | // but that would propagate an stl dependency out which we'd rather not |
44 | | // do (see bug 666609). Plus, the entries array is expect to stay small |
45 | | // so doing a realloc everytime we add a new entry shouldn't be too costly |
46 | | entries = static_cast<Entry*>(realloc(entries, sizeof(Entry)*(count+1))); |
47 | | |
48 | | if (!entries) { |
49 | | MOZ_CRASH("GFX: UserData::Add"); |
50 | | } |
51 | | |
52 | | entries[count].key = key; |
53 | | entries[count].userData = userData; |
54 | | entries[count].destroy = destroy; |
55 | | |
56 | | count++; |
57 | | } |
58 | | |
59 | | /* Remove and return user data associated with key, without destroying it */ |
60 | | void* Remove(UserDataKey *key) |
61 | 0 | { |
62 | 0 | for (int i=0; i<count; i++) { |
63 | 0 | if (key == entries[i].key) { |
64 | 0 | void *userData = entries[i].userData; |
65 | 0 | // decrement before looping so entries[i+1] doesn't read past the end: |
66 | 0 | --count; |
67 | 0 | for (;i<count; i++) { |
68 | 0 | entries[i] = entries[i+1]; |
69 | 0 | } |
70 | 0 | return userData; |
71 | 0 | } |
72 | 0 | } |
73 | 0 | return nullptr; |
74 | 0 | } |
75 | | |
76 | | /* Remove and destroy a given key */ |
77 | | void RemoveAndDestroy(UserDataKey *key) |
78 | | { |
79 | | for (int i=0; i<count; i++) { |
80 | | if (key == entries[i].key) { |
81 | | if (entries[i].destroy) { |
82 | | entries[i].destroy(entries[i].userData); |
83 | | } |
84 | | // decrement before looping so entries[i+1] doesn't read past the end: |
85 | | --count; |
86 | | for (;i<count; i++) { |
87 | | entries[i] = entries[i+1]; |
88 | | } |
89 | | } |
90 | | } |
91 | | } |
92 | | |
93 | | /* Retrives the userData for the associated key */ |
94 | | void *Get(UserDataKey *key) const |
95 | | { |
96 | | for (int i=0; i<count; i++) { |
97 | | if (key == entries[i].key) { |
98 | | return entries[i].userData; |
99 | | } |
100 | | } |
101 | | return nullptr; |
102 | | } |
103 | | |
104 | | bool Has(UserDataKey *key) |
105 | 0 | { |
106 | 0 | for (int i=0; i<count; i++) { |
107 | 0 | if (key == entries[i].key) { |
108 | 0 | return true; |
109 | 0 | } |
110 | 0 | } |
111 | 0 | return false; |
112 | 0 | } |
113 | | |
114 | | void Destroy() |
115 | | { |
116 | | for (int i=0; i<count; i++) { |
117 | | if (entries[i].destroy) { |
118 | | entries[i].destroy(entries[i].userData); |
119 | | } |
120 | | } |
121 | | free(entries); |
122 | | entries = nullptr; |
123 | | count = 0; |
124 | | } |
125 | | |
126 | | ~UserData() |
127 | | { |
128 | | Destroy(); |
129 | | } |
130 | | |
131 | | private: |
132 | | struct Entry { |
133 | | const UserDataKey *key; |
134 | | void *userData; |
135 | | destroyFunc destroy; |
136 | | }; |
137 | | |
138 | | int count; |
139 | | Entry *entries; |
140 | | |
141 | | }; |
142 | | |
143 | | } // namespace gfx |
144 | | } // namespace mozilla |
145 | | |
146 | | #endif /* MOZILLA_GFX_USERDATA_H_ */ |