source: box/trunk/lib/compress/Compress.h @ 2127

Revision 2127, 4.6 KB checked in by chris, 4 years ago (diff)

Undo mangling by tailor

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    Compress.h
5//              Purpose: Interface to zlib compression
6//              Created: 5/12/03
7//
8// --------------------------------------------------------------------------
9
10#ifndef COMPRESSCONTEXT__H
11#define COMPRESSCONTEXT__H
12
13#include <zlib.h>
14
15#include "CompressException.h"
16
17// --------------------------------------------------------------------------
18//
19// Class
20//              Name:    Compress
21//              Purpose: Interface to zlib compression, only very slight wrapper.
22//                               (Use CompressStream for a more friendly interface.)
23//              Created: 5/12/03
24//
25// --------------------------------------------------------------------------
26template<bool Compressing>
27class Compress
28{
29public:
30        Compress()
31                : mFinished(false),
32                  mFlush(Z_NO_FLUSH)
33        {       
34                // initialise stream
35                mStream.zalloc = Z_NULL;
36                mStream.zfree = Z_NULL;
37                mStream.opaque = Z_NULL;
38                mStream.data_type = Z_BINARY;
39
40                if((Compressing)?(deflateInit(&mStream, Z_DEFAULT_COMPRESSION))
41                        :(inflateInit(&mStream)) != Z_OK)
42                {
43                        THROW_EXCEPTION(CompressException, InitFailed)
44                }
45               
46                mStream.avail_in = 0;
47        }
48       
49        ~Compress()
50        {
51                int r = 0;
52                if((r = ((Compressing)?(deflateEnd(&mStream))
53                        :(inflateEnd(&mStream)))) != Z_OK)
54                {
55                        BOX_WARNING("zlib error code = " << r);
56                        if(r == Z_DATA_ERROR)
57                        {
58                                BOX_WARNING("End of compress/decompress "
59                                        "without all input being consumed, "
60                                        "possible corruption?");
61                        }
62                        else
63                        {
64                                THROW_EXCEPTION(CompressException, EndFailed)
65                        }
66                }
67        }
68               
69        // --------------------------------------------------------------------------
70        //
71        // Function
72        //              Name:    Compress<Function>::InputRequired()
73        //              Purpose: Input required yet?
74        //              Created: 5/12/03
75        //
76        // --------------------------------------------------------------------------
77        bool InputRequired()
78        {
79                return mStream.avail_in <= 0;
80        }
81       
82        // --------------------------------------------------------------------------
83        //
84        // Function
85        //              Name:    Compress<Function>::Input(const void *, int)
86        //              Purpose: Set the input buffer ready for next output call.
87        //              Created: 5/12/03
88        //
89        // --------------------------------------------------------------------------
90        void Input(const void *pInBuffer, int InLength)
91        {
92                // Check usage
93                if(mStream.avail_in != 0)
94                {
95                        THROW_EXCEPTION(CompressException, BadUsageInputNotRequired)
96                }
97               
98                // Store info
99                mStream.next_in = (unsigned char *)pInBuffer;
100                mStream.avail_in = InLength;
101        }
102       
103        // --------------------------------------------------------------------------
104        //
105        // Function
106        //              Name:    Compress<Function>::FinishInput()
107        //              Purpose: When compressing, no more input will be given.
108        //              Created: 5/12/03
109        //
110        // --------------------------------------------------------------------------
111        void FinishInput()
112        {
113                mFlush = Z_FINISH;
114        }
115               
116        // --------------------------------------------------------------------------
117        //
118        // Function
119        //              Name:    Compress<Function>::Output(void *, int)
120        //              Purpose: Get some output data
121        //              Created: 5/12/03
122        //
123        // --------------------------------------------------------------------------
124        int Output(void *pOutBuffer, int OutLength, bool SyncFlush = false)
125        {
126                // need more input?
127                if(mStream.avail_in == 0 && mFlush != Z_FINISH && !SyncFlush)
128                {
129                        return 0;
130                }
131       
132                // Buffers
133                mStream.next_out = (unsigned char *)pOutBuffer;
134                mStream.avail_out = OutLength;
135               
136                // Call one of the functions
137                int flush = mFlush;
138                if(SyncFlush && mFlush != Z_FINISH)
139                {
140                        flush = Z_SYNC_FLUSH;
141                }
142                int ret = (Compressing)?(deflate(&mStream, flush)):(inflate(&mStream, flush));
143               
144                if(SyncFlush && ret == Z_BUF_ERROR)
145                {
146                        // No progress possible. Just return 0.
147                        return 0;
148                }
149               
150                // Check errors
151                if(ret < 0)
152                {
153                        BOX_WARNING("zlib error code = " << ret);                       
154                        THROW_EXCEPTION(CompressException, TransformFailed)
155                }
156               
157                // Parse result
158                if(ret == Z_STREAM_END)
159                {
160                        mFinished = true;
161                }
162               
163                // Return how much data was output
164                return OutLength - mStream.avail_out;
165        }
166       
167        // --------------------------------------------------------------------------
168        //
169        // Function
170        //              Name:    Compress<Function>::OutputHasFinished()
171        //              Purpose: No more output to be recieved
172        //              Created: 5/12/03
173        //
174        // --------------------------------------------------------------------------
175        bool OutputHasFinished()
176        {
177                return mFinished;
178        }
179       
180       
181private:
182        z_stream mStream;
183        bool mFinished;
184        int mFlush;
185};
186
187template<typename Integer>
188Integer Compress_MaxSizeForCompressedData(Integer InLen)
189{
190        // Conservative rendition of the info found here: http://www.gzip.org/zlib/zlib_tech.html
191        int blocks = (InLen + 32*1024 - 1) / (32*1024);
192        return InLen + (blocks * 6) + 8;
193}
194
195
196#endif // COMPRESSCONTEXT__H
197
Note: See TracBrowser for help on using the repository browser.