解答例 - j2.lesson08.HalReader

package j2.lesson08;

import java.io.IOException;
import java.io.Reader;

/**
 * 課題2104 - 解答例.
 * 簡単な暗号を復号する {@link Reader}.
 @author arakawa
 @version $Id: HalReader_java.rps,v 1.1 2006/03/06 12:56:15 java2005 Exp $
 */
public class HalReader extends Reader {

    private final Reader plain;
    
    /**
     * 暗号化されたキャラクタストリーム ({@link Reader}) を指定して、
     * そのストリームに接続された暗号を復号化するキャラクタストリームを作成する。
     @param plain 接続する暗号化されたキャラクタストリーム
     */
    public HalReader(Reader plain) {
        super();
        this.plain = plain;
    }
    
    /**
     * このキャラクタストリームに接続されているストリームから指定した文字数だけ読み込んで、バッファの指定した位置に保存する。
     * このとき、暗号化された内容が復号化される。
     @param cbuf 保存先のバッファ
     @param off 保存先バッファの書き込む先頭位置
     @param len 読み込む長さ
     @return 実際に読み込めた長さ。ストリームの終端に達していた場合は<code>-1</code>
     @throws IOException 読み込み中に例外が発生した場合
     */
    public int read(char[] cbuf, int off, int lenthrows IOException {
        int count = this.plain.read(cbuf, off, len);
        for (int i = 0; i < count; i++) {
            cbuf[off + i(charconvert(cbuf[off + i]);
        }
        return count;
    }
    
    /**
     * このキャラクタストリームに接続されているストリームから一文字読み込んで返す。
     * このとき、暗号化された内容が復号化される。
     * 接続先のストリームが終端に達していた場合は、読んだ文字ではなく<code>-1</code>が返される。
     @return 読み込んだ値、または<code>-1</code>
     @throws IOException 読み込み中に例外が発生した場合
     */
    public int read() throws IOException {
        // 毎回 new char[1] をされるのは気に入らないのでオーバーライドする
        return convert(this.plain.read());
    }

    /**
     * 引数に渡された文字を復号化する。
     @param c 復号化する文字
     @return 復号化した文字
     */
    protected int convert(int c) {
        if (('A' <= c && c <= 'Y'|| ('a' <= c && c <= 'y'|| ('0' <= c && c <= '8')) {
            return c + 1;
        }
        else if (c == 'z') {
            return 'a';
        }
        else if (c == 'Z') {
            return 'A';
        }
        else if (c == '9') {
            return '0';
        }
        else {
            return c;
        }
    }

    /**
     * このストリームに接続されているストリームを閉じる。
     @throws IOException 閉じている最中に例外が発生した場合
     */
    public void close() throws IOException {
        this.plain.close();
    }
}