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