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