jigdo API
Last update by Admin on 2010-05-23
zstream.hh
Go to the documentation of this file.00001 /* $Id: zstream.hh,v 1.22 2003/03/03 20:47:18 richard Exp $ -*- C++ -*- 00002 __ _ 00003 |_) /| Copyright (C) 2001-2005 | richard@ 00004 | \/¯| Richard Atterer | atterer.net 00005 ¯ '` ¯ 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License, version 2. See 00008 the file COPYING for details. 00009 00010 */ 00022 #ifndef ZSTREAM_HH 00023 #define ZSTREAM_HH 00024 00025 #include <config.h> 00026 00027 #include <iostream> 00028 00029 #include <bstream.hh> 00030 #include <config.h> 00031 #include <debug.hh> 00032 #include <md5sum.fh> 00033 #include <zstream.fh> 00034 //______________________________________________________________________ 00035 00038 struct Zerror : Error { 00039 Zerror(int s, const string& m) : Error(m), status(s) { } 00040 int status; 00041 }; 00042 00054 class Zobstream { 00055 public: 00056 00057 inline explicit Zobstream(MD5Sum* md = 0); 00060 virtual ~Zobstream() { close(); delete zipBuf; Assert(todoBuf == 0); } 00061 bool is_open() const { return stream != 0; } 00063 void close(); 00064 00066 bostream& getStream() { return *stream; } 00067 00069 inline Zobstream& put(unsigned char x); 00070 inline Zobstream& put(signed char x); 00072 inline Zobstream& put(int x); 00073 inline Zobstream& put(char x); 00075 Zobstream& put(uint32 x); 00076 /* Output n characters */ 00077 // inline Zobstream& write(const char* x, size_t n); 00078 // inline Zobstream& write(const signed char* x, size_t n); 00079 // Zobstream& write(const unsigned char* x, size_t n); 00080 // inline Zobstream& write(const void* x, size_t n); 00081 inline Zobstream& write(const byte* x, unsigned n); 00082 00083 protected: 00084 static const unsigned ZIPDATA_SIZE = 64*1024; 00085 00086 // Child classes must call this when their open() is called 00087 inline void open(bostream& s, unsigned chunkLimit, unsigned todoBufSz); 00088 unsigned chunkLim() const { return chunkLimVal; } 00089 // Write data in zipBuf 00090 void writeZipped(unsigned partId); 00091 00092 virtual void deflateEnd() = 0; // May throw Zerror 00093 virtual void deflateReset() = 0; // May throw Zerror 00094 00095 virtual unsigned totalOut() const = 0; 00096 virtual unsigned totalIn() const = 0; 00097 virtual unsigned availOut() const = 0; 00098 virtual unsigned availIn() const = 0; 00099 virtual byte* nextOut() const = 0; 00100 virtual byte* nextIn() const = 0; 00101 virtual void setTotalOut(unsigned n) = 0; 00102 virtual void setTotalIn(unsigned n) = 0; 00103 virtual void setAvailOut(unsigned n) = 0; 00104 virtual void setAvailIn(unsigned n) = 0; 00105 virtual void setNextOut(byte* n) = 0; 00106 virtual void setNextIn(byte* n) = 0; 00107 00108 virtual void zip2(byte* start, unsigned len, bool finish) = 0; 00109 00110 /* Compressed data is stored in a linked list of ZipData objects. 00111 During the Zobstream object's lifetime, the list is only ever 00112 added to, never shortened. */ 00113 struct ZipData { 00114 ZipData() : next(0) { } 00115 ~ZipData() { delete next; } 00116 ZipData* next; 00117 byte data[ZIPDATA_SIZE]; 00118 }; 00119 ZipData* zipBuf; // Start of linked list 00120 ZipData* zipBufLast; // Last link 00121 00122 private: 00123 static const unsigned MIN_TODOBUF_SIZE = 256; 00124 00125 // // Throw a Zerror exception, or bad_alloc() for status==Z_MEM_ERROR 00126 // inline void throwZerror(int status, const char* zmsg); 00127 // Pipe contents of todoBuf through zlib into zipBuf 00128 // void zip(byte* start, unsigned len, int flush = Z_NO_FLUSH); 00129 inline void zip(byte* start, unsigned len, bool finish = false); 00130 00131 //z_stream z; 00132 byte* todoBuf; // Allocated during open(), deallocated during close() 00133 unsigned todoBufSize; // Size of todoBuf 00134 unsigned todoCount; // Offset of 1st unused byte in todoBuf 00135 00136 bostream* stream; 00137 00138 unsigned chunkLimVal; 00139 00140 MD5Sum* md5sum; 00141 }; 00142 //______________________________________________________________________ 00143 00147 class Zibstream { 00148 public: 00149 00151 class Impl { 00152 public: 00153 virtual ~Impl() { } 00154 00155 virtual unsigned totalOut() const = 0; 00156 virtual unsigned totalIn() const = 0; 00157 virtual unsigned availOut() const = 0; 00158 virtual unsigned availIn() const = 0; 00159 virtual byte* nextOut() const = 0; 00160 virtual byte* nextIn() const = 0; 00161 virtual void setTotalOut(unsigned n) = 0; 00162 virtual void setTotalIn(unsigned n) = 0; 00163 virtual void setAvailIn(unsigned n) = 0; 00164 virtual void setNextIn(byte* n) = 0; 00165 00168 virtual void init() = 0; 00170 virtual void end() = 0; 00172 virtual void reset() = 0; 00173 00175 virtual void inflate(byte** nextOut, unsigned* availOut) = 0; 00177 virtual bool streamEnd() const = 0; 00179 virtual bool ok() const = 0; 00180 00183 virtual void throwError() const = 0; /* throws Zerror */ 00184 }; 00185 //________________________________________ 00186 00187 inline explicit Zibstream(unsigned bufSz = 64*1024); 00190 virtual ~Zibstream() { close(); delete buf; if (z != 0) z->end(); delete z; } 00191 inline Zibstream(bistream& s, unsigned bufSz = 64*1024); 00192 bool is_open() const { return stream != 0; } 00193 void close(); 00194 00196 bistream& getStream() { return *stream; } 00197 00199 // inline Zibstream& get(unsigned char& x); 00200 // inline Zibstream& get(signed char& x); 00202 //Zibstream& get(uint32 x); 00204 // inline Zibstream& read(const char* x, size_t n); 00205 // inline Zibstream& read(const signed char* x, size_t n); 00206 // Zibstream& read(const unsigned char* x, size_t n); 00207 // inline Zibstream& read(const void* x, size_t n); 00208 Zibstream& read(byte* x, unsigned n); 00209 typedef uint64 streamsize; 00211 inline streamsize gcount() const { 00212 streamsize n = gcountVal; gcountVal = 0; return n; 00213 } 00214 00215 bool good() const { return is_open() && buf != 0; } 00216 bool eof() const { return dataUnc == 0; } 00217 bool fail() const { return !good(); } 00218 bool bad() const { return false; } 00219 operator void*() const { return fail() ? (void*)0 : (void*)(-1); } 00220 bool operator!() const { return fail(); } 00221 00222 00223 private: 00224 // Throw a Zerror exception, or bad_alloc() for status==Z_MEM_ERROR 00225 //inline void throwZerror(int status, const char* zmsg); 00226 00227 static const unsigned DATA = 0x41544144u; 00228 static const unsigned BZIP = 0x50495a42u; 00229 00230 void open(bistream& s); 00231 00232 // z_stream z; 00233 Impl* z; 00234 bistream* stream; 00235 mutable streamsize gcountVal; 00236 unsigned bufSize; 00237 byte* buf; // Contains compressed data 00238 uint64 dataLen; // bytes remaining to be read from current DATA part 00239 uint64 dataUnc; // bytes remaining in uncompressed DATA part 00240 byte* nextOut; // Pointer into output buffer 00241 unsigned availOut; // Bytes remaining in output buffer 00242 }; 00243 //______________________________________________________________________ 00244 00245 /* Initialising todoBufSize and todoCount in this way allows us to 00246 move Assert(is_open) out of the inline functions and into zip() for 00247 calls to put() and write() */ 00248 Zobstream::Zobstream(MD5Sum* md) 00249 : zipBuf(0), zipBufLast(0), todoBuf(0), todoBufSize(0), todoCount(0), 00250 stream(0), md5sum(md) { } 00251 //________________________________________ 00252 00253 void Zobstream::open(bostream& s, unsigned chunkLimit, unsigned todoBufSz) { 00254 Assert(!is_open()); 00255 todoBufSize = (MIN_TODOBUF_SIZE > todoBufSz ? MIN_TODOBUF_SIZE :todoBufSz); 00256 chunkLimVal = chunkLimit; 00257 00258 todoCount = 0; 00259 todoBuf = new byte[todoBufSize]; 00260 00261 stream = &s; // Declare as open 00262 Paranoid(stream != 0); 00263 } 00264 00265 void Zobstream::zip(byte* start, unsigned len, bool finish) { 00266 if (len != 0 || finish) 00267 zip2(start, len, finish); 00268 todoCount = 0; 00269 } 00270 //________________________________________ 00271 00272 Zobstream& Zobstream::put(unsigned char x) { 00273 if (todoCount >= todoBufSize) zip(todoBuf, todoCount); 00274 todoBuf[todoCount] = static_cast<byte>(x); 00275 ++todoCount; 00276 return *this; 00277 } 00278 00279 Zobstream& Zobstream::put(signed char x) { 00280 if (todoCount >= todoBufSize) zip(todoBuf, todoCount); 00281 todoBuf[todoCount] = static_cast<byte>(x); 00282 ++todoCount; 00283 return *this; 00284 } 00285 00286 Zobstream& Zobstream::put(char x) { 00287 if (todoCount >= todoBufSize) zip(todoBuf, todoCount); 00288 todoBuf[todoCount] = static_cast<byte>(x); 00289 ++todoCount; 00290 return *this; 00291 } 00292 00293 Zobstream& Zobstream::put(int x) { 00294 if (todoCount >= todoBufSize) zip(todoBuf, todoCount); 00295 todoBuf[todoCount] = static_cast<byte>(x); 00296 ++todoCount; 00297 return *this; 00298 } 00299 00300 Zobstream& Zobstream::write(const byte* x, unsigned n) { 00301 Assert(is_open()); 00302 if (n > 0) { 00303 zip(todoBuf, todoCount); // Zip remaining data in todoBuf 00304 zip(const_cast<byte*>(x), n); // Zip byte array 00305 } 00306 return *this; 00307 } 00308 //________________________________________ 00309 00310 Zibstream::Zibstream(unsigned bufSz) 00311 : z(0), stream(0), bufSize(bufSz), buf(0) { 00312 } 00313 00314 Zibstream::Zibstream(bistream& s, unsigned bufSz) 00315 : z(0), stream(0), bufSize(bufSz), buf(0) { 00316 // data* will be init'ed by open() 00317 open(s); 00318 } 00319 00320 #endif
Generated on Tue Sep 23 14:27:42 2008 for jigdo by
