KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > quadcap > util > text > Scanner


1 package com.quadcap.util.text;
2
3 /* Copyright 1997 - 2003 Quadcap Software. All rights reserved.
4  *
5  * This software is distributed under the Quadcap Free Software License.
6  * This software may be used or modified for any purpose, personal or
7  * commercial. Open Source redistributions are permitted. Commercial
8  * redistribution of larger works derived from, or works which bundle
9  * this software requires a "Commercial Redistribution License"; see
10  * http://www.quadcap.com/purchase.
11  *
12  * Redistributions qualify as "Open Source" under one of the following terms:
13  *
14  * Redistributions are made at no charge beyond the reasonable cost of
15  * materials and delivery.
16  *
17  * Redistributions are accompanied by a copy of the Source Code or by an
18  * irrevocable offer to provide a copy of the Source Code for up to three
19  * years at the cost of materials and delivery. Such redistributions
20  * must allow further use, modification, and redistribution of the Source
21  * Code under substantially the same terms as this license.
22  *
23  * Redistributions of source code must retain the copyright notices as they
24  * appear in each source code file, these license terms, and the
25  * disclaimer/limitation of liability set forth as paragraph 6 below.
26  *
27  * Redistributions in binary form must reproduce this Copyright Notice,
28  * these license terms, and the disclaimer/limitation of liability set
29  * forth as paragraph 6 below, in the documentation and/or other materials
30  * provided with the distribution.
31  *
32  * The Software is provided on an "AS IS" basis. No warranty is
33  * provided that the Software is free of defects, or fit for a
34  * particular purpose.
35  *
36  * Limitation of Liability. Quadcap Software shall not be liable
37  * for any damages suffered by the Licensee or any third party resulting
38  * from use of the Software.
39  */

40
41 import java.io.BufferedInputStream JavaDoc;
42 import java.io.IOException JavaDoc;
43 import java.io.InputStream JavaDoc;
44 import java.io.OutputStream JavaDoc;
45
46 import com.quadcap.util.Debug;
47
48 //#ifdef DEBUG
49
import java.io.ByteArrayOutputStream JavaDoc;
50 import com.quadcap.io.LogInputStream;
51 //#endif
52

53 /**
54  * The class implements a series of low-level stream scanning operations,
55  * using OctetMaps to implement 'while' and 'until'.
56  * @author Stan Bailes
57  */

