1 |
#Region "Microsoft.VisualBasic::047f3e6ce86c0dbb480007a88dd9406d, Microsoft.VisualBasic.Core\Serialization\DumpData\DumpData.vb"
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
#End Region
|
43 |
|
44 |
Imports System.Text
|
45 |
Imports System.Runtime.CompilerServices
|
46 |
|
47 |
Namespace Serialization
|
48 |
|
49 |
Public Module MemoryDump
|
50 |
|
51 |
<Extension> Public Function I_CreateDump(Of T As Class)(obj As T, Optional DumpLevel As UInteger = 0) As String
|
52 |
Dim DumpBuilder As StringBuilder = New StringBuilder(1024)
|
53 |
|
54 |
Call Console.WriteLine("Create memory dump for {0}.", obj.GetType.FullName)
|
55 |
|
56 |
Call DumpBuilder.AppendLine("// ")
|
57 |
Call DumpBuilder.AppendLine(String.Format("// Microsoft (R) VisualBasic.NET Memory Dump Creator. Version {0}", Application.ProductVersion))
|
58 |
Call DumpBuilder.AppendLine("// Copyright (c) Microsoft Corporation. All rights reserved.")
|
59 |
Call DumpBuilder.AppendLine("// ")
|
60 |
Call DumpBuilder.AppendLine(String.Format("// Dump Time {0} ", Now.ToString))
|
61 |
Call DumpBuilder.AppendLine("// ")
|
62 |
|
63 |
Call DumpBuilder.AppendLine(__dumpInvoke(obj, DumpLevel))
|
64 |
Return DumpBuilder.ToString
|
65 |
End Function
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
Private Function __dumpInvoke(obj As Object, DumpLevel As Integer) As String
|
75 |
Dim DumpBuilder As StringBuilder = New StringBuilder(1024)
|
76 |
Dim Type As System.Type = obj.GetType
|
77 |
Dim LevelBlanks As String = New String(vbTab, DumpLevel)
|
78 |
Dim PropertyCollection As System.Reflection.PropertyInfo() = (From [property] As System.Reflection.PropertyInfo
|
79 |
In Type.GetProperties(System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
|
80 |
Let attrs As Object() = [property].GetCustomAttributes(attributeType:=DumpNode.GetTypeId, inherit:=True)
|
81 |
Where Not attrs.IsNullOrEmpty
|
82 |
Select [property]).ToArray
|
83 |
Dim FieldsCollection As System.Reflection.FieldInfo() = (From Field As System.Reflection.FieldInfo
|
84 |
In Type.GetFields(System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
|
85 |
Let attrs As Object() = Field.GetCustomAttributes(attributeType:=DumpNode.GetTypeId, inherit:=True)
|
86 |
Where Not attrs.IsNullOrEmpty
|
87 |
Select Field).ToArray
|
88 |
|
89 |
If PropertyCollection.IsNullOrEmpty AndAlso FieldsCollection.IsNullOrEmpty Then
|
90 |
Return ""
|
91 |
End If
|
92 |
|
93 |
Call DumpBuilder.AppendLine()
|
94 |
Call DumpBuilder.AppendLine(String.Format("{0}/* =============== DUMP_CLASS_TYPE {1} =================== */" & vbCrLf, LevelBlanks, Type.FullName))
|
95 |
Call DumpBuilder.AppendLine(String.Format("{0}{1}", LevelBlanks, Type.FullName))
|
96 |
Call DumpBuilder.AppendLine(LevelBlanks & "{")
|
97 |
|
98 |
Call DumpBuilder.AppendLine(DumpFieldCollection(obj, FieldsCollection, DumpLevel))
|
99 |
Call DumpBuilder.AppendLine(DumpPropertyCollection(obj, PropertyCollection, DumpLevel))
|
100 |
|
101 |
Call DumpBuilder.AppendLine(String.Format("{0}! // end of dump {1}", LevelBlanks, Type.FullName).Replace("!", "}"))
|
102 |
|
103 |
Return DumpBuilder.ToString
|
104 |
End Function
|
105 |
|
106 |
Private Function DumpFieldCollection(obj As Object, FieldCollection As System.Reflection.FieldInfo(), DumpLevel As UInteger) As String
|
107 |
Dim DumpBuilder As StringBuilder = New StringBuilder(1024)
|
108 |
Dim LevelBlanks As String = New String(vbTab, DumpLevel + 1)
|
109 |
|
110 |
If Not FieldCollection.IsNullOrEmpty Then Call DumpBuilder.AppendLine(LevelBlanks & "// class type fields" & vbCrLf)
|
111 |
|
112 |
For Each Field As System.Reflection.FieldInfo In FieldCollection
|
113 |
Call DumpBuilder.AppendLine(DumpPropertyOrField(Field.GetValue(obj), Field.FieldType, Field.Name, DumpLevel, "field"))
|
114 |
Next
|
115 |
|
116 |
Return DumpBuilder.ToString
|
117 |
End Function
|
118 |
|
119 |
Private Function DumpPropertyCollection(obj As Object, PropertyCollection As System.Reflection.PropertyInfo(), DumpLevel As UInteger) As String
|
120 |
Dim DumpBuilder As StringBuilder = New StringBuilder(1024)
|
121 |
Dim LevelBlanks As String = New String(vbTab, DumpLevel + 1)
|
122 |
|
123 |
If Not PropertyCollection.IsNullOrEmpty Then Call DumpBuilder.AppendLine(LevelBlanks & "// class type properties" & vbCrLf)
|
124 |
|
125 |
For Each [property] As System.Reflection.PropertyInfo In PropertyCollection
|
126 |
Call DumpBuilder.AppendLine(DumpPropertyOrField([property].GetValue(obj, Nothing), [property].PropertyType, [property].Name, DumpLevel, "property"))
|
127 |
Next
|
128 |
|
129 |
Return DumpBuilder.ToString
|
130 |
End Function
|
131 |
|
132 |
Private Function DumpArray(ElementType As System.Type, ArrayTitle As String, ArrayData As Object(), DumpLevel As Integer) As String
|
133 |
Dim DumpBuilder As StringBuilder = New StringBuilder(1024) : DumpLevel += 1
|
134 |
Dim LevelBlanks As String = New String(vbTab, DumpLevel)
|
135 |
Dim ElementIsArrayType As Boolean = ElementType.IsArray
|
136 |
|
137 |
If ElementIsArrayType Then
|
138 |
For i As Integer = 0 To ArrayData.Length - 1
|
139 |
Dim ArrayItem As Object() = GetArray(DirectCast(ArrayData(i), IEnumerable))
|
140 |
Dim ItemTitle As String = String.Format("{0}{1}[{2},] -->" & vbCrLf, LevelBlanks, ArrayTitle, i)
|
141 |
|
142 |
Call DumpBuilder.AppendLine(ItemTitle)
|
143 |
|
144 |
If ArrayItem.IsNullOrEmpty Then
|
145 |
Call DumpBuilder.AppendLine(New String(vbTab, DumpLevel + 1) & "null inner array")
|
146 |
Else
|
147 |
ElementType = ArrayItem.First.GetType
|
148 |
Call DumpBuilder.AppendLine(DumpArray(ElementType, ItemTitle, ArrayItem, DumpLevel))
|
149 |
End If
|
150 |
Next
|
151 |
ElseIf ElementType.IsClass AndAlso ElementType IsNot GetType(String) Then
|
152 |
For i As Integer = 0 To ArrayData.Length - 1
|
153 |
Dim item = ArrayData(i)
|
154 |
Call DumpBuilder.AppendFormat("{0}[{1}] --> {2} ", LevelBlanks, i, ElementType.Name)
|
155 |
Call DumpBuilder.AppendLine("{")
|
156 |
Call DumpBuilder.AppendLine(vbCrLf & __dumpInvoke(item, DumpLevel + 1))
|
157 |
Call DumpBuilder.AppendLine(LevelBlanks & "}")
|
158 |
Next
|
159 |
Else
|
160 |
For i As Integer = 0 To ArrayData.Length - 1
|
161 |
Dim strData As String = ArrayData(i).ToString
|
162 |
Call DumpBuilder.AppendLine(String.Format("{0}[{1}] --> {2}", LevelBlanks, i, strData))
|
163 |
Next
|
164 |
End If
|
165 |
|
166 |
Return DumpBuilder.ToString
|
167 |
End Function
|
168 |
|
169 |
Private Function IsGenericEnumerable(Type As Type) As Boolean
|
170 |
Dim IsGenericType = Type.IsGenericType
|
171 |
Dim p = Array.IndexOf(Type.GetInterfaces, GetType(IEnumerable))
|
172 |
Dim f = IsGenericType AndAlso p > -1
|
173 |
Return f
|
174 |
End Function
|
175 |
|
176 |
Private Function GetArray(en As IEnumerable) As Object()
|
177 |
Dim LQuery As Object() = (From obj As Object In en Select obj).ToArray
|
178 |
Return LQuery
|
179 |
End Function
|
180 |
|
181 |
Private Function DumpPropertyOrField(value As Object, TypeInfo As Type, Name As String, DumpLevel As UInteger, def As String) As String
|
182 |
Dim LevelBlanks As String = New String(vbTab, DumpLevel + 1)
|
183 |
Dim DumpBuilder As StringBuilder = New StringBuilder(1024)
|
184 |
|
185 |
Dim IsArrayType As Boolean = TypeInfo.IsArray
|
186 |
Dim IsEnumerableType As Boolean = IsGenericEnumerable(TypeInfo)
|
187 |
|
188 |
If value Is Nothing Then
|
189 |
Return ""
|
190 |
End If
|
191 |
|
192 |
If TypeInfo.IsArray OrElse IsEnumerableType Then
|
193 |
Dim ArrayData As Object() = GetArray(DirectCast(value, IEnumerable))
|
194 |
|
195 |
If ArrayData.IsNullOrEmpty Then
|
196 |
Return ""
|
197 |
End If
|
198 |
|
199 |
Dim ElementType = ArrayData.First.GetType()
|
200 |
|
201 |
Call DumpBuilder.AppendLine(String.Format("{0}.{1} {2} ({3}) =>", LevelBlanks, def, Name, TypeInfo.FullName))
|
202 |
Call DumpBuilder.AppendLine(LevelBlanks & "{")
|
203 |
Call DumpBuilder.AppendLine(DumpArray(ElementType, Name, ArrayData, DumpLevel + 1))
|
204 |
Call DumpBuilder.AppendLine(LevelBlanks & "}" & String.Format(" // end of array {0} {1}", def, Name))
|
205 |
ElseIf TypeInfo.IsClass AndAlso Not TypeInfo Is GetType(String) Then
|
206 |
Call DumpBuilder.AppendLine(String.Format("{0}.{1} {2} {3} =>", LevelBlanks, def, Name, TypeInfo.FullName))
|
207 |
Call DumpBuilder.AppendLine(LevelBlanks & "{")
|
208 |
Call DumpBuilder.AppendLine(__dumpInvoke(value, DumpLevel + 2))
|
209 |
Call DumpBuilder.AppendLine(LevelBlanks & "} // end of " & Name)
|
210 |
Else
|
211 |
Return String.Format("{0}.{1} {2} ({3}) = {4}", LevelBlanks, def, Name, TypeInfo.FullName, value.ToString)
|
212 |
End If
|
213 |
|
214 |
Return DumpBuilder.ToString
|
215 |
End Function
|
216 |
End Module
|
217 |
End Namespace
|