xref: /haiku/src/kits/debugger/model/ExpressionValues.cpp (revision 6a2d53e7237764eab0c7b6d121772f26d636fb60)
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