1 // natDeflater.cc - Implementation of Deflater native methods.
2 
3 /* Copyright (C) 1999, 2002  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 jint
getTotalIn()97 java::util::zip::Deflater::getTotalIn ()
98 {
99   JvSynchronize sync (this);
100   z_streamp s = (z_streamp) zstream;
101   return s->total_in;
102 }
103 
104 jint
getTotalOut()105 java::util::zip::Deflater::getTotalOut ()
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