Updated version to 2.1.
[salza2.git] / stream.lisp
blobbe0d10a48acfaaa7adead02a2c9be8f7f82855ff
1 ;;;
2 ;;; Copyright (c) 2021 Eric Timmons, All Rights Reserved
3 ;;;
4 ;;; Redistribution and use in source and binary forms, with or without
5 ;;; modification, are permitted provided that the following conditions
6 ;;; are met:
7 ;;;
8 ;;; * Redistributions of source code must retain the above copyright
9 ;;; notice, this list of conditions and the following disclaimer.
10 ;;;
11 ;;; * Redistributions in binary form must reproduce the above
12 ;;; copyright notice, this list of conditions and the following
13 ;;; disclaimer in the documentation and/or other materials
14 ;;; provided with the distribution.
15 ;;;
16 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
17 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 ;;;
29 (in-package #:salza2)
31 (define-condition stream-closed-error (stream-error)
33 (:documentation "Signaled when attempting to write to a closed COMPRESSING-STREAM.")
34 (:report (lambda (condition stream)
35 (format stream "Stream ~S is closed" (stream-error-stream condition)))))
37 (defclass compressing-stream (trivial-gray-streams:fundamental-binary-output-stream)
38 ((openp
39 :initform t
40 :accessor openp)
41 (compressor
42 :initarg :compressor
43 :accessor compressor))
44 (:documentation
45 "A gray stream that transparently compresses its input and writes the
46 compressed data to another stream."))
48 (defun make-compressing-stream (compressor-type stream)
49 "Return a COMPRESSING-STREAM that transparently compresses its input and
50 writes it to STREAM. COMPRESSOR-TYPE is a symbol naming the compressor class to
51 use.
53 Closing the returned COMPRESSING-STREAM merely finalizes the compression and
54 does not close STREAM."
55 (make-instance
56 'compressing-stream
57 :compressor (make-instance
58 compressor-type
59 :callback (make-stream-output-callback stream))))
62 (defmethod trivial-gray-streams:stream-write-byte ((stream compressing-stream) byte)
63 (unless (openp stream)
64 (error 'stream-closed-error :stream stream))
65 (compress-octet byte (compressor stream))
66 byte)
68 (defmethod trivial-gray-streams:stream-write-sequence ((stream compressing-stream) sequence start end &key)
69 (unless (openp stream)
70 (error 'stream-closed-error :stream stream))
71 (let ((vector (if (typep sequence 'vector)
72 sequence
73 (coerce sequence 'vector))))
74 (compress-octet-vector vector (compressor stream) :start start :end end))
75 sequence)
77 (defmethod trivial-gray-streams:stream-file-position ((stream compressing-stream))
78 "Does not keep track of position in the stream."
79 nil)
81 (defmethod (setf trivial-gray-streams:stream-file-position) (newval (stream compressing-stream))
82 "Unable to seek within the stream."
83 (declare (ignore newval))
84 nil)
86 (defmethod stream-element-type ((stream compressing-stream))
87 '(unsigned-byte 8))
89 (defmethod close ((stream compressing-stream) &key abort)
90 (declare (ignore abort))
91 (when (openp stream)
92 (finish-compression (compressor stream))
93 (setf (openp stream) nil)
94 t))