-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathDumpFileLoader.pas
116 lines (90 loc) · 2.79 KB
/
DumpFileLoader.pas
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
105
106
107
108
109
110
111
112
113
114
115
116
unit DumpFileLoader;
{$mode objfpc}{$H+}
interface
uses
ViewTypes;
function CreateDumpFileLoadTask(const FilePath: string): TLayoutLoadTask;
implementation
uses
SysUtils, laz2_XMLRead, laz2_DOM, Logging;
type
{ TDeviceMonitorDumpLoadTask }
TDeviceMonitorDumpLoadTask = class(TLayoutLoadTask)
private
FFilePath: string;
protected
procedure Run; override;
public
constructor Create(const AFilePath: string);
end;
{ TDeviceMonitorDumpLoadTask }
constructor TDeviceMonitorDumpLoadTask.Create(const AFilePath: string);
begin
FFilePath := AFilePath;
end;
procedure TDeviceMonitorDumpLoadTask.Run;
function GetAttribute(Node: TDOMNode; const Name: string): string;
begin
Node := Node.Attributes.GetNamedItem(Name);
if Assigned(Node) then
Result := Node.TextContent
else
Result := EmptyStr;
end;
function CreateView(Node: TDOMNode; Depth: integer = 0): TView;
var
Left, Top, Right, Bottom: integer;
S: string;
ChildNode: TDOMNode;
begin
CheckCanceled;
// These bounds are provided right how we need them, that is,
// window absolute.
SScanf(GetAttribute(Node, 'bounds'), '[%d,%d][%d,%d]',
[@Left, @Top, @Right, @Bottom]);
Result := TView.Create(Left, Top, Right, Bottom, Depth);
try
Result.QualifiedClassName := GetAttribute(Node, 'class');
S := GetAttribute(Node, 'text');
if S <> EmptyStr then
Result.SetProperty('text:mText', S);
S := GetAttribute(Node, 'resource-id');
if S <> EmptyStr then
Result.SetProperty('mID', S);
for ChildNode in Node do
if ChildNode.NodeType <> COMMENT_NODE then
Result.AddChild(CreateView(ChildNode, Depth + 1));
except
Result.Free;
raise;
end;
end;
var
Document: TXMLDocument;
Node: TDOMNode;
begin
Log('TDeviceMonitorDumpLoadTask.Run: FileName=''%s''', [FFilePath]);
ReadXMLFile(Document, FFilePath);
try
Node := Document.FirstChild;
while Assigned(Node) and (Node.NodeType = COMMENT_NODE) do
Node := Node.NextSibling;
if not Assigned(Node) or (Node.CompareName('hierarchy') <> 0) then
raise Exception.Create('Root element is not "hierarchy"');
Node := Node.FirstChild;
while Assigned(Node) and (Node.NodeType = COMMENT_NODE) do
Node := Node.NextSibling;
if not Assigned(Node) or (Node.CompareName('node') <> 0) then
raise Exception.Create('Root element child is not "node"');
// Since we already checked for the presence of at least the root node,
// we'll always return at least one view.
SetResult(TViewLayout.Create(CreateView(Node), FFilePath));
finally
Document.Free;
end;
end;
function CreateDumpFileLoadTask(const FilePath: string): TLayoutLoadTask;
begin
Result := TDeviceMonitorDumpLoadTask.Create(FilePath);
end;
end.