vfs: check userland buffers before reading them.
[haiku.git] / src / kits / debugger / model / ExpressionValues.cpp
blob7032bb0702e02d4178e60b1a51d6acc6dc327bc6
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 */
8 #include "ExpressionValues.h"
10 #include <new>
12 #include "FunctionID.h"
13 #include "model/Thread.h"
14 #include "StringUtils.h"
17 struct ExpressionValues::Key {
18 FunctionID* function;
19 ::Thread* thread;
20 BString expression;
22 Key(FunctionID* function, ::Thread* thread, const BString& expression)
24 function(function),
25 thread(thread),
26 expression(expression)
30 uint32 HashValue() const
32 return function->HashValue() ^ thread->ID()
33 ^ StringUtils::HashValue(expression);
36 bool operator==(const Key& other) const
38 return *function == *other.function
39 && thread->ID() == other.thread->ID()
40 && expression == other.expression;
45 struct ExpressionValues::ValueEntry : Key {
46 BVariant value;
47 ValueEntry* next;
49 ValueEntry(FunctionID* function, ::Thread* thread,
50 const BString& expression)
52 Key(function, thread, expression)
54 function->AcquireReference();
55 thread->AcquireReference();
58 ~ValueEntry()
60 function->ReleaseReference();
61 thread->ReleaseReference();
66 struct ExpressionValues::ValueEntryHashDefinition {
67 typedef Key KeyType;
68 typedef ValueEntry ValueType;
70 size_t HashKey(const Key& key) const
72 return key.HashValue();
75 size_t Hash(const ValueEntry* value) const
77 return value->HashValue();
80 bool Compare(const Key& key, const ValueEntry* value) const
82 return key == *value;
85 ValueEntry*& GetLink(ValueEntry* value) const
87 return value->next;
92 ExpressionValues::ExpressionValues()
94 fValues(NULL)
99 ExpressionValues::ExpressionValues(const ExpressionValues& other)
101 fValues(NULL)
103 try {
104 // init
105 if (Init() != B_OK)
106 throw std::bad_alloc();
108 // clone all values
109 for (ValueTable::Iterator it = other.fValues->GetIterator();
110 ValueEntry* entry = it.Next();) {
111 if (SetValue(entry->function, entry->thread, entry->expression,
112 entry->value) != B_OK) {
113 throw std::bad_alloc();
116 } catch (...) {
117 _Cleanup();
118 throw;
123 ExpressionValues::~ExpressionValues()
125 _Cleanup();
129 status_t
130 ExpressionValues::Init()
132 fValues = new(std::nothrow) ValueTable;
133 if (fValues == NULL)
134 return B_NO_MEMORY;
136 return fValues->Init();
140 bool
141 ExpressionValues::GetValue(FunctionID* function, ::Thread* thread,
142 const BString* expression, BVariant& _value) const
144 ValueEntry* entry = fValues->Lookup(Key(function, thread, *expression));
145 if (entry == NULL)
146 return false;
148 _value = entry->value;
149 return true;
153 bool
154 ExpressionValues::HasValue(FunctionID* function, ::Thread* thread,
155 const BString* expression) const
157 return fValues->Lookup(Key(function, thread, *expression)) != NULL;
161 status_t
162 ExpressionValues::SetValue(FunctionID* function, ::Thread* thread,
163 const BString& expression, const BVariant& value)
165 ValueEntry* entry = fValues->Lookup(Key(function, thread, expression));
166 if (entry == NULL) {
167 entry = new(std::nothrow) ValueEntry(function, thread, expression);
168 if (entry == NULL)
169 return B_NO_MEMORY;
170 fValues->Insert(entry);
173 entry->value = value;
174 return B_OK;
178 void
179 ExpressionValues::_Cleanup()
181 if (fValues != NULL) {
182 ValueEntry* entry = fValues->Clear(true);
184 while (entry != NULL) {
185 ValueEntry* next = entry->next;
186 delete entry;
187 entry = next;
190 delete fValues;
191 fValues = NULL;