]> cygwin.com Git - cygwin-apps/setup.git/blame - compress_bz.cc
Use solver to check for problems and produce a list of package transactions
[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
MB
21#include <stdexcept>
22using namespace std;
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;
b24c88b3
RC
38
39 initialisedOk = 0;
3e4ddc99 40 endReached = 0;
b24c88b3
RC
41 writing = 0;
42 strm.bzalloc = 0;
43 strm.bzfree = 0;
44 strm.opaque = 0;
45 int ret = BZ2_bzDecompressInit (&(strm), 0, 0);
46 if (ret)
47 {
48 lasterr = ret;
49 return;
50 }
51 strm.avail_in = 0;
52 strm.next_in = 0;
53 initialisedOk = 1;
54}
55
387cb501
RC
56ssize_t
57compress_bz::read (void *buffer, size_t len)
b24c88b3
RC
58{
59 if (!initialisedOk || writing)
30f42053
JT
60 {
61 lasterr = EBADF;
62 return -1;
63 }
3e4ddc99
JT
64 if (endReached)
65 return 0;
b24c88b3
RC
66 if (len == 0)
67 return 0;
68
69 if (peeklen)
92ef6cf8
BD
70 {
71 ssize_t tmplen = std::min (peeklen, len);
72 peeklen -= tmplen;
73 memcpy (buffer, peekbuf, tmplen);
74 memmove (peekbuf, peekbuf + tmplen, tmplen);
75 ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen);
76 if (tmpread >= 0)
b24c88b3 77 return tmpread + tmplen;
92ef6cf8 78 else
b24c88b3
RC
79 return tmpread;
80 }
fe9a0ef9 81
b24c88b3
RC
82 strm.avail_out = len;
83 strm.next_out = (char *) buffer;
92ef6cf8 84 int rlen = 1;
b24c88b3
RC
85 while (1)
86 {
fe9a0ef9
JT
87 int ret = BZ2_bzDecompress (&strm);
88
b24c88b3
RC
89 if (strm.avail_in == 0 && rlen > 0)
90 {
91 rlen = original->read (buf, 4096);
92 if (rlen < 0)
93 {
fe9a0ef9 94 lasterr = original->error ();
b24c88b3
RC
95 return -1;
96 }
b24c88b3
RC
97 strm.avail_in = rlen;
98 strm.next_in = buf;
99 }
fe9a0ef9 100
b24c88b3
RC
101 if (ret != BZ_OK && ret != BZ_STREAM_END)
102 {
103 lasterr = ret;
104 return -1;
105 }
106 if (ret == BZ_OK && rlen == 0 && strm.avail_out)
107 {
108 /* unexpected end of file */
109 lasterr = EIO;
110 return -1;
111 }
112 if (ret == BZ_STREAM_END)
387cb501 113 {
fe9a0ef9
JT
114 /* Are we also at EOF? */
115 if (rlen == 0)
116 {
117 endReached = 1;
118 }
119 else
120 {
121 /* BZ_SSTREAM_END but not at EOF means the file contains
122 another stream */
123 BZ2_bzDecompressEnd (&strm);
124 BZ2_bzDecompressInit (&(strm), 0, 0);
125 /* This doesn't reinitialize strm, so strm.next_in still
126 points at strm.avail_in bytes left to decompress in buf */
127 }
128
387cb501
RC
129 position += len - strm.avail_out;
130 return len - strm.avail_out;
131 }
b24c88b3 132 if (strm.avail_out == 0)
387cb501
RC
133 {
134 position += len;
135 return len;
136 }
b24c88b3
RC
137 }
138
139 /* not reached */
140 return 0;
141}
142
ca9506cc 143ssize_t compress_bz::write (const void *buffer, size_t len)
b24c88b3 144{
92ef6cf8 145 throw new logic_error ("compress_bz::write is not implemented");
b24c88b3
RC
146}
147
148ssize_t compress_bz::peek (void *buffer, size_t len)
149{
b24c88b3 150 if (writing)
92ef6cf8
BD
151 {
152 lasterr = EBADF;
b24c88b3 153 return -1;
92ef6cf8 154 }
30f42053 155
b24c88b3
RC
156 /* can only peek 512 bytes */
157 if (len > 512)
30f42053
JT
158 {
159 lasterr = ENOMEM;
160 return -1;
161 }
b24c88b3
RC
162
163 if (len > peeklen)
92ef6cf8
BD
164 {
165 size_t want = len - peeklen;
166 ssize_t got = read (&peekbuf[peeklen], want);
167 if (got >= 0)
168 peeklen += got;
169 else
170 /* error */
171 return got;
172
173 /* we may have read less than requested. */
174 memcpy (buffer, peekbuf, peeklen);
175 return peeklen;
176 }
b24c88b3 177 else
92ef6cf8
BD
178 {
179 memcpy (buffer, peekbuf, len);
180 return len;
181 }
b24c88b3
RC
182 return 0;
183}
184
185long
186compress_bz::tell ()
187{
387cb501 188 if (writing)
92ef6cf8
BD
189 throw new logic_error ("compress_bz::tell is not implemented "
190 "in writing mode");
387cb501 191 return position;
b24c88b3
RC
192}
193
ca9506cc
RC
194int
195compress_bz::seek (long where, io_stream_seek_t whence)
196{
92ef6cf8 197 throw new logic_error ("compress_bz::seek is not implemented");
ca9506cc
RC
198}
199
b24c88b3
RC
200int
201compress_bz::error ()
202{
c1754473 203 return lasterr;
b24c88b3
RC
204}
205
206int
26922cd2 207compress_bz::set_mtime (time_t time)
b24c88b3
RC
208{
209 if (original)
26922cd2 210 return original->set_mtime (time);
b24c88b3
RC
211 return 1;
212}
213
b41c2908 214time_t
b24c88b3
RC
215compress_bz::get_mtime ()
216{
217 if (original)
218 return original->get_mtime ();
219 return 0;
220}
221
b41c2908
CV
222mode_t
223compress_bz::get_mode ()
224{
225 if (original)
226 return original->get_mode ();
227 return 0;
228}
229
5bc84ff1
CW
230void
231compress_bz::release_original ()
232{
233 owns_original = false;
234}
235
b24c88b3
RC
236compress_bz::~compress_bz ()
237{
b24c88b3
RC
238 if (initialisedOk)
239 BZ2_bzDecompressEnd (&strm);
5bc84ff1 240 if (original && owns_original)
92ef6cf8 241 delete original;
b24c88b3 242}
This page took 0.095278 seconds and 5 git commands to generate.