changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / lisp/ffi/zstd/pkg.lisp

changeset 507: 4dd7b6320efc
parent: c6caddf91c72
child: 937a6f354047
author: Richard Westhaver <ellis@rwest.io>
date: Thu, 04 Jul 2024 16:42:46 -0400
permissions: -rw-r--r--
description: zstd alien errors
1 ;;; ffi/zstd/pkg.lisp --- ZSTD FFI
2 
3 ;; Zstd compression support for Lisp
4 
5 ;;; Commentary:
6 
7 ;; Initially I was thinking of this as an SB-CONTRIB module which links up
8 ;; with whatever C runtime functions exposed by the built-in SBCL compression
9 ;; support. However, there isn't actually much going on in the runtime and
10 ;; it's not publicly exposed at all. The SBCL/Zstd surface-area is restrained
11 ;; to FASL read/write streams and not of much use outside it.
12 
13 ;; So, we'll be applying the same from-scratch strategy we've become
14 ;; accustomed to, exposing as much of the C API as possible and building up
15 ;; our abstractions.
16 
17 ;; The low-level abstractions are in this package - ZSTD.
18 
19 ;; For the high-level abstractions see IO/FLATE and IO/ZSTD in the IO package.
20 
21 ;; The following programs have compile-time support for linking Zstd:
22 
23 ;; SBCL
24 ;; QEMU
25 ;; RocksDB
26 
27 #| from zstd.h:
28 Introduction ; ; ; ; ; ;
29  ; ; ; ; ; ;
30 zstd, short for Zstandard, is a fast lossless compression algorithm, targeting ; ; ; ; ; ;
31 real-time compression scenarios at zlib-level and better compression ratios. ; ; ; ; ; ;
32 The zstd compression library provides in-memory compression and decompression ; ; ; ; ; ;
33 functions. ; ; ; ; ; ;
34  ; ; ; ; ; ;
35 The library supports regular compression levels from 1 up to ZSTD_maxCLevel(), ; ; ; ; ; ;
36 which is currently 22. Levels >= 20, labeled `--ultra`, should be used with ; ; ; ; ; ;
37 caution, as they require more memory. The library also offers negative ; ; ; ; ; ;
38 compression levels, which extend the range of speed vs. ratio preferences. ; ; ; ; ; ;
39 The lower the level, the faster the speed (at the cost of compression). ; ; ; ; ; ;
40  ; ; ; ; ; ;
41 Compression can be done in: ; ; ; ; ; ;
42 - a single step (described as Simple API) ; ; ; ; ; ;
43 - a single step, reusing a context (described as Explicit context) ; ; ; ; ; ;
44 - unbounded multiple steps (described as Streaming compression) ; ; ; ; ; ;
45  ; ; ; ; ; ;
46 The compression ratio achievable on small data can be highly improved using ; ; ; ; ; ;
47 a dictionary. Dictionary compression can be performed in: ; ; ; ; ; ;
48 - a single step (described as Simple dictionary API) ; ; ; ; ; ;
49 - a single step, reusing a dictionary (described as Bulk-processing ; ; ; ; ; ;
50 dictionary API) ; ; ; ; ; ;
51  ; ; ; ; ; ;
52 Advanced experimental functions can be accessed using ; ; ; ; ; ;
53 `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h. ; ; ; ; ; ;
54  ; ; ; ; ; ;
55 Advanced experimental APIs should never be used with a dynamically-linked ; ; ; ; ; ;
56 library. They are not "stable"; their definitions or signatures may change in ; ; ; ; ; ;
57 the future. Only static linking is allowed. ; ; ; ; ; ;
58 |#
59 
60 ;;; Code:
61 (defpackage :zstd
62  (:use :cl :std :sb-alien)
63  (:nicknames :zstd)
64  (:export :zstd-alien-error :with-zstd-cstream :with-zstd-dstream
65  :zstd-versionnumber :zstd-cstreaminsize :zstd-cstreamoutsize :zstd-inbuffer
66  :zstd-iserror :zstd-defaultclevel :zstd-compress :zstd-decompress
67  :zstd-cstream :zstd-dstream :zstd-compressstream :zstd-decompressstream
68  :zstd-compressstream2 :zstd-outbuffer :zstd-geterrorname :zstd-geterrorcode
69  :zstdc :zstdd
70  :zstd-alien-error :zstd-dstream-error :zstd-cstream-error))
71 
72 (in-package :zstd)
73 
74 (define-alien-loader "zstd" t "/usr/lib/")
75 
76 ;;; Types
77 (deftype zstd-error-code ()
78  `(integer 0 120))
79 
80 (deftype zstd-strategy-designator ()
81  `(or (integer ,(zstd-minclevel) ,(zstd-maxclevel))
82  (member :fast :dfast :greedy :lazy
83  :lazy2 :btlazy2 :btopt :btultra
84  :btultra2)))
85 
86 (deftype zstd-compression-parameter ()
87  `(integer 100 1024))
88 (deftype zstd-decompression-parameter ()
89  `(integer 100 1024))
90 
91 (deftype zstd-reset-directive ()
92  `(or (integer 1 3) (member :session-only :parameters :session-and-parameters)))
93 (deftype zstd-end-directive ()
94  `(or (integer 0 2) (member :continue :flus :end)))
95 
96 ;;; Errors
97 (define-condition zstd-alien-condition () ()
98  (:documentation "Superclass of all conditions triggered by the ZSTD FFI."))
99 
100 (deferror zstd-alien-error (error)
101  ((code :initarg :code :accessor zstd-error-code))
102  (:documentation "Error signaled from Zstd Alien."))
103 
104 ;; found in zstd_errors.h
105 (define-alien-enum (zstd-errorcode int)
106  :no-error 0
107  :generic 1
108  :prefix-unknown 10
109  :version-unsupported 12
110  :frameparameter-unsupported 14
111  :frameparameter-windowtoolarge 16
112  :corruption-detected 20
113  :checksum-wrong 22
114  :literals-headerwrong 24
115  :dictionary-corrupted 30
116  :dictionary-wrong 32
117  :dictionarycreation-failed 34
118  :parameter-unsupported 40
119  :parameter-combination-unsupported 41
120  :parameter-outofbound 42
121  :tablelog-toolarge 44
122  :maxsymbolvalue-toolarge 46
123  :maxsymbolvalue-toosmall 48
124  :stabilitycondition-notrespected 50
125  :stage-wrong 60
126  :init-missing 62
127  :memory-allocation 64
128  :workspace-toosmall 66
129  :dstsize-toosmall 70
130  :srcsize-wrong 72
131  :dstbuffer-null 74
132  :noforwardprogress-destfull 80
133  :noforwardprogress-inputempty 82
134  ;; unstable
135  :frameindex-toolarge 100
136  :seekableio 102
137  :dstbuffer-wrong 104
138  :srcbuffer-wrong 105
139  :sequenceproducer-failed 106
140  :externalsequences-invalid 107
141  :maxcode 120)
142 
143 ;;; Utils
144 (define-alien-routine "ZSTD_versionNumber" unsigned)
145 (define-alien-routine "ZSTD_versionString" c-string)
146 (define-alien-routine "ZSTD_compressBound" size-t (src-size size-t))
147 (define-alien-routine "ZSTD_isError" unsigned (code size-t))
148 (define-alien-routine "ZSTD_getErrorName" c-string (code size-t))
149 ;; zstd_errors.h - does this work?
150 (define-alien-routine "ZSTD_getErrorCode" int (function-result size-t))
151 (define-alien-routine "ZSTD_getErrorString" c-string (code int))
152 
153 (define-alien-routine "ZSTD_minCLevel" int)
154 (define-alien-routine "ZSTD_maxCLevel" int)
155 (define-alien-routine "ZSTD_defaultCLevel" int)
156 
157 (define-alien-routine "ZSTD_findFrameCompressedSize" size-t
158  (src (* t))
159  (src-size size-t))
160 
161 (define-alien-routine "ZSTD_getFrameContentSize" unsigned-long-long
162  (src (* t))
163  (src-size size-t))
164 
165 (define-alien-routine "ZSTD_decompressBound" unsigned-long-long
166  (src (* t))
167  (src-size size-t))
168 
169 ;;; Explicit Context API
170 (define-alien-type zstd-cctx (struct zstd-cctx-s))
171 
172 (define-alien-routine "ZSTD_createCCtx" (* zstd-cctx))
173 (define-alien-routine "ZSTD_freeCCtx" void (cctx (* zstd-cctx)))
174 (define-alien-routine "ZSTD_compressCCtx" size-t
175  (cctx (* zstd-cctx))
176  (dst (* t)) (dst-capacity size-t)
177  (src (* t)) (src-size size-t)
178  (compression-level int))
179 
180 (define-alien-type zstd-dctx (struct zstd-dctx-s))
181 
182 (define-alien-routine "ZSTD_createDCtx" (* zstd-dctx))
183 (define-alien-routine "ZSTD_freeDCtx" void (dctx (* zstd-dctx)))
184 (define-alien-routine "ZSTD_decompressDCtx" size-t
185  (dctx (* zstd-dctx))
186  (dst (* t)) (dst-capacity size-t)
187  (src (* t)) (src-size size-t))
188 ;;; Advanced API
189 (define-alien-enum (zstd-strategy int)
190  :fast 1
191  :dfast 2
192  :greedy 3
193  :lazy 4
194  :lazy2 5
195  :btlazy2 6
196  :btopt 7
197  :btultra 8
198  :btultra2 9)
199 
200 (define-alien-enum (zstd-cparameter int)
201  :compression-level 100
202  :window-log 101
203  :hash-log 102
204  :chain-log 103
205  :search-log 104
206  :min-match 105
207  :target-length 106
208  :strategy 107
209  :target-c-block-size 130
210  :enable-long-distance-matching 160
211  :ldm-hash-log 161
212  :ldm-min-match 162
213  :ldm-bucket-size-log 163
214  :ldm-hash-rate-log 164
215  :content-size-flag 200
216  :checksum-flag 201
217  :dict-id-flag 202
218  :nb-workers 400
219  :job-size 401
220  :overlap-log 402
221  :expiremental1 500
222  :expiremental2 10
223  :expiremental3 1000
224  :expiremental4 1001
225  :expiremental5 1002
226  ;; :expiremental6 1003 ;; is now target-c-block-size
227  :expiremental7 1004
228  :expiremental8 1005
229  :expiremental9 1006
230  :expiremental10 1007
231  :expiremental11 1008
232  :expiremental12 1009
233  :expiremental13 1010
234  :expiremental14 1011
235  :expiremental15 1012
236  :expiremental16 1013
237  :expiremental17 1014
238  :expiremental18 1015
239  :expiremental19 1016)
240 
241 (define-alien-enum (zstd-reset-directive int)
242  :session-only 1
243  :parameters 2
244  :session-and-parameters 3)
245 
246 (define-alien-enum (zstd-dparameter int)
247  :window-log-max 100
248  :experimental1 1000
249  :experimental2 1001
250  :experimental3 1002
251  :experimental4 1003
252  :experimental5 1004
253  :experimental6 1005)