root/branches/3.00/src/compress_bz.cc

Revision 644, 4.1 kB (checked in by fujii, 3 years ago)

Add new netinstall source.

Line 
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: compress_bz.cc,v 2.10 2004/11/18 01:19:09 maxb Exp $\n";
23 #endif
24
25 #include <algorithm>
26 #include "win32.h"
27 #include <stdio.h>
28 #include <errno.h>
29 #include "log.h"
30
31 #include "io_stream.h"
32 #include "compress.h"
33 #include "compress_bz.h"
34
35 compress_bz::compress_bz (io_stream * parent) : peeklen (0), position (0)
36 {
37   /* read only via this constructor */
38   original = 0;
39   lasterr = 0;
40   if (!parent || parent->error ())
41     {
42       lasterr = EBADF;
43       return;
44     }
45   original = parent;
46
47   initialisedOk = 0;
48   bufN = 0;
49   writing = 0;
50   strm.bzalloc = 0;
51   strm.bzfree = 0;
52   strm.opaque = 0;
53   int ret = BZ2_bzDecompressInit (&(strm), 0, 0);
54   if (ret)
55     {
56       lasterr = ret;
57       return;
58     }
59   strm.avail_in = 0;
60   strm.next_in = 0;
61   initialisedOk = 1;
62 }
63
64 ssize_t
65 compress_bz::read (void *buffer, size_t len)
66 {
67   if (!initialisedOk || writing)
68     return EBADF;
69   if (len == 0)
70     return 0;
71
72   if (peeklen)
73   {
74     ssize_t tmplen = std::min (peeklen, len);
75     peeklen -= tmplen;
76     memcpy (buffer, peekbuf, tmplen);
77     memmove (peekbuf, peekbuf + tmplen, tmplen);
78     ssize_t tmpread = read (&((char *) buffer)[tmplen], len - tmplen);
79     if (tmpread >= 0)
80         return tmpread + tmplen;
81     else
82         return tmpread;
83   }
84  
85   strm.avail_out = len;
86   strm.next_out = (char *) buffer;
87   int
88     rlen = 1;
89   while (1)
90     {
91       if (original->error ())
92         {
93           lasterr = original->error ();
94           return -1;
95         }
96       if (strm.avail_in == 0 && rlen > 0)
97         {
98           rlen = original->read (buf, 4096);
99           if (rlen < 0)
100             {
101               if (original->error())
102                 lasterr = original->error();
103               else
104                 lasterr = rlen;
105               return -1;
106             }
107           bufN = rlen;
108           strm.avail_in = rlen;
109           strm.next_in = buf;
110         }
111       int
112         ret = BZ2_bzDecompress (&strm);
113       if (ret != BZ_OK && ret != BZ_STREAM_END)
114         {
115           lasterr = ret;
116           return -1;
117         }
118       if (ret == BZ_OK && rlen == 0 && strm.avail_out)
119         {
120           /* unexpected end of file */
121           lasterr = EIO;
122           return -1;
123         }
124       if (ret == BZ_STREAM_END)
125         {
126           position += len - strm.avail_out;
127           return len - strm.avail_out;
128         }
129       if (strm.avail_out == 0)
130         {
131           position += len;
132           return len;
133         }
134     }
135
136   /* not reached */
137   return 0;
138 }
139
140 ssize_t compress_bz::write (const void *buffer, size_t len)
141 {
142   log (LOG_TIMESTAMP, "compress_bz::write called");
143   return 0;
144 }
145
146 ssize_t compress_bz::peek (void *buffer, size_t len)
147 {
148   if (writing)
149   {
150     lasterr = EBADF;
151       return -1;
152   }
153   /* can only peek 512 bytes */
154   if (len > 512)
155       return ENOMEM;
156
157   if (len > peeklen)
158       {
159             size_t want = len - peeklen;
160                 ssize_t got = read (&peekbuf[peeklen], want);
161                     if (got >= 0)
162                             peeklen += got;
163                         else
164                                 /* error */
165                                 return got;
166                             /* we may have read less than requested. */
167                             memcpy (buffer, peekbuf, peeklen);
168                                 return peeklen;
169                                   }
170   else
171       {
172             memcpy (buffer, peekbuf, len);
173                 return len;
174                   }
175   return 0;
176 }
177
178 long
179 compress_bz::tell ()
180 {
181   if (writing)
182     {
183       log (LOG_TIMESTAMP, "compress_bz::tell called for writing mode");
184       return 0;
185     }
186   return position;
187 }
188
189 int
190 compress_bz::seek (long where, io_stream_seek_t whence)
191 {
192     log (LOG_TIMESTAMP, "compress_bz::seek called");
193     return -1;
194 }
195
196 int
197 compress_bz::error ()
198 {
199   return lasterr;
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 }
Note: See TracBrowser for help on using the browser.