classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Informative throws


From: Eric Blake
Subject: RE: Informative throws
Date: Fri, 27 Jul 2001 16:51:01 +0100

> -----Original Message-----
> From: Tom Tromey [mailto:address@hidden
> Sent: 26 July 2001 19:23
> To: Eric Blake
> Cc: classpath
> Subject: Re: Informative throws
>
> Eric> Then, in places like Integer.decode() (which, by the way, is
> Eric> buggy at the moment)
>
> What is wrong with Integer.decode?

I assume that what is wrong in Classpath will also need to be corrected in
gcj, since you just merged them.  The problems I've noticed: In decode(),
all 3 bases (not just decimal) are permitted to start with '-', and
decode(null) should throw a NullPointerException, not a
NumberFormatException.  In parseInt, the check for radices is redundant
since Character.digit() will do it, and parseInt(null) should throw a
NumberFormatException, not NullPointerException.  And, there are still
plenty of optimizations to add.

Long, Short, and Byte suffer the same problems.  Also, I'm not sure if
parseLong(String) is worth special casing from parseLong(String, radix); the
minimal savings of hard-coding a radix that is not a power of 2 isn't worth
the increased code footprint and potential for bugs between the two
versions.

I actually liked the old version better, where parseInt and decode shared
more code, so that all the complex code resides in a single method rather
than 3.  Here is the version I have locally; after reducing as many bytes as
I could from Jikes compilation (possibly at the expense of readability):

  /**
   * Parses an integer.  Package visible, for use by Byte and Short.
   *
   * @param s the String to parse
   * @param radix the radix to use, must be 10 if decode is true
   * @param decode true to attempt decoding the radix from s
   * @return the parsed int
   * @throws NullPointerException if the string is null and decode is true
   * @throws NumberFormatException if the parse fails, including when the
   *         string is null but decode is false
   *
   * @see #Integer(String)
   * @see #valueOf(String)
   * @see #parseInt(String, int)
   * @see #decode(String)
   * @see Byte#parseInt(String, int, boolean)
   * @see Short#parseInt(String, int, boolean)
   */
  static int parseInt(String s, int radix, boolean decode)
  {
    // we throw exceptions with no message for a smaller .class file

    int i;
    final int length;

    // For parseInt, an invalid radix is detected during Character.digit()
    if ((! decode && s == null) || (length = s.length()) == 0)
      throw new NumberFormatException(/*"invalid string"*/);

    // check for a negative value, setup the initial index for digits
    boolean negative = false;
    if (s.charAt(i = 0) == '-')
      {
        if (length == 1)
          throw new NumberFormatException(/*"no digits"*/);
        negative = true;
        i++;
      }

    // determine the base.
    if (decode)
      {
        char c; // cache
        if ((c = s.charAt(i)) == '0')
          if (++i < length && ((c = s.charAt(i)) == 'x' || c == 'X'))
            {
              radix = 16;
              if (++i == length)
                throw new NumberFormatException(/*"no digits"*/);
            }
          else
            radix = 8; // no digits is okay, because it is then decimal 0
        else if (c == '#')
          {
            radix = 16;
            if (++i == length)
              throw new NumberFormatException(/*"no digits"*/);
          }
      }

    int result = 0;

    while (i < length)
      {
        int c;
        if ((c = Character.digit(s.charAt(i++), radix)) < 0)
          throw new NumberFormatException(/*"invalid char or radix"*/);
        // check for overflow, but allow MIN_VALUE
        if ((result = result * radix + c) < 0 &&
            (i < length || ! negative || result != MIN_VALUE))
          throw new NumberFormatException(/*"overflow"*/);
      }

    if (negative)
      return -result;
    return result;
  }

--
Eric Blake, Elixent, Castlemead, Lwr Castle St., Bristol BS1 3AG, UK
address@hidden   tel:+44(0)117 917 5611




reply via email to

[Prev in Thread] Current Thread [Next in Thread]