22 ; sections
: section array
25 let sbufplus sbuf pos
=
30 let sbufpos (_
, pos
) = pos
;;
32 let sbufblt sbuf ~src_pos ~dst ~dst_pos ~len
=
33 let (src
, pos
) = sbuf
in
34 let src_pos = src_pos + pos
in
43 let sbuferr sbuf pos msg
=
44 let p = sbufpos sbuf
in
45 let s = Printf.sprintf
"%08x(%08x): %s" p (p+pos
) msg
in
51 let rb pos2
= Char.code
(String.get
s (pos
+ pos1
+ pos2
)) in
52 let w0 = (rb 0) lor ((rb 1) lsl 8)
53 and w1
= (rb 2) lor ((rb 3) lsl 8) in
54 let u = Int32.shift_left
(Int32.of_int w1
) 16
55 and l
= Int32.of_int
w0 in
61 let rb pos2
= Char.code
(String.get
s (pos
+ pos1
+ pos2
)) in
62 (rb 0) lor ((rb 1) lsl 8)
66 let v = r16 sbuf pos
in
67 v - ((v land 0x8000) lsl 1)
72 String.get
s (pos
+ pos1
)
77 Char.code
(String.get
s (pos
+ pos1
))
81 let i32 = r32 sbuf pos
in
86 let i32 = r32 sbuf pos
in
87 Int32.float_of_bits
i32
92 let c'
= String.get
s (pos
+n
) in
96 let check32 sbuf n
i32 =
97 let i32'
= r32 sbuf
(n
*4) in
101 let checklist cf sbuf l
=
102 let rec f n
= function
104 | e
:: rest
when cf sbuf n e
-> f (n
+1) rest
110 let checkstr cf sbuf
s =
111 let l = String.length
s in
114 | n
when cf sbuf
(l-n
) s.[l-n
] -> f (n
-1)
120 let cmp sbuf
= function
121 | `chars
s -> checkstr checkc sbuf
s
122 | `dwords
l -> checklist check32 sbuf
l
125 let rcstrtabent sbuf pos at
=
126 let (src
, pos1
) = sbuf
in
127 let begpos = pos1
+ pos
+ at
in
128 let endpos = String.index_from src
begpos '
\000'
in
129 let len = endpos - begpos in
130 let dst = String.create
len in
141 let roffsets sbuf pos
=
142 let ri n
= rint sbuf
(pos
+ n
*4) in
154 let rstrpos sbuf pos count
=
155 let r n
= rint sbuf
(pos
+ n
*4) in
159 let rsection sbuf offs secstrpos index
=
160 let secpos = offs
.sec
+ index
*8*4 in
161 let len = rint sbuf
(secpos + 2*4)
162 and off
= rint sbuf
(secpos + 7*4)
163 and name
= rcstrtabent sbuf offs
.secstr
(Array.get secstrpos index
) in
171 let s = String.create
0x50 in
173 let () = really_input ic
s 0 0x50 in
174 let rc n
= String.get
s n
in
176 if rc 0 <> 'x'
|| rc 1 <> '
f'
|| rc 2 <> '
f'
||
177 (let c = rc 3 in not
(c == '
2'
|| c == '
\000'
))
179 failwith
"Not an xff"
182 let size = rint sbuf (5*4)
183 and entry
= rint sbuf (19*4)
184 and seccount
= rint sbuf (16*4) in
187 let s'
= String.create
size in
188 let () = really_input ic
s'
0x50 (size-0x50) in
199 let offsets = roffsets sbuf 0x50 in
201 let secstrpos = rstrpos sbuf offsets.secstrpos seccount
in
202 let sections = Array.init seccount
(fun n
-> rsection sbuf offsets secstrpos n
) in
206 ; sections = sections
211 let ic = open_in_bin path
in
217 let index_path = ref "index/index";;
218 let base_path = ref None
;;
223 let ic = open_in_bin
!index_path in
224 let l = input_value
ic in
231 let (path
, off
, len) =
232 let rec find = function
233 | [] -> failwith
("can't find " ^ name
)
234 | (path
, h
) :: rest
->
236 let off, len = Hashtbl.find h name
in
241 find (Lazy.force
index)
244 match !base_path with
245 | Some base
-> Filename.concat base
(Filename.basename
path)
248 if false then Format.eprintf
"%s %s %08x %d@." name
path off len;
249 let ic = open_in_bin
path in
251 let (_
, (s, _
)) as r = rxff ic in