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, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.compress.compressors.lzma; 020 021import java.io.IOException; 022import java.io.InputStream; 023import org.tukaani.xz.LZMAInputStream; 024 025import org.apache.commons.compress.compressors.CompressorInputStream; 026 027/** 028 * LZMA decompressor. 029 * @since 1.6 030 */ 031public class LZMACompressorInputStream extends CompressorInputStream { 032 private final InputStream in; 033 034 /** 035 * Creates a new input stream that decompresses LZMA-compressed data 036 * from the specified input stream. 037 * 038 * @param inputStream where to read the compressed data 039 * 040 * @throws IOException if the input is not in the .lzma format, 041 * the input is corrupt or truncated, the .lzma 042 * headers specify sizes that are not supported 043 * by this implementation, or the underlying 044 * <code>inputStream</code> throws an exception 045 */ 046 public LZMACompressorInputStream(final InputStream inputStream) 047 throws IOException { 048 in = new LZMAInputStream(inputStream); 049 } 050 051 /** {@inheritDoc} */ 052 @Override 053 public int read() throws IOException { 054 final int ret = in.read(); 055 count(ret == -1 ? 0 : 1); 056 return ret; 057 } 058 059 /** {@inheritDoc} */ 060 @Override 061 public int read(final byte[] buf, final int off, final int len) throws IOException { 062 final int ret = in.read(buf, off, len); 063 count(ret); 064 return ret; 065 } 066 067 /** {@inheritDoc} */ 068 @Override 069 public long skip(final long n) throws IOException { 070 return in.skip(n); 071 } 072 073 /** {@inheritDoc} */ 074 @Override 075 public int available() throws IOException { 076 return in.available(); 077 } 078 079 /** {@inheritDoc} */ 080 @Override 081 public void close() throws IOException { 082 in.close(); 083 } 084 085 /** 086 * Checks if the signature matches what is expected for an lzma file. 087 * 088 * @param signature 089 * the bytes to check 090 * @param length 091 * the number of bytes to check 092 * @return true, if this stream is an lzma compressed stream, false otherwise 093 * 094 * @since 1.10 095 */ 096 public static boolean matches(final byte[] signature, final int length) { 097 098 if (signature == null || length < 3) { 099 return false; 100 } 101 102 if (signature[0] != 0x5d) { 103 return false; 104 } 105 106 if (signature[1] != 0) { 107 return false; 108 } 109 110 if (signature[2] != 0) { 111 return false; 112 } 113 114 return true; 115 } 116}