All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.orangesignal.jlha.LhaInputStream Maven / Gradle / Ivy

Go to download

OrangeSignal CSV is a very flexible csv (comma-separated values) read and write library for Java.

The newest version!
/**
 * Copyright (C) 2002  Michel Ishizuka  All rights reserved.
 * 
 * 以下の条件に同意するならばソースとバイナリ形式の再配布と使用を
 * 変更の有無にかかわらず許可する。
 * 
 * 1.ソースコードの再配布において著作権表示と この条件のリスト
 *     および下記の声明文を保持しなくてはならない。
 * 
 * 2.バイナリ形式の再配布において著作権表示と この条件のリスト
 *     および下記の声明文を使用説明書もしくは その他の配布物内に
 *     含む資料に記述しなければならない。
 * 
 * このソフトウェアは石塚美珠瑠によって無保証で提供され、特定の目
 * 的を達成できるという保証、商品価値が有るという保証にとどまらず、
 * いかなる明示的および暗示的な保証もしない。
 * 石塚美珠瑠は このソフトウェアの使用による直接的、間接的、偶発
 * 的、特殊な、典型的な、あるいは必然的な損害(使用によるデータの
 * 損失、業務の中断や見込まれていた利益の遺失、代替製品もしくは
 * サービスの導入費等が考えられるが、決してそれだけに限定されない
 * 損害)に対して、いかなる事態の原因となったとしても、契約上の責
 * 任や無過失責任を含む いかなる責任があろうとも、たとえそれが不
 * 正行為のためであったとしても、またはそのような損害の可能性が報
 * 告されていたとしても一切の責任を負わないものとする。
 */

package com.orangesignal.jlha;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Properties;

