2 * Copyright (c) 2001, Robert Collins.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
16 /* Archive IO operations for bz2 files. Derived from the fd convenience
17 functions in the libbz2 package. */
19 #include "compress_bz.h"
26 compress_bz::compress_bz (io_stream
* parent
) : peeklen (0), position (0)
28 /* read only via this constructor */
31 if (!parent
|| parent
->error ())
42 compress_bz::init_state(void)
50 int ret
= BZ2_bzDecompressInit (&(strm
), 0, 0);
62 compress_bz::read (void *buffer
, size_t len
)
64 if (!initialisedOk
|| writing
)
76 ssize_t tmplen
= std::min (peeklen
, len
);
78 memcpy (buffer
, peekbuf
, tmplen
);
79 memmove (peekbuf
, peekbuf
+ tmplen
, tmplen
);
80 ssize_t tmpread
= read (&((char *) buffer
)[tmplen
], len
- tmplen
);
82 return tmpread
+ tmplen
;
88 strm
.next_out
= (char *) buffer
;
92 int ret
= BZ2_bzDecompress (&strm
);
94 if (strm
.avail_in
== 0 && rlen
> 0)
96 rlen
= original
->read (buf
, 4096);
99 lasterr
= original
->error ();
102 strm
.avail_in
= rlen
;
106 if (ret
!= BZ_OK
&& ret
!= BZ_STREAM_END
)
111 if (ret
== BZ_OK
&& rlen
== 0 && strm
.avail_out
)
113 /* unexpected end of file */
117 if (ret
== BZ_STREAM_END
)
119 /* Are we also at EOF? */
126 /* BZ_SSTREAM_END but not at EOF means the file contains
128 BZ2_bzDecompressEnd (&strm
);
129 BZ2_bzDecompressInit (&(strm
), 0, 0);
130 /* This doesn't reinitialize strm, so strm.next_in still
131 points at strm.avail_in bytes left to decompress in buf */
134 position
+= len
- strm
.avail_out
;
135 return len
- strm
.avail_out
;
137 if (strm
.avail_out
== 0)
148 ssize_t
compress_bz::write (const void *buffer
, size_t len
)
150 throw new std::logic_error ("compress_bz::write is not implemented");
153 ssize_t
compress_bz::peek (void *buffer
, size_t len
)
161 /* can only peek 512 bytes */
170 size_t want
= len
- peeklen
;
171 ssize_t got
= read (&peekbuf
[peeklen
], want
);
178 /* we may have read less than requested. */
179 memcpy (buffer
, peekbuf
, peeklen
);
184 memcpy (buffer
, peekbuf
, len
);
194 throw new std::logic_error ("compress_bz::tell is not implemented "
200 compress_bz::seek (off_t where
, io_stream_seek_t whence
)
202 if ((whence
== IO_SEEK_SET
) && (where
== 0))
204 off_t result
= original
->seek(where
, whence
);
209 throw new std::logic_error ("compress_bz::seek is not implemented");
213 compress_bz::error ()
219 compress_bz::set_mtime (time_t time
)
222 return original
->set_mtime (time
);
227 compress_bz::get_mtime ()
230 return original
->get_mtime ();
235 compress_bz::get_mode ()
238 return original
->get_mode ();
243 compress_bz::release_original ()
245 owns_original
= false;
248 compress_bz::~compress_bz ()
251 BZ2_bzDecompressEnd (&strm
);
252 if (original
&& owns_original
)