diff options
author | Maxime Devos <maxime.devos@student.kuleuven.be> | 2020-11-08 17:17:02 +0000 |
---|---|---|
committer | Maxime Devos <maximedevos@telenet.be> | 2021-09-21 12:08:22 +0200 |
commit | 0c9b61388cbc7987be4d6b806da578bf63a33475 (patch) | |
tree | 4d35e871c83f0b5c8f2c8c3371887e5b443a0295 /gnu/gnunet/utils/decompress.scm | |
parent | 0759bf62adcb311aeedbe114503222113a267280 (diff) | |
download | gnunet-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.scm | 142 |
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 | ||
49 | either 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 | |||
79 | Return 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 | ||
89 | strictly 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 | |||
133 | Return the decompressed buffer as a fresh bytevector. | ||
134 | In 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 | |||