/**
 * 接続されたストリームからLHA書庫データを読みこみ、 エントリを解凍しつつ読み込むためのユーティリティクラス。
* java.util.zip.ZipInputStream と似たインターフェイスを持つように作った。
* 壊れた書庫の処理に関しては壊れたエントリ以降の 壊れていないエントリも正常に読みこめない可能性がある。
* *
 * -- revision history --
 * $Log: LhaInputStream.java,v $
 * Revision 1.1.2.1  2003/07/20 13:22:31  dangan
 * [bug fix]
 *     getNextEntry() で CompressMethod.connectDecoder に 
 *     this.limit を渡すべきところで this.in を渡していた。
 * 
 * Revision 1.1  2002/12/08 00:00:00  dangan
 * [maintenance]
 *     LhaConstants から CompressMethod へのクラス名の変更に合わせて修正。
 * 
 * Revision 1.0  2002/08/05 00:00:00  dangan
 * add to version control
 * [change]
 *     コンストラクタから 引数に String encode を取るものを廃止、
 *     Properties を引数に取るものを追加。
 *     書庫終端に達した場合はそれ以上読み込めないように修正。
 *     available() の振る舞いを java.util.zip.ZipInputStream と同じように
 *     エントリの終端に達していない場合は 1 エントリの終端に達した場合は 0 を返すように変更。
 * [maintenance]
 *     ソース整備
 *     タブ廃止
 *     ライセンス文の修正
 * 
 * 
* * @author $Author: dangan $ * @version $Revision: 1.1.2.1 $ */ public class LhaInputStream extends InputStream { /** * LHA書庫形式のデータを供給するInputStream。 */ private InputStream source; /** * 既に最初のエントリを読み込んでいるかを示す。 */ private boolean alreadyOpenedFirstEnrty; /** * 書庫終端に達したかを示す。 */ private boolean reachedEndOfArchive; /** * LHA書庫内の1エントリの解凍されたデータ を供給する InputStream。 */ private InputStream in; /** * LHA書庫内の1エントリの圧縮されたデータ を供給するLimitedInputStream。 closeEntry 時にスキップするため。 */ private LimitedInputStream limit; /** * 現在処理中のエントリの終端に達した時に true にセットされる。 */ private boolean reachedEndOfEntry; /** * reachEndOfEntry のバックアップ用 */ private boolean markReachedEndOfEntry; /** * 各圧縮形式に対応した復号器の生成式等が含まれるプロパティ */ private Properties property; // ------------------------------------------------------------------ // Constructor /** * in から LHA書庫のデータを読み取る InputStream を構築する。
* 各圧縮形式に対応した復号器の生成式等を持つプロパティには LhaProperty.getProperties() で得られたプロパティが使用される。
* * @param in LHA書庫形式のデータを供給する入力ストリーム * * @see LhaProperty#getProperties() */ public LhaInputStream(final InputStream in) { final Properties property = LhaProperty.getProperties(); try { constructerHelper(in, property); // After Java 1.1 throws UnsupportedEncodingException } catch (final UnsupportedEncodingException exception) { throw new Error("Unsupported encoding \"" + property.getProperty("lha.encoding") + "\"."); } } /** * in から LHA書庫のデータを読み取る InputStreamを構築する。
* * @param in LHA書庫形式のデータを供給する入力ストリーム * @param property 各圧縮形式に対応した復号器の生成式等が含まれるプロパティ * @exception UnsupportedEncodingException property.getProperty( "lha.encoding" ) で得られた エンコーディング名がサポートされない場合 */ public LhaInputStream(final InputStream in, final Properties property) throws UnsupportedEncodingException { constructerHelper(in, property); // After Java 1.1 throws UnsupportedEncodingException } /** * コンストラクタの初期化処理を担当するメソッド。 * * @param in LHA書庫形式のデータを供給する入力ストリーム * @param property 各圧縮形式に対応した復号器の生成式等が含まれるプロパティ * @exception UnsupportedEncodingException encode がサポートされない場合 */ private void constructerHelper(final InputStream in, final Properties property) throws UnsupportedEncodingException { if (in != null && property != null) { String encoding = property.getProperty("lha.encoding"); if (encoding == null) { encoding = LhaProperty.getProperty("lha.encoding"); } // encoding名チェック encoding.getBytes(encoding); // After Java 1.1 throws UnsupportedEncodingException if (in.markSupported()) { source = in; } else { source = new BufferedInputStream(in); } this.in = null; limit = null; this.property = (Properties) property.clone(); reachedEndOfEntry = false; reachedEndOfArchive = false; } else if (in == null) { throw new NullPointerException("in"); } else { throw new NullPointerException("property"); } } // ------------------------------------------------------------------ // method of java.io.InputStream /** * 現在のエントリから 1バイトのデータを読み込む。 * * @return 読みこまれた 1バイトのデータ。
* 既にエントリの終端に達した場合は -1 * * @exception IOException 現在読み込み中のエントリが無いか 入出力エラーが発生した場合 */ @Override public int read() throws IOException { if (in != null) { final int ret = in.read(); // throws IOException if (ret < 0) { reachedEndOfEntry = true; } return ret; } throw new IOException("no entry"); } /** * 現在のエントリから buffer を満たすようにデータを読み込む。 * * @param buffer データを読み込むバッファ * @return 読みこまれたデータの量。
既にエントリの終端に達した場合は -1。 * @exception IOException 現在読み込み中のエントリが無いか 入出力エラーが発生した場合 */ @Override public int read(final byte[] buffer) throws IOException { return this.read(buffer, 0, buffer.length); // throws IOException } /** * 現在のエントリから buffer のindexへ lengthバイトの データをを読み込む。 * * @param buffer データを読み込むバッファ * @param index buffer内のデータ読み込み開始位置 * @param length 読み込むデータ量 * @return 読みこまれたデータの量。
既にエントリの終端に達した場合は -1。 * @exception IOException 現在読み込み中のエントリが無いか 入出力エラーが発生した場合 */ @Override public int read(final byte[] buffer, final int index, final int length) throws IOException { if (in != null) { final int ret = in.read(buffer, index, length); // throws IOException if (ret < 0) { reachedEndOfEntry = true; } return ret; } throw new IOException("no entry"); } /** * 現在のエントリのデータを length バイト読みとばす。 * * @param length 読みとばすデータ量 * @return 実際に読みとばしたデータ量 * @exception IOException 現在読み込み中のエントリが無いか 入出力エラーが発生した場合 */ @Override public long skip(final long length) throws IOException { if (in != null) { if (0 < length) { final long len = in.skip(length - 1); // throws IOException final int ret = in.read(); // throws IOException if (ret < 0) { reachedEndOfEntry = true; return len; } return len + 1; } return 0; } throw new IOException("no entry"); } /** * 現在読み取り中のエントリの現在位置にマークを設定し、 reset() でマークした読み込み位置に戻れるようにする。
* * @param readLimit マーク位置に戻れる限界読み込み量。 このバイト数を超えてデータを読み込んだ場合 reset() できる保証はない。 * @exception IllegalStateException 現在読み込み中のエントリが無い場合 */ @Override public void mark(final int readLimit) { if (in != null) { in.mark(readLimit); markReachedEndOfEntry = reachedEndOfEntry; } else { throw new IllegalStateException(); } } /** * 現在読み取り中のエントリの読み込み位置を最後に mark() メソッドが呼び出されたときの位置に設定する。 * * @exception IOException 現在読み込み中のエントリが無いか 入出力エラーが発生した場合 */ @Override public void reset() throws IOException { if (in != null) { in.reset(); // throws IOException reachedEndOfEntry = markReachedEndOfEntry; } else { throw new IOException("no entry"); } } /** * 接続された入力ストリームが mark()と reset()をサポートするかを得る。
* ヘッダ読み込み時に mark/reset が必須のため コンストラクタで渡された in が markSupported() で false を返す場合、このクラスは in を mark/reset をサポートする BufferedInputStream でラップする。 そのため、このメソッドは常に true を返す。 * * @return 常に true */ @Override public boolean markSupported() { return source.markSupported(); } /** * 現在読み取り中のエントリの終端に達したかを得る。
* ブロックしないで読み込めるデータ量を返さない事に注意すること。 * * @return 現在読み取り中のエントリの終端に達した場合 0 達していない場合 1 * @exception IOException 現在読み込み中のエントリが無いか 入出力エラーが発生した場合 * @see java.util.zip.ZipInputStream#available() */ @Override public int available() throws IOException { if (in != null) { return reachedEndOfEntry ? 0 : 1; } throw new IOException("no entry"); } /** * この入力ストリームを閉じ、使用していた 全てのリソースを開放する。 * * @exception IOException 入出力エラーが発生した場合 */ @Override public void close() throws IOException { if (in != null) { in.close(); limit = null; in = null; } source.close(); source = null; } // ------------------------------------------------------------------ // original method ( on the model of java.util.zip.ZipInputStream ) /** * 次のエントリを解凍しながら読みこむようにストリームを設定する。
* * @return エントリの情報を持つ LhaHeader * @exception IOException 入出力エラーが発生した場合 */ public LhaHeader getNextEntry() throws IOException { if (!reachedEndOfArchive) { if (in != null) { closeEntry(); // throws IOException } byte[] HeaderData; if (alreadyOpenedFirstEnrty) { HeaderData = LhaHeader.getNextHeaderData(source); } else { HeaderData = LhaHeader.getFirstHeaderData(source); alreadyOpenedFirstEnrty = true; } if (null != HeaderData) { final LhaHeader header = LhaHeader.createInstance(HeaderData, property); in = new DisconnectableInputStream(source); limit = new LimitedInputStream(in, header.getCompressedSize()); in = CompressMethod.connectDecoder(limit, header.getCompressMethod(), property, header.getOriginalSize()); reachedEndOfEntry = false; markReachedEndOfEntry = false; return header; } reachedEndOfArchive = true; return null; } return null; } /** * 次のエントリを解凍しないで読みこむようにストリームを設定する。
* * @return エントリの情報を持つ LhaHeader * @exception IOException 入出力エラーが発生した場合 */ public LhaHeader getNextEntryWithoutExtract() throws IOException { if (!reachedEndOfArchive) { if (in != null) { closeEntry(); // throws IOException } byte[] HeaderData; if (alreadyOpenedFirstEnrty) { HeaderData = LhaHeader.getNextHeaderData(source); } else { HeaderData = LhaHeader.getFirstHeaderData(source); alreadyOpenedFirstEnrty = true; } if (HeaderData != null) { final LhaHeader header = LhaHeader.createInstance(HeaderData, property); in = new DisconnectableInputStream(source); limit = new LimitedInputStream(in, header.getCompressedSize()); in = limit; reachedEndOfEntry = false; markReachedEndOfEntry = false; return header; } reachedEndOfArchive = true; return null; } return null; } /** * 現在読み取り中のエントリを閉じ、 次のエントリを読みこめるようにストリームを設定する。 * * @exception IOException 入出力エラーが発生した場合 */ public void closeEntry() throws IOException { if (in != null) { while (0 <= limit.read()) { limit.skip(Long.MAX_VALUE); } in.close(); in = null; limit = null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy