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