/*
 **********************************************************************
 * Copyright (c) 2006-2007, Google and others.  All Rights Reserved.
 **********************************************************************
 * Author: Mark Davis
 **********************************************************************
 */
package org.unicode.cldr.util;

/**
 * Implements a sequence of chars that is logically based on another source,
 * which may require incremental processing. For example, where a 10M document
 * is being searched, one may not want to convert the whole document if an item
 * might be found in the first few lines. Thus there is no length() method; use
 * hasCharAt instead.
 * <ul>
 * <li>To force the source to grow to the end, use hasCharAt(Integer.MAX_VALUE).
 * <li>The method discardBefore can be called to release the source before a given offset. Once it is called, then any
 * attempt to access data or offsets before that point will cause an exception.
 * <li>To see
 * </ul>
 * 
 * @author markdavis
 * 
 */
public interface CharSource {
    /**
     * Determine whether there is a char at the position. When converting from
     * code that uses String or other CharSequence:
     * <ul>
     * <li>replace index < x.length() with x.hasCharAt(index)
     * <li>replace index >= x.length() with !x.hasCharAt(index)
     * <li>replace index == x.length() also with !x.hasCharAt(index) <b> [whenever we are iterating index upwards]</b>
     * </ul>
     * Throws an exception if index < 0.
     * 
     * @param index
     * @return
     */
    public boolean hasCharAt(int index);

    /**
     * Get the character at the index. Will grow the charlist if the source can
     * supply the character. Will throw an exception if the index is less than
     * zero or not less than the length.
     */
    public char charAt(int index);

    /**
     * Get the source offset for the index. For example, where the source is
     * UTF-8, this will differ significantly from the UTF-16 index used in
     * CharSequence or String Java. It will grow the internal source if possible to get to the index.
     * This will throw an exception if the index is
     * greater than or equal to the length, or if it is less than the last.
     * 
     * @param index
     * @return
     */
    public int toSourceOffset(int index);

    /**
     * Get the index from the source offset; the reverse of the toSourceOffset method. It will not grow the source,
     * however.
     * 
     * @param index
     * @return
     */
    public int fromSourceOffset(int index);

    /**
     * Corresponds to subSequence or subString. May grow the charlist if needed to
     * get the char before end.
     * 
     * @param start
     * @param end
     * @return
     */
    public CharSource sublist(int start, int end);

    /**
     * Corresponds to subSequence or subString. May grow the charlist if needed to
     * get the char before end.
     * 
     * @param start
     * @param end
     * @return
     */
    public CharSequence subSequence(int start, int end);

    /**
     * Returns a CharList that starts at the given point, and extends further.
     * Operations on either one may affect the other.
     * 
     * @param start
     * @param end
     * @return
     */
    public CharSource sublist(int start);

    /**
     * Return the length known so far. If hasCharAt(getKnownLength()) == false,
     * then it is the real length.
     * 
     * @return
     */
    public int getKnownLength();

    /**
     * Allow the implementation to discard source before the given index. After
     * this is called, all attempted access to data or offsets before the given
     * offset may throw an exception. This is a request; the implementation may
     * ignore it, and just leave the start at 0.
     */
    public CharSource setStart(int index);

    /**
     * Get the start index.
     */
    public int getStart();
}