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 | 1 | ;;; io/flate.lisp --- Compressed IO Interface |
2 | ||
3 | ;; Use compression (ZSTD) with Lisp objects and streams. |
|
4 | ||
5 | ;;; Commentary: |
|
6 | ||
7 | ;; compression ref: https://www.xach.com/lisp/salza2/ (compression only) |
|
8 | ||
9 | ;; decompression ref: https://github.com/sharplispers/chipz (decompression only) |
|
10 | ||
11 | ;; The libraries above are the current state-of-the-art for compression and |
|
12 | ;; decompression in Common Lisp. They are portable packages which depend on |
|
13 | ;; gray streams. They loosely cover deflate, zlib, gzip, and bzip2 data. |
|
14 | ||
15 | ;; The compression backends are themselves hand-coded in Common Lisp, making |
|
16 | ;; them excellent reference material. However, we don't have much use for the |
|
17 | ;; compression backend offered. |
|
18 | ||
19 | ;; We intend to almost exclusively support Zstd compression and decompression |
|
20 | ;; using our ZSTD FFI Lisp system, so we'll make a new library - FLATE - which |
|
21 | ;; provides a shared zstd compression/decompression to Lisp objects and |
|
22 | ;; streams. |
|
23 | ||
24 | ;;; Code: |
|
25 | (in-package :io/flate) |
|
26 | ||
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 | 30 | |
31 | ;;; Utils |
|
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 | 55 | ;;; Compression |
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 | 83 | |
84 | ;;; Decompression |
|
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 | 87 | |
88 | ;; From chipz: |
|
89 | ;; We provide several convenience functions for decompression: |
|
90 | ;; |
|
91 | ;; * decompress a buffer to a newly-consed buffer; |
|
92 | ;; * decompress a stream to a newly-consed buffer; |
|
93 | ;; * decompress a pathname to a newly-consed buffer; |
|
94 | ;; * decompress a buffer to a user-specified buffer; |
|
95 | ;; * decompress a buffer to a stream; |
|
96 | ;; * decompress a stream to a stream. |
|
97 | ;; * decompress a pathname to another pathname; |
|
98 | ;; * decompress a pathname to a stream; |
|
99 | ;; |
|
100 | ;; We do not provide stream->buffer decompression, as we have no way of |
|
101 | ;; knowing how much to read from the stream to fill the buffer, no way |
|
102 | ;; of determining what to do with possible state left in the |
|
103 | ;; INFLATE-STATE that we used, etc. Application-specific logic will |
|
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 |