1 /* Bzip2 encoding (ENCODING_BZIP2) backend */
13 #include <bzlib.h> /* Everything needs this after stdio.h */
19 #include "encoding/bzip2.h"
20 #include "encoding/encoding.h"
21 #include "util/memory.h"
23 #define ELINKS_BZ_BUFFER_LENGTH BZ_MAX_UNUSED
28 int last_read
; /* If err after last bzDecompress was BZ_STREAM_END.. */
29 unsigned char buf
[ELINKS_BZ_BUFFER_LENGTH
]; /* must be the last */
33 bzip2_open(struct stream_encoded
*stream
, int fd
)
35 struct bz2_enc_data
*data
= mem_alloc(sizeof(*data
));
42 memset(data
, 0, sizeof(struct bz2_enc_data
) - ELINKS_BZ_BUFFER_LENGTH
);
47 err
= BZ2_bzDecompressInit(&data
->fbz_stream
, 0, 0);
59 bzip2_read(struct stream_encoded
*stream
, unsigned char *buf
, int len
)
61 struct bz2_enc_data
*data
= (struct bz2_enc_data
*) stream
->data
;
68 if (data
->last_read
) return 0;
70 data
->fbz_stream
.avail_out
= len
;
71 data
->fbz_stream
.next_out
= buf
;
74 if (data
->fbz_stream
.avail_in
== 0) {
75 int l
= safe_read(data
->fdread
, data
->buf
,
76 ELINKS_BZ_BUFFER_LENGTH
);
82 return -1; /* I/O error */
84 /* EOF. It is error: we wait for more bytes */
88 data
->fbz_stream
.next_in
= data
->buf
;
89 data
->fbz_stream
.avail_in
= l
;
92 err
= BZ2_bzDecompress(&data
->fbz_stream
);
93 if (err
== BZ_STREAM_END
) {
96 } else if (err
!= BZ_OK
) {
99 } while (data
->fbz_stream
.avail_out
> 0);
101 return len
- data
->fbz_stream
.avail_out
;
104 static unsigned char *
105 bzip2_decode(struct stream_encoded
*stream
, unsigned char *data
, int len
,
113 #define BZIP2_SMALL 1
115 #define BZIP2_SMALL 0
118 static unsigned char *
119 bzip2_decode_buffer(unsigned char *data
, int len
, int *new_len
)
122 unsigned char *buffer
= NULL
;
125 memset(&stream
, 0, sizeof(bz_stream
));
126 stream
.next_in
= data
;
127 stream
.avail_in
= len
;
129 if (BZ2_bzDecompressInit(&stream
, 0, BZIP2_SMALL
) != BZ_OK
)
133 unsigned char *new_buffer
;
134 size_t size
= stream
.total_out_lo32
+ MAX_STR_LEN
;
136 /* FIXME: support for 64 bit. real size is
138 * (total_in_hi32 << * 32) + total_in_lo32
141 assertm(!stream
.total_out_hi32
, "64 bzip2 decoding not supported");
143 new_buffer
= mem_realloc(buffer
, size
);
145 error
= BZ_MEM_ERROR
;
150 stream
.next_out
= buffer
+ stream
.total_out_lo32
;
151 stream
.avail_out
= MAX_STR_LEN
;
153 error
= BZ2_bzDecompress(&stream
);
154 if (error
== BZ_STREAM_END
) {
155 *new_len
= stream
.total_out_lo32
;
160 /* Apparently BZ_STREAM_END is not forced when the end of input
161 * is reached. At least lindi- reported that it caused a
162 * reproducable infinite loop. Maybe it has to do with decoding
163 * an incomplete file. */
164 } while (error
== BZ_OK
&& stream
.avail_in
> 0);
166 BZ2_bzDecompressEnd(&stream
);
168 if (error
!= BZ_OK
) {
169 if (buffer
) mem_free(buffer
);
178 bzip2_close(struct stream_encoded
*stream
)
180 struct bz2_enc_data
*data
= (struct bz2_enc_data
*) stream
->data
;
183 BZ2_bzDecompressEnd(&data
->fbz_stream
);
190 static unsigned char *bzip2_extensions
[] = { ".bz2", ".tbz", NULL
};
192 struct decoding_backend bzip2_decoding_backend
= {