/* UTF_8.java --
   Copyright (C) 2002, 2004, 2005  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 gnu.java.nio.charset;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;

/**
 * UTF-8 charset.
 *
 * <p> UTF-8 references:
 * <ul>
 *   <li> <a href="http://ietf.org/rfc/rfc2279.txt">RFC 2279</a>
 *   <li> The <a href="http://www.unicode.org/unicode/standard/standard.html">
 *     Unicode standard</a> and
 *     <a href="http://www.unicode.org/versions/corrigendum1.html">
 *      Corrigendum</a>
 * </ul>
 *
 * @author Jesse Rosenstock
 */
final class UTF_8 extends Charset
{
  UTF_8 ()
  {
    super ("UTF-8", new String[] {
        /* These names are provided by
         * http://oss.software.ibm.com/cgi-bin/icu/convexp?s=ALL
         */
        "ibm-1208", "ibm-1209", "ibm-5304", "ibm-5305",
        "windows-65001", "cp1208",
        // see http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html
        "UTF8"
    });
  }

  public boolean contains (Charset cs)
  {
    return cs instanceof US_ASCII || cs instanceof ISO_8859_1
      || cs instanceof UTF_8 || cs instanceof UTF_16BE
      || cs instanceof UTF_16LE || cs instanceof UTF_16;
  }

  public CharsetDecoder newDecoder ()
  {
    return new Decoder (this);
  }

  public CharsetEncoder newEncoder ()
  {
    return new Encoder (this);
  }

  private static final class Decoder extends CharsetDecoder
  {
    // Package-private to avoid a trampoline constructor.
    Decoder (Charset cs)
    {
      super (cs, 1f, 1f);
    }

    protected CoderResult decodeLoop (ByteBuffer in, CharBuffer out)
    {
      // TODO: Optimize this in the case in.hasArray() / out.hasArray()
      int inPos = in.position();
      try
        {
          while (in.hasRemaining ())
            {
              char c;
              byte b1 = in.get ();
              int highNibble = ((b1 & 0xFF) >> 4) & 0xF;
              switch (highNibble)
                {
                  case 0: case 1: case 2: case 3:
                  case 4: case 5: case 6: case 7:
                    if (out.remaining () < 1)
                      return CoderResult.OVERFLOW;
                    out.put ((char) b1);
                    inPos++;
                    break;

                  case 0xC: case 0xD:
                    byte b2;
                    if (in.remaining () < 1)
                      return CoderResult.UNDERFLOW;
                    if (out.remaining () < 1)
                      return CoderResult.OVERFLOW;
                    if (!isContinuation (b2 = in.get ()))
                      return CoderResult.malformedForLength (1);
                    c = (char) (((b1 & 0x1F) << 6) | (b2 & 0x3F));
                    // check that we had the shortest encoding
                    if (c <= 0x7F)
                      return CoderResult.malformedForLength (2);
                    out.put (c);
                    inPos += 2;
                    break;

                  case 0xE:
                    byte b3;
                    if (in.remaining () < 2)
                      return CoderResult.UNDERFLOW;
                    if (out.remaining () < 1)
                      return CoderResult.OVERFLOW;
                    if (!isContinuation (b2 = in.get ()))
                      return CoderResult.malformedForLength (1);
                    if (!isContinuation (b3 = in.get ()))
                      return CoderResult.malformedForLength (1);
                    c = (char) (((b1 & 0x0F) << 12)
                                | ((b2 & 0x3F) << 6)
                                | (b3 & 0x3F));
                    // check that we had the shortest encoding
                    if (c <= 0x7FF)
                      return CoderResult.malformedForLength (3);
                    out.put (c);
                    inPos += 3;
                    break;

                  case 0xF:
                    byte b4;
                    if (in.remaining () < 3)
                      return CoderResult.UNDERFLOW;
                    if((b1&0x0F) > 4)
                      return CoderResult.malformedForLength (4);
                    if (out.remaining () < 2)
                      return CoderResult.OVERFLOW;
                    if (!isContinuation (b2 = in.get ()))
                      return CoderResult.malformedForLength (3);
                    if (!isContinuation (b3 = in.get ()))
                      return CoderResult.malformedForLength (2);
                    if (!isContinuation (b4 = in.get ()))
                      return CoderResult.malformedForLength (1);
                    int n = (((b1 & 0x3) << 18)
                             | ((b2 & 0x3F) << 12)
                             | ((b3 & 0x3F) << 6)
                             | (b4 & 0x3F)) - 0x10000;
                    char c1 = (char)(0xD800 | (n & 0xFFC00)>>10);
                    char c2 = (char)(0xDC00 | (n & 0x003FF));
                    out.put (c1);
                    out.put (c2);
                    inPos += 4;
                    break;

                  default:
                    return CoderResult.malformedForLength (1);
                }
            }

          return CoderResult.UNDERFLOW;
        }
      finally
        {
          // In case we did a get(), then encountered an error, reset the
          // position to before the error.  If there was no error, this
          // will benignly reset the position to the value it already has.
          in.position (inPos);
        }
    }

