Coverage report

| %line | %branch
--- | --- | ---
org.apache.commons.net.io.DotTerminatedMessageReader |
0% |
0% |

1 |  |
     /*
2 |  |
      * Copyright 2001-2005 The Apache Software Foundation
3 |  |
      *
4 |  |
      * Licensed under the Apache License, Version 2.0 (the "License");
5 |  |
      * you may not use this file except in compliance with the License.
6 |  |
      * You may obtain a copy of the License at
7 |  |
      *
8 |  |
      *     http://www.apache.org/licenses/LICENSE-2.0
9 |  |
      *
10 |  |
      * Unless required by applicable law or agreed to in writing, software
11 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
12 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 |  |
      * See the License for the specific language governing permissions and
14 |  |
      * limitations under the License.
15 |  |
      */
16 |  |
     package org.apache.commons.net.io;
17 |  |
18 |  |
     import java.io.IOException;
19 |  |
     import java.io.PushbackReader;
20 |  |
     import java.io.Reader;
21 |  |
22 |  |
     /**
23 |  |
      * DotTerminatedMessageReader is a class used to read messages from a
24 |  |
      * server that are terminated by a single dot followed by a
25 |  |
      * &lt;CR&gt;&lt;LF&gt;
26 |  |
      * sequence and with double dots appearing at the begining of lines which
27 |  |
      * do not signal end of message yet start with a dot.  Various Internet
28 |  |
      * protocols such as NNTP and POP3 produce messages of this type.
29 |  |
      * <p>
30 |  |
      * This class handles stripping of the duplicate period at the beginning
31 |  |
      * of lines starting with a period, converts NETASCII newlines to the
32 |  |
      * local line separator format, truncates the end of message indicator,
33 |  |
      * and ensures you cannot read past the end of the message.
34 |  |
      * @author <a href="mailto:savarese@apache.org">Daniel F. Savarese</a>
35 |  |
      * @version $Id: DotTerminatedMessageReader.java 165675 2005-05-02 20:09:55Z rwinston $
36 |  |
      */
37 |  |
     public final class DotTerminatedMessageReader extends Reader
