/*
* FlatCharRope.java
* Copyright (C) 2007 Amin Ahmad.
*
* This file is part of Java Ropes.
*
* Java Ropes is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Java Ropes is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Java Ropes. If not, see .
*
* Amin Ahmad can be contacted at amin.ahmad@gmail.com or on the web at
* www.ahmadsoft.org.
*/
package org.ahmadsoft.ropes.impl;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Iterator;
import org.ahmadsoft.ropes.Rope;
/**
* A rope constructed from a character array. This rope is even
* flatter than a regular flat rope.
* @author Amin Ahmad
*/
public final class FlatCharArrayRope extends AbstractRope implements FlatRope {
private final char[] sequence;
/**
* Constructs a new rope from a character array.
* @param sequence the character array.
*/
public FlatCharArrayRope(final char[] sequence) {
this(sequence, 0, sequence.length);
}
/**
* Constructs a new rope from a character array range.
* @param sequence the character array.
* @param offset the offset in the array.
* @param length the length of the array.
*/
public FlatCharArrayRope(final char[] sequence, final int offset, final int length) {
if (length > sequence.length)
throw new IllegalArgumentException("Length must be less than " + sequence.length);
this.sequence = new char[length];
System.arraycopy(sequence, offset, this.sequence, 0, length);
}
@Override
public char charAt(final int index) {
return this.sequence[index];
}
@Override
public byte depth() {
return 0;
}
/*
* Implementation Note: This is a reproduction of the AbstractRope
* indexOf implementation. Calls to charAt have been replaced
* with direct array access to improve speed.
*/
@Override
public int indexOf(final char ch) {
for (int j=0; j= this.length())
throw new IndexOutOfBoundsException("Rope index out of range: " + fromIndex);
for (int j=fromIndex; j iterator(final int start) {
if (start < 0 || start > this.length())
throw new IndexOutOfBoundsException("Rope index out of range: " + start);
return new Iterator() {
int current = start;
@Override
public boolean hasNext() {
return this.current < FlatCharArrayRope.this.length();
}
@Override
public Character next() {
return FlatCharArrayRope.this.sequence[this.current++];
}
@Override
public void remove() {
throw new UnsupportedOperationException("Rope iterator is read-only.");
}
};
}
@Override
public int length() {
return this.sequence.length;
}
@Override
public Rope reverse() {
return new ReverseRope(this);
}
@Override
public Iterator reverseIterator(final int start) {
if (start < 0 || start > this.length())
throw new IndexOutOfBoundsException("Rope index out of range: " + start);
return new Iterator() {
int current = FlatCharArrayRope.this.length() - start;
@Override
public boolean hasNext() {
return this.current > 0;
}
@Override
public Character next() {
return FlatCharArrayRope.this.sequence[--this.current];
}
@Override
public void remove() {
throw new UnsupportedOperationException("Rope iterator is read-only.");
}
};
}
@Override
public Rope subSequence(final int start, final int end) {
if (start == 0 && end == this.length())
return this;
if (end - start < 16) {
return new FlatCharArrayRope(this.sequence, start, end-start);
} else {
return new SubstringRope(this, start, end-start);
}
}
@Override
public String toString() {
return new String(this.sequence);
}
public String toString(final int offset, final int length) {
return new String(this.sequence, offset, length);
}
@Override
public void write(final Writer out) throws IOException {
this.write(out, 0, this.length());
}
@Override
public void write(final Writer out, final int offset, final int length) throws IOException {
out.write(this.sequence, offset, length);
}
}