This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
binary-io (was Re: rfc 2045 base64 encoding/decoding module)
- To: guile at sourceware dot cygnus dot com
- Subject: binary-io (was Re: rfc 2045 base64 encoding/decoding module)
- From: sen_ml at eccosys dot com
- Date: Thu, 03 Feb 2000 15:54:03 +0900
- References: <200001302055.UAA00476@ossau><20000131200954R.1000@eccosys.com><m2aelm2x0z.fsf@kamysh.materials.kiev.ua>
i'm working on implementing the module `binary-io', as described by
Valentin Kamyshenko <val@kamysh.materials.kiev.ua>. i've got routines
for reading and writing signed and unsigned integers of various length
for both big and little endians (see below for samples).
i'm at a loss as to how to deal w/ native format numbers that have a
length of more than 1 byte.
val> ;; native format
val> read-int read-short read-long
val> read-unsigned read-ushort read-ulong
...
val> ;; native format
val> write-int write-short write-long
val> write-unsigned write-ushort write-ulong
how can i tell from w/in a scheme program how wide a short or long is
for the native architecture?
i don't personally have a use for reading and writing floats and
doubles at the moment, but i'm willing to take a look at what might be
involved in implementing support for reading and writing them.
i presume support for the ieee format is desirable (of which i know
nothing ;-) ). so, i'm looking for online references for ieee
floating point format (754 and 854?). i've found a few:
http://HTTP.CS.Berkeley.EDU/~wkahan/ieee754status/ieee754.ps
http://archive.stsci.edu/fits/fits_standard/node91.html
but i'm wondering if there are any especially recommended resources. i
presume that the real standards must be purchased from ieee.
for reference, below are some samples of what i've got so far for reading
and writing big and little endians of various lengths.
btw, should i use `error' to indicate problems such as no more bytes
available on a port -- i am currently using `display', which i presume
isn't a good idea.
thanks for all your help! (as always)
(define-module (binary-io))
(export
;; reading
;; native format
read-int
read-unsigned
;; variants with different "endiands"
read-int16/big-endian read-unsigned16/big-endian
read-int16/little-endian read-unsigned16/little-endian
read-int32/big-endian read-unsigned32/big-endian
read-int32/little-endian read-unsigned32/little-endian
;; writing
;; native format
write-int
write-unsigned
;; variants with different "endiands"
write-int16/big-endian write-unsigned16/big-endian
write-int16/little-endian write-unsigned16/little-endian
write-int32/big-endian write-unsigned32/big-endian
write-int32/little-endian write-unsigned32/little-endian
;; output port
binary-io-output-port)
(define binary-io-output-port (current-output-port))
(define (read-unsigned port)
(let ((byte1 #f))
(catch
'done
(lambda ()
(set! byte1 (read-char port))
(cond
((eof-object? byte1)
(throw 'done 'no-chars)))
(char->integer byte1))
(lambda (key value)
(case value
((no-chars)
(display "no characters available on port\n")))))))
(define (read-int16/big-endian port)
(let ((byte1 #f)
(byte2 #f)
(result #f))
(catch
'done
(lambda ()
(set! byte1 (read-char port))
(cond
((eof-object? byte1)
(throw 'done 'no-chars)))
(set! byte2 (read-char port))
(cond
((eof-object? byte2)
(throw 'done 'only-one-char)))
(set! result (+ (* (char->integer byte1) 256)
(char->integer byte2)))
(cond
((> result 32768)
(set! result (- result 65536))))
result)
(lambda (key value)
(case value
((no-chars)
(display "no characters available on port\n"))
((only-one-char)
(display "only one character available on port\n")))))))
(define (write-int int)
(cond
((>= int 0)
(write-char
(integer->char
(logand int #b11111111))
binary-io-output-port))
((< int 0)
(write-char
(integer-char
(+ 256 (logand int #b11111111)))
binary-io-output-port))))
(define (write-unsigned32/little-endian unsigned32)
(write-char
(integer->char
(logand unsigned16 #b00000000000000000000000011111111))
binary-io-output-port)
(write-char
(integer->char
(/ (logand unsigned16 #b00000000000000001111111100000000) 256))
binary-io-output-port)
(write-char
(integer->char
(/ (logand unsigned16 #b00000000111111110000000000000000) 32767))
binary-io-output-port)
(write-char
(integer->char
(/ (logand unsigned16 #b11111111000000000000000000000000) 16777216))
binary-io-output-port))