// Path: src/main/java/uk/elementarysoftware/quickcsv/decoder/doubles/DoubleParser.java
// public interface DoubleParser {
//     public double parse(byte[] in, int startIndex, int length);
// 
//     default public double parse(String s) {
//         return parse(s.getBytes(), 0, s.length());
//     };
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/decoder/doubles/JDKDoubleParserAdapter.java
// public class JDKDoubleParserAdapter implements DoubleParser {
// 
//     public double parse(byte[] in, int startIndex, int length) {
//         return JDKDoubleParser.readJavaFormatString(in, startIndex, length).doubleValue();
//     }
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/decoder/doubles/QuickDoubleParser.java
// public class QuickDoubleParser implements DoubleParser {
// 
//     private static final int RADIX = 10;
//     private static final int DOT = '.'-'0';
//     
//     private JDKDoubleParserAdapter fallBack = new JDKDoubleParserAdapter();
//     
//     public double parse(byte[] bytes, int offset, int length) {
//         if (bytes == null || length <=0)
//             throw new NumberFormatException("Empty input");
//         long result = 0;
//         boolean isNegative = false;
//         int index = offset, dotIndex=offset+length-1, endIndex = offset+length;
// 
//         byte firstByte = bytes[index];
//         if (firstByte < '0') {
//             if (firstByte == '-') {
//                 isNegative = true;
//             }
//             index++;
//         }
//         int nDigits = 0;
//         while (index < endIndex) {
//             int digit = bytes[index] - '0';
//             if (digit == DOT) {
//                 dotIndex=index;
//             }else  if (digit < 0 || digit>9) {
//                 throw new NumberFormatException("For: "+new String(bytes, offset, length));
//             } else {
//                 result *= RADIX;
//                 result -= digit;
//                 nDigits++; 
//             }
//             index++;
//         }
//         
//         double mantissa = -result;
//         int negExponent = length-(dotIndex-offset)-1;
//         
//         if (nDigits <= JDKDoubleParser.maxDecimalDigits) {
//             if (negExponent == 0 || mantissa == 0.0) {
//                 return (isNegative) ? -mantissa : mantissa;
//             }  
//             double rValue = mantissa / JDKDoubleParser.small10pow[negExponent];
//             return (isNegative) ? -rValue : rValue;
//         } else { //harder case, use JDK implementation
//             return fallBack.parse(bytes, offset, length);
//         }
//     }
// }


import static org.junit.Assert.*;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.LineIterator;
import org.junit.Test;
import uk.elementarysoftware.quickcsv.decoder.doubles.DoubleParser;
import uk.elementarysoftware.quickcsv.decoder.doubles.JDKDoubleParserAdapter;
import uk.elementarysoftware.quickcsv.decoder.doubles.QuickDoubleParser;
package uk.elementarysoftware.quickcsv.decoder.doubles;






public class DoubleParserTest {
    
    @Test
    public void testSimpleCases() {
        doTestSimpleCases(new JDKDoubleParserAdapter());
        doTestSimpleCases(new QuickDoubleParser());
    }
    
    @Test
    public void testBigBuffer() {
        doTestBigBuffer(new JDKDoubleParserAdapter());
        doTestBigBuffer(new QuickDoubleParser());
    }
    
    @Test
    public void testFile() throws Exception {
        doTestFile(new JDKDoubleParserAdapter());
        doTestFile(new QuickDoubleParser());
    }
    
