1. /*
  2. * @(#)Inflater.java 1.32 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util.zip;
  8. /**
  9. * This class provides support for general purpose decompression using
  10. * popular ZLIB compression library. The ZLIB compression library was
  11. * initially developed as part of the PNG graphics standard and is not
  12. * protected by patents. It is fully described in the specifications at
  13. * the <a href="package-summary.html#package_description">java.util.zip
  14. * package description</a>.
  15. *
  16. * @see Deflater
  17. * @version 1.32, 11/29/01
  18. * @author David Connelly
  19. *
  20. */
  21. public
  22. class Inflater {
  23. private long strm;
  24. private byte[] buf = new byte[0];
  25. private int off, len;
  26. private boolean finished;
  27. private boolean needDict;
  28. /*
  29. * Loads the ZLIB library.
  30. */
  31. static {
  32. java.security.AccessController.doPrivileged(
  33. new sun.security.action.LoadLibraryAction("zip"));
  34. initIDs();
  35. }
  36. /**
  37. * Creates a new decompressor. If the parameter 'nowrap' is true then
  38. * the ZLIB header and checksum fields will not be used. This provides
  39. * compatibility with the compression format used by both GZIP and PKZIP.
  40. * <p>
  41. * Note: When using the 'nowrap' option it is also necessary to provide
  42. * an extra "dummy" byte as input. This is required by the ZLIB native
  43. * library in order to support certain optimizations.
  44. *
  45. * @param nowrap if true then support GZIP compatible compression
  46. */
  47. public Inflater(boolean nowrap) {
  48. strm = init(nowrap);
  49. }
  50. /**
  51. * Creates a new decompressor.
  52. */
  53. public Inflater() {
  54. this(false);
  55. }
  56. /**
  57. * Sets input data for decompression. Should be called whenever
  58. * needsInput() returns true indicating that more input data is
  59. * required.
  60. * @param b the input data bytes
  61. * @param off the start offset of the input data
  62. * @param len the length of the input data
  63. * @see Inflater#needsInput
  64. */
  65. public synchronized void setInput(byte[] b, int off, int len) {
  66. if (b == null) {
  67. throw new NullPointerException();
  68. }
  69. if (off < 0 || len < 0 || off + len > b.length) {
  70. throw new ArrayIndexOutOfBoundsException();
  71. }
  72. this.buf = b;
  73. this.off = off;
  74. this.len = len;
  75. }
  76. /**
  77. * Sets input data for decompression. Should be called whenever
  78. * needsInput() returns true indicating that more input data is
  79. * required.
  80. * @param b the input data bytes
  81. * @see Inflater#needsInput
  82. */
  83. public void setInput(byte[] b) {
  84. setInput(b, 0, b.length);
  85. }
  86. /**
  87. * Sets the preset dictionary to the given array of bytes. Should be
  88. * called when inflate() returns 0 and needsDictionary() returns true
  89. * indicating that a preset dictionary is required. The method getAdler()
  90. * can be used to get the Adler-32 value of the dictionary needed.
  91. * @param b the dictionary data bytes
  92. * @param off the start offset of the data
  93. * @param len the length of the data
  94. * @see Inflater#needsDictionary
  95. * @see Inflater#getAdler
  96. */
  97. public synchronized void setDictionary(byte[] b, int off, int len) {
  98. if (strm == 0 || b == null) {
  99. throw new NullPointerException();
  100. }
  101. if (off < 0 || len < 0 || off + len > b.length) {
  102. throw new ArrayIndexOutOfBoundsException();
  103. }
  104. setDictionary(strm, b, off, len);
  105. needDict = false;
  106. }
  107. /**
  108. * Sets the preset dictionary to the given array of bytes. Should be
  109. * called when inflate() returns 0 and needsDictionary() returns true
  110. * indicating that a preset dictionary is required. The method getAdler()
  111. * can be used to get the Adler-32 value of the dictionary needed.
  112. * @param b the dictionary data bytes
  113. * @see Inflater#needsDictionary
  114. * @see Inflater#getAdler
  115. */
  116. public void setDictionary(byte[] b) {
  117. setDictionary(b, 0, b.length);
  118. }
  119. /**
  120. * Returns the total number of bytes remaining in the input buffer.
  121. * This can be used to find out what bytes still remain in the input
  122. * buffer after decompression has finished.
  123. */
  124. public synchronized int getRemaining() {
  125. return len;
  126. }
  127. /**
  128. * Returns true if no data remains in the input buffer. This can
  129. * be used to determine if #setInput should be called in order
  130. * to provide more input.
  131. */
  132. public synchronized boolean needsInput() {
  133. return len <= 0;
  134. }
  135. /**
  136. * Returns true if a preset dictionary is needed for decompression.
  137. * @see InflatesetDictionary
  138. */
  139. public synchronized boolean needsDictionary() {
  140. return needDict;
  141. }
  142. /**
  143. * Return true if the end of the compressed data stream has been
  144. * reached.
  145. */
  146. public synchronized boolean finished() {
  147. return finished;
  148. }
  149. /**
  150. * Uncompresses bytes into specified buffer. Returns actual number
  151. * of bytes uncompressed. A return value of 0 indicates that
  152. * needsInput() or needsDictionary() should be called in order to
  153. * determine if more input data or a preset dictionary is required.
  154. * In the later case, getAdler() can be used to get the Adler-32
  155. * value of the dictionary required.
  156. * @param b the buffer for the uncompressed data
  157. * @param off the start offset of the data
  158. * @param len the maximum number of uncompressed bytes
  159. * @return the actual number of uncompressed bytes
  160. * @exception DataFormatException if the compressed data format is invalid
  161. * @see Inflater#needsInput
  162. * @see Inflater#needsDictionary
  163. */
  164. public synchronized int inflate(byte[] b, int off, int len)
  165. throws DataFormatException
  166. {
  167. if (b == null) {
  168. throw new NullPointerException();
  169. }
  170. if (off < 0 || len < 0 || off + len > b.length) {
  171. throw new ArrayIndexOutOfBoundsException();
  172. }
  173. return inflateBytes(b, off, len);
  174. }
  175. /**
  176. * Uncompresses bytes into specified buffer. Returns actual number
  177. * of bytes uncompressed. A return value of 0 indicates that
  178. * needsInput() or needsDictionary() should be called in order to
  179. * determine if more input data or a preset dictionary is required.
  180. * In the later case, getAdler() can be used to get the Adler-32
  181. * value of the dictionary required.
  182. * @param b the buffer for the uncompressed data
  183. * @return the actual number of uncompressed bytes
  184. * @exception DataFormatException if the compressed data format is invalid
  185. * @see Inflater#needsInput
  186. * @see Inflater#needsDictionary
  187. */
  188. public int inflate(byte[] b) throws DataFormatException {
  189. return inflate(b, 0, b.length);
  190. }
  191. /**
  192. * Returns the ADLER-32 value of the uncompressed data.
  193. */
  194. public synchronized int getAdler() {
  195. if (strm == 0) {
  196. throw new NullPointerException();
  197. }
  198. return getAdler(strm);
  199. }
  200. /**
  201. * Returns the total number of bytes input so far.
  202. */
  203. public synchronized int getTotalIn() {
  204. if (strm == 0) {
  205. throw new NullPointerException();
  206. }
  207. return getTotalIn(strm);
  208. }
  209. /**
  210. * Returns the total number of bytes output so far.
  211. */
  212. public synchronized int getTotalOut() {
  213. if (strm == 0) {
  214. throw new NullPointerException();
  215. }
  216. return getTotalOut(strm);
  217. }
  218. /**
  219. * Resets inflater so that a new set of input data can be processed.
  220. */
  221. public synchronized void reset() {
  222. if (strm == 0) {
  223. throw new NullPointerException();
  224. }
  225. reset(strm);
  226. finished = false;
  227. needDict = false;
  228. off = len = 0;
  229. }
  230. /**
  231. * Closes the decompressor and discards any unprocessed input.
  232. * This method should be called when the decompressor is no longer
  233. * being used, but will also be called automatically by the finalize()
  234. * method. Once this method is called, the behavior of the Inflater
  235. * object is undefined.
  236. */
  237. public synchronized void end() {
  238. if (strm != 0) {
  239. end(strm);
  240. strm = 0;
  241. }
  242. }
  243. /**
  244. * Closes the decompressor when garbage is collected.
  245. */
  246. protected void finalize() {
  247. end();
  248. }
  249. private native static void initIDs();
  250. private native static long init(boolean nowrap);
  251. private native static void setDictionary(long strm, byte[] b, int off,
  252. int len);
  253. private native int inflateBytes(byte[] b, int off, int len)
  254. throws DataFormatException;
  255. private native static int getAdler(long strm);
  256. private native static int getTotalIn(long strm);
  257. private native static int getTotalOut(long strm);
  258. private native static void reset(long strm);
  259. private native static void end(long strm);
  260. }