xref: /haiku/src/kits/debugger/model/StackFrameValues.cpp (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "StackFrameValues.h"
8 
9 #include <new>
10 
11 #include "FunctionID.h"
12 #include "TypeComponentPath.h"
13 
14 
15 struct StackFrameValues::Key {
16 	ObjectID*			variable;
17 	TypeComponentPath*	path;
18 
19 	Key(ObjectID* variable, TypeComponentPath* path)
20 		:
21 		variable(variable),
22 		path(path)
23 	{
24 	}
25 
26 	uint32 HashValue() const
27 	{
28 		return variable->HashValue() ^ path->HashValue();
29 	}
30 
31 	bool operator==(const Key& other) const
32 	{
33 		return *variable == *other.variable && *path == *other.path;
34 	}
35 };
36 
37 
38 struct StackFrameValues::ValueEntry : Key {
39 	BVariant			value;
40 	ValueEntry*			next;
41 
42 	ValueEntry(ObjectID* variable, TypeComponentPath* path)
43 		:
44 		Key(variable, path)
45 	{
46 		variable->AcquireReference();
47 		path->AcquireReference();
48 	}
49 
50 	~ValueEntry()
51 	{
52 		variable->ReleaseReference();
53 		path->ReleaseReference();
54 	}
55 };
56 
57 
58 struct StackFrameValues::ValueEntryHashDefinition {
59 	typedef Key			KeyType;
60 	typedef	ValueEntry	ValueType;
61 
62 	size_t HashKey(const Key& key) const
63 	{
64 		return key.HashValue();
65 	}
66 
67 	size_t Hash(const ValueEntry* value) const
68 	{
69 		return value->HashValue();
70 	}
71 
72 	bool Compare(const Key& key, const ValueEntry* value) const
73 	{
74 		return key == *value;
75 	}
76 
77 	ValueEntry*& GetLink(ValueEntry* value) const
78 	{
79 		return value->next;
80 	}
81 };
82 
83 
84 StackFrameValues::StackFrameValues()
85 	:
86 	fValues(NULL)
87 {
88 }
89 
90 
91 StackFrameValues::StackFrameValues(const StackFrameValues& other)
92 	:
93 	fValues(NULL)
94 {
95 	try {
96 		// init
97 		if (Init() != B_OK)
98 			throw std::bad_alloc();
99 
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();
105 		}
106 	} catch (...) {
107 		_Cleanup();
108 		throw;
109 	}
110 }
111 
112 
113 StackFrameValues::~StackFrameValues()
114 {
115 	_Cleanup();
116 }
117 
118 
119 status_t
120 StackFrameValues::Init()
121 {
122 	fValues = new(std::nothrow) ValueTable;
123 	if (fValues == NULL)
124 		return B_NO_MEMORY;
125 
126 	return fValues->Init();
127 }
128 
129 
130 bool
131 StackFrameValues::GetValue(ObjectID* variable, const TypeComponentPath* path,
132 	BVariant& _value) const
133 {
134 	ValueEntry* entry = fValues->Lookup(
135 		Key(variable, (TypeComponentPath*)path));
136 	if (entry == NULL)
137 		return false;
138 
139 	_value = entry->value;
140 	return true;
141 }
142 
143 
144 bool
145 StackFrameValues::HasValue(ObjectID* variable, const TypeComponentPath* path)
146 	const
147 {
148 	return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
149 }
150 
151 
152 status_t
153 StackFrameValues::SetValue(ObjectID* variable, TypeComponentPath* path,
154 	const BVariant& value)
155 {
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);
162 	}
163 
164 	entry->value = value;
165 	return B_OK;
166 }
167 
168 
169 void
170 StackFrameValues::_Cleanup()
171 {
172 	if (fValues != NULL) {
173 		ValueEntry* entry = fValues->Clear(true);
174 
175 		while (entry != NULL) {
176 			ValueEntry* next = entry->next;
177 			delete entry;
178 			entry = next;
179 		}
180 
181 		delete fValues;
182 		fValues = NULL;
183 	}
184 }
185