1 // natDeflater.cc - Implementation of Deflater native methods.
2
3 /* Copyright (C) 1999, 2002, 2006 Free Software Foundation
4
5 This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
10
11 // Written by Tom Tromey <tromey@cygnus.com>
12
13 #include <config.h>
14
15 #include <zlib.h>
16 #include <stdlib.h>
17
18 #include <gcj/cni.h>
19 #include <jvm.h>
20
21 #include <java/util/zip/Deflater.h>
22 #include <java/util/zip/DataFormatException.h>
23
24 #include <java/lang/InternalError.h>
25 #include <java/lang/NullPointerException.h>
26 #include <java/lang/ArrayIndexOutOfBoundsException.h>
27
28 extern void *_Jv_ZMalloc (void *, uInt nitems, uInt size);
29 extern void _Jv_ZFree (void *, void *addr);
30
31
32
33 jint
deflate(jbyteArray buf,jint off,jint len)34 java::util::zip::Deflater::deflate (jbyteArray buf, jint off, jint len)
35 {
36 JvSynchronize sync (this);
37 z_streamp s = (z_streamp) zstream;
38
39 if (! buf)
40 throw new java::lang::NullPointerException;
41 if (off < 0 || len < 0 || off + len > buf->length)
42 throw new java::lang::ArrayIndexOutOfBoundsException;
43
44 if (len == 0)
45 return 0;
46
47 s->next_out = (Bytef *) (elements (buf) + off);
48 s->avail_out = len;
49
50 switch (::deflate (s, flush_flag))
51 {
52 case Z_STREAM_END:
53 is_finished = true;
54 if (s->avail_out == (unsigned int) len)
55 return -1;
56 break;
57
58 case Z_STREAM_ERROR:
59 case Z_BUF_ERROR:
60 // FIXME?
61 throw new java::lang::InternalError;
62 break;
63
64 case Z_OK:
65 break;
66 }
67
68 return len - s->avail_out;
69 }
70
71 void
end()72 java::util::zip::Deflater::end ()
73 {
74 JvSynchronize sync (this);
75 // Just ignore errors.
76 deflateEnd ((z_streamp) zstream);
77 _Jv_Free (zstream);
78 zstream = NULL;
79 }
80
81 void
finish()82 java::util::zip::Deflater::finish ()
83 {
84 JvSynchronize sync (this);
85 flush_flag = Z_FINISH;
86 }
87
88 jint
getAdler()89 java::util::zip::Deflater::getAdler ()
90 {
91 JvSynchronize sync (this);
92 z_streamp s = (z_streamp) zstream;
93 return s->adler;
94 }
95
96 jlong
getBytesRead()97 java::util::zip::Deflater::getBytesRead ()
98 {
99 JvSynchronize sync (this);
100 z_streamp s = (z_streamp) zstream;
101 return s->total_in;
102 }
103
104 jlong
getBytesWritten()105 java::util::zip::Deflater::getBytesWritten ()
106 {
107 JvSynchronize sync (this);
108 z_streamp s = (z_streamp) zstream;
109 return s->total_out;
110 }
111
112 jboolean
needsInput()113 java::util::zip::Deflater::needsInput ()
114 {
115 JvSynchronize sync (this);
116 z_streamp s = (z_streamp) zstream;
117 return s->avail_in == 0;
118 }
119
120 void
reset()121 java::util::zip::Deflater::reset ()
122 {
123 JvSynchronize sync (this);
124 z_streamp s = (z_streamp) zstream;
125 // Just ignore errors.
126 deflateReset (s);
127 s->avail_in = 0;
128 flush_flag = 0;
129 is_finished = false;
130 }
131
132 void
setDictionary(jbyteArray buf,jint off,jint len)133 java::util::zip::Deflater::setDictionary (jbyteArray buf, jint off, jint len)
134 {
135 JvSynchronize sync (this);
136 z_streamp s = (z_streamp) zstream;
137
138 if (! buf)
139 throw new java::lang::NullPointerException;
140 if (off < 0 || len < 0 || off + len > buf->length)
141 throw new java::lang::ArrayIndexOutOfBoundsException;
142
143 // Ignore errors.
144 deflateSetDictionary (s, (Bytef *) (elements (buf) + off), len);
145 }
146
147 void
setInput(jbyteArray buf,jint off,jint len)148 java::util::zip::Deflater::setInput (jbyteArray buf, jint off, jint len)
149 {
150 JvSynchronize sync (this);
151 z_streamp s = (z_streamp) zstream;
152
153 if (! buf)
154 throw new java::lang::NullPointerException;
155 if (off < 0 || len < 0 || off + len > buf->length)
156 throw new java::lang::ArrayIndexOutOfBoundsException;
157
158 s->next_in = (Bytef *) (elements (buf) + off);
159 s->avail_in = len;
160 }
161
162 void
update()163 java::util::zip::Deflater::update ()
164 {
165 JvSynchronize sync (this);
166 z_streamp s = (z_streamp) zstream;
167
168 int strat = Z_DEFAULT_STRATEGY;
169 switch (strategy)
170 {
171 case DEFAULT_STRATEGY:
172 strat = Z_DEFAULT_STRATEGY;
173 break;
174 case FILTERED:
175 strat = Z_FILTERED;
176 break;
177 case HUFFMAN_ONLY:
178 strat = Z_HUFFMAN_ONLY;
179 break;
180 default:
181 JvFail ("unexpected strategy");
182 }
183
184 // Ignore errors.
185 deflateParams (s, level, strat);
186 }
187
188 void
init(jint level,jboolean no_header)189 java::util::zip::Deflater::init (jint level, jboolean no_header)
190 {
191 z_stream_s *stream = (z_stream_s *) _Jv_Malloc (sizeof (z_stream_s));
192 stream->next_in = Z_NULL;
193 stream->avail_in = 0;
194 stream->zalloc = _Jv_ZMalloc;
195 stream->zfree = _Jv_ZFree;
196 stream->opaque = NULL;
197
198 // Handle NO_HEADER using undocumented zlib feature.
199 int wbits = MAX_WBITS;
200 if (no_header)
201 wbits = - wbits;
202
203 #define DEFAULT_MEM_LEVEL 8
204 if (deflateInit2 (stream, level, Z_DEFLATED, wbits,
205 DEFAULT_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
206 {
207 jstring msg = NULL;
208 if (stream->msg != NULL)
209 msg = JvNewStringLatin1 (stream->msg);
210 throw new java::lang::InternalError (msg);
211 }
212
213 zstream = reinterpret_cast<gnu::gcj::RawData *> (stream);
214 is_finished = false;
215 flush_flag = 0;
216 }
217