1 /* This file is part of Cinaest.
3 * Copyright (C) 2009 Philipp Zabel
5 * Cinaest is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Cinaest is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
22 class GzipInputStream : FilterInputStream {
24 const int CHUNK = 256*1024;
27 public uchar[] buf_in;
29 public GzipInputStream (GLib.InputStream _base_stream) {
30 Object (base_stream: _base_stream);
31 strm = InflateStream.full (15 | 32);
35 buf_in = new uchar[CHUNK];
38 public async override ssize_t read_async (void *buffer, size_t count, int io_priority, Cancellable? cancellable) throws Error {
42 if (strm.avail_in == 0) {
43 n = yield base_stream.read_async (buf_in, CHUNK, io_priority, cancellable);
44 strm.avail_in = (uint) n;
45 if (strm.avail_in == 0)
47 strm.next_in = buf_in;
50 strm.avail_out = (int) count;
51 strm.next_out = buffer;
53 ret = strm.inflate (Flush.NO_FLUSH);
54 assert (ret != Status.STREAM_ERROR);
55 if (ret == Status.NEED_DICT)
56 ret = Status.DATA_ERROR;
58 case Status.DATA_ERROR:
59 case Status.MEM_ERROR:
60 throw new IOError.FAILED("Error in gzip stream");
63 return (ssize_t) count - strm.avail_out;
66 public override ssize_t read_fn (void *buffer, size_t count, Cancellable? cancellable) throws Error {
69 if (strm.avail_in == 0) {
70 strm.avail_in = (int) base_stream.read (buf_in, CHUNK, cancellable);
71 if (strm.avail_in == 0)
73 strm.next_in = buf_in;
76 strm.avail_out = (int) count;
77 strm.next_out = buffer;
79 ret = strm.inflate (Flush.NO_FLUSH);
80 assert (ret != Status.STREAM_ERROR);
81 if (ret == Status.NEED_DICT)
82 ret = Status.DATA_ERROR;
84 case Status.DATA_ERROR:
85 case Status.MEM_ERROR:
89 return (ssize_t) count - strm.avail_out;
92 public ulong total_in () {