View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.servlets.gzip;
20  
21  import java.io.FilterOutputStream;
22  import java.io.IOException;
23  import java.io.OutputStream;
24  import java.util.zip.Deflater;
25  
26  /**
27   * Reimplementation of {@link java.util.zip.DeflaterOutputStream} that supports reusing the buffer.
28   */
29  public class DeflatedOutputStream extends FilterOutputStream
30  {
31      protected final Deflater _def;
32      protected final byte[] _buf;
33      protected boolean closed = false;
34  
35      public DeflatedOutputStream(OutputStream out, Deflater deflater, byte[] buffer)
36      {
37          super(out);
38          _def = deflater;
39          _buf = buffer;
40      }
41  
42      @Override
43      public void write(int b) throws IOException
44      {
45          byte[] buf = new byte[1];
46          buf[0] = (byte)(b & 0xff);
47          write(buf,0,1);
48      }
49  
50      @Override
51      public void write(byte[] b, int off, int len) throws IOException
52      {
53          if (_def.finished())
54              throw new IOException("Stream already finished");
55          if ((off | len | (off + len) | (b.length - (off + len))) < 0)
56              throw new IndexOutOfBoundsException();
57          if (len == 0)
58              return;
59          if (!_def.finished())
60          {
61              _def.setInput(b,off,len);
62              while (!_def.needsInput())
63              {
64                  deflate();
65              }
66          }
67      }
68  
69      private void deflate() throws IOException
70      {
71          int len = _def.deflate(_buf,0,_buf.length);
72          if (len > 0)
73          {
74              out.write(_buf,0,len);
75          }
76      }
77  
78      public synchronized void finish() throws IOException
79      {
80          if (!_def.finished())
81          {
82              _def.finish();
83              while (!_def.finished())
84              {
85                  deflate();
86              }
87          }
88      }
89  
90      @Override
91      public synchronized void close() throws IOException
92      {
93          if (!closed)
94          {
95              finish();
96              out.close();
97              closed = true;
98          }
99      }
100 
101 }