/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2003 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.dynamo.index;

class StaticCharStream implements CharStream
{
  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private char[] m_array;      // array full of characters to be read
  int m_pos = 0;               // index of next character to be read
  int m_tokenstart = 0;        // index of start of token

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  StaticCharStream(String s)
  {
    m_array = s.toCharArray();

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Implementations from interface CharStream
   *--------------------------------------------------------------------------------
   */

  /**
   * Returns the next character from the selected input.  The method
   * of selecting the input is the responsibility of the class
   * implementing this interface.  Can throw any java.io.IOException.
   */
  public char readChar() throws java.io.IOException
  {
    if (m_pos==m_array.length)
      throw new java.io.IOException("read past EOF");
    return m_array[m_pos++];

  } // end readChar

  /**
   * Returns the column position of the character last read.
   * @deprecated 
   * @see #getEndColumn
   */
  public int getColumn()
  {
    return m_pos;

  } // end getColumn

  /**
   * Returns the line number of the character last read.
   * @deprecated 
   * @see #getEndLine
   */
  public int getLine()
  {
    return 1;

  } // end getLine

  /**
   * Returns the column number of the last character for current token (being
   * matched after the last call to BeginTOken).
   */
  public int getEndColumn()
  {
    return m_pos;

  } // end getEndColumn

  /**
   * Returns the line number of the last character for current token (being
   * matched after the last call to BeginTOken).
   */
  public int getEndLine()
  {
    return 1;

  } // end getLine

  /**
   * Returns the column number of the first character for current token (being
   * matched after the last call to BeginTOken).
   */
  public int getBeginColumn()
  {
    return m_tokenstart;

  } // end getBeginColumn

  /**
   * Returns the line number of the first character for current token (being
   * matched after the last call to BeginTOken).
   */
  public int getBeginLine()
  {
    return 1;

  } // end getBeginLine

  /**
   * Backs up the input stream by amount steps. Lexer calls this method if it
   * had already read some characters, but could not use them to match a
   * (longer) token. So, they will be used again as the prefix of the next
   * token and it is the implemetation's responsibility to do this right.
   */
  public void backup(int amount)
  {
    m_pos -= amount;

  } // end backup

  /**
   * Returns the next character that marks the beginning of the next token.
   * All characters must remain in the buffer between two successive calls
   * to this method to implement backup correctly.
   */
  public char BeginToken() throws java.io.IOException
  {
    m_tokenstart = m_pos;
    return this.readChar();

  } // end BeginToken

  /**
   * Returns a string made up of characters from the marked token beginning 
   * to the current buffer position. Implementations have the choice of returning
   * anything that they want to. For example, for efficiency, one might decide
   * to just return null, which is a valid implementation.
   */
  public String GetImage()
  {
    return new String(m_array,m_tokenstart,m_pos - m_tokenstart);

  } // end GetImage

  /**
   * Returns an array of characters that make up the suffix of length 'len' for
   * the currently matched token. This is used to build up the matched string
   * for use in actions in the case of MORE. A simple and inefficient
   * implementation of this is as follows :
   *
   *   {
   *      String t = GetImage();
   *      return t.substring(t.length() - len, t.length()).toCharArray();
   *   }
   */
  public char[] GetSuffix(int len)
  {
    char[] rc = new char[len];
    System.arraycopy(m_array,m_pos - len,rc,0,len);
    return rc;

  } // end getSuffix

  /**
   * The lexer calls this function to indicate that it is done with the stream
   * and hence implementations can free any resources held by this class.
   * Again, the body of this function can be just empty and it will not
   * affect the lexer's operation.
   */
  public void Done()
  {
    m_array = null;

  } // end Done

} // end class StaticCharStream
