/* Short.java -- object wrapper for short
   Copyright (C) 1998, 2001, 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 java.lang;

/**
 * Instances of class <code>Short</code> represent primitive
 * <code>short</code> values.
 *
 * Additionally, this class provides various helper functions and variables
 * related to shorts.
 *
 * @author Paul Fisher
 * @author John Keiser
 * @author Eric Blake (ebb9@email.byu.edu)
 * @author Tom Tromey (tromey@redhat.com)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @since 1.1
 * @status updated to 1.5
 */
public final class Short extends Number implements Comparable<Short>
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = 7515723908773894738L;

  /**
   * The minimum value a <code>short</code> can represent is -32768 (or
   * -2<sup>15</sup>).
   */
  public static final short MIN_VALUE = -32768;

  /**
   * The minimum value a <code>short</code> can represent is 32767 (or
   * 2<sup>15</sup>).
   */
  public static final short MAX_VALUE = 32767;

  /**
   * The primitive type <code>short</code> is represented by this
   * <code>Class</code> object.
   */
  public static final Class<Short> TYPE = (Class<Short>) VMClassLoader.getPrimitiveClass('S');

  /**
   * The number of bits needed to represent a <code>short</code>.
   * @since 1.5
   */
  public static final int SIZE = 16;

  // This caches some Short values, and is used by boxing conversions
  // via valueOf().  We must cache at least -128..127; these constants
  // control how much we actually cache.
  private static final int MIN_CACHE = -128;
  private static final int MAX_CACHE = 127;
  private static Short[] shortCache = new Short[MAX_CACHE - MIN_CACHE + 1];

  /**
   * The immutable value of this Short.
   *
   * @serial the wrapped short
   */
  private final short value;

  /**
   * Create a <code>Short</code> object representing the value of the
   * <code>short</code> argument.
   *
   * @param value the value to use
   */
  public Short(short value)
  {
    this.value = value;
  }

  /**
   * Create a <code>Short</code> object representing the value of the
   * argument after conversion to a <code>short</code>.
   *
   * @param s the string to convert
   * @throws NumberFormatException if the String cannot be parsed
   */
  public Short(String s)
  {
    value = parseShort(s, 10);
  }

  /**
   * Converts the <code>short</code> to a <code>String</code> and assumes
   * a radix of 10.
   *
   * @param s the <code>short</code> to convert to <code>String</code>
   * @return the <code>String</code> representation of the argument
   */
  public static String toString(short s)
  {
    return String.valueOf(s);
  }

  /**
   * Converts the specified <code>String</code> into a <code>short</code>.
   * This function assumes a radix of 10.
   *
   * @param s the <code>String</code> to convert
   * @return the <code>short</code> value of <code>s</code>
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>short</code>
   */
  public static short parseShort(String s)
  {
    return parseShort(s, 10);
  }

  /**
   * Converts the specified <code>String</code> into a <code>short</code>
   * using the specified radix (base). The string must not be <code>null</code>
   * or empty. It may begin with an optional '-', which will negate the answer,
   * provided that there are also valid digits. Each digit is parsed as if by
   * <code>Character.digit(d, radix)</code>, and must be in the range
   * <code>0</code> to <code>radix - 1</code>. Finally, the result must be
   * within <code>MIN_VALUE</code> to <code>MAX_VALUE</code>, inclusive.
   * Unlike Double.parseDouble, you may not have a leading '+'.
   *
   * @param s the <code>String</code> to convert
   * @param radix the radix (base) to use in the conversion
   * @return the <code>String</code> argument converted to <code>short</code>
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>short</code>
   */
  public static short parseShort(String s, int radix)
  {
    int i = Integer.parseInt(s, radix, false);
    if ((short) i != i)
      throw new NumberFormatException();
    return (short) i;
  }

  /**
   * Creates a new <code>Short</code> object using the <code>String</code>
   * and specified radix (base).
   *
   * @param s the <code>String</code> to convert
   * @param radix the radix (base) to convert with
   * @return the new <code>Short</code>
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>short</code>
   * @see #parseShort(String, int)
   */
  public static Short valueOf(String s, int radix)
  {
    return new Short(parseShort(s, radix));
  }

  /**
   * Creates a new <code>Short</code> object using the <code>String</code>,
   * assuming a radix of 10.
   *
   * @param s the <code>String</code> to convert
   * @return the new <code>Short</code>
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>short</code>
   * @see #Short(String)
   * @see #parseShort(String)
   */
  public static Short valueOf(String s)
  {
    return new Short(parseShort(s, 10));
  }

  /**
   * Returns a <code>Short</code> object wrapping the value.
   * In contrast to the <code>Short</code> constructor, this method
   * will cache some values.  It is used by boxing conversion.
   *
   * @param val the value to wrap
   * @return the <code>Short</code>
   * @since 1.5
   */
  public static Short valueOf(short val)
  {
    if (val < MIN_CACHE || val > MAX_CACHE)
      return new Short(val);
    synchronized (shortCache)
      {
	if (shortCache[val - MIN_CACHE] == null)
	  shortCache[val - MIN_CACHE] = new Short(val);
	return shortCache[val - MIN_CACHE];
      }
  }

  /**
   * Convert the specified <code>String</code> into a <code>Short</code>.
   * The <code>String</code> may represent decimal, hexadecimal, or
   * octal numbers.
   *
   * <p>The extended BNF grammar is as follows:<br>
   * <pre>
   * <em>DecodableString</em>:
   *      ( [ <code>-</code> ] <em>DecimalNumber</em> )
   *    | ( [ <code>-</code> ] ( <code>0x</code> | <code>0X</code>
   *              | <code>#</code> ) <em>HexDigit</em> { <em>HexDigit</em> } )
   *    | ( [ <code>-</code> ] <code>0</code> { <em>OctalDigit</em> } )
   * <em>DecimalNumber</em>:
   *        <em>DecimalDigit except '0'</em> { <em>DecimalDigit</em> }
   * <em>DecimalDigit</em>:
   *        <em>Character.digit(d, 10) has value 0 to 9</em>
   * <em>OctalDigit</em>:
   *        <em>Character.digit(d, 8) has value 0 to 7</em>
   * <em>DecimalDigit</em>:
   *        <em>Character.digit(d, 16) has value 0 to 15</em>
   * </pre>
   * Finally, the value must be in the range <code>MIN_VALUE</code> to
   * <code>MAX_VALUE</code>, or an exception is thrown.
   *
   * @param s the <code>String</code> to interpret
   * @return the value of the String as a <code>Short</code>
   * @throws NumberFormatException if <code>s</code> cannot be parsed as a
   *         <code>short</code>
   * @throws NullPointerException if <code>s</code> is null
   * @see Integer#decode(String)
   */
  public static Short decode(String s)
  {
    int i = Integer.parseInt(s, 10, true);
    if ((short) i != i)
      throw new NumberFormatException();
    return new Short((short) i);
  }

  /**
   * Return the value of this <code>Short</code> as a <code>byte</code>.
   *
   * @return the byte value
   */
  public byte byteValue()
  {
    return (byte) value;
  }

  /**
   * Return the value of this <code>Short</code>.
   *
   * @return the short value
   */
  public short shortValue()
  {
    return value;
  }

  /**
   * Return the value of this <code>Short</code> as an <code>int</code>.
   *
   * @return the int value
   */
  public int intValue()
  {
    return value;
  }

  /**
   * Return the value of this <code>Short</code> as a <code>long</code>.
   *
   * @return the long value
   */
  public long longValue()
  {
    return value;
  }

  /**
   * Return the value of this <code>Short</code> as a <code>float</code>.
   *
   * @return the float value
   */
  public float floatValue()
  {
    return value;
  }

  /**
   * Return the value of this <code>Short</code> as a <code>double</code>.
   *
   * @return the double value
   */
  public double doubleValue()
  {
    return value;
  }

  /**
   * Converts the <code>Short</code> value to a <code>String</code> and
   * assumes a radix of 10.
   *
   * @return the <code>String</code> representation of this <code>Short</code>
   */
  public String toString()
  {
    return String.valueOf(value);
  }

  /**
   * Return a hashcode representing this Object. <code>Short</code>'s hash
   * code is simply its value.
   *
   * @return this Object's hash code
   */
  public int hashCode()
  {
    return value;
  }

  /**
   * Returns <code>true</code> if <code>obj</code> is an instance of
   * <code>Short</code> and represents the same short value.
   *
   * @param obj the object to compare
   * @return whether these Objects are semantically equal
   */
  public boolean equals(Object obj)
  {
    return obj instanceof Short && value == ((Short) obj).value;
  }

  /**
   * Compare two Shorts numerically by comparing their <code>short</code>
   * values. The result is positive if the first is greater, negative if the
   * second is greater, and 0 if the two are equal.
   *
   * @param s the Short to compare
   * @return the comparison
   * @since 1.2
   */
  public int compareTo(Short s)
  {
    return value - s.value;
  }

  /**
   * Reverse the bytes in val.
   * @since 1.5
   */
  public static short reverseBytes(short val)
  {
    return (short) (((val >> 8) & 0xff) | ((val << 8) & 0xff00));
  }
}
