-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathJSONDumpWriter.cs
104 lines (94 loc) · 3.08 KB
/
JSONDumpWriter.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Text;
namespace UnityHeapDumper
{
public class JSONDumpWriter : IDumpWriter
{
private StringBuilder builder = new StringBuilder();
private string path;
private bool open = false;
private IDumpWriter thisDumpWriter;
private bool firstElement = false;
public JSONDumpWriter()
{
thisDumpWriter = this;
}
void IDumpWriter.Open(string path)
{
if (open)
{
return;
}
open = true;
this.path = path;
builder.Length = 0;
builder.Append("{\"heap\":[");
firstElement = true;
}
void IDumpWriter.Close()
{
if (!open)
{
return;
}
open = false;
builder.Append("]}");
File.WriteAllText(path, builder.ToString());
}
private void CheckIfFirstElement()
{
if (!firstElement)
{
builder.Append(",");
}
else
{
firstElement = false;
}
}
void IDumpWriter.WriteField(IFieldData fieldData, ICollection<int> seenInstances)
{
CheckIfFirstElement();
builder.Append("{\"field\":{");
var declaringType = fieldData.DeclaringType;
if (!string.IsNullOrEmpty(declaringType))
{
builder.AppendFormat("\"declaring_type\":\"{0}\",", SecurityElement.Escape(declaringType));
}
builder.AppendFormat("\"name\":\"{0}\"", SecurityElement.Escape(fieldData.Name));
thisDumpWriter.WriteInstance(fieldData.InstanceData, seenInstances);
builder.Append("}}");
}
void IDumpWriter.WriteInstance(IInstanceData instanceData, ICollection<int> seenInstances)
{
CheckIfFirstElement();
builder.Append("\"instance\":{");
var id = instanceData.Id;
builder.AppendFormat("\"id\":{0}", id);
builder.AppendFormat(",\"type\":\"{0}\"", instanceData.TypeData == null ? "null" : SecurityElement.Escape(instanceData.TypeData.Type.Name));
builder.AppendFormat(",\"size\":{0}", instanceData.GetSize(seenInstances));
var fields = instanceData.Fields;
if (fields.Count > 0)
{
if (!seenInstances.Contains(id))
{
seenInstances.Add(id);
builder.Append(",\"fields\":[");
firstElement = true;
foreach (var fieldData in fields)
{
thisDumpWriter.WriteField(fieldData, seenInstances);
}
builder.Append("]");
}
else
{
builder.Append(",\"recursion\":{}");
}
}
builder.Append("}");
}
}
}