private static int parseInt( FastSimpleStringBufferForCSVProcessorAndJSONParser s, int startIndex, int strLen) throws ParseException { if (startIndex == strLen) throw new ParseException( "Failed to parse '" + s.toString() + "' at offset " + startIndex, startIndex); int res = 0; final boolean isNegative; int i = startIndex; if (s.charAt(i) == '-') { isNegative = true; i++; } else { isNegative = false; } int intValue = 0; for (; i < strLen; i++) { final char ch = s.charAt(i); if (ch < '0' || ch > '9') { throw new ParseException("Failed to parse '" + s.toString() + "' at offset " + i, i); } else { int val = ch - '0'; intValue = intValue * 10 + val; } } return isNegative ? (-1 * intValue) : intValue; }
public static double parseDouble(final FastSimpleStringBufferForCSVProcessorAndJSONParser s) throws ParseException { final int strLen = s.length(); if (strLen == 0) return Double.NaN; final double toReturn = strLen <= 9 ? parseUsingIntValue(s, strLen) : parseUsingLongValue(s, strLen); if (kDEBUG_VERSUS_JAVA_PARSING) { final double alternative = Double.parseDouble(s.toString()); if (toReturn != alternative) throw new IllegalArgumentException( s.toString() + " parsed differently! " + toReturn + " vs java " + alternative); } return toReturn; }
private static double parseUsingIntValue( FastSimpleStringBufferForCSVProcessorAndJSONParser s, int strLen) throws ParseException { final boolean isNegative; int i; if (s.charAt(0) == '-') { isNegative = true; i = 1; } else { isNegative = false; i = 0; } int intValue = 0; int exp = 0; int expDelta = 0; int numDigits = 0; for (; i < strLen; i++) { final char ch = s.charAt(i); if (ch == '.') { if (expDelta == -1) throw new ParseException("Failed to parse '" + s.toString() + "' at offset " + i, i); expDelta = -1; } else if (ch == 'E') { exp += parseInt(s, i + 1, strLen); i = strLen; } else if (ch < '0' || ch > '9') { throw new ParseException("Failed to parse '" + s.toString() + "' at offset " + i, i); } else { int val = ch - '0'; intValue = intValue * 10 + val; exp += expDelta; numDigits++; } } if (numDigits == 0) throw new ParseException("Failed to parse '" + s.toString() + "'", 0); // todo: we can probably optimize converToDouble knowing that it's of limited size. return convertToDouble(intValue, exp, isNegative, numDigits); }
private static double parseUsingLongValue( FastSimpleStringBufferForCSVProcessorAndJSONParser s, int strLen) throws ParseException { // If the string is ridiculously long, long type is not enough to hold the mantissa. // In such case, use java built in double parser as we are not likely to see those numbers // anyway... if (strLen >= 18) return Double.parseDouble(s.toString()); final boolean isNegative; int i; if (s.charAt(0) == '-') { isNegative = true; i = 1; } else { isNegative = false; i = 0; } long longValue = 0; int exp = 0; int expDelta = 0; int numDigits = 0; for (; i < strLen; i++) { final char ch = s.charAt(i); if (ch == '.') { if (expDelta == -1) throw new ParseException("Failed to parse '" + s.toString() + "' at offset " + i, i); expDelta = -1; } else if (ch == 'E') { exp += parseInt(s, i + 1, strLen); i = strLen; } else if (ch < '0' || ch > '9') { throw new ParseException("Failed to parse '" + s.toString() + "' at offset " + i, i); } else { int val = ch - '0'; longValue = longValue * 10 + val; exp += expDelta; numDigits++; } } if (numDigits == 0) throw new ParseException("Failed to parse '" + s.toString() + "'", 0); return convertToDouble((double) longValue, exp, isNegative, numDigits); }