/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "VariablesViewStateHistory.h"
#include <new>
#include "FunctionID.h"
#include "VariablesViewState.h"
// #pragma mark - Key
struct VariablesViewStateHistory::Key {
thread_id threadID;
FunctionID* functionID;
Key(thread_id threadID, FunctionID* functionID)
:
threadID(threadID),
functionID(functionID)
{
}
uint32 HashValue() const
{
return functionID->HashValue() ^ threadID;
}
bool operator==(const Key& other) const
{
return threadID == other.threadID && *functionID == *other.functionID;
}
};
// #pragma mark - StateEntry
struct VariablesViewStateHistory::StateEntry : Key, VariablesViewNodeInfo {
StateEntry* next;
VariablesViewState* state;
StateEntry(thread_id threadID, FunctionID* functionID)
:
Key(threadID, functionID),
state(NULL)
{
functionID->AcquireReference();
}
~StateEntry()
{
functionID->ReleaseReference();
if (state != NULL)
state->ReleaseReference();
}
void SetState(VariablesViewState* state)
{
if (state == this->state)
return;
if (state != NULL)
state->AcquireReference();
if (this->state != NULL)
this->state->ReleaseReference();
this->state = state;
}
};
struct VariablesViewStateHistory::StateEntryHashDefinition {
typedef Key KeyType;
typedef StateEntry ValueType;
size_t HashKey(const Key& key) const
{
return key.HashValue();
}
size_t Hash(const StateEntry* value) const
{
return HashKey(*value);
}
bool Compare(const Key& key, const StateEntry* value) const
{
return key == *value;
}
StateEntry*& GetLink(StateEntry* value) const
{
return value->next;
}
};
VariablesViewStateHistory::VariablesViewStateHistory()
:
fStates(NULL)
{
}
VariablesViewStateHistory::~VariablesViewStateHistory()
{
if (fStates != NULL) {
StateEntry* entry = fStates->Clear(true);
while (entry != NULL) {
StateEntry* next = entry->next;
delete entry;
entry = next;
}
delete fStates;
}
}
status_t
VariablesViewStateHistory::Init()
{
fStates = new(std::nothrow) StateTable;
if (fStates == NULL)
return B_NO_MEMORY;
return fStates->Init();
}
VariablesViewState*
VariablesViewStateHistory::GetState(thread_id threadID, FunctionID* functionID)
const
{
// first try an exact match with the thread ID
if (threadID >= 0) {
StateEntry* stateEntry = fStates->Lookup(Key(threadID, functionID));
if (stateEntry != NULL)
return stateEntry->state;
}
// just match the function ID
StateEntry* stateEntry = fStates->Lookup(Key(-1, functionID));
return stateEntry != NULL ? stateEntry->state : NULL;
}
VariablesViewState*
VariablesViewStateHistory::GetState(FunctionID* functionID) const
{
StateEntry* stateEntry = fStates->Lookup(Key(-1, functionID));
return stateEntry != NULL ? stateEntry->state : NULL;
}
status_t
VariablesViewStateHistory::SetState(thread_id threadID, FunctionID* functionID,
VariablesViewState* state)
{
// Make sure the default entry for the function exists.
StateEntry* defaultEntry = fStates->Lookup(Key(-1, functionID));
bool newDefaultEntry = false;
if (defaultEntry == NULL) {
defaultEntry = new(std::nothrow) StateEntry(-1, functionID);
if (defaultEntry == NULL)
return B_NO_MEMORY;
fStates->Insert(defaultEntry);
newDefaultEntry = true;
}
// If we have a valid thread ID, make sure the respective entry for the
// function exists.
StateEntry* threadEntry = NULL;
if (threadID >= 0) {
threadEntry = fStates->Lookup(Key(threadID, functionID));
if (threadEntry == NULL) {
threadEntry = new(std::nothrow) StateEntry(threadID, functionID);
if (threadEntry == NULL) {
if (newDefaultEntry) {
fStates->Remove(defaultEntry);
delete defaultEntry;
}
return B_NO_MEMORY;
}
fStates->Insert(threadEntry);
}
}
defaultEntry->SetState(state);
if (threadEntry != NULL)
threadEntry->SetState(state);
return B_OK;
}
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: next.