/* CharsetDecoder.java --
   Copyright (C) 2002 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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 2, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.nio.charset;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;

/**
 * @author Jesse Rosenstock
 * @since 1.4
 */
public abstract class CharsetDecoder
{
  private static final int STATE_RESET   = 0;
  private static final int STATE_CODING  = 1;
  private static final int STATE_END     = 2;
  private static final int STATE_FLUSHED = 3;

  private static final String DEFAULT_REPLACEMENT = "\uFFFD";

  private final Charset charset;
  private final float averageCharsPerByte;
  private final float maxCharsPerByte;
  private String replacement;

  private int state = STATE_RESET;

  private CodingErrorAction malformedInputAction
    = CodingErrorAction.REPORT;
  private CodingErrorAction unmappableCharacterAction
    = CodingErrorAction.REPORT;

  private CharsetDecoder (Charset cs, float averageCharsPerByte,
                          float maxCharsPerByte, String replacement)
  {
    if (averageCharsPerByte <= 0.0f)
      throw new IllegalArgumentException ("Non-positive averageCharsPerByte");
    if (maxCharsPerByte <= 0.0f)
      throw new IllegalArgumentException ("Non-positive maxCharsPerByte");

    this.charset = cs;
    this.averageCharsPerByte
      = averageCharsPerByte;
    this.maxCharsPerByte
      = maxCharsPerByte;
    this.replacement = replacement;
    implReplaceWith (replacement);
  }

  protected CharsetDecoder (Charset cs, float averageCharsPerByte,
                            float maxCharsPerByte)
  {
    this (cs, averageCharsPerByte, maxCharsPerByte, DEFAULT_REPLACEMENT);
  }

  public final float averageCharsPerByte ()
  {
    return averageCharsPerByte;
  }

  public final Charset charset ()
  {
    return charset;
  }

  public final CharBuffer decode (ByteBuffer in)
    throws CharacterCodingException
  {
    // XXX: Sun's Javadoc seems to contradict itself saying an
    // IllegalStateException is thrown "if a decoding operation is already
    // in progress" and also that "it resets this Decoder".
    // Should we check to see that the state is reset, or should we
    // call reset()?
    if (state != STATE_RESET)
      throw new IllegalStateException ();

    // REVIEW: Using max instead of average may allocate a very large
    // buffer.  Maybe we should do something more efficient?
    int remaining = in.remaining ();
    int n = (int) (remaining * maxCharsPerByte ());
    CharBuffer out = CharBuffer.allocate (n);

    if (remaining == 0)
      {
        state = STATE_FLUSHED;
        return out;
      }

    CoderResult cr = decode (in, out, true);
    if (cr.isError ())
      cr.throwException ();

    cr = flush (out);
    if (cr.isError ())
      cr.throwException ();

    reset();
    out.flip ();

    // Unfortunately, resizing the actual charbuffer array is required.
    char[] resized = new char[out.remaining()];
    out.get(resized);
    return CharBuffer.wrap(resized);
  }

  public final CoderResult decode (ByteBuffer in, CharBuffer out,
                                   boolean endOfInput)
  {
    int newState = endOfInput ? STATE_END : STATE_CODING;
    // XXX: Need to check for "previous step was an invocation [not] of
    // this method with a value of true for the endOfInput parameter but
    // a return value indicating an incomplete decoding operation"
    // XXX: We will not check the previous return value, just
    // that the previous call passed true for endOfInput
    if (state != STATE_RESET && state != STATE_CODING
        && !(endOfInput && state == STATE_END))
      throw new IllegalStateException ();
    state = newState;

    for (;;)
      {
        CoderResult cr;
        try
          {
            cr = decodeLoop (in, out);
          }
        catch (RuntimeException e)
          {
            throw new CoderMalfunctionError (e);
          }

        if (cr.isOverflow ())
          return cr;

        if (cr.isUnderflow ())
          {
            if (endOfInput && in.hasRemaining ())
              cr = CoderResult.malformedForLength (in.remaining ());
            else
              return cr;
          }

        CodingErrorAction action = cr.isMalformed ()
                                     ? malformedInputAction
                                     : unmappableCharacterAction;

        if (action == CodingErrorAction.REPORT)
          return cr;

        if (action == CodingErrorAction.REPLACE)
          {
            if (out.remaining () < replacement.length ())
              return CoderResult.OVERFLOW;
            out.put (replacement);
          }

        in.position (in.position () + cr.length ());
      }
  }

  protected abstract CoderResult decodeLoop (ByteBuffer in, CharBuffer out);

  public Charset detectedCharset ()
  {
    throw new UnsupportedOperationException ();
  }

  public final CoderResult flush (CharBuffer out)
  {
    // It seems weird that you can flush after reset, but Sun's javadoc
    // says an IllegalStateException is thrown "If the previous step of the
    // current decoding operation was an invocation neither of the reset
    // method nor ... of the three-argument decode method with a value of
    // true for the endOfInput parameter."
    // Further note that flush() only requires that there not be
    // an IllegalStateException if the previous step was a call to
    // decode with true as the last argument.  It does not require
    // that the call succeeded.  decode() does require that it succeeded.
    // XXX: test this to see if reality matches javadoc
    if (state != STATE_RESET && state != STATE_END)
      throw new IllegalStateException ();

    state = STATE_FLUSHED;
    return implFlush (out);
  }

  protected CoderResult implFlush (CharBuffer out)
  {
    return CoderResult.UNDERFLOW;
  }

  public final CharsetDecoder onMalformedInput (CodingErrorAction newAction)
  {
    if (newAction == null)
      throw new IllegalArgumentException ("Null action");

    malformedInputAction = newAction;
    implOnMalformedInput (newAction);
    return this;
  }

  protected void implOnMalformedInput (CodingErrorAction newAction)
  {
    // default implementation does nothing
  }

  protected void implOnUnmappableCharacter (CodingErrorAction newAction)
  {
    // default implementation does nothing
  }

  protected void implReplaceWith (String newReplacement)
  {
    // default implementation does nothing
  }

  protected void implReset ()
  {
    // default implementation does nothing
  }

  public boolean isAutoDetecting ()
  {
    return false;
  }

  public boolean isCharsetDetected ()
  {
    throw new UnsupportedOperationException ();
  }

  public CodingErrorAction malformedInputAction ()
  {
    return malformedInputAction;
  }

  public final float maxCharsPerByte ()
  {
    return maxCharsPerByte;
  }

  public final CharsetDecoder onUnmappableCharacter
    (CodingErrorAction newAction)
  {
    if (newAction == null)
      throw new IllegalArgumentException ("Null action");

    unmappableCharacterAction = newAction;
    implOnUnmappableCharacter (newAction);
    return this;
  }

  public final String replacement ()
  {
    return replacement;
  }

  public final CharsetDecoder replaceWith (String newReplacement)
  {
    if (newReplacement == null)
      throw new IllegalArgumentException ("Null replacement");
    if (newReplacement.length () == 0)
      throw new IllegalArgumentException ("Empty replacement");
    // XXX: what about maxCharsPerByte?

    this.replacement = newReplacement;
    implReplaceWith (newReplacement);
    return this;
  }

  public final CharsetDecoder reset ()
  {
    state = STATE_RESET;
    implReset ();
    return this;
  }

  public CodingErrorAction unmappableCharacterAction ()
  {
    return unmappableCharacterAction;
  }
}
