xref: /haiku/src/kits/debugger/value/value_nodes/CStringValueNode.cpp (revision fce4895d1884da5ae6fb299d23c735c598e690b1)
1 /*
2  * Copyright 2010, Rene Gollent, rene@gollent.com
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "CStringValueNode.h"
8 
9 #include <new>
10 
11 #include "Architecture.h"
12 #include "StringValue.h"
13 #include "Tracing.h"
14 #include "Type.h"
15 #include "ValueLoader.h"
16 #include "ValueLocation.h"
17 #include "ValueNodeContainer.h"
18 
19 
20 // #pragma mark - CStringValueNode
21 
22 
CStringValueNode(ValueNodeChild * nodeChild,Type * type)23 CStringValueNode::CStringValueNode(ValueNodeChild* nodeChild,
24 	Type* type)
25 	:
26 	ChildlessValueNode(nodeChild),
27 	fType(type)
28 {
29 	fType->AcquireReference();
30 }
31 
32 
~CStringValueNode()33 CStringValueNode::~CStringValueNode()
34 {
35 	fType->ReleaseReference();
36 }
37 
38 
39 Type*
GetType() const40 CStringValueNode::GetType() const
41 {
42 	return fType;
43 }
44 
45 
46 status_t
ResolvedLocationAndValue(ValueLoader * valueLoader,ValueLocation * & _location,Value * & _value)47 CStringValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader,
48 	ValueLocation*& _location, Value*& _value)
49 {
50 	// get the location
51 	ValueLocation* location = NodeChild()->Location();
52 	if (location == NULL)
53 		return B_BAD_VALUE;
54 
55 	TRACE_LOCALS("  TYPE_ADDRESS (C string)\n");
56 
57 	// get the value type
58 	type_code valueType;
59 	if (valueLoader->GetArchitecture()->AddressSize() == 4) {
60 		valueType = B_UINT32_TYPE;
61 		TRACE_LOCALS("    -> 32 bit\n");
62 	} else {
63 		valueType = B_UINT64_TYPE;
64 		TRACE_LOCALS("    -> 64 bit\n");
65 	}
66 
67 	// load the value data
68 
69 	BVariant addressData;
70 	BString valueData;
71 	status_t error = B_OK;
72 	size_t maxSize = 255;
73 	if (dynamic_cast<AddressType*>(fType) != NULL) {
74 		error = valueLoader->LoadValue(location, valueType, false,
75 			addressData);
76 		if (error != B_OK)
77 			return error;
78 	} else {
79 		addressData.SetTo(location->PieceAt(0).address);
80 		maxSize = dynamic_cast<ArrayType*>(fType)
81 			->DimensionAt(0)->CountElements();
82 	}
83 
84 	ValuePieceLocation piece;
85 	piece.SetToMemory(addressData.ToUInt64());
86 
87 	TRACE_LOCALS("    Address found: %#" B_PRIx64 "\n",
88 		addressData.ToUInt64());
89 
90 	error = valueLoader->LoadStringValue(addressData, maxSize, valueData);
91 	if (error != B_OK)
92 		return error;
93 
94 	piece.size = valueData.Length();
95 
96 	TRACE_LOCALS("    String value found, length: %" B_PRIu64 "bytes\n",
97 		piece.size);
98 
99 	ValueLocation* stringLocation = new(std::nothrow) ValueLocation(
100 		valueLoader->GetArchitecture()->IsBigEndian(), piece);
101 
102 	if (stringLocation == NULL)
103 		return B_NO_MEMORY;
104 
105 	BReference<ValueLocation> locationReference(stringLocation, true);
106 
107 	error = valueLoader->LoadStringValue(addressData, maxSize, valueData);
108 	if (error != B_OK)
109 		return error;
110 
111 	// create the type object
112 	Value* value = new(std::nothrow) StringValue(valueData);
113 	if (value == NULL)
114 		return B_NO_MEMORY;
115 
116 	NodeChild()->SetLocation(stringLocation, B_OK);
117 	_location = locationReference.Detach();
118 	_value = value;
119 	return B_OK;
120 }
121