-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathXMLDumpWriter.cs
87 lines (78 loc) · 2.67 KB
/
XMLDumpWriter.cs
1
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Text;
namespace UnityHeapDumper
{
public class XMLDumpWriter : IDumpWriter
{
private StringBuilder builder = new StringBuilder();
private string path;
private bool open = false;
private IDumpWriter thisDumpWriter;
public XMLDumpWriter()
{
thisDumpWriter = this;
}
void IDumpWriter.Open(string path)
{
if (open)
{
return;
}
open = true;
this.path = path;
builder.Length = 0;
builder.Append("<heap>");
}
void IDumpWriter.Close()
{
if (!open)
{
return;
}
open = false;
builder.Append("</heap>");
File.WriteAllText(path, builder.ToString());
}
void IDumpWriter.WriteField(IFieldData fieldData, ICollection<int> seenInstances)
{
builder.Append("<field>");
var declaringType = fieldData.DeclaringType;
if (!string.IsNullOrEmpty(declaringType))
{
builder.AppendFormat("<declaring_type>{0}</declaring_type>", SecurityElement.Escape(declaringType));
}
builder.AppendFormat("<name>{0}</name>", SecurityElement.Escape(fieldData.Name));
thisDumpWriter.WriteInstance(fieldData.InstanceData, seenInstances);
builder.Append("</field>");
}
void IDumpWriter.WriteInstance(IInstanceData instanceData, ICollection<int> seenInstances)
{
builder.Append("<instance>");
var id = instanceData.Id;
builder.AppendFormat("<id>{0}</id>", id);
builder.AppendFormat("<type>{0}</type>", instanceData.TypeData == null ? "null" : SecurityElement.Escape(instanceData.TypeData.Type.Name));
builder.AppendFormat("<size>{0}</size>", instanceData.GetSize(seenInstances));
var fields = instanceData.Fields;
if (fields.Count > 0)
{
if (!seenInstances.Contains(id))
{
seenInstances.Add(id);
builder.Append("<fields>");
foreach (var fieldData in fields)
{
thisDumpWriter.WriteField(fieldData, seenInstances);
}
builder.Append("</fields>");
}
else
{
builder.Append("<recursion/>");
}
}
builder.Append("</instance>");
}
}
}