KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > mail > iap > ResponseInputStream


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the "License"). You may not use this file except
5  * in compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * glassfish/bootstrap/legal/CDDLv1.0.txt or
9  * https://glassfish.dev.java.net/public/CDDLv1.0.html.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * HEADER in each file and include the License file at
15  * glassfish/bootstrap/legal/CDDLv1.0.txt. If applicable,
16  * add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your
18  * own identifying information: Portions Copyright [yyyy]
19  * [name of copyright owner]
20  */

21
22 /*
23  * @(#)ResponseInputStream.java 1.8 06/02/27
24  *
25  * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved.
26  */

27
28
29 package com.sun.mail.iap;
30
31 import java.io.*;
32 import com.sun.mail.iap.ByteArray;
33 import com.sun.mail.util.ASCIIUtility;
34
35 /**
36  *
37  * Inputstream that is used to read a Response.
38  *
39  * @version 1.8, 06/02/27
40  * @author Arun Krishnan
41  */

42
43 public class ResponseInputStream {
44
45     private static final int minIncrement = 256;
46     private static final int maxIncrement = 256 * 1024;
47     private byte[] buffer = null;
48     private int sz = 0;
49     private int idx= 0;
50     private BufferedInputStream bin;
51
52     /**
53      * Constructor.
54      */

55     public ResponseInputStream(InputStream in) {
56     bin = new BufferedInputStream(in, 2 * 1024);
57     }
58
59     /**
60      * Read a Response from the InputStream.
61      * @return ByteArray that contains the Response
62      */

63     public ByteArray readResponse() throws IOException {
64     buffer = new byte[128];
65     idx = 0;
66     sz = 128;
67     read0();
68     return new ByteArray(buffer, 0, idx);
69     }
70
71     /**
72      * Private method that does the actual read.
73      * This method moves data into 'buffer'.
74      */

75     private void read0() throws IOException {
76     // XXX - b needs to be an int, to handle bytes with value 0xff
77
int b = 0;
78     boolean gotCRLF=false;
79
80     // Read a CRLF terminated line from the InputStream
81
while (!gotCRLF &&
82            ((b = bin.read()) != -1)) {
83         switch (b) {
84         case '\n':
85         if ((idx > 0) && buffer[idx-1] == '\r')
86             gotCRLF = true;
87         default:
88         if (idx >= sz) {
89             if (sz < maxIncrement)
90             growBuffer(sz); // double it
91
else
92             growBuffer(maxIncrement); // grow by maxIncrement
93
}
94         buffer[idx++] = (byte)b;
95         }
96     }
97
98     if (b == -1)
99         throw new IOException(); // connection broken ?
100

101     // Now lets check for literals : {<digits>}CRLF
102
// Note: index needs to >= 5 for the above sequence to occur
103
if (idx >= 5 && buffer[idx-3] == '}') {
104         int i;
105         // look for left curly
106
for (i = idx-4; i >=0; i--)
107         if (buffer[i] == '{')
108             break;
109
110         if (i < 0) // Nope, not a literal ?
111
return;
112
113         int count = 0;
114         // OK, handle the literal ..
115
try {
116         count = ASCIIUtility.parseInt(buffer, i+1, idx-3);
117         } catch (NumberFormatException JavaDoc e) {
118         return;
119         }
120
121         // Now read 'count' bytes. (Note: count could be 0)
122
if (count > 0) {
123         int avail = sz - idx; // available space in buffer
124
if (count > avail)
125             // need count-avail more bytes
126
growBuffer(minIncrement > count - avail ?
127                    minIncrement : count - avail);
128         /*
129          * read() might not return all the bytes in one shot,
130          * so call repeatedly till we are done
131          */

132         int actual;
133         while (count > 0) {
134                 actual = bin.read(buffer, idx, count);
135             count -= actual;
136             idx += actual;
137         }
138         }
139
140         /*
141          * Recursive call to continue processing till CR-LF ..
142          * .. the additional bytes get added into 'buffer'
143          */

144          read0();
145     }
146     return;
147     }
148
149     /* Grow 'buffer' by 'incr' bytes */
150     private void growBuffer(int incr) {
151     byte[] nbuf = new byte[sz + incr];
152     if (buffer != null)
153         System.arraycopy(buffer, 0, nbuf, 0, idx);
154     buffer = nbuf;
155     sz += incr;
156     }
157 }
158
Popular Tags