зеркало из https://github.com/mozilla/pjs.git
186 строки
5.6 KiB
Java
186 строки
5.6 KiB
Java
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil -*-
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License
|
|
* Version 1.0 (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
* the License for the specific language governing rights and limitations
|
|
* under the License.
|
|
*
|
|
* The Original Code is the Grendel mail/news client.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are Copyright (C) 1997
|
|
* Netscape Communications Corporation. All Rights Reserved.
|
|
*/
|
|
|
|
package calypso.util;
|
|
|
|
import java.io.FilterInputStream;
|
|
import java.io.InputStream;
|
|
import java.io.IOException;
|
|
|
|
import calypso.util.ByteBuf;
|
|
import calypso.util.ByteLineBuffer;
|
|
|
|
public class LineBufferingInputStream extends FilterInputStream {
|
|
|
|
private static final boolean DEBUG = false;
|
|
|
|
private static final int CAPACITY = 1024;
|
|
|
|
ByteBuf curline = new ByteBuf();
|
|
ByteBuf inbuf = new ByteBuf(CAPACITY);
|
|
ByteLineBuffer linebuf = new ByteLineBuffer();
|
|
boolean eof = false;
|
|
|
|
public LineBufferingInputStream(InputStream s) {
|
|
super(s);
|
|
|
|
if (DEBUG) {
|
|
System.err.println("LBIS " + hashCode() + ": created for " + s);
|
|
}
|
|
}
|
|
|
|
/** Reads bytes into a portion of an array. This method will block
|
|
until some input is available.
|
|
<P>
|
|
The returned data will not be more than one line long: that is, there
|
|
will be at most one linebreak (CR, LF, or CRLF) and if it is present,
|
|
it will be at the end.
|
|
<P>
|
|
If the next line available to be read is smaller than `length',
|
|
then the first `length' bytes of that line will be returned, and
|
|
the remainder of the bytes on that line will be available for
|
|
subsequent reads.
|
|
|
|
@return the total number of bytes read into the buffer, or -1 if
|
|
there is no more data because the end of the stream has
|
|
been reached.
|
|
*/
|
|
public int read(byte[] buf, int start, int length) throws IOException {
|
|
|
|
if (DEBUG) {
|
|
System.err.println("LBIS " + hashCode() + ": read(byte[], " +
|
|
start + ", " + length + ")");
|
|
}
|
|
|
|
|
|
if (length <= 0) return length;
|
|
int curlen = curline.length();
|
|
if (curlen == 0) {
|
|
if (eof) return -1;
|
|
while (!linebuf.pullLine(curline)) {
|
|
inbuf.setLength(CAPACITY);
|
|
int inlen = in.read(inbuf.toBytes(), 0, CAPACITY);
|
|
|
|
if (inlen <= 0) {
|
|
eof = true;
|
|
linebuf.pushEOF();
|
|
linebuf.pullLine(curline); // Try for the last gasp...
|
|
break;
|
|
}
|
|
|
|
inbuf.setLength(inlen);
|
|
|
|
if (DEBUG) {
|
|
byte b[] = inbuf.toBytes();
|
|
System.err.print("LBIS " + hashCode() + ": read " + inlen +
|
|
" bytes: ");
|
|
for (int i = 0; i < inlen; i++)
|
|
System.err.print((b[i] == '\r' ? "\\r" :
|
|
b[i] == '\n' ? "\\n" :
|
|
b[i] == '\t' ? "\\t" :
|
|
b[i] == '\\' ? "\\\\" :
|
|
new String(b, i, 1)));
|
|
System.err.print("\n");
|
|
}
|
|
|
|
linebuf.pushBytes(inbuf);
|
|
}
|
|
|
|
curlen = curline.length();
|
|
if (curlen == 0) return -1;
|
|
}
|
|
int result = length;
|
|
if (result > curlen) result = curlen;
|
|
curline.getBytes(0, result, buf, start);
|
|
curlen -= result;
|
|
curline.remove(0, result);
|
|
|
|
if (DEBUG) {
|
|
byte b[] = curline.toBytes();
|
|
System.err.print("LBIS " + hashCode() + ": read line: ");
|
|
for (int i = 0; i < curline.length(); i++)
|
|
System.err.print((b[i] == '\r' ? "\\r" :
|
|
b[i] == '\n' ? "\\n" :
|
|
b[i] == '\t' ? "\\t" :
|
|
b[i] == '\\' ? "\\\\" :
|
|
new String(b, i, 1)));
|
|
System.err.print("\n");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
public int read(byte[] buf) throws IOException {
|
|
return read(buf, 0, buf.length);
|
|
}
|
|
|
|
byte[] singlebyte;
|
|
public int read() throws IOException {
|
|
if (singlebyte == null) singlebyte = new byte[1];
|
|
if (read(singlebyte, 0, 1) <= 0) return -1;
|
|
return singlebyte[0];
|
|
}
|
|
|
|
public long skip(long n) {
|
|
return 0; // Feh.
|
|
}
|
|
|
|
public boolean markSupported() {
|
|
return false;
|
|
}
|
|
|
|
public void close() throws IOException {
|
|
|
|
if (DEBUG) {
|
|
System.err.println("LBIS " + hashCode() + ": closed");
|
|
}
|
|
|
|
curline = null;
|
|
inbuf = null;
|
|
linebuf = null;
|
|
eof = true;
|
|
super.close();
|
|
}
|
|
|
|
/** Sets the EOL characters to look for in the incoming stream. Setting
|
|
* this to be null will cause it to look for any of <CR>, <LF>, or <CRLF>.
|
|
* Note that null (the default) could cause up to one extra to be held in
|
|
* the buffer (in the case where the last byte read from the underlying
|
|
* stream was <CR>, and no following byte (or EOF) has yet been read.)
|
|
*/
|
|
public void setInputEOL(ByteBuf buf) {
|
|
linebuf.setInputEOL(buf);
|
|
}
|
|
|
|
/**
|
|
* End of line characters <CR> & <LF> or any combination
|
|
* will be replaced by this string if it is present. Setting
|
|
* this to a zero length string will cause them to be stripped.
|
|
* Setting this to null will cause the EOL characters to be passed
|
|
* through unchanged (the default).
|
|
* @param buf ByteBuf representing EOL replacement string
|
|
*/
|
|
public void setOutputEOL(ByteBuf buf) {
|
|
linebuf.setOutputEOL(buf);
|
|
}
|
|
|
|
|
|
}
|