1 /*
2 * Copyright 2014-2016, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8 #include "ExpressionValues.h"
9
10 #include <new>
11
12 #include "FunctionID.h"
13 #include "model/Thread.h"
14
15
16 struct ExpressionValues::Key {
17 FunctionID* function;
18 ::Thread* thread;
19 BString expression;
20
KeyExpressionValues::Key21 Key(FunctionID* function, ::Thread* thread, const BString& expression)
22 :
23 function(function),
24 thread(thread),
25 expression(expression)
26 {
27 }
28
HashValueExpressionValues::Key29 uint32 HashValue() const
30 {
31 return function->HashValue() ^ thread->ID()
32 ^ expression.HashValue();
33 }
34
operator ==ExpressionValues::Key35 bool operator==(const Key& other) const
36 {
37 return *function == *other.function
38 && thread->ID() == other.thread->ID()
39 && expression == other.expression;
40 }
41 };
42
43
44 struct ExpressionValues::ValueEntry : Key {
45 BVariant value;
46 ValueEntry* next;
47
ValueEntryExpressionValues::ValueEntry48 ValueEntry(FunctionID* function, ::Thread* thread,
49 const BString& expression)
50 :
51 Key(function, thread, expression)
52 {
53 function->AcquireReference();
54 thread->AcquireReference();
55 }
56
~ValueEntryExpressionValues::ValueEntry57 ~ValueEntry()
58 {
59 function->ReleaseReference();
60 thread->ReleaseReference();
61 }
62 };
63
64
65 struct ExpressionValues::ValueEntryHashDefinition {
66 typedef Key KeyType;
67 typedef ValueEntry ValueType;
68
HashKeyExpressionValues::ValueEntryHashDefinition69 size_t HashKey(const Key& key) const
70 {
71 return key.HashValue();
72 }
73
HashExpressionValues::ValueEntryHashDefinition74 size_t Hash(const ValueEntry* value) const
75 {
76 return value->HashValue();
77 }
78
CompareExpressionValues::ValueEntryHashDefinition79 bool Compare(const Key& key, const ValueEntry* value) const
80 {
81 return key == *value;
82 }
83
GetLinkExpressionValues::ValueEntryHashDefinition84 ValueEntry*& GetLink(ValueEntry* value) const
85 {
86 return value->next;
87 }
88 };
89
90
ExpressionValues()91 ExpressionValues::ExpressionValues()
92 :
93 fValues(NULL)
94 {
95 }
96
97
ExpressionValues(const ExpressionValues & other)98 ExpressionValues::ExpressionValues(const ExpressionValues& other)
99 :
100 fValues(NULL)
101 {
102 try {
103 // init
104 if (Init() != B_OK)
105 throw std::bad_alloc();
106
107 // clone all values
108 for (ValueTable::Iterator it = other.fValues->GetIterator();
109 ValueEntry* entry = it.Next();) {
110 if (SetValue(entry->function, entry->thread, entry->expression,
111 entry->value) != B_OK) {
112 throw std::bad_alloc();
113 }
114 }
115 } catch (...) {
116 _Cleanup();
117 throw;
118 }
119 }
120
121
~ExpressionValues()122 ExpressionValues::~ExpressionValues()
123 {
124 _Cleanup();
125 }
126
127
128 status_t
Init()129 ExpressionValues::Init()
130 {
131 fValues = new(std::nothrow) ValueTable;
132 if (fValues == NULL)
133 return B_NO_MEMORY;
134
135 return fValues->Init();
136 }
137
138
139 bool
GetValue(FunctionID * function,::Thread * thread,const BString * expression,BVariant & _value) const140 ExpressionValues::GetValue(FunctionID* function, ::Thread* thread,
141 const BString* expression, BVariant& _value) const
142 {
143 ValueEntry* entry = fValues->Lookup(Key(function, thread, *expression));
144 if (entry == NULL)
145 return false;
146
147 _value = entry->value;
148 return true;
149 }
150
151
152 bool
HasValue(FunctionID * function,::Thread * thread,const BString * expression) const153 ExpressionValues::HasValue(FunctionID* function, ::Thread* thread,
154 const BString* expression) const
155 {
156 return fValues->Lookup(Key(function, thread, *expression)) != NULL;
157 }
158
159
160 status_t
SetValue(FunctionID * function,::Thread * thread,const BString & expression,const BVariant & value)161 ExpressionValues::SetValue(FunctionID* function, ::Thread* thread,
162 const BString& expression, const BVariant& value)
163 {
164 ValueEntry* entry = fValues->Lookup(Key(function, thread, expression));
165 if (entry == NULL) {
166 entry = new(std::nothrow) ValueEntry(function, thread, expression);
167 if (entry == NULL)
168 return B_NO_MEMORY;
169 fValues->Insert(entry);
170 }
171
172 entry->value = value;
173 return B_OK;
174 }
175
176
177 void
_Cleanup()178 ExpressionValues::_Cleanup()
179 {
180 if (fValues != NULL) {
181 ValueEntry* entry = fValues->Clear(true);
182
183 while (entry != NULL) {
184 ValueEntry* next = entry->next;
185 delete entry;
186 entry = next;
187 }
188
189 delete fValues;
190 fValues = NULL;
191 }
192 }
193