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 }