1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "PrimitiveValueNode.h"
8
9#include <new>
10
11#include "BoolValue.h"
12#include "FloatValue.h"
13#include "IntegerValue.h"
14#include "Tracing.h"
15#include "Type.h"
16#include "ValueLoader.h"
17#include "ValueLocation.h"
18
19
20PrimitiveValueNode::PrimitiveValueNode(ValueNodeChild* nodeChild,
21	PrimitiveType* type)
22	:
23	ChildlessValueNode(nodeChild),
24	fType(type)
25{
26	fType->AcquireReference();
27}
28
29
30PrimitiveValueNode::~PrimitiveValueNode()
31{
32	fType->ReleaseReference();
33}
34
35
36Type*
37PrimitiveValueNode::GetType() const
38{
39	return fType;
40}
41
42
43status_t
44PrimitiveValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
45	ValueLocation*& _location, Value*& _value)
46{
47	// get the location
48	ValueLocation* location = NodeChild()->Location();
49	if (location == NULL)
50		return B_BAD_VALUE;
51
52	// get the value type
53	type_code valueType = fType->TypeConstant();
54	if (!BVariant::TypeIsNumber(valueType) && valueType != B_BOOL_TYPE) {
55		TRACE_LOCALS("  -> unknown type constant\n");
56		return B_UNSUPPORTED;
57	}
58
59	bool shortValueIsFine = BVariant::TypeIsInteger(valueType)
60		|| valueType == B_BOOL_TYPE;
61
62	TRACE_LOCALS("  TYPE_PRIMITIVE: '%c%c%c%c'\n",
63		int(valueType >> 24), int(valueType >> 16),
64		int(valueType >> 8), int(valueType));
65
66	// load the value data
67	BVariant valueData;
68	status_t error = valueLoader->LoadValue(location, valueType,
69		shortValueIsFine, valueData);
70	if (error != B_OK)
71		return error;
72
73	// create the type object
74	Value* value;
75	if (valueType == B_BOOL_TYPE)
76		value = new(std::nothrow) BoolValue(valueData.ToBool());
77	else if (BVariant::TypeIsInteger(valueType))
78		value = new(std::nothrow) IntegerValue(valueData);
79	else if (BVariant::TypeIsFloat(valueType))
80		value = new(std::nothrow) FloatValue(valueData);
81	else
82		return B_UNSUPPORTED;
83
84	if (value == NULL)
85		return B_NO_MEMORY;
86
87	location->AcquireReference();
88	_location = location;
89	_value = value;
90	return B_OK;
91}
92