]> git.saurik.com Git - wxWidgets.git/blob - src/common/zstream.cpp
* Added source file info in utils/serialize/*
[wxWidgets.git] / src / common / zstream.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: zstream.cpp
3 // Purpose: Compressed stream classes
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 11/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 #ifdef __GNUG__
12 #pragma implementation "zstream.h"
13 #endif
14
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
17 #include <wx/stream.h>
18 #include <wx/zstream.h>
19 #include <wx/utils.h>
20 #include "../zlib/zlib.h" // don't change this, Robert
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #define ZSTREAM_BUFFER_SIZE 1024
27
28 //////////////////////
29 // wxZlibInputStream
30 //////////////////////
31
32 wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
33 : wxFilterInputStream(stream)
34 {
35 int err;
36
37 // I need a private stream buffer.
38 m_i_streambuf = new wxStreamBuffer(*this);
39 m_i_destroybuf = TRUE;
40
41 m_inflate.zalloc = (alloc_func)0;
42 m_inflate.zfree = (free_func)0;
43 m_inflate.opaque = (voidpf)0;
44
45 err = inflateInit(&m_inflate);
46 if (err != Z_OK) {
47 inflateEnd(&m_inflate);
48 return;
49 }
50
51 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
52 m_z_size = ZSTREAM_BUFFER_SIZE;
53
54 m_inflate.avail_in = 0;
55 m_inflate.next_in = NULL;
56 }
57
58 wxZlibInputStream::~wxZlibInputStream()
59 {
60 inflateEnd(&m_inflate);
61 }
62
63 size_t wxZlibInputStream::DoRead(void *buffer, size_t size)
64 {
65 int err;
66
67 m_inflate.next_out = (unsigned char *)buffer;
68 m_inflate.avail_out = size;
69
70 while (m_inflate.avail_out > 0) {
71 if (m_inflate.avail_in == 0) {
72
73 m_parent_i_stream->Read(m_z_buffer, m_z_size);
74 m_inflate.next_in = m_z_buffer;
75 m_inflate.avail_in = m_parent_i_stream->LastRead();
76
77 if (m_parent_i_stream->Eof())
78 return (size - m_inflate.avail_in);
79 }
80 err = inflate(&m_inflate, Z_FINISH);
81 if (err == Z_STREAM_END)
82 return (size - m_inflate.avail_in);
83 }
84
85 return size-m_inflate.avail_in;
86 }
87
88 bool wxZlibInputStream::Eof() const
89 {
90 if (!m_eof)
91 return m_parent_i_stream->Eof();
92 return m_eof;
93 }
94
95 //////////////////////
96 // wxZlibOutputStream
97 //////////////////////
98
99 wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
100 : wxFilterOutputStream(stream)
101 {
102 int err;
103
104 m_o_streambuf = new wxStreamBuffer(*this);
105 m_o_destroybuf = TRUE;
106
107 m_deflate.zalloc = (alloc_func)0;
108 m_deflate.zfree = (free_func)0;
109 m_deflate.opaque = (voidpf)0;
110
111 err = deflateInit(&m_deflate, Z_DEFAULT_COMPRESSION);
112 if (err != Z_OK) {
113 deflateEnd(&m_deflate);
114 return;
115 }
116
117 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
118 m_z_size = ZSTREAM_BUFFER_SIZE;
119
120 m_deflate.avail_in = 0;
121 m_deflate.next_out = m_z_buffer;
122 m_deflate.avail_out = m_z_size;
123 }
124
125 wxZlibOutputStream::~wxZlibOutputStream()
126 {
127 int err;
128
129 Sync();
130
131 err = deflate(&m_deflate, Z_FINISH);
132 if (err != Z_STREAM_END) {
133 wxDebugMsg("wxZlibOutputStream: an error occured while we was closing "
134 "the stream.\n");
135 return;
136 }
137
138 deflateEnd(&m_deflate);
139
140 delete[] m_z_buffer;
141 }
142
143 void wxZlibOutputStream::Sync()
144 {
145 int err;
146
147 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate.avail_out);
148 m_deflate.next_out = m_z_buffer;
149 m_deflate.avail_out = m_z_size;
150
151 err = deflate(&m_deflate, Z_FULL_FLUSH);
152 if (err != Z_OK) {
153 m_bad = TRUE;
154 return;
155 }
156
157 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate.avail_out);
158 m_deflate.next_out = m_z_buffer;
159 m_deflate.avail_out = m_z_size;
160 }
161
162 size_t wxZlibOutputStream::DoWrite(const void *buffer, size_t size)
163 {
164 int err;
165
166 m_deflate.next_in = (unsigned char *)buffer;
167 m_deflate.avail_in = size;
168
169 while (m_deflate.avail_in > 0) {
170
171 if (m_deflate.avail_out == 0) {
172 m_parent_o_stream->Write(m_z_buffer, m_z_size);
173 if (m_parent_o_stream->Bad())
174 return (size - m_deflate.avail_in);
175
176 m_deflate.next_out = m_z_buffer;
177 m_deflate.avail_out = m_z_size;
178 }
179
180 err = deflate(&m_deflate, Z_NO_FLUSH);
181 if (err != Z_OK)
182 return (size - m_deflate.avail_in);
183 }
184 return size;
185 }
186
187 bool wxZlibOutputStream::Bad() const
188 {
189 if (!m_bad)
190 return m_parent_o_stream->Bad();
191 return m_bad;
192 }