]> cygwin.com Git - cygwin-apps/setup.git/blob - compress_bz.cc
2002-07-15 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / compress_bz.cc
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
16 /* Archive IO operations for bz2 files.
17 derived from the fd convenience functions in the libbz2 package.
18 */
19
20 #if 0
21 static const char *cvsid =
22 "\n%%% $Id$\n";
23 #endif
24
25 #include "win32.h"
26 #include <stdio.h>
27 #include <errno.h>
28 #include "log.h"
29 #include "port.h"
30
31 #include "io_stream.h"
32 #include "compress.h"
33 #include "compress_bz.h"
34 #undef _WIN32
35 #include "bzlib.h"
36
37 compress_bz::compress_bz (io_stream * parent) : peeklen (0), position (0)
38 {
39 /* read only via this constructor */
40 original = 0;
41 lasterr = 0;
42 if (!parent || parent->error ())
43 {
44 lasterr = EBADF;
45 return;
46 }
47 original = parent;
48
49 initialisedOk = 0;
50 bufN = 0;
51 writing = 0;
52 strm.bzalloc = 0;
53 strm.bzfree = 0;
54 strm.opaque = 0;
55 int ret = BZ2_bzDecompressInit (&(strm), 0, 0);
56 if (ret)
57 {
58 lasterr = ret;
59 return;
60 }
61 strm.avail_in = 0;
62 strm.next_in = 0;
63 initialisedOk = 1;
64 }
65
66 ssize_t
67 compress_bz::read (void *buffer, size_t len)
68 {
69 if (!initialisedOk || writing)
70 return EBADF;
71 if (len == 0)
72 return 0;
73
74 if (peeklen)
75 {
76 ssize_t tmplen = 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)
82 return tmpread + tmplen;
83 else
84 return tmpread;
85 }
86
87 strm.avail_out = len;
88 strm.next_out = (char *) buffer;
89 int
90 rlen = 1;
91 while (1)
92 {
93 if (original->error ())
94 {
95 lasterr = original->error ();
96 return -1;
97 }
98 if (strm.avail_in == 0 && rlen > 0)
99 {
100 rlen = original->read (buf, 4096);
101 if (rlen < 0)
102 {
103 lasterr = rlen;
104 return -1;
105 }
106 bufN = rlen;
107 strm.avail_in = rlen;
108 strm.next_in = buf;
109 }
110 int
111 ret = BZ2_bzDecompress (&strm);
112 if (ret != BZ_OK && ret != BZ_STREAM_END)
113 {
114 lasterr = ret;
115 return -1;
116 }
117 if (ret == BZ_OK && rlen == 0 && strm.avail_out)
118 {
119 /* unexpected end of file */
120 lasterr = EIO;
121 return -1;
122 }
123 if (ret == BZ_STREAM_END)
124 {
125 position += len - strm.avail_out;
126 return len - strm.avail_out;
127 }
128 if (strm.avail_out == 0)
129 {
130 position += len;
131 return len;
132 }
133 }
134
135 /* not reached */
136 return 0;
137 }
138
139 ssize_t compress_bz::write (const void *buffer, size_t len)
140 {
141 log (LOG_TIMESTAMP, "compress_bz::write called");
142 return 0;
143 }
144
145 ssize_t compress_bz::peek (void *buffer, size_t len)
146 {
147 if (writing)
148 {
149 lasterr = EBADF;
150 return -1;
151 }
152 /* can only peek 512 bytes */
153 if (len > 512)
154 return ENOMEM;
155
156 if (len > peeklen)
157 {
158 size_t want = len - peeklen;
159 ssize_t got = read (&peekbuf[peeklen], want);
160 if (got >= 0)
161 peeklen += got;
162 else
163 /* error */
164 return got;
165 /* we may have read less than requested. */
166 memcpy (buffer, peekbuf, peeklen);
167 return peeklen;
168 }
169 else
170 {
171 memcpy (buffer, peekbuf, len);
172 return len;
173 }
174 return 0;
175 }
176
177 long
178 compress_bz::tell ()
179 {
180 if (writing)
181 {
182 log (LOG_TIMESTAMP, "compress_bz::tell called for writing mode");
183 return 0;
184 }
185 return position;
186 }
187
188 int
189 compress_bz::seek (long where, io_stream_seek_t whence)
190 {
191 log (LOG_TIMESTAMP, "compress_bz::seek called");
192 return -1;
193 }
194
195 int
196 compress_bz::error ()
197 {
198 log (LOG_TIMESTAMP, "compress_bz::error called");
199 return 0;
200 }
201
202 int
203 compress_bz::set_mtime (int time)
204 {
205 if (original)
206 return original->set_mtime (time);
207 return 1;
208 }
209
210 int
211 compress_bz::get_mtime ()
212 {
213 if (original)
214 return original->get_mtime ();
215 return 0;
216 }
217
218 compress_bz::~compress_bz ()
219 {
220 if (initialisedOk)
221 BZ2_bzDecompressEnd (&strm);
222 destroyed = 1;
223 return;
224 }
This page took 0.043831 seconds and 5 git commands to generate.