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.*;
022 import java.util.zip.GZIPOutputStream;
023 import org.apache.hadoop.classification.InterfaceAudience;
024 import org.apache.hadoop.classification.InterfaceStability;
025 import org.apache.hadoop.conf.Configuration;
026 import org.apache.hadoop.io.compress.DefaultCodec;
027 import org.apache.hadoop.io.compress.zlib.*;
028
029 /**
030 * This class creates gzip compressors/decompressors.
031 */
032 @InterfaceAudience.Public
033 @InterfaceStability.Evolving
034 public class GzipCodec extends DefaultCodec {
035 /**
036 * A bridge that wraps around a DeflaterOutputStream to make it
037 * a CompressionOutputStream.
038 */
039 @InterfaceStability.Evolving
040 protected static class GzipOutputStream extends CompressorStream {
041
042 private static class ResetableGZIPOutputStream extends GZIPOutputStream {
043
044 public ResetableGZIPOutputStream(OutputStream out) throws IOException {
045 super(out);
046 }
047
048 public void resetState() throws IOException {
049 def.reset();
050 }
051 }
052
053 public GzipOutputStream(OutputStream out) throws IOException {
054 super(new ResetableGZIPOutputStream(out));
055 }
056
057 /**
058 * Allow children types to put a different type in here.
059 * @param out the Deflater stream to use
060 */
061 protected GzipOutputStream(CompressorStream out) {
062 super(out);
063 }
064
065 @Override
066 public void close() throws IOException {
067 out.close();
068 }
069
070 @Override
071 public void flush() throws IOException {
072 out.flush();
073 }
074
075 @Override
076 public void write(int b) throws IOException {
077 out.write(b);
078 }
079
080 @Override
081 public void write(byte[] data, int offset, int length)
082 throws IOException {
083 out.write(data, offset, length);
084 }
085
086 @Override
087 public void finish() throws IOException {
088 ((ResetableGZIPOutputStream) out).finish();
089 }
090
091 @Override
092 public void resetState() throws IOException {
093 ((ResetableGZIPOutputStream) out).resetState();
094 }
095 }
096
097 @Override
098 public CompressionOutputStream createOutputStream(OutputStream out)
099 throws IOException {
100 return (ZlibFactory.isNativeZlibLoaded(conf)) ?
101 new CompressorStream(out, createCompressor(),
102 conf.getInt("io.file.buffer.size", 4*1024)) :
103 new GzipOutputStream(out);
104 }
105
106 @Override
107 public CompressionOutputStream createOutputStream(OutputStream out,
108 Compressor compressor)
109 throws IOException {
110 return (compressor != null) ?
111 new CompressorStream(out, compressor,
112 conf.getInt("io.file.buffer.size",
113 4*1024)) :
114 createOutputStream(out);
115 }
116
117 @Override
118 public Compressor createCompressor() {
119 return (ZlibFactory.isNativeZlibLoaded(conf))
120 ? new GzipZlibCompressor(conf)
121 : null;
122 }
123
124 @Override
125 public Class<? extends Compressor> getCompressorType() {
126 return ZlibFactory.isNativeZlibLoaded(conf)
127 ? GzipZlibCompressor.class
128 : null;
129 }
130
131 @Override
132 public CompressionInputStream createInputStream(InputStream in)
133 throws IOException {
134 return createInputStream(in, null);
135 }
136
137 @Override
138 public CompressionInputStream createInputStream(InputStream in,
139 Decompressor decompressor)
140 throws IOException {
141 if (decompressor == null) {
142 decompressor = createDecompressor(); // always succeeds (or throws)
143 }
144 return new DecompressorStream(in, decompressor,
145 conf.getInt("io.file.buffer.size", 4*1024));
146 }
147
148 @Override
149 public Decompressor createDecompressor() {
150 return (ZlibFactory.isNativeZlibLoaded(conf))
151 ? new GzipZlibDecompressor()
152 : new BuiltInGzipDecompressor();
153 }
154
155 @Override
156 public Class<? extends Decompressor> getDecompressorType() {
157 return ZlibFactory.isNativeZlibLoaded(conf)
158 ? GzipZlibDecompressor.class
159 : BuiltInGzipDecompressor.class;
160 }
161
162 @Override
163 public String getDefaultExtension() {
164 return ".gz";
165 }
166
167 static final class GzipZlibCompressor extends ZlibCompressor {
168 public GzipZlibCompressor() {
169 super(ZlibCompressor.CompressionLevel.DEFAULT_COMPRESSION,
170 ZlibCompressor.CompressionStrategy.DEFAULT_STRATEGY,
171 ZlibCompressor.CompressionHeader.GZIP_FORMAT, 64*1024);
172 }
173
174 public GzipZlibCompressor(Configuration conf) {
175 super(ZlibFactory.getCompressionLevel(conf),
176 ZlibFactory.getCompressionStrategy(conf),
177 ZlibCompressor.CompressionHeader.GZIP_FORMAT,
178 64 * 1024);
179 }
180 }
181
182 static final class GzipZlibDecompressor extends ZlibDecompressor {
183 public GzipZlibDecompressor() {
184 super(ZlibDecompressor.CompressionHeader.AUTODETECT_GZIP_ZLIB, 64*1024);
185 }
186 }
187
188 }