]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/zstream.cpp
BIG glitch.
[wxWidgets.git] / src / common / zstream.cpp
... / ...
CommitLineData
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
18#include "wx/zstream.h"
19
20#if wxUSE_ZLIB
21
22#include "wx/utils.h"
23#include "wx/intl.h"
24#include "wx/log.h"
25#include "../zlib/zlib.h" // don't change this, Robert
26
27#ifdef __BORLANDC__
28#pragma hdrstop
29#endif
30
31#define ZSTREAM_BUFFER_SIZE 1024
32
33//////////////////////
34// wxZlibInputStream
35//////////////////////
36
37wxZlibInputStream::wxZlibInputStream(wxInputStream& stream)
38 : wxFilterInputStream(stream)
39{
40 int err;
41
42 // I need a private stream buffer.
43 m_i_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::read);
44 m_i_destroybuf = TRUE;
45 m_inflate = new z_stream_s;
46
47 m_inflate->zalloc = (alloc_func)0;
48 m_inflate->zfree = (free_func)0;
49 m_inflate->opaque = (voidpf)0;
50
51 err = inflateInit(m_inflate);
52 if (err != Z_OK) {
53 inflateEnd(m_inflate);
54 delete m_inflate;
55 return;
56 }
57
58 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
59 m_z_size = ZSTREAM_BUFFER_SIZE;
60
61 m_inflate->avail_in = 0;
62 m_inflate->next_in = NULL;
63}
64
65wxZlibInputStream::~wxZlibInputStream()
66{
67 inflateEnd(m_inflate);
68 delete m_inflate;
69}
70
71size_t wxZlibInputStream::OnSysRead(void *buffer, size_t size)
72{
73 int err;
74
75 m_inflate->next_out = (unsigned char *)buffer;
76 m_inflate->avail_out = size;
77
78 while (m_inflate->avail_out > 0) {
79 if (m_inflate->avail_in == 0) {
80
81 m_parent_i_stream->Read(m_z_buffer, m_z_size);
82 m_inflate->next_in = m_z_buffer;
83 m_inflate->avail_in = m_parent_i_stream->LastRead();
84
85 if (m_parent_i_stream->LastError() != wxStream_NOERROR)
86 return (size - m_inflate->avail_in);
87 }
88 err = inflate(m_inflate, Z_FINISH);
89 if (err == Z_STREAM_END)
90 return (size - m_inflate->avail_in);
91 }
92
93 return size-m_inflate->avail_in;
94}
95
96//////////////////////
97// wxZlibOutputStream
98//////////////////////
99
100wxZlibOutputStream::wxZlibOutputStream(wxOutputStream& stream)
101 : wxFilterOutputStream(stream)
102{
103 int err;
104
105 m_o_streambuf = new wxStreamBuffer(*this, wxStreamBuffer::write);
106 m_o_destroybuf = TRUE;
107 m_deflate = new z_stream_s;
108
109 m_deflate->zalloc = (alloc_func)0;
110 m_deflate->zfree = (free_func)0;
111 m_deflate->opaque = (voidpf)0;
112
113 err = deflateInit(m_deflate, Z_DEFAULT_COMPRESSION);
114 if (err != Z_OK) {
115 deflateEnd(m_deflate);
116 return;
117 }
118
119 m_z_buffer = new unsigned char[ZSTREAM_BUFFER_SIZE];
120 m_z_size = ZSTREAM_BUFFER_SIZE;
121
122 m_deflate->avail_in = 0;
123 m_deflate->next_out = m_z_buffer;
124 m_deflate->avail_out = m_z_size;
125}
126
127wxZlibOutputStream::~wxZlibOutputStream()
128{
129 int err;
130
131 Sync();
132
133 err = deflate(m_deflate, Z_FINISH);
134 if (err != Z_STREAM_END)
135 {
136 wxLogDebug( "wxZlibOutputStream: an error occured while closing the stream.\n" );
137 return;
138 }
139
140 deflateEnd(m_deflate);
141
142 delete[] m_z_buffer;
143}
144
145void wxZlibOutputStream::Sync()
146{
147 int err;
148
149 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate->avail_out);
150 m_deflate->next_out = m_z_buffer;
151 m_deflate->avail_out = m_z_size;
152
153 err = deflate(m_deflate, Z_FULL_FLUSH);
154 if (err != Z_OK) {
155 return;
156 }
157
158 m_parent_o_stream->Write(m_z_buffer, m_z_size-m_deflate->avail_out);
159 m_deflate->next_out = m_z_buffer;
160 m_deflate->avail_out = m_z_size;
161}
162
163size_t wxZlibOutputStream::OnSysWrite(const void *buffer, size_t size)
164{
165 int err;
166
167 m_deflate->next_in = (unsigned char *)buffer;
168 m_deflate->avail_in = size;
169
170 while (m_deflate->avail_in > 0) {
171
172 if (m_deflate->avail_out == 0) {
173 m_parent_o_stream->Write(m_z_buffer, m_z_size);
174 if (m_parent_o_stream->LastError() != wxStream_NOERROR)
175 return (size - m_deflate->avail_in);
176
177 m_deflate->next_out = m_z_buffer;
178 m_deflate->avail_out = m_z_size;
179 }
180
181 err = deflate(m_deflate, Z_NO_FLUSH);
182 if (err != Z_OK)
183 return (size - m_deflate->avail_in);
184 }
185 return size;
186}
187
188#endif
189
190 // wxUSE_ZLIB
191