summaryrefslogtreecommitdiffstatshomepage
path: root/tekuti
diff options
context:
space:
mode:
authorGravatar Andy Wingo2010-10-14 12:03:39 +0200
committerGravatar Andy Wingo2010-11-13 18:47:03 +0100
commitd3cf39b5c06f3196db75ae19545c409e90556238 (patch)
tree8d0995c9f96397a60ac3855926cefd9d986f2b55 /tekuti
parent1b9e3708053491a24bda0ab3ef7310a07c895ddc (diff)
downloadtekuti-d3cf39b5c06f3196db75ae19545c409e90556238.tar.gz
tekuti-d3cf39b5c06f3196db75ae19545c409e90556238.zip
base64 efficiency hacks
* tekuti/base64.scm (bytevector-map-n-to-m): Use multiple values. (base64-encode): Inline the map-3-to-4 definition, and use multiple values. (base64-decode): Likewise, with map-4-to-3.
Diffstat (limited to 'tekuti')
-rw-r--r--tekuti/base64.scm36
1 files changed, 19 insertions, 17 deletions
diff --git a/tekuti/base64.scm b/tekuti/base64.scm
index a971e5e..a7426cb 100644
--- a/tekuti/base64.scm
+++ b/tekuti/base64.scm
@@ -60,28 +60,27 @@
(lambda (stx)
(syntax-case stx ()
((_ n m)
- (with-syntax (((byte-arg ...)
+ (with-syntax (((byte-in ...)
(map (lambda (x)
#`(bytevector-u8-ref s (+ i #,x)))
- (iota (syntax->datum #'n)))))
+ (iota (syntax->datum #'n))))
+ ((byte-out ...)
+ (generate-temporaries (iota (syntax->datum #'m))))
+ ((byte-out-idx ...)
+ (iota (syntax->datum #'m))))
#'(lambda (proc s)
(let* ((len (bytevector-length s))
(out (make-bytevector (* len (/ m n)))))
(let lp ((i 0) (j 0))
(cond
((< i len)
- (let inner ((k 0) (bytes (proc byte-arg ...)))
- (if (not (null? bytes))
- (begin (bytevector-u8-set! out (+ j k) (car bytes))
- (inner (+ k 1) (cdr bytes)))))
+ (call-with-values (lambda () (proc byte-in ...))
+ (lambda (byte-out ...)
+ (bytevector-u8-set! out (+ j byte-out-idx) byte-out)
+ ...))
(lp (+ i n) (+ j m)))
(else out))))))))))
-(define bytevector-map-3-to-4
- (bytevector-map-n-to-m 3 4))
-(define bytevector-map-4-to-3
- (bytevector-map-n-to-m 4 3))
-
(define (bytevector-fill-range! bv start end u8)
(do ((i (- end 1) (- i 1)))
((< i start))
@@ -95,11 +94,13 @@
(define (base64-encode bv)
(let* ((npad (remainder (- 3 (remainder (bytevector-length bv) 3)) 3))
- (out (bytevector-map-3-to-4
+ (out ((bytevector-map-n-to-m 3 4)
(lambda (x y z)
(let ((n (logior (ash x 16) (ash y 8) z)))
- (map int->b64-byte
- (list (ash n -18) (ash n -12) (ash n -6) n))))
+ (values (int->b64-byte (ash n -18))
+ (int->b64-byte (ash n -12))
+ (int->b64-byte (ash n -6))
+ (int->b64-byte n))))
(bytevector-pad bv (+ (bytevector-length bv) npad) 0))))
(bytevector-fill-range! out
(- (bytevector-length out) npad)
@@ -124,14 +125,15 @@
(define (base64-decode str)
(let* ((bv (string->utf8 str))
(npad (b64-bv-npad bv))
- (out (bytevector-map-4-to-3
+ (out ((bytevector-map-n-to-m 4 3)
(lambda (w x y z)
(let ((n (logior (ash (b64-byte->int w) 18)
(ash (b64-byte->int x) 12)
(ash (b64-byte->int y) 6)
(b64-byte->int z))))
- (list (ash n -16) (logand (ash n -8) 255)
- (logand n 255))))
+ (values (ash n -16)
+ (logand (ash n -8) 255)
+ (logand n 255))))
(bytevector-copy/padding bv npad (char->integer #\A))))
(result (make-bytevector (- (bytevector-length out) npad))))
(bytevector-copy! out 0 result 0 (bytevector-length result))