aboutsummaryrefslogtreecommitdiff
path: root/gnu/gnunet/utils/decompress.scm
diff options
context:
space:
mode:
authorMaxime Devos <maxime.devos@student.kuleuven.be>2020-11-08 17:17:02 +0000
committerMaxime Devos <maximedevos@telenet.be>2021-09-21 12:08:22 +0200
commit0c9b61388cbc7987be4d6b806da578bf63a33475 (patch)
tree4d35e871c83f0b5c8f2c8c3371887e5b443a0295 /gnu/gnunet/utils/decompress.scm
parent0759bf62adcb311aeedbe114503222113a267280 (diff)
downloadgnunet-scheme-0c9b61388cbc7987be4d6b806da578bf63a33475.tar.gz
gnunet-scheme-0c9b61388cbc7987be4d6b806da578bf63a33475.zip
[guile-zlib] Bind the uncompress function
Diffstat (limited to 'gnu/gnunet/utils/decompress.scm')
-rw-r--r--gnu/gnunet/utils/decompress.scm142
1 files changed, 142 insertions, 0 deletions
diff --git a/gnu/gnunet/utils/decompress.scm b/gnu/gnunet/utils/decompress.scm
new file mode 100644
index 0000000..03a4a43
--- /dev/null
+++ b/gnu/gnunet/utils/decompress.scm
@@ -0,0 +1,142 @@
1;;; Zlib bindings, adapted from Guile-zlib
2;;; Copyright © 2016, 2017 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2020 Mathieu Othacehe <othacehe@gnu.org>
4;;; Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
5;;;
6;;; This file is part of Guile-zlib.
7;;;
8;;; Guile-zlib is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; Guile-zlib is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with Guile-zlib. If not, see <http://www.gnu.org/licenses/>.
20
21;;; Commentary:
22;;;
23;;; This file is extracted from Guile-zlib, which was extracted from Guix
24;;; and originally writen by Ludovic Courtès.
25;;; Bindings to the gzip-related part of zlib's API. The main limitation of
26;;; this API is that it requires a bytevector as the source or sink.
27;;;
28;;; Code:
29
30(library (gnu gnunet utils decompress)
31 (export decompress)
32 (import (system foreign)
33 (only (guile) dynamic-link false-if-exception
34 dynamic-func)
35 (only (ice-9 match) match)
36 (only (srfi srfi-45) delay force)
37 (only (zlib config) %libz)
38 (rnrs base)
39 (rnrs control)
40 (rnrs exceptions)
41 (rnrs bytevectors)
42 (rnrs conditions))
43
44 (define %zlib
45 (delay (dynamic-link %libz)))
46
47 (define (zlib-procedure ret name parameters)
48 "Return a procedure corresponding to C function NAME in libz, or #f if
49either zlib or the function could not be found."
50 (match (false-if-exception (dynamic-func name (force %zlib)))
51 ((? pointer? ptr)
52 (pointer->procedure ret ptr parameters))
53 (#f
54 #f)))
55
56 (define-condition-type &z-error &error
57 make-z-error z-error?)
58 (define-condition-type &z-oom-error &z-error
59 make-z-oom-error z-oom-error?)
60 (define-condition-type &z-buf-error &z-error
61 make-z-buf-error z-buf-error?)
62 (define-condition-type &z-data-error &z-error
63 make-z-data-error z-data-error?)
64 (define-condition-type &z-bogus-error &violation
65 make-z-bogus-error z-bogus-error?
66 (value z-bogus-error-value))
67
68 (define Z_OK 0)
69 (define Z_DATA_ERROR -3)
70 (define Z_MEM_ERROR -4)
71 (define Z_BUF_ERROR -5)
72
73 (define uncompress!
74 (let ((proc (zlib-procedure int "uncompress" `(* * * ,unsigned-long))))
75 (lambda (dest-bv dest-offset dest-length
76 source-bv source-offset source-length)
77 "Uncompress the source buffer into the destination buffer.
78
79Return the actual buffer size on success, raise an appropriate
80&z-error otherwise.
81
82&z-oom-error: out of memory
83&z-data-error: corrupted or incomplete data
84&z-buf-error: output buffer too small
85
86@var{dest-bv}: destination buffer, as a bytevector
87@var{dest-offset}: position of the first byte in @var{dest-bv}
88@var{dest-length}: size of @var{dest-bv}. Possibly more than
89strictly required."
90 ;; Verify bounds
91 (assert (and (exact? dest-offset)
92 (integer? dest-offset)))
93 (assert (and (exact? dest-length)
94 (integer? dest-length)))
95 (assert (and (exact? source-offset)
96 (integer? source-offset)))
97 (assert (and (exact? source-length)
98 (integer? source-length)))
99 (assert (and (<= 0 dest-offset)
100 (<= dest-offset (bytevector-length dest-bv))))
101 (assert (and (<= 0 source-offset)
102 (<= source-offset (bytevector-length source-bv))))
103 (assert (and (<= (+ source-offset source-length)
104 (bytevector-length source-bv))))
105 (assert (and (<= (+ dest-offset dest-length)
106 (bytevector-length dest-bv))))
107 (let* ((dest-len-buf
108 (make-c-struct `(,unsigned-long) `(,dest-length)))
109 (ret (proc (bytevector->pointer dest-bv dest-offset)
110 dest-len-buf
111 (bytevector->pointer source-bv source-offset)
112 source-length)))
113 (cond ((= ret Z_OK)
114 (list-ref (parse-c-struct dest-len-buf `(,unsigned-long))
115 0))
116 ((= ret Z_MEM_ERROR) (raise (make-z-oom-error)))
117 ((= ret Z_BUF_ERROR) (raise (make-z-buf-error)))
118 ((= ret Z_DATA_ERROR) (raise (make-z-data-error)))
119 (else (raise
120 (condition
121 (make-z-bogus-error ret)
122 (make-message-condition "bogus zlib error value")
123 (make-who-condition 'uncompress!)))))))))
124
125 (define decompress
126 (case-lambda
127 "Uncompress a bytevector with deflate"
128 ((input-size output-size input-bv)
129 (decompress input-size output-size input-bv 0))
130 ((input-size output-size input-bv input-offset)
131 "Decompress a source buffer
132
133Return the decompressed buffer as a fresh bytevector.
134In case the input is invalid, return #f"
135 (guard (ex ((z-buf-error? ex) #f)
136 ((z-data-error? ex) #f))
137 (let* ((bv (make-bytevector output-size))
138 (bv-used (uncompress! bv 0 output-size input-bv input-offset
139 input-size)))
140 (and (= bv-used output-size)
141 bv)))))))
142