gzip.ss
#lang scheme/base
(require file/gunzip file/gzip mzlib/trace scheme/file scheme/system
         (planet bzlib/os)
         (planet bzlib/base)
         "port.ss"
         "filter.ss"
         (rename-in file/gunzip (gunzip-through-ports input-gzip-filter))
         )

(define (gzip/exe)
  (find-executable-path (+:windows "gzip.exe" "gzip")))

(define (gzip/sys path)
  (system* (gzip/exe) path))

(define (gunzip/sys path)
  (system* (gzip/exe) "-d" path))

(define (gzipped-path path)
  (string->path (string-append (if (path? path) (path->string path) path) ".gz")))

(define (open-input-gzip-port in)
  (make-input-filter-port in input-gzip-filter #f))

(define call-with-input-gzip-port
  (make-call-with-input-port open-input-gzip-port in))

(define (open-input-gzip-file path)
  (open-input-gzip-port (open-input-file path)))

(define call-with-input-gzip-file
  (make-call-with-input-port open-input-gzip-file path))

(define (output-gzip-filter in out)
  (gzip-through-ports in out #f (current-seconds)))

(define (open-output-gzip-port out)
  (make-output-filter-port out output-gzip-filter #f))

(define call-with-output-gzip-port
  (make-call-with-output-port open-output-gzip-port out))

(define (open-output-gzip-file path #:exists (exists 'replace))
  (open-output-gzip-port (open-output-file path #:exists exists)))

(define call-with-output-gzip-file
  (make-call-with-output-port open-output-gzip-file path #:exists (exists 'replace)))

(provide/contract 
 (gzip/sys (-> path-string? any))
 (gunzip/sys (-> path-string? any))
 (open-input-gzip-port (-> input-port? input-port?))
 (call-with-input-gzip-port (-> input-port? (-> input-port? any) any))
 (open-input-gzip-file (-> path-string? input-port?))
 (call-with-input-gzip-file (-> path-string? 
                          (-> input-port? any)
                          any))
 (open-output-gzip-port (-> output-port? output-port?)) 
 (call-with-output-gzip-port (-> output-port? (-> output-port? any) any))
 (open-output-gzip-file (->* (path-string?)
                             (#:exists (or/c 'replace 'truncate)) 
                             output-port?))
 (call-with-output-gzip-file (->* (path-string? 
                                   (-> output-port? any))
                                  (#:exists (or/c 'replace 'truncate))
                                 any))
 (gzipped-path (-> path-string? path-string?))
 (output-gzip-filter port-filter/c)
 )
(provide input-gzip-filter)