History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/util/zip/Deflater.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/util/zip/Deflater.java+550−0
@@ -0,0 +1,550 @@
1+/*
2+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package java.util.zip;
27+
28+/**
29+ * This class provides support for general purpose compression using the
30+ * popular ZLIB compression library. The ZLIB compression library was
31+ * initially developed as part of the PNG graphics standard and is not
32+ * protected by patents. It is fully described in the specifications at
33+ * the <a href="package-summary.html#package_description">java.util.zip
34+ * package description</a>.
35+ *
36+ * <p>The following code fragment demonstrates a trivial compression
37+ * and decompression of a string using <tt>Deflater</tt> and
38+ * <tt>Inflater</tt>.
39+ *
40+ * <blockquote><pre>
41+ * try {
42+ * // Encode a String into bytes
43+ * String inputString = "blahblahblah";
44+ * byte[] input = inputString.getBytes("UTF-8");
45+ *
46+ * // Compress the bytes
47+ * byte[] output = new byte[100];
48+ * Deflater compresser = new Deflater();
49+ * compresser.setInput(input);
50+ * compresser.finish();
51+ * int compressedDataLength = compresser.deflate(output);
52+ * compresser.end();
53+ *
54+ * // Decompress the bytes
55+ * Inflater decompresser = new Inflater();
56+ * decompresser.setInput(output, 0, compressedDataLength);
57+ * byte[] result = new byte[100];
58+ * int resultLength = decompresser.inflate(result);
59+ * decompresser.end();
60+ *
61+ * // Decode the bytes into a String
62+ * String outputString = new String(result, 0, resultLength, "UTF-8");
63+ * } catch(java.io.UnsupportedEncodingException ex) {
64+ * // handle
65+ * } catch (java.util.zip.DataFormatException ex) {
66+ * // handle
67+ * }
68+ * </pre></blockquote>
69+ *
70+ * @see Inflater
71+ * @author David Connelly
72+ */
73+public
74+class Deflater {
75+
76+ private final ZStreamRef zsRef;
77+ private byte[] buf = new byte[0];
78+ private int off, len;
79+ private int level, strategy;
80+ private boolean setParams;
81+ private boolean finish, finished;
82+
83+ /**
84+ * Compression method for the deflate algorithm (the only one currently
85+ * supported).
86+ */
87+ public static final int DEFLATED = 8;
88+
89+ /**
90+ * Compression level for no compression.
91+ */
92+ public static final int NO_COMPRESSION = 0;
93+
94+ /**
95+ * Compression level for fastest compression.
96+ */
97+ public static final int BEST_SPEED = 1;
98+
99+ /**
100+ * Compression level for best compression.
101+ */
102+ public static final int BEST_COMPRESSION = 9;
103+
104+ /**
105+ * Default compression level.
106+ */
107+ public static final int DEFAULT_COMPRESSION = -1;
108+
109+ /**
110+ * Compression strategy best used for data consisting mostly of small
111+ * values with a somewhat random distribution. Forces more Huffman coding
112+ * and less string matching.
113+ */
114+ public static final int FILTERED = 1;
115+
116+ /**
117+ * Compression strategy for Huffman coding only.
118+ */
119+ public static final int HUFFMAN_ONLY = 2;
120+
121+ /**
122+ * Default compression strategy.
123+ */
124+ public static final int DEFAULT_STRATEGY = 0;
125+
126+ /**
127+ * Compression flush mode used to achieve best compression result.
128+ *
129+ * @see Deflater#deflate(byte[], int, int, int)
130+ * @since 1.7
131+ */
132+ public static final int NO_FLUSH = 0;
133+
134+ /**
135+ * Compression flush mode used to flush out all pending output; may
136+ * degrade compression for some compression algorithms.
137+ *
138+ * @see Deflater#deflate(byte[], int, int, int)
139+ * @since 1.7
140+ */
141+ public static final int SYNC_FLUSH = 2;
142+
143+ /**
144+ * Compression flush mode used to flush out all pending output and
145+ * reset the deflater. Using this mode too often can seriously degrade
146+ * compression.
147+ *
148+ * @see Deflater#deflate(byte[], int, int, int)
149+ * @since 1.7
150+ */
151+ public static final int FULL_FLUSH = 3;
152+
153+ static {
154+ /* Zip library is loaded from System.initializeSystemClass */
155+ initIDs();
156+ }
157+
158+ /**
159+ * Creates a new compressor using the specified compression level.
160+ * If 'nowrap' is true then the ZLIB header and checksum fields will
161+ * not be used in order to support the compression format used in
162+ * both GZIP and PKZIP.
163+ * @param level the compression level (0-9)
164+ * @param nowrap if true then use GZIP compatible compression
165+ */
166+ public Deflater(int level, boolean nowrap) {
167+ this.level = level;
168+ this.strategy = DEFAULT_STRATEGY;
169+ this.zsRef = new ZStreamRef(init(level, DEFAULT_STRATEGY, nowrap));
170+ }
171+
172+ /**
173+ * Creates a new compressor using the specified compression level.
174+ * Compressed data will be generated in ZLIB format.
175+ * @param level the compression level (0-9)
176+ */
177+ public Deflater(int level) {
178+ this(level, false);
179+ }
180+
181+ /**
182+ * Creates a new compressor with the default compression level.
183+ * Compressed data will be generated in ZLIB format.
184+ */
185+ public Deflater() {
186+ this(DEFAULT_COMPRESSION, false);
187+ }
188+
189+ /**
190+ * Sets input data for compression. This should be called whenever
191+ * needsInput() returns true indicating that more input data is required.
192+ * @param b the input data bytes
193+ * @param off the start offset of the data
194+ * @param len the length of the data
195+ * @see Deflater#needsInput
196+ */
197+ public void setInput(byte[] b, int off, int len) {
198+ if (b== null) {
199+ throw new NullPointerException();
200+ }
201+ if (off < 0 || len < 0 || off > b.length - len) {
202+ throw new ArrayIndexOutOfBoundsException();
203+ }
204+ synchronized (zsRef) {
205+ this.buf = b;
206+ this.off = off;
207+ this.len = len;
208+ }
209+ }
210+
211+ /**
212+ * Sets input data for compression. This should be called whenever
213+ * needsInput() returns true indicating that more input data is required.
214+ * @param b the input data bytes
215+ * @see Deflater#needsInput
216+ */
217+ public void setInput(byte[] b) {
218+ setInput(b, 0, b.length);
219+ }
220+
221+ /**
222+ * Sets preset dictionary for compression. A preset dictionary is used
223+ * when the history buffer can be predetermined. When the data is later
224+ * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
225+ * in order to get the Adler-32 value of the dictionary required for
226+ * decompression.
227+ * @param b the dictionary data bytes
228+ * @param off the start offset of the data
229+ * @param len the length of the data
230+ * @see Inflater#inflate
231+ * @see Inflater#getAdler
232+ */
233+ public void setDictionary(byte[] b, int off, int len) {
234+ if (b == null) {
235+ throw new NullPointerException();
236+ }
237+ if (off < 0 || len < 0 || off > b.length - len) {
238+ throw new ArrayIndexOutOfBoundsException();
239+ }
240+ synchronized (zsRef) {
241+ ensureOpen();
242+ setDictionary(zsRef.address(), b, off, len);
243+ }
244+ }
245+
246+ /**
247+ * Sets preset dictionary for compression. A preset dictionary is used
248+ * when the history buffer can be predetermined. When the data is later
249+ * uncompressed with Inflater.inflate(), Inflater.getAdler() can be called
250+ * in order to get the Adler-32 value of the dictionary required for
251+ * decompression.
252+ * @param b the dictionary data bytes
253+ * @see Inflater#inflate
254+ * @see Inflater#getAdler
255+ */
256+ public void setDictionary(byte[] b) {
257+ setDictionary(b, 0, b.length);
258+ }
259+
260+ /**
261+ * Sets the compression strategy to the specified value.
262+ * @param strategy the new compression strategy
263+ * @exception IllegalArgumentException if the compression strategy is
264+ * invalid
265+ */
266+ public void setStrategy(int strategy) {
267+ switch (strategy) {
268+ case DEFAULT_STRATEGY:
269+ case FILTERED:
270+ case HUFFMAN_ONLY:
271+ break;
272+ default:
273+ throw new IllegalArgumentException();
274+ }
275+ synchronized (zsRef) {
276+ if (this.strategy != strategy) {
277+ this.strategy = strategy;
278+ setParams = true;
279+ }
280+ }
281+ }
282+
283+ /**
284+ * Sets the current compression level to the specified value.
285+ * @param level the new compression level (0-9)
286+ * @exception IllegalArgumentException if the compression level is invalid
287+ */
288+ public void setLevel(int level) {
289+ if ((level < 0 || level > 9) && level != DEFAULT_COMPRESSION) {
290+ throw new IllegalArgumentException("invalid compression level");
291+ }
292+ synchronized (zsRef) {
293+ if (this.level != level) {
294+ this.level = level;
295+ setParams = true;
296+ }
297+ }
298+ }
299+
300+ /**
301+ * Returns true if the input data buffer is empty and setInput()
302+ * should be called in order to provide more input.
303+ * @return true if the input data buffer is empty and setInput()
304+ * should be called in order to provide more input
305+ */
306+ public boolean needsInput() {
307+ return len <= 0;
308+ }
309+
310+ /**
311+ * When called, indicates that compression should end with the current
312+ * contents of the input buffer.
313+ */
314+ public void finish() {
315+ synchronized (zsRef) {
316+ finish = true;
317+ }
318+ }
319+
320+ /**
321+ * Returns true if the end of the compressed data output stream has
322+ * been reached.
323+ * @return true if the end of the compressed data output stream has
324+ * been reached
325+ */
326+ public boolean finished() {
327+ synchronized (zsRef) {
328+ return finished;
329+ }
330+ }
331+
332+ /**
333+ * Compresses the input data and fills specified buffer with compressed
334+ * data. Returns actual number of bytes of compressed data. A return value
335+ * of 0 indicates that {@link #needsInput() needsInput} should be called
336+ * in order to determine if more input data is required.
337+ *
338+ * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
339+ * An invocation of this method of the form {@code deflater.deflate(b, off, len)}
340+ * yields the same result as the invocation of
341+ * {@code deflater.deflate(b, off, len, Deflater.NO_FLUSH)}.
342+ *
343+ * @param b the buffer for the compressed data
344+ * @param off the start offset of the data
345+ * @param len the maximum number of bytes of compressed data
346+ * @return the actual number of bytes of compressed data written to the
347+ * output buffer
348+ */
349+ public int deflate(byte[] b, int off, int len) {
350+ return deflate(b, off, len, NO_FLUSH);
351+ }
352+
353+ /**
354+ * Compresses the input data and fills specified buffer with compressed
355+ * data. Returns actual number of bytes of compressed data. A return value
356+ * of 0 indicates that {@link #needsInput() needsInput} should be called
357+ * in order to determine if more input data is required.
358+ *
359+ * <p>This method uses {@link #NO_FLUSH} as its compression flush mode.
360+ * An invocation of this method of the form {@code deflater.deflate(b)}
361+ * yields the same result as the invocation of
362+ * {@code deflater.deflate(b, 0, b.length, Deflater.NO_FLUSH)}.
363+ *
364+ * @param b the buffer for the compressed data
365+ * @return the actual number of bytes of compressed data written to the
366+ * output buffer
367+ */
368+ public int deflate(byte[] b) {
369+ return deflate(b, 0, b.length, NO_FLUSH);
370+ }
371+
372+ /**
373+ * Compresses the input data and fills the specified buffer with compressed
374+ * data. Returns actual number of bytes of data compressed.
375+ *
376+ * <p>Compression flush mode is one of the following three modes:
377+ *
378+ * <ul>
379+ * <li>{@link #NO_FLUSH}: allows the deflater to decide how much data
380+ * to accumulate, before producing output, in order to achieve the best
381+ * compression (should be used in normal use scenario). A return value
382+ * of 0 in this flush mode indicates that {@link #needsInput()} should
383+ * be called in order to determine if more input data is required.
384+ *
385+ * <li>{@link #SYNC_FLUSH}: all pending output in the deflater is flushed,
386+ * to the specified output buffer, so that an inflater that works on
387+ * compressed data can get all input data available so far (In particular
388+ * the {@link #needsInput()} returns {@code true} after this invocation
389+ * if enough output space is provided). Flushing with {@link #SYNC_FLUSH}
390+ * may degrade compression for some compression algorithms and so it
391+ * should be used only when necessary.
392+ *
393+ * <li>{@link #FULL_FLUSH}: all pending output is flushed out as with
394+ * {@link #SYNC_FLUSH}. The compression state is reset so that the inflater
395+ * that works on the compressed output data can restart from this point
396+ * if previous compressed data has been damaged or if random access is
397+ * desired. Using {@link #FULL_FLUSH} too often can seriously degrade
398+ * compression.
399+ * </ul>
400+ *
401+ * <p>In the case of {@link #FULL_FLUSH} or {@link #SYNC_FLUSH}, if
402+ * the return value is {@code len}, the space available in output
403+ * buffer {@code b}, this method should be invoked again with the same
404+ * {@code flush} parameter and more output space.
405+ *
406+ * @param b the buffer for the compressed data
407+ * @param off the start offset of the data
408+ * @param len the maximum number of bytes of compressed data
409+ * @param flush the compression flush mode
410+ * @return the actual number of bytes of compressed data written to
411+ * the output buffer
412+ *
413+ * @throws IllegalArgumentException if the flush mode is invalid
414+ * @since 1.7
415+ */
416+ public int deflate(byte[] b, int off, int len, int flush) {
417+ if (b == null) {
418+ throw new NullPointerException();
419+ }
420+ if (off < 0 || len < 0 || off > b.length - len) {
421+ throw new ArrayIndexOutOfBoundsException();
422+ }
423+ synchronized (zsRef) {
424+ ensureOpen();
425+ if (flush == NO_FLUSH || flush == SYNC_FLUSH ||
426+ flush == FULL_FLUSH)
427+ return deflateBytes(zsRef.address(), b, off, len, flush);
428+ throw new IllegalArgumentException();
429+ }
430+ }
431+
432+ /**
433+ * Returns the ADLER-32 value of the uncompressed data.
434+ * @return the ADLER-32 value of the uncompressed data
435+ */
436+ public int getAdler() {
437+ synchronized (zsRef) {
438+ ensureOpen();
439+ return getAdler(zsRef.address());
440+ }
441+ }
442+
443+ /**
444+ * Returns the total number of uncompressed bytes input so far.
445+ *
446+ * <p>Since the number of bytes may be greater than
447+ * Integer.MAX_VALUE, the {@link #getBytesRead()} method is now
448+ * the preferred means of obtaining this information.</p>
449+ *
450+ * @return the total number of uncompressed bytes input so far
451+ */
452+ public int getTotalIn() {
453+ return (int) getBytesRead();
454+ }
455+
456+ /**
457+ * Returns the total number of uncompressed bytes input so far.</p>
458+ *
459+ * @return the total (non-negative) number of uncompressed bytes input so far
460+ * @since 1.5
461+ */
462+ public long getBytesRead() {
463+ synchronized (zsRef) {
464+ ensureOpen();
465+ return getBytesRead(zsRef.address());
466+ }
467+ }
468+
469+ /**
470+ * Returns the total number of compressed bytes output so far.
471+ *
472+ * <p>Since the number of bytes may be greater than
473+ * Integer.MAX_VALUE, the {@link #getBytesWritten()} method is now
474+ * the preferred means of obtaining this information.</p>
475+ *
476+ * @return the total number of compressed bytes output so far
477+ */
478+ public int getTotalOut() {
479+ return (int) getBytesWritten();
480+ }
481+
482+ /**
483+ * Returns the total number of compressed bytes output so far.</p>
484+ *
485+ * @return the total (non-negative) number of compressed bytes output so far
486+ * @since 1.5
487+ */
488+ public long getBytesWritten() {
489+ synchronized (zsRef) {
490+ ensureOpen();
491+ return getBytesWritten(zsRef.address());
492+ }
493+ }
494+
495+ /**
496+ * Resets deflater so that a new set of input data can be processed.
497+ * Keeps current compression level and strategy settings.
498+ */
499+ public void reset() {
500+ synchronized (zsRef) {
501+ ensureOpen();
502+ reset(zsRef.address());
503+ finish = false;
504+ finished = false;
505+ off = len = 0;
506+ }
507+ }
508+
509+ /**
510+ * Closes the compressor and discards any unprocessed input.
511+ * This method should be called when the compressor is no longer
512+ * being used, but will also be called automatically by the
513+ * finalize() method. Once this method is called, the behavior
514+ * of the Deflater object is undefined.
515+ */
516+ public void end() {
517+ synchronized (zsRef) {
518+ long addr = zsRef.address();
519+ zsRef.clear();
520+ if (addr != 0) {
521+ end(addr);
522+ buf = null;
523+ }
524+ }
525+ }
526+
527+ /**
528+ * Closes the compressor when garbage is collected.
529+ */
530+ protected void finalize() {
531+ end();
532+ }
533+
534+ private void ensureOpen() {
535+ assert Thread.holdsLock(zsRef);
536+ if (zsRef.address() == 0)
537+ throw new NullPointerException("Deflater has been closed");
538+ }
539+
540+ private static native void initIDs();
541+ private native static long init(int level, int strategy, boolean nowrap);
542+ private native static void setDictionary(long addr, byte[] b, int off, int len);
543+ private native int deflateBytes(long addr, byte[] b, int off, int len,
544+ int flush);
545+ private native static int getAdler(long addr);
546+ private native static long getBytesRead(long addr);
547+ private native static long getBytesWritten(long addr);
548+ private native static void reset(long addr);
549+ private native static void end(long addr);
550+}