Clover coverage report - groovy - 1.0-beta-6
Coverage timestamp: Thu Jul 15 2004 13:18:22 BST
file stats: LOC: 326   Methods: 6
NCLOC: 143   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
Numbers.java 0% 0% 0% 0%
coverage
 1   
 /*
 2   
  $Id: Numbers.java,v 1.3 2004/04/07 20:19:20 cpoirier Exp $
 3   
 
 4   
  Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
 5   
 
 6   
  Redistribution and use of this software and associated documentation
 7   
  ("Software"), with or without modification, are permitted provided
 8   
  that the following conditions are met:
 9   
 
 10   
  1. Redistributions of source code must retain copyright
 11   
     statements and notices.  Redistributions must also contain a
 12   
     copy of this document.
 13   
 
 14   
  2. Redistributions in binary form must reproduce the
 15   
     above copyright notice, this list of conditions and the
 16   
     following disclaimer in the documentation and/or other
 17   
     materials provided with the distribution.
 18   
 
 19   
  3. The name "groovy" must not be used to endorse or promote
 20   
     products derived from this Software without prior written
 21   
     permission of The Codehaus.  For written permission,
 22   
     please contact info@codehaus.org.
 23   
 
 24   
  4. Products derived from this Software may not be called "groovy"
 25   
     nor may "groovy" appear in their names without prior written
 26   
     permission of The Codehaus. "groovy" is a registered
 27   
     trademark of The Codehaus.
 28   
 
 29   
  5. Due credit should be given to The Codehaus -
 30   
     http://groovy.codehaus.org/
 31   
 
 32   
  THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
 33   
  ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 34   
  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 35   
  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 36   
  THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 37   
  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 38   
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 39   
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 40   
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 41   
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 42   
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 43   
  OF THE POSSIBILITY OF SUCH DAMAGE.
 44   
 
 45   
  */
 46   
 
 47   
 package org.codehaus.groovy.syntax;
 48   
 
 49   
 import java.math.BigInteger;
 50   
 import java.math.BigDecimal;
 51   
 
 52   
 /**
 53   
  *  Helper class for processing Groovy numeric literals.
 54   
  *
 55   
  *  @author Brian Larson
 56   
  *  @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
 57   
  *
 58   
  *  @version $Id: Numbers.java,v 1.3 2004/04/07 20:19:20 cpoirier Exp $
 59   
  */
 60   
 
 61   
 public class Numbers
 62   
 {
 63   
 
 64   
 
 65   
 
 66   
   //---------------------------------------------------------------------------
 67   
   // LEXING SUPPORT
 68   
 
 69   
 
 70   
    /**
 71   
     *  Returns true if the specified character is a base-10 digit.
 72   
     */
 73   
 
 74  0
     public static boolean isDigit( char c )
 75   
     {
 76  0
         return c >= '0' && c <= '9';
 77   
     }
 78   
 
 79   
 
 80   
    /**
 81   
     *  Returns true if the specific character is a base-8 digit.
 82   
     */
 83   
 
 84  0
     public static boolean isOctalDigit( char c )
 85   
     {
 86  0
         return c >= '0' && c <= '7';
 87   
     }
 88   
 
 89   
 
 90   
    /**
 91   
     *  Returns true if the specified character is a base-16 digit.
 92   
     */
 93   
 
 94  0
     public static boolean isHexDigit( char c )
 95   
     {
 96  0
         return isDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
 97   
     }
 98   
 
 99   
 
 100   
 
 101   
    /**
 102   
     *  Returns true if the specified character is a valid type specifier
 103   
     *  for a numeric value.
 104   
     */
 105   
 
 106  0
     public static boolean isNumericTypeSpecifier( char c, boolean isDecimal )
 107   
     {
 108  0
         if( isDecimal )
 109   
         {
 110  0
             switch( c )
 111   
             {
 112   
                 case 'G':
 113   
                 case 'g':
 114   
                 case 'D':
 115   
                 case 'd':
 116   
                 case 'F':
 117   
                 case 'f':
 118  0
                     return true;
 119   
             }
 120   
         }
 121   
         else
 122   
         {
 123  0
             switch( c )
 124   
             {
 125   
                 case 'G':
 126   
                 case 'g':
 127   
                 case 'I':
 128   
                 case 'i':
 129   
                 case 'L':
 130   
                 case 'l':
 131  0
                     return true;
 132   
             }
 133   
         }
 134   
 
 135  0
         return false;
 136   
     }
 137   
 
 138   
 
 139   
 
 140   
 
 141   
 
 142   
   //---------------------------------------------------------------------------
 143   
   // PARSING SUPPORT
 144   
 
 145   
 
 146   
     private static final BigInteger MAX_LONG    = BigInteger.valueOf(Long.MAX_VALUE);
 147   
     private static final BigInteger MIN_LONG    = BigInteger.valueOf(Long.MIN_VALUE);
 148   
 
 149   
     private static final BigInteger MAX_INTEGER = BigInteger.valueOf(Integer.MAX_VALUE);
 150   
     private static final BigInteger MIN_INTEGER = BigInteger.valueOf(Integer.MIN_VALUE);
 151   
 
 152   
     private static final BigDecimal MAX_DOUBLE  = new BigDecimal(String.valueOf(Double.MAX_VALUE));
 153   
     private static final BigDecimal MIN_DOUBLE  = MAX_DOUBLE.negate();
 154   
 
 155   
     private static final BigDecimal MAX_FLOAT   = new BigDecimal(String.valueOf(Float.MAX_VALUE));
 156   
     private static final BigDecimal MIN_FLOAT   = MAX_FLOAT.negate();
 157   
 
 158   
 
 159   
 
 160   
    /**
 161   
     *  Builds a Number from the given integer descriptor.  Creates the narrowest
 162   
     *  type possible, or a specific type, if specified.
 163   
     *
 164   
     *  @param  text literal text to parse
 165   
     *  @return instantiated Number object
 166   
     *  @throws NumberFormatException if the number does not fit within the type
 167   
     *          requested by the type specifier suffix (invalid numbers don't make
 168   
     *          it here)
 169   
     */
 170   
 
 171  0
     public static Number parseInteger( String text )
 172   
     {
 173  0
         char c = ' ';
 174  0
         int length = text.length();
 175   
 
 176   
 
 177   
         //
 178   
         // Strip off the sign, if present
 179   
 
 180  0
         boolean negative = false;
 181  0
         if( (c = text.charAt(0)) == '-' || c == '+' )
 182   
         {
 183  0
             negative = (c == '-');
 184  0
             text = text.substring( 1, length );
 185  0
             length -= 1;
 186   
         }
 187   
 
 188   
 
 189   
         //
 190   
         // Determine radix (default is 10).
 191   
 
 192  0
         int radix = 10;
 193  0
         if( text.charAt(0) == '0' && length > 1 )
 194   
         {
 195  0
             if( (c = text.charAt(1)) == 'X' || c == 'x' )
 196   
             {
 197  0
                 radix = 16;
 198  0
                 text = text.substring( 2, length);
 199  0
                 length -= 2;
 200   
             }
 201   
             else
 202   
             {
 203  0
                 radix = 8;
 204   
             }
 205   
         }
 206   
 
 207   
 
 208   
         //
 209   
         // Strip off any type specifier and convert it to lower
 210   
         // case, if present.
 211   
 
 212  0
         char type = 'x';  // pick best fit
 213  0
         if( isNumericTypeSpecifier(text.charAt(length-1), false) )
 214   
         {
 215  0
             type = Character.toLowerCase( text.charAt(length-1) );
 216  0
             text = text.substring( 0, length-1);
 217   
 
 218  0
             length -= 1;
 219   
         }
 220   
 
 221   
 
 222   
         //
 223   
         // Add the sign back, if necessary
 224   
 
 225  0
         if( negative )
 226   
         {
 227  0
             text = "-" + text;
 228   
         }
 229   
 
 230   
 
 231   
         //
 232   
         // Build the specified type or, if no type was specified, the
 233   
         // smallest type in which the number will fit.
 234   
 
 235  0
         switch (type)
 236   
         {
 237   
             case 'i':
 238  0
                 return new Integer( Integer.parseInt(text, radix) );
 239   
 
 240   
             case 'l':
 241  0
                 return new Long( Long.parseLong(text, radix) );
 242   
 
 243   
             case 'g':
 244  0
                 return new BigInteger( text, radix );
 245   
 
 246   
             default:
 247   
 
 248   
                 //
 249   
                 // If not specified, we will return the narrowest possible
 250   
                 // of Integer, Long, and BigInteger.
 251   
 
 252  0
                 BigInteger value = new BigInteger( text, radix );
 253   
 
 254  0
                 if( value.compareTo(MAX_INTEGER) <= 0 && value.compareTo(MIN_INTEGER) >= 0 )
 255   
                 {
 256  0
                     return new Integer(value.intValue());
 257   
                 }
 258  0
                 else if( value.compareTo(MAX_LONG) <= 0 && value.compareTo(MIN_LONG) >= 0 )
 259   
                 {
 260  0
                     return new Long(value.longValue());
 261   
                 }
 262   
 
 263  0
                 return value;
 264   
         }
 265   
     }
 266   
 
 267   
 
 268   
 
 269   
    /**
 270   
     *  Builds a Number from the given decimal descriptor.  Uses BigDecimal,
 271   
     *  unless, Double or Float is requested.
 272   
     *
 273   
     *  @param  text literal text to parse
 274   
     *  @return instantiated Number object
 275   
     *  @throws NumberFormatException if the number does not fit within the type
 276   
     *          requested by the type specifier suffix (invalid numbers don't make
 277   
     *          it here)
 278   
     */
 279   
 
 280  0
     public static Number parseDecimal( String text )
 281   
     {
 282  0
         int length = text.length();
 283   
 
 284   
 
 285   
         //
 286   
         // Strip off any type specifier and convert it to lower
 287   
         // case, if present.
 288   
 
 289  0
         char type = 'x';
 290  0
         if( isNumericTypeSpecifier(text.charAt(length-1), true) )
 291   
         {
 292  0
             type = Character.toLowerCase( text.charAt(length-1) );
 293  0
             text = text.substring( 0, length-1 );
 294   
 
 295  0
             length -= 1;
 296   
         }
 297   
 
 298   
 
 299   
         //
 300   
         // Build the specified type or default to BigDecimal
 301   
 
 302  0
         BigDecimal value = new BigDecimal( text );
 303  0
         switch( type )
 304   
         {
 305   
             case 'f':
 306  0
                 if( value.compareTo(MAX_FLOAT) <= 0 && value.compareTo(MIN_FLOAT) >= 0)
 307   
                 {
 308  0
                     return new Float( text );
 309   
                 }
 310  0
                 throw new NumberFormatException( "out of range" );
 311   
 
 312   
             case 'd':
 313  0
                 if( value.compareTo(MAX_DOUBLE) <= 0 && value.compareTo(MIN_DOUBLE) >= 0)
 314   
                 {
 315  0
                     return new Double( text );
 316   
                 }
 317  0
                 throw new NumberFormatException( "out of range" );
 318   
 
 319   
             case 'g':
 320   
             default:
 321  0
                 return value;
 322   
         }
 323   
     }
 324   
 
 325   
 }
 326