001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package org.apache.hadoop.io.compress;
020    
021    import java.io.IOException;
022    import java.io.OutputStream;
023    
024    import org.apache.hadoop.classification.InterfaceAudience;
025    import org.apache.hadoop.classification.InterfaceStability;
026    
027    /**
028     * A compression output stream.
029     */
030    @InterfaceAudience.Public
031    @InterfaceStability.Evolving
032    public abstract class CompressionOutputStream extends OutputStream {
033      /**
034       * The output stream to be compressed. 
035       */
036      protected final OutputStream out;
037    
038      /**
039       * If non-null, this is the Compressor object that we should call
040       * CodecPool#returnCompressor on when this stream is closed.
041       */
042      private Compressor trackedCompressor;
043    
044      /**
045       * Create a compression output stream that writes
046       * the compressed bytes to the given stream.
047       * @param out
048       */
049      protected CompressionOutputStream(OutputStream out) {
050        this.out = out;
051      }
052    
053      void setTrackedCompressor(Compressor compressor) {
054        trackedCompressor = compressor;
055      }
056    
057      @Override
058      public void close() throws IOException {
059        finish();
060        out.close();
061        if (trackedCompressor != null) {
062          CodecPool.returnCompressor(trackedCompressor);
063          trackedCompressor = null;
064        }
065      }
066      
067      @Override
068      public void flush() throws IOException {
069        out.flush();
070      }
071      
072      /**
073       * Write compressed bytes to the stream.
074       * Made abstract to prevent leakage to underlying stream.
075       */
076      @Override
077      public abstract void write(byte[] b, int off, int len) throws IOException;
078    
079      /**
080       * Finishes writing compressed data to the output stream 
081       * without closing the underlying stream.
082       */
083      public abstract void finish() throws IOException;
084      
085      /**
086       * Reset the compression to the initial state. 
087       * Does not reset the underlying stream.
088       */
089      public abstract void resetState() throws IOException;
090    
091    }