vfs: check userland buffers before reading them.
[haiku.git] / src / kits / debugger / model / StackFrameValues.cpp
blob113d4c8e41ca84a4a7b4e4fd433fe910afbf158a
1 /*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "StackFrameValues.h"
9 #include <new>
11 #include "FunctionID.h"
12 #include "TypeComponentPath.h"
15 struct StackFrameValues::Key {
16 ObjectID* variable;
17 TypeComponentPath* path;
19 Key(ObjectID* variable, TypeComponentPath* path)
21 variable(variable),
22 path(path)
26 uint32 HashValue() const
28 return variable->HashValue() ^ path->HashValue();
31 bool operator==(const Key& other) const
33 return *variable == *other.variable && *path == *other.path;
38 struct StackFrameValues::ValueEntry : Key {
39 BVariant value;
40 ValueEntry* next;
42 ValueEntry(ObjectID* variable, TypeComponentPath* path)
44 Key(variable, path)
46 variable->AcquireReference();
47 path->AcquireReference();
50 ~ValueEntry()
52 variable->ReleaseReference();
53 path->ReleaseReference();
58 struct StackFrameValues::ValueEntryHashDefinition {
59 typedef Key KeyType;
60 typedef ValueEntry ValueType;
62 size_t HashKey(const Key& key) const
64 return key.HashValue();
67 size_t Hash(const ValueEntry* value) const
69 return value->HashValue();
72 bool Compare(const Key& key, const ValueEntry* value) const
74 return key == *value;
77 ValueEntry*& GetLink(ValueEntry* value) const
79 return value->next;
84 StackFrameValues::StackFrameValues()
86 fValues(NULL)
91 StackFrameValues::StackFrameValues(const StackFrameValues& other)
93 fValues(NULL)
95 try {
96 // init
97 if (Init() != B_OK)
98 throw std::bad_alloc();
100 // clone all values
101 for (ValueTable::Iterator it = other.fValues->GetIterator();
102 ValueEntry* entry = it.Next();) {
103 if (SetValue(entry->variable, entry->path, entry->value) != B_OK)
104 throw std::bad_alloc();
106 } catch (...) {
107 _Cleanup();
108 throw;
113 StackFrameValues::~StackFrameValues()
115 _Cleanup();
119 status_t
120 StackFrameValues::Init()
122 fValues = new(std::nothrow) ValueTable;
123 if (fValues == NULL)
124 return B_NO_MEMORY;
126 return fValues->Init();
130 bool
131 StackFrameValues::GetValue(ObjectID* variable, const TypeComponentPath* path,
132 BVariant& _value) const
134 ValueEntry* entry = fValues->Lookup(
135 Key(variable, (TypeComponentPath*)path));
136 if (entry == NULL)
137 return false;
139 _value = entry->value;
140 return true;
144 bool
145 StackFrameValues::HasValue(ObjectID* variable, const TypeComponentPath* path)
146 const
148 return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
152 status_t
153 StackFrameValues::SetValue(ObjectID* variable, TypeComponentPath* path,
154 const BVariant& value)
156 ValueEntry* entry = fValues->Lookup(Key(variable, path));
157 if (entry == NULL) {
158 entry = new(std::nothrow) ValueEntry(variable, path);
159 if (entry == NULL)
160 return B_NO_MEMORY;
161 fValues->Insert(entry);
164 entry->value = value;
165 return B_OK;
169 void
170 StackFrameValues::_Cleanup()
172 if (fValues != NULL) {
173 ValueEntry* entry = fValues->Clear(true);
175 while (entry != NULL) {
176 ValueEntry* next = entry->next;
177 delete entry;
178 entry = next;
181 delete fValues;
182 fValues = NULL;