    private static boolean isContinuation (byte b)
    {
      return (b & 0xC0) == 0x80;
    }
  }

  private static final class Encoder extends CharsetEncoder
  {
    // Package-private to avoid a trampoline constructor.
    Encoder (Charset cs)
    {
      // According to
      // http://www-106.ibm.com/developerworks/unicode/library/utfencodingforms/index.html
      //   On average, English takes slightly over one unit per code point.
      //   Most Latin-script languages take about 1.1 bytes. Greek, Russian,
      //   Arabic and Hebrew take about 1.7 bytes, and most others (including
      //   Japanese, Chinese, Korean and Hindi) take about 3 bytes.
      // We assume we will be dealing with latin scripts, and use 1.1
      // for averageBytesPerChar.
      super (cs, 1.1f, 4.0f);
    }

    protected CoderResult encodeLoop (CharBuffer in, ByteBuffer out)
    {
      int inPos = in.position();
      try
        {
          // TODO: Optimize this in the case in.hasArray() / out.hasArray()
          while (in.hasRemaining ())
          {
            int remaining = out.remaining ();
            char c = in.get ();

            // UCS-4 range (hex.)           UTF-8 octet sequence (binary)
            // 0000 0000-0000 007F   0xxxxxxx
            // 0000 0080-0000 07FF   110xxxxx 10xxxxxx
            // 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx

            //        Scalar Value          UTF-16                byte 1     byte 2     byte 3     byte 4
            //        0000 0000 0xxx xxxx   0000 0000 0xxx xxxx   0xxx xxxx
            //        0000 0yyy yyxx xxxx   0000 0yyy yyxx xxxx   110y yyyy  10xx xxxx
            //        zzzz yyyy yyxx xxxx   zzzz yyyy yyxx xxxx   1110 zzzz  10yy yyyy  10xx xxxx
            // u uuuu zzzz yyyy yyxx xxxx   1101 10ww wwzz zzyy   1111 0uuu  10uu zzzz  10yy yyyy  10xx xxxx
            //                            + 1101 11yy yyxx xxxx
            // Note: uuuuu = wwww + 1
            if (c <= 0x7F)
              {
                if (remaining < 1)
                  return CoderResult.OVERFLOW;
                out.put ((byte) c);
                inPos++;
              }
            else if (c <= 0x7FF)
              {
                if (remaining < 2)
                  return CoderResult.OVERFLOW;
                out.put ((byte) (0xC0 | (c >> 6)));
                out.put ((byte) (0x80 | (c & 0x3F)));
                inPos++;
              }
            else if (0xD800 <= c && c <= 0xDFFF)
              {
                if (remaining < 4)
                  return CoderResult.OVERFLOW;

                // we got a low surrogate without a preciding high one
                if (c > 0xDBFF)
                  return CoderResult.malformedForLength (1);

                // high surrogates
                if (!in.hasRemaining ())
                  return CoderResult.UNDERFLOW;

                char d = in.get ();

                // make sure d is a low surrogate
                if (d < 0xDC00 || d > 0xDFFF)
                  return CoderResult.malformedForLength (1);

                // make the 32 bit value
                // int value2 = (c - 0xD800) * 0x400 + (d - 0xDC00) + 0x10000;
                int value = (((c & 0x3FF) << 10) | (d & 0x3FF)) + 0x10000;
                // assert value == value2;
                out.put ((byte) (0xF0 | ((value >> 18) & 0x07)));
                out.put ((byte) (0x80 | ((value >> 12) & 0x3F)));
                out.put ((byte) (0x80 | ((value >>  6) & 0x3F)));
                out.put ((byte) (0x80 | ((value      ) & 0x3F)));
                inPos += 2;
              }
            else
              {
                if (remaining < 3)
                  return CoderResult.OVERFLOW;

                out.put ((byte) (0xE0 | (c >> 12)));
                out.put ((byte) (0x80 | ((c >> 6) & 0x3F)));
                out.put ((byte) (0x80 | (c & 0x3F)));
                inPos++;
              }
          }

          return CoderResult.UNDERFLOW;
        }
      finally
        {
          // In case we did a get(), then encountered an error, reset the
          // position to before the error.  If there was no error, this
          // will benignly reset the position to the value it already has.
          in.position (inPos);
        }
    }
  }
}
