package net.katsuster.strview.util;

/**
 * <p>
 * 半開区間 [start, end) を表すクラスです。
 * </p>
 *
 * <p>
 * end = start + length です。
 * </p>
 *
 * @author katsuhiro
 */
public class SimpleRange
        implements Range, Cloneable {
    private long start;
    private long length;

    /**
     * <p>
     * 開始点と終了点を指定せず半開区間を構築します。
     * </p>
     */
    public SimpleRange() {
        this(0, 0);
    }

    /**
     * <p>
     * 開始点と終了点を指定して半開区間を構築します。
     * </p>
     *
     * @param s 区間の開始地点
     * @param l 区間の長さ
     */
    public SimpleRange(long s, long l) {
        start = s;
        length = l;
    }

    /**
     * <p>
     * 半開区間を構築します。
     * </p>
     *
     * @param obj 区間
     */
    public SimpleRange(Range obj) {
        this(obj.getStart(), obj.getLength());
    }

    /**
     * <p>
     * 区間の位置と長さを、
     * コピーした新たな区間を返します。
     * </p>
     *
     * @return コピーされたオブジェクト
     * @throws CloneNotSupportedException インスタンスを複製できない場合
     */
    public SimpleRange clone() throws CloneNotSupportedException {
        SimpleRange obj = (SimpleRange)super.clone();

        return obj;
    }

    /**
     * <p>
     * オブジェクトを指定されたオブジェクトと比較します。
     * 結果が true になるのは、引数が null ではなく、
     * このオブジェクトと同じ生成元、開始位置、
     * 長さを持つオブジェクトである場合だけです。
     * </p>
     *
     * @param obj 比較対象のオブジェクト
     * @return オブジェクトが同じである場合は true、そうでない場合は false
     */
    @Override
    public boolean equals(Object obj) {
        SimpleRange objp;

        if (!(obj instanceof SimpleRange)) {
            return false;
        }
        objp = (SimpleRange)obj;

        if ((start != objp.start)
                || (length != objp.length)) {
            return false;
        }

        return true;
    }

    /**
     * <p>
     * オブジェクトのハッシュコードを返します。
     * </p>
     *
     * @return オブジェクトが保持する start, length を、
     * 変換式 (val ^ (val &gt;&gt; 32)) にて int に変換した値を
     * 全て xor した値
     */
    @Override
    public int hashCode() {
        return (int)((start ^ (start >> 32))
                ^ (length ^ (length >> 32)));
    }

    @Override
    public long getStart() {
        return start;
    }

    @Override
    public void setStart(long p) {
        start = p;
    }

    @Override
    public long getEnd() {
        return start + length;
    }

    @Override
    public void setEnd(long p) {
        length = p - start;
    }

    @Override
    public long getLength() {
        return length;
    }

    @Override
    public void setLength(long l) {
        length = l;
    }

    @Override
    public boolean isHit(long i) {
        if (getStart() <= i && i < getEnd()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return String.format("addr:%d-%d(len:%d)",
                getStart(), getEnd(), getLength());
    }
}

@@ -547,32 +547,286 @@
 ng s, long l) %7B%0A
+        if (s %3C 0) %7B%0A            throw new IllegalArgumentException(%22start:%22 + s + %22 is negative.%22);%0A        %7D%0A        if (l != Range.LENGTH_UNKNOWN && l %3C 0) %7B%0A            throw new NegativeArraySizeException(%22length:%22 + l + %22 is negative.%22);%0A        %7D%0A
         start = 
@@ -2410,151 +2410,503 @@
     
-start = p;%0A    %7D%0A%0A    @Override%0A    public long getEnd() %7B%0A        return start + length;%0A    %7D%0A%0A    @Override%0A    public void setEnd(long p) %7B
+if (p %3C 0) %7B%0A            throw new IllegalArgumentException(%22new start:%22 + p + %22 is negative.%22);%0A        %7D%0A        start = p;%0A    %7D%0A%0A    @Override%0A    public long getEnd() %7B%0A        if (length == Range.LENGTH_UNKNOWN) %7B%0A            return Range.LENGTH_UNKNOWN;%0A        %7D%0A        return start + length;%0A    %7D%0A%0A    @Override%0A    public void setEnd(long p) %7B%0A        if (p %3C start) %7B%0A            throw new NegativeArraySizeException(%22new end:%22 + p + %22 is less than start:%22 + start + %22.%22);%0A        %7D
 %0A   
@@ -3053,32 +3053,179 @@
 ength(long l) %7B%0A
+        if (l != Range.LENGTH_UNKNOWN && l %3C 0) %7B%0A            throw new NegativeArraySizeException(%22new length:%22 + l + %22 is negative.%22);%0A        %7D%0A
         length =

Add error checks in SimpleRange class.