    private void doTestSimpleCases(DoubleParser parser) {
        assertEquals(0.0, parser.parse("0"), 1E-14);
        assertEquals(3.14159265, parser.parse("3.14159265"), 1E-14);
        assertEquals(-93231637.47759183, parser.parse("-93231637.47759183"), 1E-14);
        assertEquals(-0.3903, parser.parse("-0.3903"), 1E-14);
        assertEquals(2.71828183, parser.parse("2.71828183"), 1E-14);
    }
    
// Path: src/main/java/uk/elementarysoftware/quickcsv/decoder/doubles/DoubleParser.java
// public interface DoubleParser {
//     public double parse(byte[] in, int startIndex, int length);
// 
//     default public double parse(String s) {
//         return parse(s.getBytes(), 0, s.length());
//     };
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/decoder/doubles/JDKDoubleParserAdapter.java
// public class JDKDoubleParserAdapter implements DoubleParser {
// 
//     public double parse(byte[] in, int startIndex, int length) {
//         return JDKDoubleParser.readJavaFormatString(in, startIndex, length).doubleValue();
//     }
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/decoder/doubles/QuickDoubleParser.java
// public class QuickDoubleParser implements DoubleParser {
// 
//     private static final int RADIX = 10;
//     private static final int DOT = '.'-'0';
//     
//     private JDKDoubleParserAdapter fallBack = new JDKDoubleParserAdapter();
//     
//     public double parse(byte[] bytes, int offset, int length) {
//         if (bytes == null || length <=0)
//             throw new NumberFormatException("Empty input");
//         long result = 0;
//         boolean isNegative = false;
//         int index = offset, dotIndex=offset+length-1, endIndex = offset+length;
// 
//         byte firstByte = bytes[index];
//         if (firstByte < '0') {
//             if (firstByte == '-') {
//                 isNegative = true;
//             }
//             index++;
//         }
//         int nDigits = 0;
//         while (index < endIndex) {
//             int digit = bytes[index] - '0';
//             if (digit == DOT) {
//                 dotIndex=index;
//             }else  if (digit < 0 || digit>9) {
//                 throw new NumberFormatException("For: "+new String(bytes, offset, length));
//             } else {
//                 result *= RADIX;
//                 result -= digit;
//                 nDigits++; 
//             }
//             index++;
//         }
//         
//         double mantissa = -result;
//         int negExponent = length-(dotIndex-offset)-1;
//         
//         if (nDigits <= JDKDoubleParser.maxDecimalDigits) {
//             if (negExponent == 0 || mantissa == 0.0) {
//                 return (isNegative) ? -mantissa : mantissa;
//             }  
//             double rValue = mantissa / JDKDoubleParser.small10pow[negExponent];
//             return (isNegative) ? -rValue : rValue;
//         } else { //harder case, use JDK implementation
//             return fallBack.parse(bytes, offset, length);
//         }
//     }
// }


// Path: src/test/java/uk/elementarysoftware/quickcsv/decoder/doubles/DoubleParserTest.java
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.charset.Charset;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.LineIterator;
import org.junit.Test;
import uk.elementarysoftware.quickcsv.decoder.doubles.DoubleParser;
import uk.elementarysoftware.quickcsv.decoder.doubles.JDKDoubleParserAdapter;
import uk.elementarysoftware.quickcsv.decoder.doubles.QuickDoubleParser;

package uk.elementarysoftware.quickcsv.decoder.doubles;






public class DoubleParserTest {
    
    @Test
    public void testSimpleCases() {
        doTestSimpleCases(new JDKDoubleParserAdapter());
        doTestSimpleCases(new QuickDoubleParser());
    }
    
    @Test
    public void testBigBuffer() {
        doTestBigBuffer(new JDKDoubleParserAdapter());
        doTestBigBuffer(new QuickDoubleParser());
    }
    
    @Test
    public void testFile() throws Exception {
        doTestFile(new JDKDoubleParserAdapter());
        doTestFile(new QuickDoubleParser());
    }
    
    private void doTestSimpleCases(DoubleParser parser) {
        assertEquals(0.0, parser.parse("0"), 1E-14);
        assertEquals(3.14159265, parser.parse("3.14159265"), 1E-14);
        assertEquals(-93231637.47759183, parser.parse("-93231637.47759183"), 1E-14);
        assertEquals(-0.3903, parser.parse("-0.3903"), 1E-14);
        assertEquals(2.71828183, parser.parse("2.71828183"), 1E-14);
    }
    
    private void doTestBigBuffer(DoubleParser parser) {