15867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com/* 25867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * [The "BSD licence"] 300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke) 45867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * All rights reserved. 55867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 65867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without 75867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions 85867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * are met: 95867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright 105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer. 115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright 125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * notice, this list of conditions and the following disclaimer in the 135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * documentation and/or other materials provided with the distribution. 145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products 155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * derived from this software without specific prior written permission. 165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * 175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com */ 285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.compackage org.jf.smali; 305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 31a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruverimport java.util.regex.Matcher; 32a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruverimport java.util.regex.Pattern; 33a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver 344dbfae78e9638f2ce7c13b97e40941e837c09d00Ben Gruverpublic class LiteralTools 355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com{ 365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte parseByte(String byteLiteral) 375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throws NumberFormatException { 385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (byteLiteral == null) { 395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is null"); 405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (byteLiteral.length() == 0) { 425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is blank"); 435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com char[] byteChars; 465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (byteLiteral.toUpperCase().endsWith("T")) { 475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byteChars = byteLiteral.substring(0, byteLiteral.length()-1).toCharArray(); 485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byteChars = byteLiteral.toCharArray(); 505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int position = 0; 535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int radix = 10; 545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com boolean negative = false; 555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (byteChars[position] == '-') { 565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com negative = true; 585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (byteChars[position] == '0') { 615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (position == byteChars.length) { 635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return 0; 645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (byteChars[position] == 'x' || byteChars[position] == 'X') { 655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 16; 665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (Character.digit(byteChars[position], 8) >= 0) { 685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 8; 695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte result = 0; 735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte shiftedResult; 745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int digit; 755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte maxValue = (byte)(Byte.MAX_VALUE / (radix / 2)); 765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com while (position < byteChars.length) { 785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com digit = Character.digit(byteChars[position], radix); 795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (digit < 0) { 805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("The string contains invalid an digit - '" + byteChars[position] + "'"); 815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com shiftedResult = (byte)(result * radix); 835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > maxValue) { 845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(byteLiteral + " cannot fit into a byte"); 855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shiftedResult < 0 && shiftedResult >= -digit) { 875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(byteLiteral + " cannot fit into a byte"); 885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (byte)(shiftedResult + digit); 905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (negative) { 945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //allow -0x80, which is = 0x80 955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result == Byte.MIN_VALUE) { 965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (result < 0) { 985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(byteLiteral + " cannot fit into a byte"); 995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return (byte)(result * -1); 1015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 1025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static short parseShort(String shortLiteral) 1075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throws NumberFormatException { 1085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shortLiteral == null) { 1095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is null"); 1105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shortLiteral.length() == 0) { 1125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is blank"); 1135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com char[] shortChars; 1165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shortLiteral.toUpperCase().endsWith("S")) { 1175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com shortChars = shortLiteral.substring(0, shortLiteral.length()-1).toCharArray(); 1185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 1195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com shortChars = shortLiteral.toCharArray(); 1205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int position = 0; 1235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int radix = 10; 1245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com boolean negative = false; 1255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shortChars[position] == '-') { 1265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 1275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com negative = true; 1285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shortChars[position] == '0') { 1315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 1325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (position == shortChars.length) { 1335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return 0; 1345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (shortChars[position] == 'x' || shortChars[position] == 'X') { 1355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 16; 1365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 1375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (Character.digit(shortChars[position], 8) >= 0) { 1385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 8; 1395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com short result = 0; 1435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com short shiftedResult; 1445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int digit; 1455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com short maxValue = (short)(Short.MAX_VALUE / (radix / 2)); 1465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com while (position < shortChars.length) { 1485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com digit = Character.digit(shortChars[position], radix); 1495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (digit < 0) { 1505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("The string contains invalid an digit - '" + shortChars[position] + "'"); 1515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com shiftedResult = (short)(result * radix); 1535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > maxValue) { 1545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(shortLiteral + " cannot fit into a short"); 1555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shiftedResult < 0 && shiftedResult >= -digit) { 1575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(shortLiteral + " cannot fit into a short"); 1585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = (short)(shiftedResult + digit); 1605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 1615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (negative) { 1645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //allow -0x8000, which is = 0x8000 1655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result == Short.MIN_VALUE) { 1665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (result < 0) { 1685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(shortLiteral + " cannot fit into a short"); 1695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return (short)(result * -1); 1715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 1725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 1735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static int parseInt(String intLiteral) 1775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throws NumberFormatException { 1785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (intLiteral == null) { 1795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is null"); 1805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (intLiteral.length() == 0) { 1825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is blank"); 1835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com char[] intChars = intLiteral.toCharArray(); 1865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int position = 0; 1875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int radix = 10; 1885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com boolean negative = false; 1895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (intChars[position] == '-') { 1905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 1915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com negative = true; 1925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 1935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 1945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (intChars[position] == '0') { 1955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 1965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (position == intChars.length) { 1975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return 0; 1985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (intChars[position] == 'x' || intChars[position] == 'X') { 1995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 16; 2005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 2015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (Character.digit(intChars[position], 8) >= 0) { 2025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 8; 2035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int result = 0; 2075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int shiftedResult; 2085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int digit; 2095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int maxValue = Integer.MAX_VALUE / (radix / 2); 2105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com while (position < intChars.length) { 2125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com digit = Character.digit(intChars[position], radix); 2135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (digit < 0) { 2145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("The string contains an invalid digit - '" + intChars[position] + "'"); 2155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com shiftedResult = result * radix; 2175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > maxValue) { 2185867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(intLiteral + " cannot fit into an int"); 2195867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2205867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shiftedResult < 0 && shiftedResult >= -digit) { 2215867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(intLiteral + " cannot fit into an int"); 2225867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2235867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = shiftedResult + digit; 2245867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 2255867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2265867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2275867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (negative) { 2285867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //allow -0x80000000, which is = 0x80000000 2295867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result == Integer.MIN_VALUE) { 2305867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2315867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (result < 0) { 2325867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(intLiteral + " cannot fit into an int"); 2335867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2345867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result * -1; 2355867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2365867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 2375867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2385867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2395867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2405867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static long parseLong(String longLiteral) 2415867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throws NumberFormatException { 2425867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (longLiteral == null) { 2435867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is null"); 2445867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2455867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (longLiteral.length() == 0) { 2465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("string is blank"); 2475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com char[] longChars; 2505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (longLiteral.toUpperCase().endsWith("L")) { 2515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com longChars = longLiteral.substring(0, longLiteral.length()-1).toCharArray(); 2525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 2535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com longChars = longLiteral.toCharArray(); 2545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int position = 0; 2575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int radix = 10; 2585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com boolean negative = false; 2595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (longChars[position] == '-') { 2605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 2615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com negative = true; 2625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (longChars[position] == '0') { 2655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 2665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (position == longChars.length) { 2675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return 0; 2685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (longChars[position] == 'x' || longChars[position] == 'X') { 2695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 16; 2705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 2715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (Character.digit(longChars[position], 8) >= 0) { 2725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com radix = 8; 2735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com long result = 0; 2775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com long shiftedResult; 2785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com int digit; 2795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com long maxValue = Long.MAX_VALUE / (radix / 2); 2805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com while (position < longChars.length) { 2825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com digit = Character.digit(longChars[position], radix); 2835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (digit < 0) { 2845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException("The string contains an invalid digit - '" + longChars[position] + "'"); 2855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com shiftedResult = result * radix; 2875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result > maxValue) { 2885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(longLiteral + " cannot fit into a long"); 2895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (shiftedResult < 0 && shiftedResult >= -digit) { 2915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(longLiteral + " cannot fit into a long"); 2925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com result = shiftedResult + digit; 2945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com position++; 2955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 2965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 2975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (negative) { 2985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com //allow -0x8000000000000000, which is = 0x8000000000000000 2995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (result == Long.MIN_VALUE) { 3005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 3015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else if (result < 0) { 3025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(longLiteral + " cannot fit into a long"); 3035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result * -1; 3055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 3065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return result; 3075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 310a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver private static Pattern specialFloatRegex = Pattern.compile("((-)?infinityf)|(nanf)", Pattern.CASE_INSENSITIVE); 311a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver public static float parseFloat(String floatString) { 312a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver Matcher m = specialFloatRegex.matcher(floatString); 313a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver if (m.matches()) { 314a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver //got an infinity 315a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver if (m.start(1) != -1) { 316a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver if (m.start(2) != -1) { 317a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Float.NEGATIVE_INFINITY; 318a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } else { 319a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Float.POSITIVE_INFINITY; 320a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 321a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } else { 322a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Float.NaN; 323a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 324a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 325a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Float.parseFloat(floatString); 326a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 327a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver 328a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver private static Pattern specialDoubleRegex = Pattern.compile("((-)?infinityd?)|(nand?)", Pattern.CASE_INSENSITIVE); 329a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver public static double parseDouble(String doubleString) { 330a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver Matcher m = specialDoubleRegex.matcher(doubleString); 331a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver if (m.matches()) { 332a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver //got an infinity 333a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver if (m.start(1) != -1) { 334a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver if (m.start(2) != -1) { 335a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Double.NEGATIVE_INFINITY; 336a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } else { 337a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Double.POSITIVE_INFINITY; 338a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 339a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } else { 340a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Double.NaN; 341a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 342a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 343a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver return Double.parseDouble(doubleString); 344a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver } 345a3dce1f48ce565387783c1c916d8bf73ec1ac660Ben Gruver 3465867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] longToBytes(long value) { 3475867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] bytes = new byte[8]; 3485867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3495867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i=0; value != 0; i++) { 3505867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[i] = (byte)value; 3515867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value = value >>> 8; 3525867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3535867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return bytes; 3545867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3555867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3565867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] intToBytes(int value) { 3575867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] bytes = new byte[4]; 3585867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3595867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com for (int i=0; value != 0; i++) { 3605867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[i] = (byte)value; 3615867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com value = value >>> 8; 3625867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3635867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return bytes; 3645867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3655867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3665867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] shortToBytes(short value) { 3675867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com byte[] bytes = new byte[2]; 3685867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3695867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[0] = (byte)value; 3705867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com bytes[1] = (byte)(value >>> 8); 3715867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return bytes; 3725867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3735867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3745867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] floatToBytes(float value) { 3755867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return intToBytes(Float.floatToRawIntBits(value)); 3765867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3775867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3785867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] doubleToBytes(double value) { 3795867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return longToBytes(Double.doubleToRawLongBits(value)); 3805867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3815867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3825867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] charToBytes(char value) { 3835867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return shortToBytes((short)value); 3845867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3855867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3865867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static byte[] boolToBytes(boolean value) { 3875867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (value) { 3885867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return new byte[] { 0x01 }; 3895867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } else { 3905867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com return new byte[] { 0x00 }; 3915867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3925867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3935867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 3945867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static void checkInt(long value) { 3955867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (value > 0xFFFFFFFF || value < -0x80000000) { 3965867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(Long.toString(value) + " cannot fit into an int"); 3975867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3985867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 3995867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 4005867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static void checkShort(long value) { 4015867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (value > 0xFFFF | value < -0x8000) { 4025867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(Long.toString(value) + " cannot fit into a short"); 4035867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 4045867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 4055867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 4065867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static void checkByte(long value) { 4075867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (value > 0xFF | value < -0x80) { 4085867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(Long.toString(value) + " cannot fit into a byte"); 4095867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 4105867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 4115867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com 4125867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com public static void checkNibble(long value) { 4135867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com if (value > 0x0F | value < -0x08) { 4145867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com throw new NumberFormatException(Long.toString(value) + " cannot fit into a nibble"); 4155867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 4165867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com } 4175867263eb588f4671400895d1e6b01c01535061bJesusFreke@JesusFreke.com} 418