net/base64: faster encode
Make encoding almost twice as fast by treating input chunks of 3 that turn into output chunks of 4.
This commit is contained in:
parent
7179df6009
commit
9d53990e18
|
@ -26,35 +26,49 @@
|
||||||
(if (>= bits 8)
|
(if (>= bits 8)
|
||||||
(let ([bits (- bits 8)])
|
(let ([bits (- bits 8)])
|
||||||
(write-byte (arithmetic-shift data (- bits)) out)
|
(write-byte (arithmetic-shift data (- bits)) out)
|
||||||
(loop (bitwise-and data (vector-ref ones bits)) bits))
|
(loop (bitwise-and data (vector*-ref ones bits)) bits))
|
||||||
(let ([c (read-byte in)])
|
(let ([c (read-byte in)])
|
||||||
(unless (or (eof-object? c) (eq? c =byte))
|
(unless (or (eof-object? c) (eq? c =byte))
|
||||||
(let ([v (vector-ref base64-digit c)])
|
(let ([v (vector*-ref base64-digit c)])
|
||||||
(if v
|
(if v
|
||||||
(loop (+ (arithmetic-shift data 6) v) (+ bits 6))
|
(loop (+ (arithmetic-shift data 6) v) (+ bits 6))
|
||||||
(loop data bits))))))))
|
(loop data bits))))))))
|
||||||
|
|
||||||
(define (base64-encode-stream in out [linesep #"\n"])
|
(define (base64-encode-stream in out [linesep #"\n"])
|
||||||
(let loop ([data 0] [bits 0] [width 0])
|
;; each set of three input bytes turns into four output bytes
|
||||||
(define (write-char)
|
(define (o! c) (write-byte (vector*-ref digit-base64 c) out))
|
||||||
(write-byte (vector-ref digit-base64 (arithmetic-shift data (- 6 bits)))
|
(define (fill!) (write-byte (char->integer #\=) out))
|
||||||
out)
|
(define (line!) (display linesep out))
|
||||||
(let ([width (modulo (add1 width) 72)])
|
(let loop ([width 0])
|
||||||
(when (zero? width) (display linesep out))
|
(define b1 (read-byte in))
|
||||||
width))
|
(unless (eof-object? b1)
|
||||||
(if (>= bits 6)
|
(let ([width (if (eqv? width 72)
|
||||||
(let ([bits (- bits 6)])
|
|
||||||
(loop (bitwise-and data (vector-ref ones bits)) bits (write-char)))
|
|
||||||
(let ([c (read-byte in)])
|
|
||||||
(if (eof-object? c)
|
|
||||||
;; flush extra bits
|
|
||||||
(begin
|
(begin
|
||||||
(let ([width (if (> bits 0) (write-char) width)])
|
(display linesep out)
|
||||||
(when (> width 0)
|
0)
|
||||||
(for ([i (in-range (modulo (- width) 4))])
|
width)])
|
||||||
(write-byte =byte out))
|
(o! (arithmetic-shift b1 -2))
|
||||||
(display linesep out))))
|
(define b2 (read-byte in))
|
||||||
(loop (+ (arithmetic-shift data 8) c) (+ bits 8) width))))))
|
(cond
|
||||||
|
[(eof-object? b2)
|
||||||
|
(o! (arithmetic-shift (bitwise-and b1 #b11) 4))
|
||||||
|
(fill!)
|
||||||
|
(fill!)
|
||||||
|
(line!)]
|
||||||
|
[else
|
||||||
|
(o! (bitwise-ior (arithmetic-shift (bitwise-and b1 #b11) 4)
|
||||||
|
(arithmetic-shift b2 -4)))
|
||||||
|
(define b3 (read-byte in))
|
||||||
|
(cond
|
||||||
|
[(eof-object? b3)
|
||||||
|
(o! (arithmetic-shift (bitwise-and b2 #b1111) 2))
|
||||||
|
(fill!)
|
||||||
|
(line!)]
|
||||||
|
[else
|
||||||
|
(o! (bitwise-ior (arithmetic-shift (bitwise-and b2 #b1111) 2)
|
||||||
|
(arithmetic-shift b3 -6)))
|
||||||
|
(o! (bitwise-and b3 #b111111))
|
||||||
|
(loop (+ width 4))])])))))
|
||||||
|
|
||||||
(define (base64-decode src)
|
(define (base64-decode src)
|
||||||
(let ([s (open-output-bytes)])
|
(let ([s (open-output-bytes)])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user