root/src/kits/debugger/value/value_nodes/PrimitiveValueNode.cpp
/*
 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */


#include "PrimitiveValueNode.h"

#include <new>

#include "BoolValue.h"
#include "FloatValue.h"
#include "IntegerValue.h"
#include "Tracing.h"
#include "Type.h"
#include "ValueLoader.h"
#include "ValueLocation.h"


PrimitiveValueNode::PrimitiveValueNode(ValueNodeChild* nodeChild,
        PrimitiveType* type)
        :
        ChildlessValueNode(nodeChild),
        fType(type)
{
        fType->AcquireReference();
}


PrimitiveValueNode::~PrimitiveValueNode()
{
        fType->ReleaseReference();
}


Type*
PrimitiveValueNode::GetType() const
{
        return fType;
}


status_t
PrimitiveValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
        ValueLocation*& _location, Value*& _value)
{
        // get the location
        ValueLocation* location = NodeChild()->Location();
        if (location == NULL)
                return B_BAD_VALUE;

        // get the value type
        type_code valueType = fType->TypeConstant();
        if (!BVariant::TypeIsNumber(valueType) && valueType != B_BOOL_TYPE) {
                TRACE_LOCALS("  -> unknown type constant\n");
                return B_UNSUPPORTED;
        }

        bool shortValueIsFine = BVariant::TypeIsInteger(valueType)
                || valueType == B_BOOL_TYPE;

        TRACE_LOCALS("  TYPE_PRIMITIVE: '%c%c%c%c'\n",
                int(valueType >> 24), int(valueType >> 16),
                int(valueType >> 8), int(valueType));

        // load the value data
        BVariant valueData;
        status_t error = valueLoader->LoadValue(location, valueType,
                shortValueIsFine, valueData);
        if (error != B_OK)
                return error;

        // create the type object
        Value* value;
        if (valueType == B_BOOL_TYPE)
                value = new(std::nothrow) BoolValue(valueData.ToBool());
        else if (BVariant::TypeIsInteger(valueType))
                value = new(std::nothrow) IntegerValue(valueData);
        else if (BVariant::TypeIsFloat(valueType))
                value = new(std::nothrow) FloatValue(valueData);
        else
                return B_UNSUPPORTED;

        if (value == NULL)
                return B_NO_MEMORY;

        location->AcquireReference();
        _location = location;
        _value = value;
        return B_OK;
}