View Javadoc

1   package org.astrogrid.tools.ascii;
2   
3   
4   /***
5    * An InputStream that provides a set of convenience routines for reading from
6    * an ASCII file.  Such files may be separated by some character (often a comma
7    * for comma-separated variables) or may be arranged in columns.  This stream
8    * provides methods for reading type-specific variables (eg, Integers, Strings,
9    * Booleans, etc) from both.
10   * Creation date: Jan 2001
11   * @author: M Hill
12   */
13  
14  import java.io.*;
15  
16  public class AsciiInputStream extends FilterInputStream
17  {
18      public static int c_eoLine = Codes.LF;
19      public static int c_eoFile = -1;
20      private char defaultEoField = ',';
21      private boolean isEOL = false;
22      private boolean checkForEOLine = true;
23      
24      /***
25       * Constructor - pass in the stream that it should read from
26       */
27      public AsciiInputStream(java.io.InputStream in) {
28          super(in);
29      }
30  
31      /***
32       * Private method used to see if the given character is an end of line
33       * marker (ie, a line feed) or indicates the end of file when no more
34       * characters are available
35       * @return boolean true if given character is end of line
36       * @param c int
37       */
38      private boolean charIsEOLine(int c) {
39          if (checkForEOLine)
40              return ((c == c_eoLine) || (c == c_eoFile));
41          else
42              return false;
43      }
44  
45      /***
46       * Returns true if the end of line marker is set
47       */
48      public boolean isEOLine() {
49          return isEOL;
50      }
51  
52      /***
53       * Sets the eoField character
54       */
55      public void setEoField(char newEoFieldMarker)
56      {
57          defaultEoField = newEoFieldMarker;
58      }
59      
60      /***
61       * Returns true/false if it thinks the given string indicates true/false,
62       * or throws exception if it can't tell
63       */
64      private boolean isFieldBoolean(String field) throws IOException
65      {
66          String firstChar = field.substring(0,0);
67          
68          if (firstChar.equalsIgnoreCase("Y") || firstChar.equalsIgnoreCase("T")) //yes or true
69              return true;
70          
71          if (firstChar.equalsIgnoreCase("N") || firstChar.equalsIgnoreCase("F")) //yes or true
72              return false;
73  
74          throw new IOException("Cannot resolve "+field+" to boolean");
75      }
76      
77      /***
78       * Reads up to next defaultEoField character and returns whether it thinks
79       * that field indicates true or false.
80       * @see isFieldBoolean
81       */
82      public boolean readBoolean() throws IOException
83      {
84          return isFieldBoolean(readString().trim());
85      }
86      
87      /***
88       * Reads up to the next occurence of the given character, and returns whether
89       * it thinks that field indicates true or false
90       * @see isFieldBoolean
91       */
92      public boolean readBoolean(char eoField) throws IOException
93      {
94          return isFieldBoolean(readString(eoField).trim());
95      }
96  
97      /***
98       * Reads up to the next defaultEoField character and returns a long
99       * representation of it
100      */
101     public long readNum() throws IOException {
102         return readNum(defaultEoField);
103     }
104 
105     /***
106      * Reads an integer from the ASCII stream, by reading a string until
107      * the given end-of-field marker and then converting it to an integer.
108      * @return int
109      */
110     public long readNum(char eoField) throws IOException {
111         
112         //read string of given width
113         //trim cuts spaces and all chars less than a space (eg cr/lf)
114         String numString = readString(eoField).trim();
115         
116         if (numString.length() == 0)
117             return 0;
118         
119         //convert to integer object...
120         Long numLong = new Long(numString);
121         
122         //,,,so that we can convert that to an int.
123         return numLong.longValue();
124     }
125 
126     /***
127      * Reads an integer from the ASCII stream, by reading a string of the
128      * given length (ie, column width) and then converting it to an integer.
129      */
130     public long readNum(int width) throws IOException {
131         
132         //read string of given width
133         //trim cuts spaces and all chars less than a space (eg cr/lf)
134         String numString = readString(width).trim();
135         
136         if (numString.length() == 0)
137             return 0;
138         
139         //convert to integer object...
140         Long numLong = new Long(numString);
141         
142         //,,,so that we can convert that to an int.
143         return numLong.longValue();
144     }
145 
146     /***
147      * Reads the characters up to the next default end-of-field marker
148      */
149     public String readString() throws IOException
150     {
151         return readString(defaultEoField);
152     }
153 
154     /***
155      * Reads the characters up to the next occurence of the given end-of-field
156      * marker, ignoring all initial spaces.
157      */
158     public String readString(char eoFieldMarker) throws IOException
159     {
160         String returnString = "";
161         
162         int c = read();
163         
164         //read spaces
165         while ( c == Codes.SPACE) c = read();
166         
167         //read until end of field marker found
168         while (( c != eoFieldMarker) && !charIsEOLine(c)) {
169             returnString = returnString + (char) c;
170             c =  read();
171         }
172         
173         isEOL = charIsEOLine(c);    //mark if reached end of line
174         
175         return returnString;
176     }
177     
178     /***
179      * Reads the next number of characters corresponding to the given column
180      * width
181      */
182     public String readString(int width) throws IOException
183     {
184         String returnString = "";
185         
186         int c = Codes.NUL;
187         
188         while ((width > 0) && !charIsEOLine(c)) {
189             c = read();
190             
191             if (!charIsEOLine(c)) {
192                 returnString = returnString +  (char) c;
193             }
194             
195             width --;
196         }
197         
198         isEOL = charIsEOLine(c);    //mark if reached end of line
199         
200         return returnString;
201     }
202     
203     /***
204      * Reads to the end of the line, returning all characters from the current
205      * point to there.  If the pointer is already at the end of the line (due
206      * to reading the last field, for example), nothing happens but the next
207      * read will start the next line.
208     */
209     public String readToEOL() throws IOException {
210         
211         int c = Codes.NUL;
212         String r = "";
213         
214         //if we've already reached the end of line, eg due to a readString(),
215         //we don't want to do this as we'll end up reading the complete next
216         //line
217         if (!isEOL) {
218             while ((c != c_eoFile) && (c != c_eoLine)) {
219                 c = read();
220                 r = r + (char) c;
221             }
222         }
223         
224         isEOL = false;
225         
226         return r;
227     }
228 }
229