(import test zlib chicken.port chicken.blob chicken.io) (test-group ;; taken from zstd's run.scm "zlib-decompressing-input-port" (define abcdefghijklmn.zlib "\x78\x5e\x4b\x4c\x4a\x4e\x49\x4d\x4b\xcf\xc8\xcc\xca\xce\xc9\xcd\x03\x00\x29\x9e\x05\xaa") (define (wifdip proc) (with-input-from-port (zlib-decompressing-input-port ;; ,--- zlib header + deflate data (open-input-string abcdefghijklmn.zlib) #:buffer (make-string 4096)) proc)) (test "read all" "abcdefghijklmn" (wifdip (lambda () (read-string #f)))) (test "r" #\a (wifdip (lambda () (read-char)))) (test "rr" #\b (wifdip (lambda () (read-char) (read-char)))) (test "rrr" #\c (wifdip (lambda () (read-char) (read-char) (read-char)))) (define peeked #f) (test "rpr" #\b (wifdip (lambda () (read-char) (set! peeked (peek-char)) (read-char)))) (test "peeked" #\b peeked) (test "r s1" "b" (wifdip (lambda () (read-char) (read-string 1)))) (test "r s4" "bcde" (wifdip (lambda () (read-char) (read-string 4)))) (test "r s1k" "bcdefghijklmn" (wifdip (lambda () (read-char) (read-string 1024)))) (test "p s1k" "abcdefghijklmn" (wifdip (lambda () (peek-char) (read-string 1024)))) (with-input-from-port (zlib-decompressing-input-port (open-input-string abcdefghijklmn.zlib) buffer: (make-string 1)) ;; trigger many refills (lambda () (test "small buffer char "#\a (read-char)) (test "small buffer string1 " "b" (read-string 1)) (test "small buffer rest " "cdefghijklmn" (read-string 1024)) (test "eof" #!eof (read-string #f)))) (with-input-from-port (zlib-decompressing-input-port (open-input-string abcdefghijklmn.zlib)) (lambda () (test "ab" (read-string 2)) (close-input-port (current-input-port)) (test-error "read after close" (read-string 1))))) ;; ======================================== DEFLATE ======================================== (test-group "deflate parameters" (define (compress-through-port original . params) (call-with-output-string (lambda (os) (let ((op (apply open-zlib-compressed-output-port (cons os params)))) (display original op) (close-output-port op))))) ;; $ python3 ;; >>> import zlib ;; >>> zlib.decompress(bytes.fromhex('78dacb48cdc9c95728cf2fca4901001a0b045d')) ;; b'hello world' (test "deflate zlib no compression" ;; ,-- these are RFC1950 (zlib) headers "x\x01\x01\v\x00\xf4\xffhello world\x1a\v\x04]" (compress-through-port "hello world" #:level 'no)) (test "deflate zlib best" #${78dacb48cdc9c95728cf2fca4901001a0b045d} (string->blob (compress-through-port "hello world" #:level 'best))) (test "deflate raw" ;; ,-- no zlib or gzip headers! #${cb48cdc9c95728cf2fca490100} (string->blob (compress-through-port "hello world" #:window-bits -15))) (test "deflate gzip" ;; ,-- voila! gzip headers! "\x1f\213\b\x00\x00\x00\x00\x00\x04\x03\x01\v\x00\364\377hello world\205\x11J\r\v\x00\x00\x00" (compress-through-port "hello world" #:level 0 #:window-bits (+ 15 16)))) (test-group ;; these test are taken from the zstd egg "deflate streaming" (test "basic port" #t (output-port? (zlib-compressing-output-port (current-output-port)))) (define (with-output-to-compressed-string-and-back thunk) (let ((compressed (with-output-to-string (lambda () (define cp (open-zlib-compressed-output-port (current-output-port))) (with-output-to-port cp thunk) (close-output-port cp))))) (read-string #f (open-zlib-compressed-input-port (open-input-string compressed))))) (define wotcsab with-output-to-compressed-string-and-back) (test "no output" #!eof (wotcsab (lambda () #f))) (test "\"a\"" "a" (wotcsab (lambda () (display "a")))) (test "hello world" "hello world\n" (wotcsab (lambda () (print "hello world")))) (test "hello world" "abc" (wotcsab (lambda () (display "a") (display "b") (display "c")))) (test "writing empty string" "x" (wotcsab (lambda () (display "") (display "x")))) (test "big string" (values (make-string (* 1024 1024) #\x)) (wotcsab (lambda () (display (make-string (* 1024 1024) #\x))))) (define (spam) (let loop ((n 0)) (print "isd83jdgvlhjdu4cvukitsq1aryj " n) (when (< n 100000) (loop (+ n 1))))) ;; I want to trigger when decompress cant consume all input, ie (≠ ipos (number-of-bytes str)) (test "small transit buffer and lots of data" (with-output-to-string spam) (read-string #f (zlib-decompressing-input-port (open-input-string (call-with-output-string (lambda (os) (with-output-to-port (zlib-compressing-output-port os buffer: " ") (lambda () (spam) (close-output-port (current-output-port))))))))))) (test-group "file io (provoking Z_BUF_ERROR)" (test ;; I've been unable to reproduce this on anything but file io ;; ports which is strange. 4194304 (with-input-from-file "zeros.zlib" (lambda () (current-input-port (zlib-decompressing-input-port (current-input-port))) (port-fold (lambda (str sum) (+ sum (string-length str))) 0 (lambda () (read-string 4096))))))) (test-exit)