changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/lib/io/flate.lisp

changeset 435: 849bbe48e32d
parent: c40d2a41d7ce
child: 9fa3b9154bb2
author: Richard Westhaver <ellis@rwest.io>
date: Tue, 11 Jun 2024 15:47:38 -0400
permissions: -rw-r--r--
description: added dat/mime, removed sans-io
400
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; io/flate.lisp --- Compressed IO Interface
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;; Use compression (ZSTD) with Lisp objects and streams.
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Commentary:
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 ;; compression ref: https://www.xach.com/lisp/salza2/ (compression only)
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
8
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
9
 ;; decompression ref: https://github.com/sharplispers/chipz (decompression only)
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
10
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
11
 ;; The libraries above are the current state-of-the-art for compression and
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
12
 ;; decompression in Common Lisp. They are portable packages which depend on
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
13
 ;; gray streams. They loosely cover deflate, zlib, gzip, and bzip2 data.
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
14
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
15
 ;; The compression backends are themselves hand-coded in Common Lisp, making
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
16
 ;; them excellent reference material. However, we don't have much use for the
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
17
 ;; compression backend offered.
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
18
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
19
 ;; We intend to almost exclusively support Zstd compression and decompression
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
20
 ;; using our ZSTD FFI Lisp system, so we'll make a new library - FLATE - which
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
21
 ;; provides a shared zstd compression/decompression to Lisp objects and
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
22
 ;; streams.
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
24
 ;;; Code:
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
25
 (in-package :io/flate)
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
26
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
27
 ;;; Vars
431
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
28
 (defparameter *compression-buffer-size* 4096)
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
29
 (defparameter *decompression-buffer-size* 4096)
400
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
30
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
31
 ;;; Utils
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
32
 
431
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
33
 ;;; Proto
435
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents: 431
diff changeset
34
 
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents: 431
diff changeset
35
 (eval-always (deferror flate-error () () (:auto t)))
431
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
36
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
37
 (deferror compression-error (flate-error) () (:auto t))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
38
 (deferror decompression-error (flate-error) () (:auto t))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
39
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
40
 (defgeneric finish-compression (self))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
41
 (defgeneric finish-decompression (self))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
42
 ;; TODO 2024-06-08: maybe move this to generic io/stream protocol - 'RESET'
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
43
 (defgeneric reset-compressor (self))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
44
 (defgeneric reset-decompressor (self))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
45
 (defgeneric make-compressing-stream (compressor stream))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
46
 (defgeneric make-decompressing-stream (decompressor stream))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
47
 (defgeneric compress-object (self))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
48
 (defgeneric decompress-object (self))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
49
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
50
 (defgeneric compress (input state output))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
51
 (defgeneric decompress (input state output))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
52
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
53
 ;; decompress
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
54
 
400
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
55
 ;;; Compression
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
56
 
431
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
57
 ;; AKA 'DEFLATE'
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
58
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
59
 ;; compress-octet
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
60
 ;; compress-octet-vector
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
61
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
62
 ;; finish-compression (finish-output?)
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
63
 ;; with-compressor
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
64
 ;; reset-compressor
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
65
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
66
 ;; make-compressing-stream
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
67
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
68
 (defclass compressor ()
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
69
   ((input
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
70
     :initarg :input
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
71
     :accessor compressor-input)
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
72
    (start
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
73
     :initarg :start
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
74
     :accessor compressor-start)
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
75
    (end
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
76
     :initarg :end
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
77
     :accessor compressor-end)))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
78
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
79
 (defclass compressing-stream (fundamental-binary-output-stream)
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
80
   ((compressor
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
81
     :initarg :compressor
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
82
     :accessor compressor)))
400
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
83
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
 ;;; Decompression
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
85
 
431
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
86
 ;; AKA 'INFLATE'
400
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
87
 
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
88
 ;; From chipz:
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
89
 ;; We provide several convenience functions for decompression:
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
90
 ;;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
91
 ;; * decompress a buffer to a newly-consed buffer;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
92
 ;; * decompress a stream to a newly-consed buffer;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
 ;; * decompress a pathname to a newly-consed buffer;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
 ;; * decompress a buffer to a user-specified buffer;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
 ;; * decompress a buffer to a stream;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
 ;; * decompress a stream to a stream.
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
 ;; * decompress a pathname to another pathname;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
 ;; * decompress a pathname to a stream;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
 ;;
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
 ;; We do not provide stream->buffer decompression, as we have no way of
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
 ;; knowing how much to read from the stream to fill the buffer, no way
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
 ;; of determining what to do with possible state left in the
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
 ;; INFLATE-STATE that we used, etc.  Application-specific logic will
122554547517 init flate.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
 ;; have to handle those bits.
431
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
105
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
106
 ;; make-decompressing-stream
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
107
 ;; decompress-octet
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
108
 ;; decompress-octet-vector
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
109
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
110
 (defclass decompressor () ())
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
111
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
112
 (defclass decompressing-stream (fundamental-binary-input-stream)
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
113
   ((decompressor
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
114
     :initarg :compressor
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
115
     :accessor decompressor)))
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
116
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
117
 ;;; API
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
118
 
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
119
 ;; zstd-stream
c40d2a41d7ce source concatenating std.lisp, more systems, got zstd simple working, IO work, added dat/tar
Richard Westhaver <ellis@rwest.io>
parents: 400
diff changeset
120
 ;; zstd-file