sync zlibstubs.c with upstream
[mldonkey.git] / src / utils / cdk / bzip2stubs.c
blobd06e0c1a8eff2960da633f92cddfac10f99b1282
1 /*
2 This library is free software; you can redistribute it and/or
3 modify it under the terms of the GNU Library General Public
4 License as published by the Free Software Foundation; either
5 version 2 of the License, or (at your option) any later version.
7 This library is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 Library General Public License for more details.
12 You should have received a copy of the GNU Library General Public
13 License along with this library; if not, write to the
14 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
15 Boston, MA 02110-1301, USA.
18 #include "../../../config/config.h"
20 #ifdef USE_BZIP2
21 #include <bzlib.h>
22 #endif
24 #include <caml/mlvalues.h>
25 #include <caml/alloc.h>
26 #include <caml/callback.h>
27 #include <caml/fail.h>
28 #include <caml/memory.h>
30 /* Bzip2 interface code */
32 #define BZStream_val(v) ((bz_stream *) (v))
34 static const value * camlzip_bzerror_exn = NULL;
36 #ifdef USE_BZIP2
37 static void camlzip_bzerror(char * fn, int err)
39 char * msg;
40 value s1 = Val_unit, s2 = Val_unit, bucket = Val_unit;
42 if (camlzip_bzerror_exn == NULL) {
43 camlzip_bzerror_exn = caml_named_value("Bzlib.Error");
44 if (camlzip_bzerror_exn == NULL)
45 invalid_argument("Exception Bzlib.Error not initialized");
47 Begin_roots3(s1, s2, bucket);
48 s1 = copy_string(fn);
49 switch (err) {
50 case BZ_CONFIG_ERROR:
51 s2 = Val_int(0);
52 break;
53 case BZ_SEQUENCE_ERROR:
54 s2 = Val_int(1);
55 break;
56 case BZ_PARAM_ERROR:
57 s2 = Val_int(2);
58 break;
59 case BZ_MEM_ERROR:
60 s2 = Val_int(3);
61 break;
62 case BZ_DATA_ERROR:
63 s2 = Val_int(4);
64 break;
65 case BZ_DATA_ERROR_MAGIC:
66 s2 = Val_int(5);
67 break;
68 default:
69 s2 = Val_int(6);
71 bucket = alloc_small(3, 0);
72 Field(bucket, 0) = *camlzip_bzerror_exn;
73 Field(bucket, 1) = s1;
74 Field(bucket, 2) = s2;
75 End_roots();
76 mlraise(bucket);
79 static value camlzip_new_bzstream(void)
81 bz_stream * bzs = (bz_stream *) malloc(sizeof(bz_stream));
82 bzs->bzalloc = NULL;
83 bzs->bzfree = NULL;
84 bzs->opaque = NULL;
85 bzs->next_in = NULL;
86 bzs->next_out = NULL;
87 return (value) bzs;
90 int camlzip_action_table[] = { BZ_RUN, BZ_FLUSH, BZ_FINISH };
91 #endif
94 value camlzip_bzCompressInit(value blockSize100k, value verbosity, value workFactor) {
95 #ifdef USE_BZIP2
96 int err;
97 value vbzs = camlzip_new_bzstream();
98 if ((err = BZ2_bzCompressInit(BZStream_val(vbzs),
99 Int_val(blockSize100k),
100 Int_val(verbosity),
101 Int_val(workFactor))) != BZ_OK)
102 camlzip_bzerror("Zlib.deflateInit", err);
103 return vbzs;
104 #else
105 failwith("Bzip2 compression not supported.");
106 #endif
109 value camlzip_bzCompress(value vzs, value srcbuf, value srcpos, value srclen,
110 value dstbuf, value dstpos, value dstlen,
111 value vflush)
113 #ifdef USE_BZIP2
114 bz_stream * zs = BZStream_val(vzs);
115 int retcode;
116 long used_in, used_out;
117 value res;
119 zs->next_in = &Byte(srcbuf, Long_val(srcpos));
120 zs->avail_in = Long_val(srclen);
121 zs->next_out = &Byte(dstbuf, Long_val(dstpos));
122 zs->avail_out = Long_val(dstlen);
123 retcode = BZ2_bzCompress(zs, camlzip_action_table[Int_val(vflush)]);
124 if (retcode < 0) camlzip_bzerror("Bzlib.compress", retcode);
125 used_in = Long_val(srclen) - zs->avail_in;
126 used_out = Long_val(dstlen) - zs->avail_out;
127 zs->next_in = NULL; /* not required, but cleaner */
128 zs->next_out = NULL; /* (avoid dangling pointers into Caml heap) */
129 res = alloc_small(3, 0);
130 Field(res, 0) = Val_bool(retcode == BZ_STREAM_END);
131 Field(res, 1) = Val_int(used_in);
132 Field(res, 2) = Val_int(used_out);
133 return res;
134 #else
135 failwith("Bzip2 compression not supported");
136 #endif
139 value camlzip_bzCompress_bytecode(value * arg, int nargs)
141 return camlzip_bzCompress(arg[0], arg[1], arg[2], arg[3],
142 arg[4], arg[5], arg[6], arg[7]);
145 value camlzip_bzCompressEnd(value stream) {
146 #ifdef USE_BZIP2
147 int err;
148 if ((err = BZ2_bzCompressEnd(BZStream_val(stream))) != BZ_OK)
149 camlzip_bzerror("Bzlib.compress_end", err);
150 free(BZStream_val(stream));
151 #else
152 failwith("Bzip2 compression not supported");
153 #endif
154 return Val_unit;
157 value camlzip_bzDecompressInit(value verbosity, value small)
159 #ifdef USE_BZIP2
160 int err;
161 value vzs = camlzip_new_bzstream();
162 if ((err = BZ2_bzDecompressInit(BZStream_val(vzs), Int_val(verbosity), Bool_val(small))) != BZ_OK)
163 camlzip_bzerror("Bzlib.decompress_init", err);
164 return vzs;
165 #else
166 failwith("Bzip2 compression not supported");
167 #endif
170 value camlzip_bzDecompress(value vzs, value srcbuf, value srcpos, value srclen,
171 value dstbuf, value dstpos, value dstlen)
173 #ifdef USE_BZIP2
174 bz_stream * zs = BZStream_val(vzs);
175 int retcode;
176 long used_in, used_out;
177 value res;
179 zs->next_in = &Byte(srcbuf, Long_val(srcpos));
180 zs->avail_in = Long_val(srclen);
181 zs->next_out = &Byte(dstbuf, Long_val(dstpos));
182 zs->avail_out = Long_val(dstlen);
183 retcode = BZ2_bzDecompress(zs);
184 if (retcode < 0)
185 camlzip_bzerror("Bzlib.decompress", retcode);
186 used_in = Long_val(srclen) - zs->avail_in;
187 used_out = Long_val(dstlen) - zs->avail_out;
188 zs->next_in = NULL; /* not required, but cleaner */
189 zs->next_out = NULL; /* (avoid dangling pointers into Caml heap) */
190 res = alloc_small(3, 0);
191 Field(res, 0) = Val_bool(retcode == BZ_STREAM_END);
192 Field(res, 1) = Val_int(used_in);
193 Field(res, 2) = Val_int(used_out);
194 return res;
195 #else
196 failwith("Bzip2 compression not supported");
197 #endif
200 value camlzip_bzDecompress_bytecode(value * arg, int nargs)
202 return camlzip_bzDecompress(arg[0], arg[1], arg[2], arg[3],
203 arg[4], arg[5], arg[6]);
206 value camlzip_bzDecompressEnd(value stream) {
207 #ifdef USE_BZIP2
208 int err;
209 if ((err = BZ2_bzDecompressEnd(BZStream_val(stream))) != BZ_OK)
210 camlzip_bzerror("Bzlib.decompressEnd", err);
211 free(BZStream_val(stream));
212 #else
213 failwith("Bzip2 compression not supported");
214 #endif
215 return Val_unit;
218 int camlzip_bzlibversion(void)
220 CAMLparam0 ();
221 CAMLlocal1 (v);
222 #ifdef HAVE_BZLIBVERSION
223 v = copy_string (BZ2_bzlibVersion());
224 CAMLreturn (v);
225 #else
226 failwith("bzlibVersion not found");
227 #endif