1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.commons.numbers.gamma; 18 19 import java.io.BufferedReader; 20 import java.io.IOException; 21 import java.io.InputStream; 22 import java.io.InputStreamReader; 23 import java.math.BigDecimal; 24 import java.util.regex.Pattern; 25 import org.junit.jupiter.api.Assertions; 26 27 /** 28 * Class to read data fields from a test resource file. 29 */ 30 class DataReader implements AutoCloseable { 31 /** Comment character. */ 32 private static final char COMMENT = '#'; 33 /** Pattern to split data fields. */ 34 private static final Pattern FIELD_PATTERN = Pattern.compile("[, ]+"); 35 36 /** Input to read. */ 37 private final BufferedReader in; 38 39 /** The current set of fields. */ 40 private String[] tokens; 41 42 /** 43 * @param filename Resource filename to read 44 */ 45 DataReader(String filename) { 46 final InputStream resourceAsStream = this.getClass().getResourceAsStream(filename); 47 Assertions.assertNotNull(resourceAsStream, () -> "Could not find resource " + filename); 48 in = new BufferedReader(new InputStreamReader(resourceAsStream)); 49 } 50 51 /** 52 * Read the next line of data fields. 53 * 54 * @return true if data is available 55 * @throws IOException Signals that an I/O exception has occurred. 56 */ 57 boolean next() throws IOException { 58 tokens = null; 59 for (String line = in.readLine(); line != null; line = in.readLine()) { 60 if (line.isEmpty() || line.charAt(0) == COMMENT || line.trim().isEmpty()) { 61 continue; 62 } 63 tokens = FIELD_PATTERN.split(line); 64 return true; 65 } 66 return false; 67 } 68 69 /** 70 * Gets the double from the field. 71 * 72 * @param i Field index 73 * @return the number 74 * @see #next() 75 * @throws NumberFormatException if the field cannot be parsed as a double 76 * @throws NullPointerException if no field data is available 77 * @throws IndexOutOfBoundsException if the field index is invalid 78 */ 79 double getDouble(int i) { 80 return Double.parseDouble(tokens[i]); 81 } 82 83 /** 84 * Gets the BigDecimal from the field. 85 * 86 * @param i Field index 87 * @return the number 88 * @see #next() 89 * @throws NumberFormatException if the field cannot be parsed as a BigDecimal 90 * @throws NullPointerException if no field data is available 91 * @throws IndexOutOfBoundsException if the field index is invalid 92 */ 93 BigDecimal getBigDecimal(int i) { 94 return new BigDecimal(tokens[i]); 95 } 96 97 /** 98 * Gets the current fields. This is returned as a reference. 99 * 100 * <p>This is null if no fields are available for reading. 101 * 102 * @return the fields 103 * @see #next() 104 */ 105 String[] getFields() { 106 return tokens; 107 } 108 109 @Override 110 public void close() throws IOException { 111 in.close(); 112 } 113 }