content: /*
   * [The "BSD licence"]
   * Copyright (c) 2010 Ben Gruver (JesusFreke)
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 3. The name of the author may not be used to endorse or promote products
   *    derived from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   */
  
  package org.jf.smali;
  
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  public class LiteralTools {
      public static byte parseByte(String byteLiteral)
  	throws NumberFormatException {
          if (byteLiteral == null) {
              throw new NumberFormatException("string is null");
          }
          if (byteLiteral.length() == 0) {
              throw new NumberFormatException("string is blank");
          }
  
          char[] byteChars;
          if (byteLiteral.toUpperCase().endsWith("T")) {
              byteChars = byteLiteral.substring(0, byteLiteral.length() - 1).toCharArray();
          } else {
              byteChars = byteLiteral.toCharArray();
          }
  
          int position = 0;
          int radix = 10;
          boolean negative = false;
          if (byteChars[position] == '-') {
              position++;
              negative = true;
          }
  
          if (byteChars[position] == '0') {
              position++;
              if (position == byteChars.length) {
                  return 0;
              } else if (byteChars[position] == 'x' || byteChars[position] == 'X') {
                  radix = 16;
                  position++;
              } else if (Character.digit(byteChars[position], 8) >= 0) {
                  radix = 8;
              }
          }
  
          byte result = 0;
          byte shiftedResult;
          int digit;
          byte maxValue = (byte)(Byte.MAX_VALUE / (radix / 2));
  
          while (position < byteChars.length) {
              digit = Character.digit(byteChars[position], radix);
              if (digit < 0) {
                  throw new NumberFormatException("The string contains invalid an digit - '" + byteChars[position] + "'");
              }
              shiftedResult = (byte)(result * radix);
              if (result > maxValue) {
                  throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
              }
              if (shiftedResult < 0 && shiftedResult >= -digit) {
                  throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
              }
              result = (byte)(shiftedResult + digit);
              position++;
          }
  
          if (negative) {
              //allow -0x80, which is = 0x80
              if (result == Byte.MIN_VALUE) {
                  return result;
              } else if (result < 0) {
                  throw new NumberFormatException(byteLiteral + " cannot fit into a byte");
              }
              return (byte)(result * -1);
          } else {
              return result;
          }
      }
  
      public static short parseShort(String shortLiteral)
  	throws NumberFormatException {
          if (shortLiteral == null) {
              throw new NumberFormatException("string is null");
          }
          if (shortLiteral.length() == 0) {
              throw new NumberFormatException("string is blank");
          }
  
          char[] shortChars;
          if (shortLiteral.toUpperCase().endsWith("S")) {
              shortChars = shortLiteral.substring(0, shortLiteral.length() - 1).toCharArray();
          } else {
              shortChars = shortLiteral.toCharArray();
          }
  
          int position = 0;
          int radix = 10;
          boolean negative = false;
          if (shortChars[position] == '-') {
              position++;
              negative = true;
          }
  
          if (shortChars[position] == '0') {
              position++;
              if (position == shortChars.length) {
                  return 0;
              } else if (shortChars[position] == 'x' || shortChars[position] == 'X') {
                  radix = 16;
                  position++;
              } else if (Character.digit(shortChars[position], 8) >= 0) {
                  radix = 8;
              }
          }
  
          short result = 0;
          short shiftedResult;
          int digit;
          short maxValue = (short)(Short.MAX_VALUE / (radix / 2));
  
          while (position < shortChars.length) {
              digit = Character.digit(shortChars[position], radix);
              if (digit < 0) {
                  throw new NumberFormatException("The string contains invalid an digit - '" + shortChars[position] + "'");
              }
              shiftedResult = (short)(result * radix);
              if (result > maxValue) {
                  throw new NumberFormatException(shortLiteral + " cannot fit into a short");
              }
              if (shiftedResult < 0 && shiftedResult >= -digit) {
                  throw new NumberFormatException(shortLiteral + " cannot fit into a short");
              }
              result = (short)(shiftedResult + digit);
              position++;
          }
  
          if (negative) {
              //allow -0x8000, which is = 0x8000
              if (result == Short.MIN_VALUE) {
                  return result;
              } else if (result < 0) {
                  throw new NumberFormatException(shortLiteral + " cannot fit into a short");
              }
              return (short)(result * -1);
          } else {
              return result;
          }
      }
  
      public static int parseInt(String intLiteral)
  	throws NumberFormatException {
          if (intLiteral == null) {
              throw new NumberFormatException("string is null");
          }
          if (intLiteral.length() == 0) {
              throw new NumberFormatException("string is blank");
          }
  
          char[] intChars = intLiteral.toCharArray();
          int position = 0;
          int radix = 10;
          boolean negative = false;
          if (intChars[position] == '-') {
              position++;
              negative = true;
          }
  
          if (intChars[position] == '0') {
              position++;
              if (position == intChars.length) {
                  return 0;
              } else if (intChars[position] == 'x' || intChars[position] == 'X') {
                  radix = 16;
                  position++;
              } else if (Character.digit(intChars[position], 8) >= 0) {
                  radix = 8;
              }
          }
  
          int result = 0;
          int shiftedResult;
          int digit;
          int maxValue = Integer.MAX_VALUE / (radix / 2);
  
          while (position < intChars.length) {
              digit = Character.digit(intChars[position], radix);
              if (digit < 0) {
                  throw new NumberFormatException("The string contains an invalid digit - '" + intChars[position] + "'");
              }
              shiftedResult = result * radix;
              if (result > maxValue) {
                  throw new NumberFormatException(intLiteral + " cannot fit into an int");
              }
              if (shiftedResult < 0 && shiftedResult >= -digit) {
                  throw new NumberFormatException(intLiteral + " cannot fit into an int");
              }
              result = shiftedResult + digit;
              position++;
          }
  
          if (negative) {
              //allow -0x80000000, which is = 0x80000000
              if (result == Integer.MIN_VALUE) {
                  return result;
              } else if (result < 0) {
                  throw new NumberFormatException(intLiteral + " cannot fit into an int");
              }
              return result * -1;
          } else {
              return result;
          }
      }
  
      public static long parseLong(String longLiteral)
  	throws NumberFormatException {
          if (longLiteral == null) {
              throw new NumberFormatException("string is null");
          }
          if (longLiteral.length() == 0) {
              throw new NumberFormatException("string is blank");
          }
  
          char[] longChars;
          if (longLiteral.toUpperCase().endsWith("L")) {
              longChars = longLiteral.substring(0, longLiteral.length() - 1).toCharArray();
          } else {
              longChars = longLiteral.toCharArray();
          }
  
          int position = 0;
          int radix = 10;
          boolean negative = false;
          if (longChars[position] == '-') {
              position++;
              negative = true;
          }
  
          if (longChars[position] == '0') {
              position++;
              if (position == longChars.length) {
                  return 0;
              } else if (longChars[position] == 'x' || longChars[position] == 'X') {
                  radix = 16;
                  position++;
              } else if (Character.digit(longChars[position], 8) >= 0) {
                  radix = 8;
              }
          }
  
          long result = 0;
          long shiftedResult;
          int digit;
          long maxValue = Long.MAX_VALUE / (radix / 2);
  
          while (position < longChars.length) {
              digit = Character.digit(longChars[position], radix);
              if (digit < 0) {
                  throw new NumberFormatException("The string contains an invalid digit - '" + longChars[position] + "'");
              }
              shiftedResult = result * radix;
              if (result > maxValue) {
                  throw new NumberFormatException(longLiteral + " cannot fit into a long");
              }
              if (shiftedResult < 0 && shiftedResult >= -digit) {
                  throw new NumberFormatException(longLiteral + " cannot fit into a long");
              }
              result = shiftedResult + digit;
              position++;
          }
  
          if (negative) {
              //allow -0x8000000000000000, which is = 0x8000000000000000
              if (result == Long.MIN_VALUE) {
                  return result;
              } else if (result < 0) {
                  throw new NumberFormatException(longLiteral + " cannot fit into a long");
              }
              return result * -1;
          } else {
              return result;
          }
      }
  
      private static Pattern specialFloatRegex = Pattern.compile("((-)?infinityf)|(nanf)", Pattern.CASE_INSENSITIVE);
      public static float parseFloat(String floatString) {
          Matcher m = specialFloatRegex.matcher(floatString);
          if (m.matches()) {
              //got an infinity
              if (m.start(1) != -1) {
                  if (m.start(2) != -1) {
                      return Float.NEGATIVE_INFINITY;
                  } else {
                      return Float.POSITIVE_INFINITY;
                  }
              } else {
                  return Float.NaN;
              }
          }
          return Float.parseFloat(floatString);
      }
  
      private static Pattern specialDoubleRegex = Pattern.compile("((-)?infinityd?)|(nand?)", Pattern.CASE_INSENSITIVE);
      public static double parseDouble(String doubleString) {
          Matcher m = specialDoubleRegex.matcher(doubleString);
          if (m.matches()) {
              //got an infinity
              if (m.start(1) != -1) {
                  if (m.start(2) != -1) {
                      return Double.NEGATIVE_INFINITY;
                  } else {
                      return Double.POSITIVE_INFINITY;
                  }
              } else {
                  return Double.NaN;
              }
          }
          return Double.parseDouble(doubleString);
      }
  
      public static byte[] longToBytes(long value) {
          byte[] bytes = new byte[8];
  
          for (int i=0; value != 0; i++) {
              bytes[i] = (byte)value;
              value = value >>> 8;
          }
          return bytes;
      }
  
      public static byte[] intToBytes(int value) {
          byte[] bytes = new byte[4];
  
          for (int i=0; value != 0; i++) {
              bytes[i] = (byte)value;
              value = value >>> 8;
          }
          return bytes;
      }
  
      public static byte[] shortToBytes(short value) {
          byte[] bytes = new byte[2];
  
          bytes[0] = (byte)value;
          bytes[1] = (byte)(value >>> 8);
          return bytes;
      }
  
      public static byte[] floatToBytes(float value) {
          return intToBytes(Float.floatToRawIntBits(value));
      }
  
      public static byte[] doubleToBytes(double value) {
          return longToBytes(Double.doubleToRawLongBits(value));
      }
  
      public static byte[] charToBytes(char value) {
          return shortToBytes((short)value);
      }
  
      public static byte[] boolToBytes(boolean value) {
          if (value) {
              return new byte[] { 0x01 };
          } else {
              return new byte[] { 0x00 };
          }
      }
  
      public static void checkInt(long value) {
          if (value > 0xFFFFFFFF || value < -0x80000000) {
              throw new NumberFormatException(Long.toString(value) + " cannot fit into an int");
          }
      }
  
      public static void checkShort(long value) {
          if (value > 0xFFFF | value < -0x8000) {
              throw new NumberFormatException(Long.toString(value) + " cannot fit into a short");
          }
      }
  
      public static void checkByte(long value) {
          if (value > 0xFF | value < -0x80) {
              throw new NumberFormatException(Long.toString(value) + " cannot fit into a byte");
          }
      }
  
      public static void checkNibble(long value) {
          if (value > 0x0F | value < -0x08) {
              throw new NumberFormatException(Long.toString(value) + " cannot fit into a nibble");
          }
      }
  }
  
  
  /*
  增加检查寄存器和数字
  增加检查当前项目所有smali的开关，关闭时只检查寄存器和数字，不检查方法和字段（完全检查）
  优化错误的提示方式，直接在编辑器中提示
  增加中文错误提示
  
  */
  