Siegfried Gonzi wrote:
The first 3 numbers in the file are Fortran integer numbers which describe the 3d dimension of the array and the following numbers in the binary file are the content of the array.
Depends on whether you're for portability or speed.
A pure-scheme solution (you'll have to adapt if the integers are signed, or if the matrix doesn't contain integers but floats or so):
(define int-width-in-bytes 4)
(define (u8vector-bigendian-unsigned-number-ref vec pos) (let lp ((i 0) (res 0)) (if (< i int-width-in-bytes) (lp (+ i 1) (+ res (arithmetic-shift (u8vector-ref vec (+ pos i)) (arithmetic-shift i 3)))) res)))
(define (read-idl-matrix port) (let* ((dimensions-len (* 3 int-width-in-bytes)) (dimensions (make-u8vector dimensions-len))) (if (= (read-subu8vector dimensions 0 dimensions-len port) dimensions-len) (let ((x (u8vector-bigendian-unsigned-number-ref dimensions 0)) (y (u8vector-bigendian-unsigned-number-ref dimensions int-width-in-bytes)) (z (u8vector-bigendian-unsigned-number-ref dimensions (* 2 int-width-in-bytes)))) (let* ((matrix-len (* int-width-in-bytes x y z)) (matrix (make-u8vector matrix-len))) (if (= (read-subu8vector matrix 0 matrix-len port) matrix-len) (list x y z matrix) (error "file too short (2)")))) (error "file too short (1)"))))
If you're after speed and on a bigendian architecture (or are reading standard floats or doubles) and don't mind giving up portability, you could just create a u32vector, s32vector, f64vector or whatever you need and then fill that in with the unsafe variant of read-subu8vector, ##read-subu8vector. Just be careful you calculate the needed length correctly.
Christian.