39 |
* @author <a href="mailto:dog@gnu.org">Chris Burdess</a> |
* @author <a href="mailto:dog@gnu.org">Chris Burdess</a> |
40 |
* @version $Revision$ $Date$ |
* @version $Revision$ $Date$ |
41 |
*/ |
*/ |
42 |
public class MessageInputStream |
public class MessageInputStream extends FilterInputStream |
|
extends FilterInputStream |
|
43 |
{ |
{ |
44 |
|
|
45 |
/** |
/** |
46 |
* The stream termination octet ('.'). |
* The stream termination octet ('.'). |
47 |
*/ |
*/ |
48 |
public static final int END = 46; |
public static final int END = 46; |
49 |
|
|
50 |
/** |
/** |
51 |
* The line termination octet ('\n'). |
* The line termination octet ('\n'). |
52 |
*/ |
*/ |
53 |
public static final int LF = 10; |
public static final int LF = 10; |
54 |
|
|
55 |
protected boolean eof; |
protected boolean eof; |
56 |
|
|
57 |
protected int buf1 = -1; |
protected int buf1 = -1; |
58 |
protected int buf2 = -1; |
protected int buf2 = -1; |
59 |
|
|
60 |
protected int markBuf1; |
protected int markBuf1; |
61 |
protected int markBuf2; |
protected int markBuf2; |
62 |
|
|
63 |
/** |
/** |
64 |
* Constructs a message input stream connected to the specified input stream. |
* Constructs a message input stream connected to the specified input stream. |
65 |
*/ |
*/ |
66 |
public MessageInputStream(InputStream in) |
public MessageInputStream(InputStream in) |
67 |
{ |
{ |
68 |
super(in); |
super(in); |
69 |
eof = false; |
eof = false; |
70 |
} |
} |
71 |
|
|
72 |
/** |
/** |
73 |
* Reads the next byte of data from this message input stream. |
* Reads the next byte of data from this message input stream. |
74 |
* Returns -1 if the end of the message stream has been reached. |
* Returns -1 if the end of the message stream has been reached. |
75 |
* @exception IOException if an I/O error occurs |
* @exception IOException if an I/O error occurs |
76 |
*/ |
*/ |
77 |
public int read() |
public int read() throws IOException |
78 |
throws IOException |
{ |
79 |
{ |
if (eof) |
80 |
if (eof) |
return -1; |
81 |
return -1; |
int c; |
82 |
int c; |
if (buf1 != -1) |
83 |
if (buf1!=-1) |
{ |
84 |
{ |
c = buf1; |
85 |
c = buf1; |
buf1 = buf2; |
86 |
buf1 = buf2; |
buf2 = -1; |
87 |
buf2 = -1; |
} |
88 |
} |
else |
89 |
else |
c = super.read(); |
90 |
c = super.read(); |
if (c == LF) |
91 |
if (c==LF) |
{ |
92 |
{ |
if (buf1 == -1) |
93 |
if (buf1==-1) |
{ |
94 |
{ |
buf1 = super.read(); |
95 |
buf1 = super.read(); |
if (buf1 == END) |
96 |
if (buf1==END) |
{ |
97 |
{ |
buf2 = super.read(); |
98 |
buf2 = super.read(); |
if (buf2 == LF) |
99 |
if (buf2==LF) |
{ |
100 |
{ |
eof = true; |
101 |
eof = true; |
// Allow the final LF to be read |
102 |
// Allow the final LF to be read |
} |
103 |
} |
} |
104 |
} |
} |
105 |
} |
else if (buf1 == END) |
106 |
else if (buf1==END) |
{ |
107 |
{ |
if (buf2 == -1) |
108 |
if (buf2==-1) |
{ |
109 |
{ |
buf2 = super.read(); |
110 |
buf2 = super.read(); |
if (buf2 == LF) |
111 |
if (buf2==LF) |
eof = true; |
112 |
eof = true; |
} |
113 |
} |
else if (buf2 == LF) |
114 |
else if (buf2==LF) |
eof = true; |
115 |
eof = true; |
} |
116 |
} |
} |
117 |
} |
return c; |
118 |
return c; |
} |
119 |
} |
|
120 |
|
/** |
|
/** |
|
121 |
* Reads up to b.length bytes of data from this input stream into |
* Reads up to b.length bytes of data from this input stream into |
122 |
* an array of bytes. |
* an array of bytes. |
123 |
* Returns -1 if the end of the stream has been reached. |
* Returns -1 if the end of the stream has been reached. |
124 |
* @exception IOException if an I/O error occurs |
* @exception IOException if an I/O error occurs |
125 |
*/ |
*/ |
126 |
public int read(byte[] b) |
public int read(byte[]b) throws IOException |
127 |
throws IOException |
{ |
128 |
{ |
return read(b, 0, b.length); |
129 |
return read(b, 0, b.length); |
} |
130 |
} |
|
131 |
|
/** |
|
/** |
|
132 |
* Reads up to len bytes of data from this input stream into an |
* Reads up to len bytes of data from this input stream into an |
133 |
* array of bytes, starting at the specified offset. |
* array of bytes, starting at the specified offset. |
134 |
* Returns -1 if the end of the stream has been reached. |
* Returns -1 if the end of the stream has been reached. |
135 |
* @exception IOException if an I/O error occurs |
* @exception IOException if an I/O error occurs |
136 |
*/ |
*/ |
137 |
public int read(byte[] b, int off, int len) |
public int read(byte[]b, int off, int len) throws IOException |
138 |
throws IOException |
{ |
139 |
{ |
if (eof) |
140 |
if (eof) |
return -1; |
141 |
return -1; |
int c, end = off + len; |
142 |
int c, end = off+len; |
for (int i = off; i < end; i++) |
143 |
for (int i=off; i<end; i++) |
{ |
144 |
{ |
c = read(); |
145 |
c = read(); |
if (c == -1) |
146 |
if (c==-1) |
{ |
147 |
{ |
len = i - off; |
148 |
len = i-off; |
break; |
149 |
break; |
} |
150 |
} |
else |
151 |
else |
b[i] = (byte) c; |
152 |
b[i] = (byte)c; |
} |
153 |
} |
return len; |
154 |
return len; |
} |
155 |
} |
|
156 |
|
public boolean markSupported() |
157 |
public boolean markSupported() |
{ |
158 |
{ |
return in.markSupported(); |
159 |
return in.markSupported(); |
} |
160 |
} |
|
161 |
|
public void mark(int readlimit) |
162 |
public void mark(int readlimit) |
{ |
163 |
{ |
in.mark(readlimit); |
164 |
in.mark(readlimit); |
markBuf1 = buf1; |
165 |
markBuf1 = buf1; |
markBuf2 = buf2; |
166 |
markBuf2 = buf2; |
} |
167 |
} |
|
168 |
|
public void reset() throws IOException |
169 |
public void reset() |
{ |
170 |
throws IOException |
in.reset(); |
171 |
{ |
buf1 = markBuf1; |
172 |
in.reset(); |
buf2 = markBuf2; |
173 |
buf1 = markBuf1; |
} |
174 |
buf2 = markBuf2; |
|
|
} |
|
|
|
|
175 |
} |
} |