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"))
69 return true;
70
71 if (firstChar.equalsIgnoreCase("N") || firstChar.equalsIgnoreCase("F"))
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
113
114 String numString = readString(eoField).trim();
115
116 if (numString.length() == 0)
117 return 0;
118
119
120 Long numLong = new Long(numString);
121
122
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
133
134 String numString = readString(width).trim();
135
136 if (numString.length() == 0)
137 return 0;
138
139
140 Long numLong = new Long(numString);
141
142
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
165 while ( c == Codes.SPACE) c = read();
166
167
168 while (( c != eoFieldMarker) && !charIsEOLine(c)) {
169 returnString = returnString + (char) c;
170 c = read();
171 }
172
173 isEOL = charIsEOLine(c);
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);
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
215
216
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