]> cygwin.com Git - cygwin-apps/setup.git/blame - compress_bz.cc
Suggest URLs for updated setup based on build architecture
[cygwin-apps/setup.git] / compress_bz.cc
CommitLineData
b24c88b3
RC
1/*
2 * Copyright (c) 2001, Robert Collins.
3 *
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.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
92ef6cf8
BD
16/* Archive IO operations for bz2 files. Derived from the fd convenience
17 functions in the libbz2 package. */
b24c88b3 18
b24c88b3 19#include "compress_bz.h"
b24c88b3 20
b16e07fc 21#include <stdexcept>
155eacb6 22
b16e07fc 23#include <errno.h>
a2651d16 24#include <string.h>
b16e07fc 25
387cb501 26compress_bz::compress_bz (io_stream * parent) : peeklen (0), position (0)
b24c88b3
RC
27{
28 /* read only via this constructor */
29 original = 0;
30 lasterr = 0;
31 if (!parent || parent->error ())
32 {
33 lasterr = EBADF;
34 return;
35 }
36 original = parent;
5bc84ff1 37 owns_original = true;
840e95c1
JT
38 init_state();
39}
b24c88b3 40
840e95c1
JT
41void
42compress_bz::init_state(void)
43{
b24c88b3 44 initialisedOk = 0;
3e4ddc99 45 endReached = 0;
b24c88b3
RC
46 writing = 0;
47 strm.bzalloc = 0;
48 strm.bzfree = 0;
49 strm.opaque = 0;
50 int ret = BZ2_bzDecompressInit (&(strm), 0, 0);
51 if (ret)
52 {
53 lasterr = ret;
54 return;
55 }
56 strm.avail_in = 0;
57 strm.next_in = 0;
58 initialisedOk = 1;
59}
60
387cb501
RC
61ssize_t
62compress_bz::read (void *buffer, size_t len)
b24c88b3
RC
63{
64 if (!initialisedOk || writing)
30f42053
JT
65 {
66 lasterr = EBADF;
67 return -1;
68 }
3e4ddc99
JT
69 if (endReached)
70 return 0;
b24c88b3
RC
71 if (len == 0)
72 return 0;
73
74 if (peeklen)
92ef6cf8
BD
75 {
76 ssize_t tmplen = std::min (peeklen, len);
77 peeklen -= tmplen;
78 memcpy (buffer, peekbuf, tmplen);
79 memmove (peekbuf, peekbuf + tmplen, tmplen);
80 ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen);
81 if (tmpread >= 0)
b24c88b3 82 return tmpread + tmplen;
92ef6cf8 83 else
b24c88b3
RC
84 return tmpread;
85 }
fe9a0ef9 86
b24c88b3
RC
87 strm.avail_out = len;
88 strm.next_out = (char *) buffer;
92ef6cf8 89 int rlen = 1;
b24c88b3
RC
90 while (1)
91 {
fe9a0ef9
JT
92 int ret = BZ2_bzDecompress (&strm);
93
b24c88b3
RC
94 if (strm.avail_in == 0 && rlen > 0)
95 {
96 rlen = original->read (buf, 4096);
97 if (rlen < 0)
98 {
fe9a0ef9 99 lasterr = original->error ();
b24c88b3
RC
100 return -1;
101 }
b24c88b3
RC
102 strm.avail_in = rlen;
103 strm.next_in = buf;
104 }
fe9a0ef9 105
b24c88b3
RC
106 if (ret != BZ_OK && ret != BZ_STREAM_END)
107 {
108 lasterr = ret;
109 return -1;
110 }
111 if (ret == BZ_OK && rlen == 0 && strm.avail_out)
112 {
113 /* unexpected end of file */
114 lasterr = EIO;
115 return -1;
116 }
117 if (ret == BZ_STREAM_END)
387cb501 118 {
fe9a0ef9
JT
119 /* Are we also at EOF? */
120 if (rlen == 0)
121 {
122 endReached = 1;
123 }
124 else
125 {
126 /* BZ_SSTREAM_END but not at EOF means the file contains
127 another stream */
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 */
132 }
133
387cb501
RC
134 position += len - strm.avail_out;
135 return len - strm.avail_out;
136 }
b24c88b3 137 if (strm.avail_out == 0)
387cb501
RC
138 {
139 position += len;
140 return len;
141 }
b24c88b3
RC
142 }
143
144 /* not reached */
145 return 0;
146}
147
ca9506cc 148ssize_t compress_bz::write (const void *buffer, size_t len)
b24c88b3 149{
155eacb6 150 throw new std::logic_error ("compress_bz::write is not implemented");
b24c88b3
RC
151}
152
153ssize_t compress_bz::peek (void *buffer, size_t len)
154{
b24c88b3 155 if (writing)
92ef6cf8
BD
156 {
157 lasterr = EBADF;
b24c88b3 158 return -1;
92ef6cf8 159 }
30f42053 160
b24c88b3
RC
161 /* can only peek 512 bytes */
162 if (len > 512)
30f42053
JT
163 {
164 lasterr = ENOMEM;
165 return -1;
166 }
b24c88b3
RC
167
168 if (len > peeklen)
92ef6cf8
BD
169 {
170 size_t want = len - peeklen;
171 ssize_t got = read (&peekbuf[peeklen], want);
172 if (got >= 0)
173 peeklen += got;
174 else
175 /* error */
176 return got;
177
178 /* we may have read less than requested. */
179 memcpy (buffer, peekbuf, peeklen);
180 return peeklen;
181 }
b24c88b3 182 else
92ef6cf8
BD
183 {
184 memcpy (buffer, peekbuf, len);
185 return len;
186 }
b24c88b3
RC
187 return 0;
188}
189
44d31ea0 190off_t
b24c88b3
RC
191compress_bz::tell ()
192{
387cb501 193 if (writing)
155eacb6
AG
194 throw new std::logic_error ("compress_bz::tell is not implemented "
195 "in writing mode");
387cb501 196 return position;
b24c88b3
RC
197}
198
44d31ea0
CV
199off_t
200compress_bz::seek (off_t where, io_stream_seek_t whence)
ca9506cc 201{
840e95c1
JT
202 if ((whence == IO_SEEK_SET) && (where == 0))
203 {
44d31ea0 204 off_t result = original->seek(where, whence);
840e95c1
JT
205 init_state();
206 return result;
207 }
208
155eacb6 209 throw new std::logic_error ("compress_bz::seek is not implemented");
ca9506cc
RC
210}
211
b24c88b3
RC
212int
213compress_bz::error ()
214{
c1754473 215 return lasterr;
b24c88b3
RC
216}
217
218int
26922cd2 219compress_bz::set_mtime (time_t time)
b24c88b3
RC
220{
221 if (original)
26922cd2 222 return original->set_mtime (time);
b24c88b3
RC
223 return 1;
224}
225
b41c2908 226time_t
b24c88b3
RC
227compress_bz::get_mtime ()
228{
229 if (original)
230 return original->get_mtime ();
231 return 0;
232}
233
b41c2908
CV
234mode_t
235compress_bz::get_mode ()
236{
237 if (original)
238 return original->get_mode ();
239 return 0;
240}
241
5bc84ff1
CW
242void
243compress_bz::release_original ()
244{
245 owns_original = false;
246}
247
b24c88b3
RC
248compress_bz::~compress_bz ()
249{
b24c88b3
RC
250 if (initialisedOk)
251 BZ2_bzDecompressEnd (&strm);
5bc84ff1 252 if (original && owns_original)
92ef6cf8 253 delete original;
b24c88b3 254}
This page took 0.164375 seconds and 6 git commands to generate.