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]

Re: rfc 2045 base64 encoding/decoding module



thanks for the responses, ttn@mingle.glug.org and roland.kaufmann@space.at.

ttn> have you looked into swig (http://www.swig.org)?  getting swig's guile
ttn> module up to snuff would allow wrapping of arbitrary libraries (assuming
ttn> they have a reasonable published interface).

it's actually been a few years since i've looked at swig ;-)  i'll have
a look at swig and swig's guile module.  thanks for the suggestion.

roland> it would be more efficient to use a C library, but if you want
roland> to write it in Scheme, the Emacs Lisp version in William M. Perry's
roland> World Wide Web browser 'w3' might be helpful.

aha!  i will look at w3 too.  thanks for the suggestion.

before sleep claimed me last night, i started hacking on a native
implementation that is supposed to mirror the interface of the perl
MIME::Base64 module.  i haven't really thought about whether the
interface is good -- i just wanted to get some practice.  if people
have thoughts about interfaces i'm all ears!

below is what i've got so far.  the code isn't complete, but if anyone
has any comments about what i've got so far, i'd love to hear them ;-)

i'm also curios about whether to use define-public -- i noticed in the
example posted by neil@ossau.uklinux.net it wasn't used.  judging from
comments on the list and in the docs, i guess the module system is
going to be changed, so i suppose i'll be rewriting, but that's
probably a good thing for me at this point anyway.

btw, is inserting ^L in a message acceptable on this list?

(define-module (ice9 base64))

(export encode_base64
	decode_base64)

(define base64-table (make-vector 64))
;; may be this shouldn't be sitting out here naked...
(let ((index 0))
  ;; A-Z
  (while (< index 26)
	 (hashv-set! base64-table
		     index
		     (integer->char (+ index 65)))
	 (set! index (1+ index)))
  ;; a-z
  (while (< index 52)
	 (hashv-set! base64-table
		     index
		     (integer->char (+ index 71)))
	 (set! index (1+ index)))
  ;; 0-9
  (while (< index 62)
	 (hashv-set! base64-table
		     index
		     (integer->char (+ index 48)))
	 (set! index (1+ index)))
  ;; +
  (hashv-set! base64-table 62 #\+)
  ;; /
  (hashv-set! base64-table 63 #\/))

(define (encode_base64 str eol)
  (if (null? eol)
      (set! eol #\nl))
  (let* ((outlength (+ (string-length str) 
		       (- 3 (remainder (string-length str) 3))))
	 (outstr (make-string outlength))
	 (index 0)
	 24bits)
    ;; NOTE: are shared substrings being used?  if not, may be they should be.
    (while (> (string-length str) 3)
	   (set! 24bits (substring str 0 3))
	   ;; TODO: decide whether looping is better here
	   (string-set! outstr 
			index
			(hashv-ref base64-table (bit-extract 24bits 0 5)))
	   (1+ index)
	   (string-set! outstr 
			index
			(hashv-ref base64-table (bit-extract 24bits 6 11)))
	   (1+ index)
	   (string-set! outstr 
			index
			(hashv-ref base64-table (bit-extract 24bits 12 17)))
	   (1+ index)
	   (string-set! outstr 
			index
			(hashv-ref base64-table (bit-extract 24bits 18 23)))
	   (1+ index)
	   (set! str (substring str 3)))
    ;; TODO: handle the remaining bytes (1, 2, or 3)
    ;; TODO: do something w/ eol
    ))

;; TODO: implement :-)
(define (decode_base64 str)
  (display "not even close to done!")
  )


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