1. /*
  2. * @(#)DeflaterOutputStream.java 1.27 00/02/02
  3. *
  4. * Copyright 1996-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.util.zip;
  11. import java.io.FilterOutputStream;
  12. import java.io.OutputStream;
  13. import java.io.InputStream;
  14. import java.io.IOException;
  15. /**
  16. * This class implements an output stream filter for compressing data in
  17. * the "deflate" compression format. It is also used as the basis for other
  18. * types of compression filters, such as GZIPOutputStream.
  19. *
  20. * @see Deflater
  21. * @version 1.27, 02/02/00
  22. * @author David Connelly
  23. */
  24. public
  25. class DeflaterOutputStream extends FilterOutputStream {
  26. /**
  27. * Compressor for this stream.
  28. */
  29. protected Deflater def;
  30. /**
  31. * Output buffer for writing compressed data.
  32. */
  33. protected byte[] buf;
  34. /**
  35. * Creates a new output stream with the specified compressor and
  36. * buffer size.
  37. * @param out the output stream
  38. * @param def the compressor ("deflater")
  39. * @param size the output buffer size
  40. * @exception IllegalArgumentException if size is <= 0
  41. */
  42. public DeflaterOutputStream(OutputStream out, Deflater def, int size) {
  43. super(out);
  44. if (out == null || def == null) {
  45. throw new NullPointerException();
  46. } else if (size <= 0) {
  47. throw new IllegalArgumentException("buffer size <= 0");
  48. }
  49. this.def = def;
  50. buf = new byte[size];
  51. }
  52. /**
  53. * Creates a new output stream with the specified compressor and
  54. * a default buffer size.
  55. * @param out the output stream
  56. * @param def the compressor ("deflater")
  57. */
  58. public DeflaterOutputStream(OutputStream out, Deflater def) {
  59. this(out, def, 512);
  60. }
  61. /**
  62. * Creates a new output stream with a defaul compressor and buffer size.
  63. * @param out the output stream
  64. */
  65. public DeflaterOutputStream(OutputStream out) {
  66. this(out, new Deflater());
  67. }
  68. /**
  69. * Writes a byte to the compressed output stream. This method will
  70. * block until the byte can be written.
  71. * @param b the byte to be written
  72. * @exception IOException if an I/O error has occurred
  73. */
  74. public void write(int b) throws IOException {
  75. byte[] buf = new byte[1];
  76. buf[0] = (byte)(b & 0xff);
  77. write(buf, 0, 1);
  78. }
  79. /**
  80. * Writes an array of bytes to the compressed output stream. This
  81. * method will block until all the bytes are written.
  82. * @param b the data to be written
  83. * @param off the start offset of the data
  84. * @param len the length of the data
  85. * @exception IOException if an I/O error has occurred
  86. */
  87. public void write(byte[] b, int off, int len) throws IOException {
  88. if (def.finished()) {
  89. throw new IOException("write beyond end of stream");
  90. }
  91. if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
  92. throw new IndexOutOfBoundsException();
  93. } else if (len == 0) {
  94. return;
  95. }
  96. if (!def.finished()) {
  97. def.setInput(b, off, len);
  98. while (!def.needsInput()) {
  99. deflate();
  100. }
  101. }
  102. }
  103. /**
  104. * Finishes writing compressed data to the output stream without closing
  105. * the underlying stream. Use this method when applying multiple filters
  106. * in succession to the same output stream.
  107. * @exception IOException if an I/O error has occurred
  108. */
  109. public void finish() throws IOException {
  110. if (!def.finished()) {
  111. def.finish();
  112. while (!def.finished()) {
  113. deflate();
  114. }
  115. }
  116. }
  117. /**
  118. * Writes remaining compressed data to the output stream and closes the
  119. * underlying stream.
  120. * @exception IOException if an I/O error has occurred
  121. */
  122. public void close() throws IOException {
  123. finish();
  124. out.close();
  125. }
  126. /**
  127. * Writes next block of compressed data to the output stream.
  128. * @throws IOException if an I/O error has occurred
  129. */
  130. protected void deflate() throws IOException {
  131. int len = def.deflate(buf, 0, buf.length);
  132. if (len > 0) {
  133. out.write(buf, 0, len);
  134. }
  135. }
  136. }