KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > james > imapserver > ImapRequestLineReader


1 /***********************************************************************
2  * Copyright (c) 2000-2004 The Apache Software Foundation. *
3  * All rights reserved. *
4  * ------------------------------------------------------------------- *
5  * Licensed under the Apache License, Version 2.0 (the "License"); you *
6  * may not use this file except in compliance with the License. You *
7  * 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 *
14  * implied. See the License for the specific language governing *
15  * permissions and limitations under the License. *
16  ***********************************************************************/

17
18 package org.apache.james.imapserver;
19
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.OutputStream JavaDoc;
23
24 /**
25  * Wraps the client input reader with a bunch of convenience methods, allowing lookahead=1
26  * on the underlying character stream.
27  * TODO need to look at encoding, and whether we should be wrapping an InputStream instead.
28  *
29  *
30  * @version $Revision: 1.4.2.3 $
31  */

32 public class ImapRequestLineReader
33 {
34     private InputStream JavaDoc input;
35     private OutputStream JavaDoc output;
36
37     private boolean nextSeen = false;
38     private char nextChar; // unknown
39

40     ImapRequestLineReader( InputStream JavaDoc input, OutputStream JavaDoc output )
41     {
42         this.input = input;
43         this.output = output;
44     }
45
46     /**
47      * Reads the next regular, non-space character in the current line. Spaces are skipped
48      * over, but end-of-line characters will cause a {@link ProtocolException} to be thrown.
49      * This method will continue to return
50      * the same character until the {@link #consume()} method is called.
51      * @return The next non-space character.
52      * @throws ProtocolException If the end-of-line or end-of-stream is reached.
53      */

54     public char nextWordChar() throws ProtocolException
55     {
56         char next = nextChar();
57         while ( next == ' ' ) {
58             consume();
59             next = nextChar();
60         }
61
62         if ( next == '\r' || next == '\n' ) {
63             throw new ProtocolException( "Missing argument." );
64         }
65
66         return next;
67     }
68
69     /**
70      * Reads the next character in the current line. This method will continue to return
71      * the same character until the {@link #consume()} method is called.
72      * @return The next character.
73      * @throws ProtocolException If the end-of-stream is reached.
74      */

75     public char nextChar() throws ProtocolException
76     {
77         if ( ! nextSeen ) {
78             int next = -1;
79
80             try {
81                 next = input.read();
82             }
83             catch ( IOException JavaDoc e ) {
84                 throw new ProtocolException( "Error reading from stream." );
85             }
86             if ( next == -1 ) {
87                 throw new ProtocolException( "Unexpected end of stream." );
88             }
89
90             nextSeen = true;
91             nextChar = ( char ) next;
92 // System.out.println( "Read '" + nextChar + "'" );
93
}
94         return nextChar;
95     }
96
97     /**
98      * Moves the request line reader to end of the line, checking that no non-space
99      * character are found.
100      * @throws ProtocolException If more non-space tokens are found in this line,
101      * or the end-of-file is reached.
102      */

103     public void eol() throws ProtocolException
104     {
105         char next = nextChar();
106
107         // Ignore trailing spaces.
108
while ( next == ' ' ) {
109             consume();
110             next = nextChar();
111         }
112
113         // handle DOS and unix end-of-lines
114
if ( next == '\r' ) {
115             consume();
116             next = nextChar();
117         }
118
119         // Check if we found extra characters.
120
if ( next != '\n' ) {
121             // TODO debug log here and other exceptions
122
throw new ProtocolException( "Expected end-of-line, found more characters.");
123         }
124     }
125
126     /**
127      * Consumes the current character in the reader, so that subsequent calls to the request will
128      * provide a new character. This method does *not* read the new character, or check if
129      * such a character exists. If no current character has been seen, the method moves to
130      * the next character, consumes it, and moves on to the subsequent one.
131      * @throws ProtocolException if a the current character can't be obtained (eg we're at
132      * end-of-file).
133      */

134     public char consume() throws ProtocolException
135     {
136         char current = nextChar();
137         nextSeen = false;
138         nextChar = 0;
139         return current;
140     }
141
142
143     /**
144      * Reads and consumes a number of characters from the underlying reader,
145      * filling the char array provided.
146      * @param holder A char array which will be filled with chars read from the underlying reader.
147      * @throws ProtocolException If a char can't be read into each array element.
148      */

149     public void read( byte[] holder ) throws ProtocolException
150     {
151         int readTotal = 0;
152         try
153         {
154             while ( readTotal < holder.length )
155             {
156                 int count = 0;
157                 count = input.read( holder, readTotal, holder.length - readTotal );
158                 if ( count == -1 ) {
159                     throw new ProtocolException( "Unexpectd end of stream." );
160                 }
161                 readTotal += count;
162             }
163             // Unset the next char.
164
nextSeen = false;
165             nextChar = 0;
166         }
167         catch ( IOException JavaDoc e ) {
168             throw new ProtocolException( "Error reading from stream." );
169         }
170
171     }
172
173     /**
174      * Sends a server command continuation request '+' back to the client,
175      * requesting more data to be sent.
176      */

177     public void commandContinuationRequest()
178             throws ProtocolException
179     {
180         try {
181             output.write( '+' );
182             output.write( '\r' );
183             output.write( '\n' );
184             output.flush();
185         }
186         catch ( IOException JavaDoc e ) {
187             throw new ProtocolException("Unexpected exception in sending command continuation request.");
188         }
189     }
190
191     public void consumeLine()
192             throws ProtocolException
193     {
194         char next = nextChar();
195         while ( next != '\n' ) {
196             consume();
197             next = nextChar();
198         }
199         consume();
200     }
201 }
202
Popular Tags