87e544fee3fce8cf2a94a655ed961dd2b9296e96
[jigdo.git] / src / zstream-gz.hh
1 /* $Id: zstream-gz.hh,v 1.5 2005/04/09 23:09:52 atterer Exp $ -*- C++ -*-
2   __   _
3   |_) /|  Copyright (C) 2004-2005  |  richard@
4   | \/¯|  Richard Atterer          |  atterer.org
5   ¯ '` ¯
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License, version 2. See
8   the file COPYING for details.
9
10 *//** @file
11
12   zlib (gzip-style) compression and decompression for zstream
13
14 */
15
16 #ifndef ZSTREAM_GZ_HH
17 #define ZSTREAM_GZ_HH
18
19 #include <config.h>
20
21 #include <zlib.h>
22
23 #include <log.hh>
24 #include <zstream.hh>
25 //______________________________________________________________________
26
27 struct ZerrorGz : public Zerror {
28   ZerrorGz(int s, const string& m) : Zerror(s, m) { }
29   int status;
30 };
31 //______________________________________________________________________
32
33 class ZobstreamGz : public Zobstream {
34 public:
35   inline ZobstreamGz(bostream& s, unsigned chunkLimit,
36                      int level = Z_DEFAULT_COMPRESSION, int windowBits = 15,
37                      int memLevel = 8, unsigned todoBufSz = 256U,
38                      MD5Sum* md = 0);
39   ~ZobstreamGz() { Assert(memReleased); }
40
41   /** @param s Output stream
42       @param chunkLimit Size limit for output data, will buffer this much
43       @param level 0 to 9
44       @param windowBits zlib param
45       @param memLevel zlib param
46       @param todoBufSz Size of mini buffer, which holds data sent to
47       the stream with single put() calls or << statements */
48   void open(bostream& s, unsigned chunkLimit, int level =Z_DEFAULT_COMPRESSION,
49             int windowBits = 15, int memLevel = 8, unsigned todoBufSz = 256U);
50
51 protected:
52   virtual unsigned partId();
53   virtual void deflateEnd();
54   virtual void deflateReset();
55   virtual unsigned totalOut() const { return z.total_out; }
56   virtual unsigned totalIn() const { return z.total_in; }
57   virtual unsigned availOut() const { return z.avail_out; }
58   virtual unsigned availIn() const { return z.avail_in; }
59   virtual byte* nextOut() const { return z.next_out; }
60   virtual byte* nextIn() const { return z.next_in; }
61   virtual void setTotalOut(unsigned n) { z.total_out = n; }
62   virtual void setTotalIn(unsigned n) { z.total_in = n; }
63   virtual void setAvailOut(unsigned n) { z.avail_out = n; }
64   virtual void setAvailIn(unsigned n) { z.avail_in = n; }
65   virtual void setNextOut(byte* n) { z.next_out = n; }
66   virtual void setNextIn(byte* n) { z.next_in = n; }
67   virtual void zip2(byte* start, unsigned len, bool finish = false);
68
69 private:
70   // Throw a Zerror exception, or bad_alloc() for status==Z_MEM_ERROR
71 //   inline void throwZerror(int status, const char* zmsg);
72
73   z_stream z;
74   // To keep track in the dtor whether deflateEnd() has been called
75   bool memReleased;
76 };
77 //______________________________________________________________________
78
79 class ZibstreamGz : public Zibstream::Impl {
80 public:
81
82   class ZibstreamGzError : public Zerror {
83   public:
84     ZibstreamGzError(int s, const string& m) : Zerror(s, m) { }
85   };
86
87   ZibstreamGz() : status(0), memReleased(true) { }
88   ~ZibstreamGz() { Assert(memReleased); }
89
90   virtual unsigned totalOut() const { return z.total_out; }
91   virtual unsigned totalIn() const { return z.total_in; }
92   virtual unsigned availOut() const { return z.avail_out; }
93   virtual unsigned availIn() const { return z.avail_in; }
94   virtual byte* nextOut() const { return z.next_out; }
95   virtual byte* nextIn() const { return z.next_in; }
96   virtual void setTotalOut(unsigned n) { z.total_out = n; }
97   virtual void setTotalIn(unsigned n) { z.total_in = n; }
98   virtual void setAvailIn(unsigned n) { z.avail_in = n; }
99   virtual void setNextIn(byte* n) { z.next_in = n; }
100
101   virtual void init() {
102     //memset(&z, 0, sizeof(z));
103     z.zalloc = (alloc_func)0;
104     z.zfree = (free_func)0;
105     z.opaque = 0;
106     status = inflateInit(&z);
107     if (ok()) memReleased = false;
108   }
109   virtual void end() { status = inflateEnd(&z); memReleased = true; }
110   virtual void reset() { status = inflateReset(&z); }
111
112   virtual void inflate(byte** nextOut, unsigned* availOut) {
113     z.next_out = *nextOut; z.avail_out = *availOut;
114     status = ::inflate(&z, Z_NO_FLUSH);
115     *nextOut = z.next_out; *availOut = z.avail_out;
116   }
117   virtual bool streamEnd() const { return status == Z_STREAM_END; }
118   virtual bool ok() const { return status == Z_OK; }
119
120   virtual void throwError() const { throw ZibstreamGzError(status, z.msg); }
121 private:
122   int status;
123   z_stream z;
124   // To keep track in the dtor whether deflateEnd() has been called
125   bool memReleased;
126 };
127 //======================================================================
128
129 ZobstreamGz::ZobstreamGz(bostream& s, unsigned chunkLimit, int level,
130                          int windowBits, int memLevel, unsigned todoBufSz,
131                          MD5Sum* md) : Zobstream(md), memReleased(true) {
132   z.zalloc = (alloc_func)0;
133   z.zfree = (free_func)0;
134   z.opaque = 0;
135   open(s, chunkLimit, level, windowBits, memLevel, todoBufSz);
136 }
137
138 #endif