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; 023 024import org.apache.commons.compress.MemoryLimitException; 025import org.tukaani.xz.LZMAInputStream; 026 027import org.apache.commons.compress.compressors.CompressorInputStream; 028 029/** 030 * LZMA decompressor. 031 * @since 1.6 032 */ 033public class LZMACompressorInputStream extends CompressorInputStream { 034 private final InputStream in; 035 036 /** 037 * Creates a new input stream that decompresses LZMA-compressed data 038 * from the specified input stream. 039 * 040 * @param inputStream where to read the compressed data 041 * 042 * @throws IOException if the input is not in the .lzma format, 043 * the input is corrupt or truncated, the .lzma 044 * headers specify sizes that are not supported 045 * by this implementation, or the underlying 046 * <code>inputStream</code> throws an exception 047 */ 048 public LZMACompressorInputStream(final InputStream inputStream) 049 throws IOException { 050 in = new LZMAInputStream(inputStream, -1); 051 } 052 053 /** 054 * Creates a new input stream that decompresses LZMA-compressed data 055 * from the specified input stream. 056 * 057 * @param inputStream where to read the compressed data 058 * 059 * @param memoryLimitInKb calculated memory use threshold. Throws MemoryLimitException 060 * if calculate memory use is above this threshold 061 * 062 * @throws IOException if the input is not in the .lzma format, 063 * the input is corrupt or truncated, the .lzma 064 * headers specify sizes that are not supported 065 * by this implementation, or the underlying 066 * <code>inputStream</code> throws an exception 067 * 068 * @since 1.14 069 */ 070 public LZMACompressorInputStream(final InputStream inputStream, int memoryLimitInKb) 071 throws IOException { 072 try { 073 in = new LZMAInputStream(inputStream, memoryLimitInKb); 074 } catch (org.tukaani.xz.MemoryLimitException e) { 075 //convert to commons-compress exception 076 throw new MemoryLimitException(e.getMemoryNeeded(), e.getMemoryLimit(), e); 077 } 078 } 079 080 /** {@inheritDoc} */ 081 @Override 082 public int read() throws IOException { 083 final int ret = in.read(); 084 count(ret == -1 ? 0 : 1); 085 return ret; 086 } 087 088 /** {@inheritDoc} */ 089 @Override 090 public int read(final byte[] buf, final int off, final int len) throws IOException { 091 final int ret = in.read(buf, off, len); 092 count(ret); 093 return ret; 094 } 095 096 /** {@inheritDoc} */ 097 @Override 098 public long skip(final long n) throws IOException { 099 return in.skip(n); 100 } 101 102 /** {@inheritDoc} */ 103 @Override 104 public int available() throws IOException { 105 return in.available(); 106 } 107 108 /** {@inheritDoc} */ 109 @Override 110 public void close() throws IOException { 111 in.close(); 112 } 113 114 /** 115 * Checks if the signature matches what is expected for an lzma file. 116 * 117 * @param signature 118 * the bytes to check 119 * @param length 120 * the number of bytes to check 121 * @return true, if this stream is an lzma compressed stream, false otherwise 122 * 123 * @since 1.10 124 */ 125 public static boolean matches(final byte[] signature, final int length) { 126 return signature != null && length >= 3 && 127 signature[0] == 0x5d && signature[1] == 0 && 128 signature[2] == 0; 129 } 130}