38 |  |
     {
39 |  |
         private static final String LS;
40 |  |
         private static final char[] LS_CHARS;
41 |  |
42 |  |
         static
43 |  |
         {
44 | 0 |
             LS = System.getProperty("line.separator");
45 | 0 |
             LS_CHARS = LS.toCharArray();
46 | 0 |
         }
47 |  |
48 |  |
         private boolean atBeginning;
49 |  |
         private boolean eof;
50 |  |
         private int pos;
51 |  |
         private char[] internalBuffer;
52 |  |
         private PushbackReader internalReader;
53 |  |
54 |  |
         /**
55 |  |
          * Creates a DotTerminatedMessageReader that wraps an existing Reader
56 |  |
          * input source.
57 |  |
          * @param reader  The Reader input source containing the message.
58 |  |
          */
59 |  |
         public DotTerminatedMessageReader(Reader reader)
60 |  |
         {
61 | 0 |
             super(reader);
62 | 0 |
             internalBuffer = new char[LS_CHARS.length + 3];
63 | 0 |
             pos = internalBuffer.length;
64 |  |
             // Assumes input is at start of message
65 | 0 |
             atBeginning = true;
66 | 0 |
             eof = false;
67 | 0 |
             internalReader = new PushbackReader(reader);
68 | 0 |
         }
69 |  |
70 |  |
         /**
71 |  |
          * Reads and returns the next character in the message.  If the end of the
72 |  |
          * message has been reached, returns -1.  Note that a call to this method
73 |  |
          * may result in multiple reads from the underlying input stream to decode
74 |  |
          * the message properly (removing doubled dots and so on).  All of
75 |  |
          * this is transparent to the programmer and is only mentioned for
76 |  |
          * completeness.
77 |  |
          * @return The next character in the message. Returns -1 if the end of the
78 |  |
          *          message has been reached.
79 |  |
          * @exception IOException If an error occurs while reading the underlying
80 |  |
          *            stream.
81 |  |
          */
82 |  |
         public int read() throws IOException
83 |  |
         {
84 |  |
             int ch;
85 |  |
86 | 0 |
             synchronized (lock)
87 |  |
             {
88 | 0 |
                 if (pos < internalBuffer.length)
89 |  |
                 {
90 | 0 |
                     return internalBuffer[pos++];
91 |  |
                 }
92 |  |
93 | 0 |
                 if (eof)
94 |  |
                 {
95 | 0 |
                     return -1;
96 |  |
                 }
97 |  |
98 | 0 |
                 if ((ch = internalReader.read()) == -1)
99 |  |
                 {
100 | 0 |
                     eof = true;
101 | 0 |
                     return -1;
102 |  |
                 }
103 |  |
104 | 0 |
                 if (atBeginning)
105 |  |
                 {
106 | 0 |
                     atBeginning = false;
107 | 0 |
                     if (ch == '.')
108 |  |
                     {
109 | 0 |
                         ch = internalReader.read();
110 |  |
111 | 0 |
                         if (ch != '.')
112 |  |
                         {
113 |  |
                             // read newline
114 | 0 |
                             eof = true;
115 | 0 |
                             internalReader.read();
116 | 0 |
                             return -1;
117 |  |
                         }
118 |  |
                         else
119 |  |
                         {
120 | 0 |
                             return '.';
121 |  |
                         }
122 |  |
                     }
123 |  |
                 }
124 |  |
125 | 0 |
                 if (ch == '\r')
126 |  |
                 {
127 | 0 |
                     ch = internalReader.read();
128 |  |
129 | 0 |
                     if (ch == '\n')
130 |  |
                     {
131 | 0 |
                         ch = internalReader.read();
132 |  |
133 | 0 |
                         if (ch == '.')
134 |  |
                         {
135 | 0 |
                             ch = internalReader.read();
136 |  |
137 | 0 |
                             if (ch != '.')
138 |  |
                             {
139 |  |
                                 // read newline and indicate end of file
140 | 0 |
                                 internalReader.read();
141 | 0 |
                                 eof = true;
142 |  |
                             }
143 |  |
                             else
144 |  |
                             {
145 | 0 |
                                 internalBuffer[--pos] = (char) ch;
146 |  |
                             }
147 |  |
                         }
148 |  |
                         else
149 |  |
                         {
150 | 0 |
                             internalReader.unread(ch);
151 |  |
                         }
152 |  |
153 | 0 |
                         pos -= LS_CHARS.length;
154 | 0 |
                         System.arraycopy(LS_CHARS, 0, internalBuffer, pos,
155 |  |
                                          LS_CHARS.length);
156 | 0 |
                         ch = internalBuffer[pos++];
157 |  |
                     }
158 |  |
                     else
159 |  |
                     {
160 | 0 |
                         internalBuffer[--pos] = (char) ch;
161 | 0 |
                         return '\r';
162 |  |
                     }
163 |  |
                 }
164 |  |
165 | 0 |
                 return ch;
166 | 0 |
             }
167 |  |
         }
168 |  |
169 |  |
         /**
170 |  |
          * Reads the next characters from the message into an array and
171 |  |
          * returns the number of characters read.  Returns -1 if the end of the
172 |  |
          * message has been reached.
173 |  |
          * @param buffer  The character array in which to store the characters.
174 |  |
          * @return The number of characters read. Returns -1 if the
175 |  |
          *          end of the message has been reached.
176 |  |
          * @exception IOException If an error occurs in reading the underlying
177 |  |
          *            stream.
178 |  |
          */
179 |  |
         public int read(char[] buffer) throws IOException
180 |  |
         {
181 | 0 |
             return read(buffer, 0, buffer.length);
182 |  |
         }
183 |  |
184 |  |
         /**
185 |  |
          * Reads the next characters from the message into an array and
186 |  |
          * returns the number of characters read.  Returns -1 if the end of the
187 |  |
          * message has been reached.  The characters are stored in the array
188 |  |
          * starting from the given offset and up to the length specified.
189 |  |
          * @param buffer  The character array in which to store the characters.
190 |  |
          * @param offset   The offset into the array at which to start storing
191 |  |
          *              characters.
192 |  |
          * @param length   The number of characters to read.
193 |  |
          * @return The number of characters read. Returns -1 if the
194 |  |
          *          end of the message has been reached.
195 |  |
          * @exception IOException If an error occurs in reading the underlying
196 |  |
          *            stream.
197 |  |
          */
198 |  |
         public int read(char[] buffer, class="keyword">int offset, class="keyword">int length) throws IOException
199 |  |
         {
200 |  |
             int ch, off;
201 | 0 |
             synchronized (lock)
202 |  |
             {
203 | 0 |
                 if (length < 1)
204 |  |
                 {
205 | 0 |
                     return 0;
206 |  |
                 }
207 | 0 |
                 if ((ch = read()) == -1)
208 |  |
                 {
209 | 0 |
                     return -1;
210 |  |
                 }
211 | 0 |
                 off = offset;
212 |  |
213 |  |
                 do
214 |  |
                 {
215 | 0 |
                     buffer[offset++] = (char) ch;
216 |  |
                 }
217 | 0 |
                 while (--length > 0 && (ch = read()) != -1);
218 |  |
219 | 0 |
                 return (offset - off);
220 | 0 |
             }
221 |  |
         }
222 |  |
223 |  |
         /**
224 |  |
          * Determines if the message is ready to be read.
225 |  |
          * @return True if the message is ready to be read, false if not.
226 |  |
          * @exception IOException If an error occurs while checking the underlying
227 |  |
          *            stream.
228 |  |
          */
229 |  |
         public boolean ready() throws IOException
230 |  |
         {
231 | 0 |
             synchronized (lock)
232 |  |
             {
233 | 0 |
                 return (pos < internalBuffer.length || internalReader.ready());
234 | 0 |
             }
235 |  |
         }
236 |  |
237 |  |
         /**
238 |  |
          * Closes the message for reading.  This doesn't actually close the
239 |  |
          * underlying stream.  The underlying stream may still be used for
240 |  |
          * communicating with the server and therefore is not closed.
241 |  |
          * <p>
242 |  |
          * If the end of the message has not yet been reached, this method
243 |  |
          * will read the remainder of the message until it reaches the end,
244 |  |
          * so that the underlying stream may continue to be used properly
245 |  |
          * for communicating with the server.  If you do not fully read
246 |  |
          * a message, you MUST close it, otherwise your program will likely
247 |  |
          * hang or behave improperly.
248 |  |
          * @exception IOException  If an error occurs while reading the
249 |  |
          *            underlying stream.
250 |  |
          */
251 |  |
         public void close() throws IOException
252 |  |
         {
253 | 0 |
             synchronized (lock)
254 |  |
             {
255 | 0 |
                 if (internalReader == null)
256 |  |
                 {
257 | 0 |
                     return;
258 |  |
                 }
259 |  |
260 | 0 |
                 if (!eof)
261 |  |
                 {
262 | 0 |
                     while (read() != -1)
263 |  |
                     {
264 | 0 |
                         ;
265 |  |
                     }
266 |  |
                 }
267 | 0 |
                 eof = true;
268 | 0 |
                 atBeginning = false;
269 | 0 |
                 pos = internalBuffer.length;
270 | 0 |
                 internalReader = null;
271 | 0 |
             }
272 | 0 |
         }
273 |  |
     }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.