38 |
|
|
39 |
package gnu.java.net; |
package gnu.java.net; |
40 |
|
|
41 |
|
import java.io.BufferedInputStream; |
42 |
import java.io.FilterInputStream; |
import java.io.FilterInputStream; |
43 |
import java.io.IOException; |
import java.io.IOException; |
44 |
import java.io.InputStream; |
import java.io.InputStream; |
61 |
*/ |
*/ |
62 |
public static final int LF = 10; |
public static final int LF = 10; |
63 |
|
|
64 |
/** |
private boolean doReset; |
|
* Buffer. |
|
|
*/ |
|
|
protected int buf = -1; |
|
|
|
|
|
/** |
|
|
* Buffer at time of mark. |
|
|
*/ |
|
|
protected int markBuf = -1; |
|
65 |
|
|
66 |
/** |
/** |
67 |
* Constructs a CR/LF input stream connected to the specified input |
* Constructs a CR/LF input stream connected to the specified input |
69 |
*/ |
*/ |
70 |
public CRLFInputStream(InputStream in) |
public CRLFInputStream(InputStream in) |
71 |
{ |
{ |
72 |
super(in); |
super(in.markSupported() ? in : new BufferedInputStream(in)); |
73 |
} |
} |
74 |
|
|
75 |
/** |
/** |
80 |
public int read() |
public int read() |
81 |
throws IOException |
throws IOException |
82 |
{ |
{ |
83 |
int c; |
int c = in.read(); |
84 |
if (buf != -1) |
if (c == CR) |
85 |
{ |
{ |
86 |
c = buf; |
in.mark(1); |
87 |
buf = -1; |
int d = in.read(); |
88 |
return c; |
if (d == LF) |
|
} |
|
|
else |
|
|
{ |
|
|
c = super.read(); |
|
|
if (c == CR) |
|
89 |
{ |
{ |
90 |
buf = super.read(); |
c = d; |
91 |
if (buf == LF) |
} |
92 |
{ |
else |
93 |
c = buf; |
{ |
94 |
buf = -1; |
in.reset(); |
|
} |
|
95 |
} |
} |
96 |
} |
} |
97 |
return c; |
return c; |
118 |
public int read(byte[] b, int off, int len) |
public int read(byte[] b, int off, int len) |
119 |
throws IOException |
throws IOException |
120 |
{ |
{ |
121 |
int shift = 0; |
in.mark(len + 1); |
122 |
if (buf != -1) |
int l = in.read(b, off, len); |
123 |
|
if (l > 0) |
124 |
{ |
{ |
125 |
// Push buf onto start of byte array |
int i = indexOfCRLF(b, off, l); |
126 |
b[off] = (byte) buf; |
if (doReset) |
127 |
off++; |
{ |
128 |
len--; |
in.reset(); |
129 |
buf = -1; |
if (i != -1) |
130 |
shift++; |
{ |
131 |
|
l = in.read(b, off, i + 1); // read to CR |
132 |
|
in.read(); // skip LF |
133 |
|
b[i] = LF; // fix CR as LF |
134 |
|
} |
135 |
|
else |
136 |
|
{ |
137 |
|
l = in.read(b, off, len); // CR(s) but no LF |
138 |
|
} |
139 |
|
} |
140 |
} |
} |
|
int l = super.read(b, off, len); |
|
|
l = removeCRLF(b, off - shift, l); |
|
141 |
return l; |
return l; |
142 |
} |
} |
143 |
|
|
144 |
/** |
private int indexOfCRLF(byte[] b, int off, int len) |
|
* Indicates whether this stream supports the mark and reset methods. |
|
|
*/ |
|
|
public boolean markSupported() |
|
|
{ |
|
|
return in.markSupported(); |
|
|
} |
|
|
|
|
|
/** |
|
|
* Marks the current position in this stream. |
|
|
*/ |
|
|
public void mark(int readlimit) |
|
|
{ |
|
|
in.mark(readlimit); |
|
|
markBuf = buf; |
|
|
} |
|
|
|
|
|
/** |
|
|
* Repositions this stream to the position at the time the mark method was |
|
|
* called. |
|
|
*/ |
|
|
public void reset() |
|
145 |
throws IOException |
throws IOException |
146 |
{ |
{ |
147 |
in.reset(); |
doReset = false; |
148 |
buf = markBuf; |
int lm1 = len - 1; |
149 |
} |
for (int i = off; i < len; i++) |
|
|
|
|
private int removeCRLF(byte[] b, int off, int len) |
|
|
{ |
|
|
int end = off + len; |
|
|
for (int i = off; i < end; i++) |
|
150 |
{ |
{ |
151 |
if (b[i] == CR) |
if (b[i] == CR) |
152 |
{ |
{ |
153 |
if (i + 1 == end) |
int d; |
154 |
|
if (i == lm1) |
155 |
{ |
{ |
156 |
// This is the last byte, impossible to determine whether CRLF |
d = in.read(); |
157 |
buf = CR; |
doReset = true; |
|
len--; |
|
158 |
} |
} |
159 |
else if (b[i + 1] == LF) |
else |
160 |
{ |
{ |
161 |
// Shift left |
d = b[i + 1]; |
162 |
end--; |
} |
163 |
for (int j = i; j < end; j++) |
if (d == LF) |
164 |
{ |
{ |
165 |
b[j] = b[j + 1]; |
doReset = true; |
166 |
} |
return i; |
|
len--; |
|
|
end = off + len; |
|
167 |
} |
} |
168 |
} |
} |
169 |
} |
} |
170 |
return len; |
return -1; |
171 |
} |
} |
172 |
|
|
173 |
} |
} |
174 |
|
|