View Javadoc
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 }