[gambit-list] Reading binary files

Christian Jaeger christian at pflanze.mine.nu
Tue Dec 18 11:59:42 EST 2007


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.






More information about the Gambit-list mailing list