private IVariableInformation GetVisualizationWrapper(IVariableInformation variable) { VisualizerInfo visualizer = FindType(variable); if (visualizer == null || variable is VisualizerWrapper) // don't stack wrappers { return(null); } ExpandType1 expandType = (ExpandType1)Array.Find(visualizer.Visualizer.Items, (o) => { return(o is ExpandType1); }); if (expandType == null) { return(null); } // return expansion with [Visualizer View] child as first element return(new VisualizerWrapper(ResourceStrings.VisualizedView, _process.Engine, variable, visualizer, isVisualizerView: true)); }
private IVariableInformation[] ExpandVisualized(IVariableInformation variable) { VisualizerInfo visualizer = FindType(variable); if (visualizer == null) { return(variable.Children); } List <IVariableInformation> children = new List <IVariableInformation>(); ExpandType1 expandType = (ExpandType1)Array.Find(visualizer.Visualizer.Items, (o) => { return(o is ExpandType1); }); if (expandType == null) { return(variable.Children); } foreach (var i in expandType.Items) { if (i is ItemType) { ItemType item = (ItemType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } IVariableInformation expr = GetExpression(item.Value, variable, visualizer.ScopedNames, item.Name); children.Add(expr); } else if (i is ArrayItemsType) { ArrayItemsType item = (ArrayItemsType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } uint size = 0; string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames); size = MICore.Debugger.ParseUint(val, throwOnError: true); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion ValuePointerType[] vptrs = item.ValuePointer; foreach (var vp in vptrs) { if (EvalCondition(vp.Condition, variable, visualizer.ScopedNames)) { IVariableInformation ptrExpr = GetExpression('*' + vp.Value, variable, visualizer.ScopedNames); string typename = ptrExpr.TypeName; if (String.IsNullOrWhiteSpace(typename)) { continue; } StringBuilder arrayBuilder = new StringBuilder(); arrayBuilder.Append('('); arrayBuilder.Append(typename); arrayBuilder.Append('['); arrayBuilder.Append(size); arrayBuilder.Append("])*("); arrayBuilder.Append(vp.Value); arrayBuilder.Append(')'); string arrayStr = arrayBuilder.ToString(); IVariableInformation arrayExpr = GetExpression(arrayStr, variable, visualizer.ScopedNames); arrayExpr.EnsureChildren(); if (arrayExpr.CountChildren != 0) { Array.ForEach(arrayExpr.Children, (c) => children.Add(c)); } break; } } } else if (i is TreeItemsType) { TreeItemsType item = (TreeItemsType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } if (String.IsNullOrWhiteSpace(item.Size) || String.IsNullOrWhiteSpace(item.HeadPointer) || String.IsNullOrWhiteSpace(item.LeftPointer) || String.IsNullOrWhiteSpace(item.RightPointer)) { continue; } if (item.ValueNode == null || String.IsNullOrWhiteSpace(item.ValueNode.Value)) { continue; } string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames); uint size = MICore.Debugger.ParseUint(val, throwOnError: true); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion IVariableInformation headVal = GetExpression(item.HeadPointer, variable, visualizer.ScopedNames); ulong head = MICore.Debugger.ParseAddr(headVal.Value); var content = new List <IVariableInformation>(); if (head != 0 && size != 0) { headVal.EnsureChildren(); Traverse goLeft = GetTraverse(item.LeftPointer, headVal); Traverse goRight = GetTraverse(item.RightPointer, headVal); Traverse getValue = null; if (item.ValueNode.Value == "this") // TODO: handle condition { getValue = (v) => v; } else if (headVal.FindChildByName(item.ValueNode.Value) != null) { getValue = (v) => v.FindChildByName(item.ValueNode.Value); } if (goLeft == null || goRight == null || getValue == null) { continue; } TraverseTree(headVal, goLeft, goRight, getValue, children, size); } } else if (i is LinkedListItemsType) { // example: // <LinkedListItems> // <Size>m_nElements</Size> -- optional, will go until NextPoint is 0 or == HeadPointer // <HeadPointer>m_pHead</HeadPointer> // <NextPointer>m_pNext</NextPointer> // <ValueNode>m_element</ValueNode> // </LinkedListItems> LinkedListItemsType item = (LinkedListItemsType)i; if (String.IsNullOrWhiteSpace(item.Condition)) { if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } } if (String.IsNullOrWhiteSpace(item.HeadPointer) || String.IsNullOrWhiteSpace(item.NextPointer)) { continue; } if (String.IsNullOrWhiteSpace(item.ValueNode)) { continue; } uint size = MAX_EXPAND; if (!String.IsNullOrWhiteSpace(item.Size)) { string val = GetExpressionValue(item.Size, variable, visualizer.ScopedNames); size = MICore.Debugger.ParseUint(val); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion } IVariableInformation headVal = GetExpression(item.HeadPointer, variable, visualizer.ScopedNames); ulong head = MICore.Debugger.ParseAddr(headVal.Value); var content = new List <IVariableInformation>(); if (head != 0 && size != 0) { headVal.EnsureChildren(); Traverse goNext = GetTraverse(item.NextPointer, headVal); Traverse getValue = null; if (item.ValueNode == "this") { getValue = (v) => v; } else if (headVal.FindChildByName(item.ValueNode) != null) { getValue = (v) => v.FindChildByName(item.ValueNode); } else { var value = GetExpression(item.ValueNode, headVal, visualizer.ScopedNames); if (value != null && !value.Error) { getValue = (v) => GetExpression(item.ValueNode, v, visualizer.ScopedNames); } } if (goNext == null || getValue == null) { continue; } TraverseList(headVal, goNext, getValue, children, size, item.NoValueHeadPointer); } } else if (i is IndexListItemsType) { // example: // <IndexListItems> // <Size>_M_vector._M_index</Size> // <ValueNode>*(_M_vector._M_array[$i])</ValueNode> // </IndexListItems> IndexListItemsType item = (IndexListItemsType)i; if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } var sizes = item.Size; uint size = 0; if (sizes == null) { continue; } foreach (var s in sizes) { if (string.IsNullOrWhiteSpace(s.Value)) { continue; } if (EvalCondition(s.Condition, variable, visualizer.ScopedNames)) { string val = GetExpressionValue(s.Value, variable, visualizer.ScopedNames); size = MICore.Debugger.ParseUint(val); size = size > MAX_EXPAND ? MAX_EXPAND : size; // limit expansion break; } } var values = item.ValueNode; if (values == null) { continue; } foreach (var v in values) { if (string.IsNullOrWhiteSpace(v.Value)) { continue; } if (EvalCondition(v.Condition, variable, visualizer.ScopedNames)) { string processedExpr = ReplaceNamesInExpression(v.Value, variable, visualizer.ScopedNames); Dictionary <string, string> indexDic = new Dictionary <string, string>(); for (uint index = 0; index < size; ++index) { indexDic["$i"] = index.ToString(CultureInfo.InvariantCulture); string finalExpr = ReplaceNamesInExpression(processedExpr, null, indexDic); IVariableInformation expressionVariable = new VariableInformation(finalExpr, variable, _process.Engine, "[" + indexDic["$i"] + "]"); expressionVariable.SyncEval(); children.Add(expressionVariable); } break; } } } else if (i is ExpandedItemType) { ExpandedItemType item = (ExpandedItemType)i; // example: // <Type Name="std::auto_ptr<*>"> // <DisplayString>auto_ptr {*_Myptr}</DisplayString> // <Expand> // <ExpandedItem>_Myptr</ExpandedItem> // </Expand> // </Type> if (item.Condition != null) { if (!EvalCondition(item.Condition, variable, visualizer.ScopedNames)) { continue; } } if (String.IsNullOrWhiteSpace(item.Value)) { continue; } var expand = GetExpression(item.Value, variable, visualizer.ScopedNames); var eChildren = Expand(expand); if (eChildren != null) { Array.ForEach(eChildren, (c) => children.Add(c)); } } } if (!(variable is VisualizerWrapper)) // don't stack wrappers { // add the [Raw View] field IVariableInformation rawView = new VisualizerWrapper(ResourceStrings.RawView, _process.Engine, variable, visualizer, isVisualizerView: false); children.Add(rawView); } return(children.ToArray()); }