This is the mail archive of the guile@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

binary-io (was Re: rfc 2045 base64 encoding/decoding module)



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))

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]