(* * An oogg file is an abstract type that can be accessed as a stream at a * particular byte location. Internally, we use a file descriptor. *) type file = Unix.file_descr;; type stream = IO.input;; type outStream = unit IO.output;; (* * opening an ooggFile *) let file_open ?(writable=false) name = if writable then Unix.openfile name [Unix.O_RDWR ; Unix.O_CREAT ; Unix.O_TRUNC] 0o644 else Unix.openfile name [Unix.O_RDONLY] 0o644;; (* * align a stream on a page boundary. We need to look for 'OggS'. * return characters consumed *) let rec align stream = let rec _check_value value = match value with | "OggS" -> 4 | l -> 4 + if (String.contains l 'O') then begin let p = String.index l 'O' in let next_read = IO.really_nread stream p in let result = String.create 4 in String.blit l p result 0 (4 - p); String.blit next_read 0 result (4 - p) p; _check_value result + p end else align stream in let first_read = IO.really_nread stream 4 in _check_value first_read;; (* * retrieving a stream from an ooggFile. Always align to an ogg page. *) let to_stream file position = ignore (Unix.lseek file position Unix.SEEK_SET); let input = IO.input_channel (Unix.in_channel_of_descr file) in let offset = (align input) - 4 in ignore (Unix.lseek file (position + offset) Unix.SEEK_SET); IO.input_channel (Unix.in_channel_of_descr file);; let to_output_stream file position = ignore (Unix.lseek file position Unix.SEEK_SET); IO.output_channel (Unix.out_channel_of_descr file);;