1 /*
   2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.jtt.loop;
  24 
  25 import org.junit.Test;
  26 
  27 import org.graalvm.compiler.jtt.JTTTest;
  28 
  29 public class LoopParseLong extends JTTTest {
  30 
  31     @SuppressWarnings("unused")
  32     public static long testShortened(String s, int radix) throws NumberFormatException {
  33         long result = 0;
  34         boolean negative = false;
  35         int len = s.length();
  36         char firstChar = s.charAt(0);
  37         if (firstChar < '0') {
  38             if (firstChar == '-') {
  39                 negative = true;
  40             } else if (firstChar != '+') {
  41                 throw new NumberFormatException();
  42             }
  43             if (len == 1) {
  44                 throw new NumberFormatException();
  45             }
  46         }
  47         return result;
  48     }
  49 
  50     public static long test(String s, int radix) throws NumberFormatException {
  51         if (s == null) {
  52             throw new NumberFormatException("null");
  53         }
  54         if (radix < Character.MIN_RADIX) {
  55             throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
  56         }
  57         if (radix > Character.MAX_RADIX) {
  58             throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
  59         }
  60         long result = 0;
  61         boolean negative = false;
  62         int i = 0;
  63         int len = s.length();
  64         long limit = -Long.MAX_VALUE;
  65         long multmin;
  66         int digit;
  67         if (len > 0) {
  68             char firstChar = s.charAt(0);
  69             if (firstChar < '0') {
  70                 if (firstChar == '-') {
  71                     negative = true;
  72                     limit = Long.MIN_VALUE;
  73                 } else if (firstChar != '+') {
  74                     throw new NumberFormatException();
  75                 }
  76                 if (len == 1) {
  77                     throw new NumberFormatException();
  78                 }
  79                 i++;
  80             }
  81             multmin = limit / radix;
  82             while (i < len) {
  83                 digit = Character.digit(s.charAt(i++), radix);
  84                 if (digit < 0) {
  85                     throw new NumberFormatException();
  86                 }
  87                 if (result < multmin) {
  88                     throw new NumberFormatException();
  89                 }
  90                 result *= radix;
  91                 if (result < limit + digit) {
  92                     throw new NumberFormatException();
  93                 }
  94                 result -= digit;
  95             }
  96         } else {
  97             throw new NumberFormatException();
  98         }
  99         return negative ? result : -result;
 100     }
 101 
 102     @Test
 103     public void run0() throws Throwable {
 104         runTest("testShortened", "7", 10);
 105     }
 106 
 107     @Test
 108     public void run1() throws Throwable {
 109         runTest("testShortened", "-100", 10);
 110     }
 111 
 112     @Test
 113     public void run2() throws Throwable {
 114         runTest("test", "7", 10);
 115     }
 116 
 117     @Test
 118     public void run3() throws Throwable {
 119         runTest("test", "-100", 10);
 120     }
 121 }