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