58 public class Scanner {
59     InputStream JavaDoc is;
60     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
61     int pushback = -1;
62
63     //#ifdef DEBUG
64
LogInputStream log = null;
65     ByteArrayOutputStream JavaDoc bos = null;
66
67     public Scanner(InputStream JavaDoc is, boolean saveit) {
68     if (saveit) {
69         bos = new ByteArrayOutputStream JavaDoc();
70         this.is = new LogInputStream(is, bos, "");
71     } else {
72             this.is = is;
73         }
74     }
75
76     public String JavaDoc getLog() { return bos.toString(); }
77     //#endif
78

79     /**
80      * Construct a new scanner, attached to the specified input stream.
81      *
82      * @param is the stream to scan.
83      */

84     public Scanner(InputStream JavaDoc is) {
85     this.is = is;
86     }
87
88     public void reset(InputStream JavaDoc is) {
89         this.is = is;
90         //#ifdef DEBUG
91
if (bos != null) {
92             bos.reset();
93             this.is = new LogInputStream(is, bos, "");
94         }
95         //#endif
96
pushback = -1;
97     }
98
99     final int read() throws IOException JavaDoc {
100         int c = pushback;
101         if (c >= 0) {
102             pushback = -1;
103         } else {
104             c = is.read();
105         }
106         return c;
107     }
108
109     final void unread(int c) {
110         pushback = c;
111     }
112
113     /**
114      * Read and discard characters until a character is found which
115      * <b>is not</b> in the map. Then push back the terminating character.
116      *
117      * @param map the set of characters to skip.
118      * @exception IOException if an I/O exception is thrown
119      */

120     final public void skipWhile(OctetMap map) throws IOException JavaDoc {
121     int c;
122     while (map.has(c = read()) && c >= 0) continue;
123     if (c >= 0) unread(c);
124     }
125
126     /**
127      * Read and discard characters until a character is found which
128      * <b>is</b> in the map. Then push back the terminating character.
129      *
130      * @param map the set of characters which skip.
131      * @exception IOException if an I/O exception is thrown
132      */

133     final public void skipUntil(OctetMap map) throws IOException JavaDoc {
134     int c;
135     while (!map.has(c = read()) && c >= 0) continue;
136     if (c >= 0) unread(c);
137     }
138     
139     /**
140      * Return the next portion of the stream which consists of characters
141      * <b>IN</b> the specified set.
142      *
143      * @param map the set of characters to parse.
144      * @exception IOException if an I/O exception is thrown
145      */

146     final public String JavaDoc parseWhile(OctetMap map) throws IOException JavaDoc {
147     sb.setLength(0);
148     int c;
149     while (map.has(c = read()) && c >= 0) {
150         sb.append((char)c);
151     }
152     if (c >= 0) unread(c);
153     return sb.toString();
154     }
155
156     /**
157      * Return the next portion of the stream which consists of characters
158      * <b>NOT IN</b> the specified set.
159      *
160      * @param map the set of characters to parse.
161      * @exception IOException if an I/O exception is thrown
162      */

163     final public String JavaDoc parseUntil(OctetMap map) throws IOException JavaDoc {
164     sb.setLength(0);
165     int c;
166     while (!map.has(c = read()) && c >= 0) {
167         sb.append((char)c);
168     }
169     if (c >= 0) unread(c);
170     return sb.toString();
171     }
172
173
174     /**
175      * Read the next character, and verify that it is equal to the expected
176      * value.
177      *
178      * @param expected the expected character
179      * @exception IOException if the character read from the stream is not
180      * equal to the specified character.
181      */

182     final public void matchChar(int expected) throws IOException JavaDoc {
183     int c = read();
184     if (c != expected) {
185         if (c < 0x1f || expected < 0x1f) {
186         throw new IOException JavaDoc("Expected: " + expected + ", got " + c);
187         } else {
188         throw new IOException JavaDoc("Expected: " + expected + "(" +
189                       (char)expected + "), got " + c + "(" +
190                       (char)c + ")");
191         }
192     }
193     }
194
195     /**
196      * Read the next string using the specified map, and verify that it
197      * <b>IS</b> equal to the expected value.
198      *
199      * @param expected the expected string
200      * @exception IOException if the character read from the stream is not
201      * equal to the specified character.
202      */

203     final public void matchString(OctetMap map, String JavaDoc expected)
204     throws IOException JavaDoc
205     {
206     String JavaDoc actual = parseWhile(map);
207     if (!actual.equals(expected)) {
208         throw new IOException JavaDoc("Expected: " + expected +
209                   ", got: " + actual);
210     }
211     }
212
213     /**
214      * Read the next string using the specified map, and verify that it
215      * <b>IS</b> equal to the expected value, if all characters in both
216      * strings are converted to monocase.
217      *
218      * @param expected the expected string
219      * @exception IOException if the character read from the stream is not
220      * equal to the specified character.
221      */

222     final public void matchStringIgnoreCase(OctetMap map,
223                                             String JavaDoc expected)
224     throws IOException JavaDoc
225     {
226     String JavaDoc actual = parseWhile(map);
227     if (!actual.equalsIgnoreCase(expected)) {
228         throw new IOException JavaDoc("Expected: " + expected +
229                   ", got: '" + actual + "', next char = " +
230                   ((char)peek()) + " (" + peek() + ")");
231     }
232     }
233
234     /**
235      * Peek ahead one character in the stream by reading, then pushing back
236      * the character.
237      *
238      * @return the next character from the stream.
239      * @exception IOException if an exception is thrown when the character
240      * is read.
241      */

242     final public int peek() throws IOException JavaDoc {
243         if (pushback > 0) {
244             return pushback;
245         } else {
246             int c = read();
247             unread(c);
248             return c;
249         }
250     }
251
252     /**
253      * Copy bytes from an input stream to an output stream until a byte
254      * not in the specified set is found. That byte is returned, or -1
255      * the end of file is reached.
256      *
257      * @param is the input stream from which bytes are is.read
258      * @param os the output stream to which bytes are written
259      * @param map the set of valid byte to copy
260      * @return the first non matching byte
261      * @exception IOException may be thrown
262      */

263     public static int copyWhile(InputStream JavaDoc is, OutputStream JavaDoc os, OctetMap map)
264         throws IOException JavaDoc
265     {
266         int c = is.read();
267         while (c >= 0 && map.has(c)) {
268             os.write(c);
269             c = is.read();
270         }
271         return c;
272     }
273
274     /**
275      * Copy bytes from an input stream to an output stream until a byte
276      * in the specified set is found. That byte is returned, or -1
277      * the end of file is reached.
278      *
279      * @param is the input stream from which bytes are is.read
280      * @param os the output stream to which bytes are written
281      * @param map the set of valid delimiter bytes
282      * @return the first matching byte
283      * @exception IOException may be thrown
284      */

285     public static int copyUntil(InputStream JavaDoc is, OutputStream JavaDoc os, OctetMap map)
286         throws IOException JavaDoc
287     {
288         int c = is.read();
289         while (c >= 0 && !map.has(c)) {
290             os.write(c);
291             c = is.read();
292         }
293         return c;
294     }
295
296     public static int copyUntil(InputStream JavaDoc is, OutputStream JavaDoc os, int dc)
297         throws IOException JavaDoc
298     {
299         int c = is.read();
300         while (c >= 0 && c != dc) {
301             os.write(c);
302             c = is.read();
303         }
304         return c;
305     }
306
307     /**
308      * Copy bytes from <code>in</code> to <code>out</code> until the
309      * specified string is is.read from <code>in</code. The string bytes
310      * are not written to <code>out</code>
311      *
312      * @param is the input stream from which bytes are is.read
313      * @param os the output stream to which bytes are written
314      * @param s the delimiter string
315      * @return < 0 if end of file is reached before the string is found,
316      * >= 0 otherwise
317      * @exception IOException may be thrown
318      */

319     public static int copyUntil(BufferedInputStream JavaDoc is, OutputStream JavaDoc os,
320                                 String JavaDoc s)
321         throws IOException JavaDoc
322     {
323         if (s.length() == 0) throw new IOException JavaDoc("empty target");
324         
325         int ret = -1;
326         int dc = s.charAt(0) & 0xff;
327         for (boolean found = false; !found; ) {
328             if (copyUntil(is, os, dc) < 0) return -1;
329             
330             is.mark(s.length());
331             found = true;
332             for (int i = 1; found && i < s.length(); i++) {
333                 int c = 0;
334                 if ((c = is.read()) != s.charAt(i)) {
335                     for (int j = 0; j < i; j++) os.write(s.charAt(j));
336
337                     if (c < 0) return -1;
338
339                     is.reset();
340                     found = false;
341                 }
342             }
343         }
344         return 1;
345     }
346
347     /**
348      * Read and discard characters until a character is found which
349      * <b>is not</b> equal to the specified character. Return the
350      * terminating character.
351      *
352      * @param dc the character to discard
353      * @exception IOException if an I/O exception is thrown
354      */

355     public static int skipWhile(InputStream JavaDoc is, int dc) throws IOException JavaDoc {
356     int c;
357     while (dc == (c = is.read())) continue;
358     return c;
359     }
360 }
361
Popular Tags