/*
* Rope.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
* A rope represents character strings. Ropes are immutable which * means that once they are created, they cannot be changed. This * makes them suitable for sharing in multi-threaded environments. *
* Rope operations, unlike string operations, scale well to very * long character strings. Most mutation operations run in O(log n) * time or better. However, random-access character retrieval is * generally slower than for a String. By traversing consecutive * characters with an iterator instead, performance improves to * O(1). *
* This rope implementation implements all performance optimizations * outlined in "Ropes: an Alternative to Strings" * by Hans-J. Boehm, Russ Atkinson and Michael Plass, including, * notably, deferred evaluation of long substrings and automatic * rebalancing. *
*CharSequences
such as Strings
,
* or else from mutable CharSequences
that your program
* start
and extends to
* the character at index end - 1
or to the end of the
* sequence if no such character exists. If
* start
is equal to end
, no changes are made.
*
* @param start The beginning index, inclusive.
* @param end The ending index, exclusive.
* @return This object.
* @throws StringIndexOutOfBoundsException if start
* is negative, greater than length()
, or
* greater than end
.
*/
//@ requires start <= end && start > -1 && end <= length();
//@ ensures \result.length() == (length() - (end-start));
Rope delete(int start, int end);
/**
* Returns the index within this rope of the first occurrence of the
* specified character. If a character with value ch
occurs
* in the character sequence represented by this Rope
* object, then the index of the first such occurrence is returned --
* that is, the smallest value k such that:
*
* this.charAt(k) == ch
*
* is true
. If no such character occurs in this string, then
* -1
is returned.
* @param ch a character.
* @return the index of the first occurrence of the character in the character
* sequence represented by this object, or -1
if the character
* does not occur.
*/
//@ ensures \result >= -1 && \result < length();
int indexOf(char ch);
/**
* Returns the index within this rope of the first occurrence of the
* specified character, beginning at the specified index. If a character
* with value ch
occurs in the character sequence
* represented by this Rope
object, then the index of the
* first such occurrence is returned—that is, the smallest value k
* such that:
*
* this.charAt(k) == ch
*
* is true
. If no such character occurs in this string, then
* -1
is returned.
* @param ch a character.
* @param fromIndex the index to start searching from.
* @return the index of the first occurrence of the character in the character
* sequence represented by this object, or -1 if the character does not occur.
*/
//@ requires fromIndex > -1 && fromIndex < length();
//@ ensures \result >= -1 && \result < length();
int indexOf(char ch, int fromIndex);
/**
* Returns the index within this rope of the first occurrence of the
* specified string. The value returned is the smallest k such
* that:
*
* this.startsWith(str, k) ** If no such k exists, then -1 is returned. * @param sequence the string to find. * @return the index of the first occurrence of the specified string, or * -1 if the specified string does not occur. */ //@ requires sequence != null; //@ ensures \result >= -1 && \result < length(); int indexOf(CharSequence sequence); /** * Returns the index within this rope of the first occurrence of the * specified string, beginning at the specified index. The value returned * is the smallest k such that: *
* k >= fromIndex && this.startsWith(str, k) ** If no such k exists, then -1 is returned. * @param sequence the string to find. * @param fromIndex the index to start searching from. * @return the index of the first occurrence of the specified string, or * -1 if the specified string does not occur. */ //@ requires sequence != null && fromIndex > -1 && fromIndex < length(); //@ ensures \result >= -1 && \result < length(); int indexOf(CharSequence sequence, int fromIndex); /** * Creates a new rope by inserting the specified
CharSequence
* into this rope.
*
* The characters of the CharSequence
argument are inserted,
* in order, into this rope at the indicated offset.
*
*
If s
is null
, then the four characters
* "null"
are inserted into this sequence.
*
* @param dstOffset the offset.
* @param s the sequence to be inserted
* @return a reference to the new Rope.
* @throws IndexOutOfBoundsException if the offset is invalid.
*/
//@ requires dstOffset > -1 && dstOffset <= length();
Rope insert(int dstOffset, CharSequence s);
/**
* Returns an iterator positioned to start at the specified index.
* @param start the start position.
* @return an iterator positioned to start at the specified index.
*/
//@ requires start > -1 && start < length();
Iterator
* Matcher m = pattern.matcher(this);
*
* The difference may be asymptotically better in some cases.
* @param pattern the pattern to match this rope against.
* @return a matcher.
*/
//@ requires pattern != null;
Matcher matcher(Pattern pattern);
/**
* Returns true
if this rope matches the specified
* Pattern
, or false
otherwise.
* @see java.util.regex.Pattern
* @param regex the specified regular expression.
* @return true
if this rope matches the specified
* Pattern
, or false
otherwise.
*/
public boolean matches(Pattern regex);
/**
* Returns true
if this rope matches the specified
* regular expression, or false
otherwise.
* @see java.util.regex.Pattern
* @param regex the specified regular expression.
* @return true
if this rope matches the specified
* regular expression, or false
otherwise.
*/
public boolean matches(String regex);
/**
* Rebalances the current rope, returning the rebalanced rope. In general,
* rope rebalancing is handled automatically, but this method is provided
* to give users more control.
*
* @return a rebalanced rope.
*/
public Rope rebalance();
/**
* Reverses this rope.
* @return a reversed copy of this rope.
*/
public Rope reverse();
/**
* Returns a reverse iterator positioned to start at the end of this
* rope. A reverse iterator moves backwards instead of forwards through
* a rope.
* @return A reverse iterator positioned at the end of this rope.
* @see Rope#reverseIterator(int)
*/
Iterator0x20
from
* the end of this rope.
* @return a rope with all trailing whitespace trimmed.
*/
//@ ensures \result.length() <= length();
Rope trimEnd();
@Override
Rope subSequence(int start, int end);
/**
* Trims all whitespace as well as characters less than 0x20
from
* the beginning and end of this string.
* @return a rope with all leading and trailing whitespace trimmed.
*/
Rope trim();
/**
* Write this rope to a Writer
.
* @param out the writer object.
*/
public void write(Writer out) throws IOException;
/**
* Write a range of this rope to a Writer
.
* @param out the writer object.
* @param offset the range offset.
* @param length the range length.
*/
public void write(Writer out, int offset, int length) throws IOException;
/**
* Increase the length of this rope to the specified length by prepending
* spaces to this rope. If the specified length is less than or equal to
* the current length of the rope, the rope is returned unmodified.
* @param toLength the desired length.
* @return the padded rope.
* @see #padStart(int, char)
*/
public Rope padStart(int toLength);
/**
* Increase the length of this rope to the specified length by repeatedly
* prepending the specified character to this rope. If the specified length
* is less than or equal to the current length of the rope, the rope is
* returned unmodified.
* @param toLength the desired length.
* @param padChar the character to use for padding.
* @return the padded rope.
* @see #padStart(int, char)
*/
public Rope padStart(int toLength, char padChar);
/**
* Increase the length of this rope to the specified length by appending
* spaces to this rope. If the specified length is less than or equal to
* the current length of the rope, the rope is returned unmodified.
* @param toLength the desired length.
* @return the padded rope.
* @see #padStart(int, char)
*/
public Rope padEnd(int toLength);
/**
* Increase the length of this rope to the specified length by repeatedly
* appending the specified character to this rope. If the specified length
* is less than or equal to the current length of the rope, the rope is
* returned unmodified.
* @param toLength the desired length.
* @param padChar the character to use for padding.
* @return the padded rope.
* @see #padStart(int, char)
*/
public Rope padEnd(int toLength, char padChar);
/**
* Returns true if and only if the length of this rope is zero.
* @return true
if and only if the length of this
* rope is zero, and false
otherwise.
*/
public boolean isEmpty();
/**
* Returns true
if this rope starts with the specified
* prefix.
* @param prefix the prefix to test.
* @return true
if this rope starts with the
* specified prefix and false
otherwise.
* @see #startsWith(CharSequence, int)
*/
public boolean startsWith(CharSequence prefix);
/**
* Returns true
if this rope, beginning from a specified
* offset, starts with the specified prefix.
* @param prefix the prefix to test.
* @param offset the start offset.
* @return true
if this rope starts with the
* specified prefix and false
otherwise.
*/
public boolean startsWith(CharSequence prefix, int offset);
/**
* Returns true
if this rope ends with the specified
* suffix.
* @param suffix the suffix to test.
* @return true
if this rope starts with the
* specified suffix and false
otherwise.
* @see #endsWith(CharSequence, int)
*/
public boolean endsWith(CharSequence suffix);
/**
* Returns true
if this rope, terminated at a specified
* offset, ends with the specified suffix.
* @param suffix the suffix to test.
* @param offset the termination offset, counted from the end of the
* rope.
* @return true
if this rope starts with the
* specified prefix and false
otherwise.
*/
public boolean endsWith(CharSequence suffix, int offset);
}