2 * Copyright 2012-2015, Rene Gollent, rene@gollent.com
3 * Distributed under the terms of the MIT License.
7 #include "BListValueNode.h"
11 #include <AutoDeleter.h>
13 #include "AddressValueNode.h"
14 #include "Architecture.h"
15 #include "StringValue.h"
16 #include "TeamTypeInformation.h"
19 #include "TypeLookupConstraints.h"
20 #include "ValueLoader.h"
21 #include "ValueLocation.h"
22 #include "ValueNodeContainer.h"
25 // maximum number of array elements to show by default
26 static const int64 kMaxArrayElementCount
= 20;
29 //#pragma mark - BListValueNode::BListElementNodeChild
32 class BListValueNode::BListElementNodeChild
: public ValueNodeChild
{
34 BListElementNodeChild(BListValueNode
* parent
,
35 int64 elementIndex
, Type
* type
);
36 virtual ~BListElementNodeChild();
38 virtual const BString
& Name() const { return fName
; };
39 virtual Type
* GetType() const { return fType
; };
40 virtual ValueNode
* Parent() const { return fParent
; };
42 virtual status_t
ResolveLocation(ValueLoader
* valueLoader
,
43 ValueLocation
*& _location
);
47 BListValueNode
* fParent
;
53 BListValueNode::BListElementNodeChild::BListElementNodeChild(
54 BListValueNode
* parent
, int64 elementIndex
, Type
* type
)
59 fElementIndex(elementIndex
),
62 fType
->AcquireReference();
63 fParent
->AcquireReference();
64 fName
.SetToFormat("[%" B_PRId64
"]", fElementIndex
);
68 BListValueNode::BListElementNodeChild::~BListElementNodeChild()
70 fType
->ReleaseReference();
71 fParent
->ReleaseReference();
76 BListValueNode::BListElementNodeChild::ResolveLocation(
77 ValueLoader
* valueLoader
, ValueLocation
*& _location
)
79 uint8 addressSize
= valueLoader
->GetArchitecture()->AddressSize();
80 ValueLocation
* location
= new(std::nothrow
) ValueLocation();
85 uint64 listAddress
= fParent
->fDataLocation
.ToUInt64();
86 listAddress
+= fElementIndex
* addressSize
;
88 ValuePieceLocation piece
;
89 piece
.SetToMemory(listAddress
);
90 piece
.SetSize(addressSize
);
91 location
->AddPiece(piece
);
98 //#pragma mark - BListItemCountNodeChild
100 class BListValueNode::BListItemCountNodeChild
: public ValueNodeChild
{
102 BListItemCountNodeChild(BVariant location
,
103 BListValueNode
* parent
, Type
* type
);
104 virtual ~BListItemCountNodeChild();
106 virtual const BString
& Name() const { return fName
; };
107 virtual Type
* GetType() const { return fType
; };
108 virtual ValueNode
* Parent() const { return fParent
; };
110 virtual status_t
ResolveLocation(ValueLoader
* valueLoader
,
111 ValueLocation
*& _location
);
115 BListValueNode
* fParent
;
121 BListValueNode::BListItemCountNodeChild::BListItemCountNodeChild(
122 BVariant location
, BListValueNode
* parent
, Type
* type
)
130 fType
->AcquireReference();
131 fParent
->AcquireReference();
135 BListValueNode::BListItemCountNodeChild::~BListItemCountNodeChild()
137 fType
->ReleaseReference();
138 fParent
->ReleaseReference();
143 BListValueNode::BListItemCountNodeChild::ResolveLocation(
144 ValueLoader
* valueLoader
, ValueLocation
*& _location
)
146 ValueLocation
* location
= new(std::nothrow
) ValueLocation();
147 if (location
== NULL
)
150 ValuePieceLocation piece
;
151 piece
.SetToMemory(fLocation
.ToUInt64());
152 piece
.SetSize(sizeof(int32
));
153 location
->AddPiece(piece
);
155 _location
= location
;
160 //#pragma mark - BListValueNode
162 BListValueNode::BListValueNode(ValueNodeChild
* nodeChild
,
165 ValueNode(nodeChild
),
167 fItemCountType(NULL
),
169 fCountChildCreated(false)
171 fType
->AcquireReference();
175 BListValueNode::~BListValueNode()
177 fType
->ReleaseReference();
178 for (int32 i
= 0; i
< fChildren
.CountItems(); i
++)
179 fChildren
.ItemAt(i
)->ReleaseReference();
181 if (fItemCountType
!= NULL
)
182 fItemCountType
->ReleaseReference();
187 BListValueNode::GetType() const
194 BListValueNode::ResolvedLocationAndValue(ValueLoader
* valueLoader
,
195 ValueLocation
*& _location
, Value
*& _value
)
198 ValueLocation
* location
= NodeChild()->Location();
199 if (location
== NULL
)
203 // get the value type
205 if (valueLoader
->GetArchitecture()->AddressSize() == 4) {
206 valueType
= B_UINT32_TYPE
;
207 TRACE_LOCALS(" -> 32 bit\n");
209 valueType
= B_UINT64_TYPE
;
210 TRACE_LOCALS(" -> 64 bit\n");
213 // load the value data
215 status_t error
= B_OK
;
216 _location
= location
;
219 ValueLocation
* memberLocation
= NULL
;
220 CompoundType
* baseType
= dynamic_cast<CompoundType
*>(fType
);
222 if (baseType
->CountTemplateParameters() != 0) {
223 // for BObjectList we need to walk up
224 // the hierarchy: BObjectList -> _PointerList_ -> BList
225 if (baseType
->CountBaseTypes() == 0)
228 baseType
= dynamic_cast<CompoundType
*>(baseType
->BaseTypeAt(0)
230 if (baseType
== NULL
|| baseType
->Name() != "_PointerList_")
233 if (baseType
->CountBaseTypes() == 0)
236 baseType
= dynamic_cast<CompoundType
*>(baseType
->BaseTypeAt(0)
238 if (baseType
== NULL
|| baseType
->Name() != "BList")
243 for (int32 i
= 0; i
< baseType
->CountDataMembers(); i
++) {
244 DataMember
* member
= baseType
->DataMemberAt(i
);
245 if (strcmp(member
->Name(), "fObjectList") == 0) {
246 error
= baseType
->ResolveDataMemberLocation(member
,
247 *location
, memberLocation
);
248 BReference
<ValueLocation
> locationRef(memberLocation
, true);
251 "BListValueNode::ResolvedLocationAndValue(): "
252 "failed to resolve location of header member: %s\n",
257 error
= valueLoader
->LoadValue(memberLocation
, valueType
,
258 false, fDataLocation
);
261 } else if (strcmp(member
->Name(), "fItemCount") == 0) {
262 error
= baseType
->ResolveDataMemberLocation(member
,
263 *location
, memberLocation
);
264 BReference
<ValueLocation
> locationRef(memberLocation
, true);
267 "BListValueNode::ResolvedLocationAndValue(): "
268 "failed to resolve location of header member: %s\n",
273 fItemCountType
= member
->GetType();
274 fItemCountType
->AcquireReference();
276 fItemCountLocation
= memberLocation
->PieceAt(0).address
;
279 error
= valueLoader
->LoadValue(memberLocation
, valueType
,
284 fItemCount
= listSize
.ToInt32();
286 "BListValueNode::ResolvedLocationAndValue(): "
287 "detected list size %" B_PRId32
"\n",
290 memberLocation
= NULL
;
298 BListValueNode::CreateChildren(TeamTypeInformation
* info
)
300 return CreateChildrenInRange(info
, 0, kMaxArrayElementCount
);
305 BListValueNode::CountChildren() const
307 return fChildren
.CountItems();
312 BListValueNode::ChildAt(int32 index
) const
314 return fChildren
.ItemAt(index
);
319 BListValueNode::IsRangedContainer() const
326 BListValueNode::IsContainerRangeFixed() const
333 BListValueNode::ClearChildren()
335 fChildren
.MakeEmpty();
336 fCountChildCreated
= false;
337 if (fContainer
!= NULL
)
338 fContainer
->NotifyValueNodeChildrenDeleted(this);
343 BListValueNode::CreateChildrenInRange(TeamTypeInformation
* info
,
344 int32 lowIndex
, int32 highIndex
)
346 if (fLocationResolutionState
!= B_OK
)
347 return fLocationResolutionState
;
351 if (highIndex
>= fItemCount
)
352 highIndex
= fItemCount
- 1;
354 if (!fCountChildCreated
&& fItemCountType
!= NULL
) {
355 BListItemCountNodeChild
* countChild
= new(std::nothrow
)
356 BListItemCountNodeChild(fItemCountLocation
, this, fItemCountType
);
358 if (countChild
== NULL
)
361 fCountChildCreated
= true;
362 countChild
->SetContainer(fContainer
);
363 fChildren
.AddItem(countChild
);
366 BReference
<Type
> addressTypeRef
;
368 CompoundType
* objectType
= dynamic_cast<CompoundType
*>(fType
);
369 if (objectType
->CountTemplateParameters() != 0) {
370 AddressType
* addressType
= NULL
;
371 status_t result
= objectType
->TemplateParameterAt(0)->GetType()
372 ->CreateDerivedAddressType(DERIVED_TYPE_POINTER
, addressType
);
377 addressTypeRef
.SetTo(type
, true);
380 TypeLookupConstraints constraints
;
381 constraints
.SetTypeKind(TYPE_ADDRESS
);
382 constraints
.SetBaseTypeName("void");
383 status_t result
= info
->LookupTypeByName(typeName
, constraints
,
389 for (int32 i
= lowIndex
; i
<= highIndex
; i
++)
391 BListElementNodeChild
* child
=
392 new(std::nothrow
) BListElementNodeChild(this, i
, type
);
395 child
->SetContainer(fContainer
);
396 fChildren
.AddItem(child
);
399 fChildrenCreated
= true;
401 if (fContainer
!= NULL
)
402 fContainer
->NotifyValueNodeChildrenCreated(this);
409 BListValueNode::SupportedChildRange(int32
& lowIndex
, int32
& highIndex
) const
412 highIndex
= fItemCount
- 1;