-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathframe-utils.dylan
107 lines (94 loc) · 3.01 KB
/
frame-utils.dylan
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
module: binary-data
author: Andreas Bogk and Hannes Mehnert
copyright: 2005-2011 Andreas Bogk and Hannes Mehnert. All rights reserved.
license: see LICENSE.txt in this distribution
define function find-frame-field
(frame :: <container-frame>,
search :: type-union(<container-frame>, <raw-frame>))
=> (res :: false-or(type-union(<frame-field>, <rep-frame-field>)))
block (ret)
for (ff in frame.concrete-frame-fields)
if (ff.value = search)
ret(ff)
end;
if (instance?(ff, <repeated-frame-field>))
let framefield = choose-by(curry(\=, search),
ff.value,
ff.frame-field-list);
if (framefield.size = 1) ret(framefield[0]) end;
end;
end;
#f
end;
end;
define open generic compute-absolute-offset
(a :: <object>, b :: <object>) => (res :: <integer>);
define method compute-absolute-offset
(frame :: type-union(<container-frame>, <raw-frame>), relative-to)
=> (res :: <integer>)
if (frame.parent & frame ~= relative-to)
let ff = find-frame-field(frame.parent, frame);
compute-absolute-offset(ff, relative-to)
else
0
end;
end;
define method compute-absolute-offset
(ff :: <rep-frame-field>, relative-to)
=> (res :: <integer>)
start-offset(ff) + compute-absolute-offset(ff.parent-frame-field, relative-to)
end;
define method compute-absolute-offset
(frame-field :: <frame-field>, relative-to)
=> (res :: <integer>)
start-offset(frame-field) + compute-absolute-offset(frame-field.frame, relative-to)
end;
define method compute-length (frame :: <header-frame>)
=> (res :: <integer>)
start-offset(sorted-frame-fields(frame).last)
end;
define method compute-length (frame :: <frame>)
=> (res :: <integer>)
frame-size(frame)
end;
define method compute-length (frame-field :: <position-mixin>)
=> (res :: <integer>)
frame-field.length
end;
define method compute-length (frame-field :: <frame-field>)
=> (res :: <integer>)
if (frame-field.field.field-name = #"payload")
compute-length(frame-field.value)
else
frame-field.length
end
end;
define method find-frame-at-offset
(frame :: <container-frame>, offset :: <integer>)
=> (result-frame)
block (ret)
for (ff in sorted-frame-fields(frame))
if ((start-offset(ff) <= offset) & (end-offset(ff) >= offset))
//format-out("looking in %s, offset %d\n", ff.field.field-name, offset - start-offset(ff));
ret(find-frame-at-offset(ff.value, offset - start-offset(ff)))
end;
end;
end;
end;
define method find-frame-at-offset
(frame :: <collection>, offset :: <integer>)
let start = 0;
block (ret)
for (ele in frame, i from 0)
if ((start <= offset) & (frame-size(ele) >= offset))
//format-out("looking in %d, offset %d\n", i, offset - start);
ret(find-frame-at-offset(ele, offset - start));
end;
start := start + frame-size(ele);
end;
end;
end;
define method find-frame-at-offset
(frame :: <leaf-frame>, offset :: <integer>)
frame
end;