📄 lineinput.java
字号:
/*
* SSL-Explorer
*
* Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
//
// Modified for use in SSL-Explorer by 3SP. These portions licensed as above,
// everything else licensed as below.
//
//
// ========================================================================
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
//
package com.sslexplorer.replacementproxy;
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Fast LineInput InputStream.
*
* This buffered InputStream provides methods for reading lines of bytes. The
* lines can be converted to String or character arrays either using the default
* encoding or a user supplied encoding.
*
* Buffering and data copying are highly optimized, making this an ideal class
* for protocols that mix character encoding lines with arbitrary byte data (eg
* HTTP).
*
* The buffer size is also the maximum line length in bytes and/or characters.
* If the byte length of a line is less than the max, but the character length
* is greater, than then trailing characters are lost.
*
* Line termination is forgiving and accepts CR, LF, CRLF or EOF. Line input
* uses the mark/reset mechanism, so any marks set prior to a readLine call are
* lost.
*
* @version $Id$
* @author Greg Wilkins (gregw)
*/
public class LineInput extends FilterInputStream {
private static Log log = LogFactory.getLog(LineInput.class);
/* ------------------------------------------------------------ */
private byte _buf[];
private ByteBuffer _byteBuffer;
private InputStreamReader _reader;
private int _mark = -1; // reset marker
private int _pos; // Start marker
private int _avail; // Available back marker, may be byte limited
private int _contents; // Absolute back marker of buffer
private int _byteLimit = -1;
private boolean _newByteLimit;
private LineBuffer _lineBuffer;
private String _encoding;
private boolean _eof = false;
private boolean _lastCr = false;
private boolean _seenCrLf = false;
private final static int LF = 10;
private final static int CR = 13;
/* ------------------------------------------------------------ */
/**
* Constructor. Default buffer and maximum line size is 2048.
*
* @param in The underlying input stream.
*/
public LineInput(InputStream in) {
this(in, 0);
}
/* ------------------------------------------------------------ */
/**
* Constructor.
*
* @param in The underlying input stream.
* @param bufferSize The buffer size and maximum line length.
*/
public LineInput(InputStream in, int bufferSize) {
super(in);
_mark = -1;
if (bufferSize == 0)
bufferSize = 8192;
_buf = ByteArrayPool.getByteArray(bufferSize);
_byteBuffer = new ByteBuffer(_buf);
_lineBuffer = new LineBuffer(bufferSize);
_reader = new InputStreamReader(_byteBuffer);
}
/* ------------------------------------------------------------ */
/**
* Constructor.
*
* @param in The underlying input stream.
* @param bufferSize The buffer size and maximum line length.
* @param encoding the character encoding to use for readLine methods.
* @exception UnsupportedEncodingException
*/
public LineInput(InputStream in, int bufferSize, String encoding) throws UnsupportedEncodingException {
super(in);
_mark = -1;
if (bufferSize == 0)
bufferSize = 2048;
_buf = ByteArrayPool.getByteArray(bufferSize);
_byteBuffer = new ByteBuffer(_buf);
_lineBuffer = new LineBuffer(bufferSize);
_reader = new InputStreamReader(_byteBuffer, encoding);
_encoding = encoding;
}
/* ------------------------------------------------------------ */
public InputStream getInputStream() {
return in;
}
/* ------------------------------------------------------------ */
/**
* Set the byte limit. If set, only this number of bytes are read before
* EOF.
*
* @param bytes Limit number of bytes, or -1 for no limit.
*/
public void setByteLimit(int bytes) {
_byteLimit = bytes;
if (bytes >= 0) {
_newByteLimit = true;
_byteLimit -= _contents - _pos;
if (_byteLimit < 0) {
_avail += _byteLimit;
_byteLimit = 0;
}
} else {
_newByteLimit = false;
_avail = _contents;
_eof = false;
}
}
/* ------------------------------------------------------------ */
/**
* Get the byte limit.
*
* @return Number of bytes until EOF is returned or -1 for no limit.
*/
public int getByteLimit() {
if (_byteLimit < 0)
return _byteLimit;
return _byteLimit + _avail - _pos;
}
/* ------------------------------------------------------------ */
/**
* Read a line ended by CR, LF or CRLF. The default or supplied encoding is
* used to convert bytes to characters.
*
* @return The line as a String or null for EOF.
* @exception IOException
*/
public synchronized String readLine() throws IOException {
int len = fillLine(_buf.length);
if (len < 0)
return null;
String s = null;
if (_encoding == null)
s = new String(_buf, _mark, len);
else {
try {
s = new String(_buf, _mark, len, _encoding);
} catch (UnsupportedEncodingException e) {
log.warn(e);
}
}
_mark = -1;
return s;
}
/* ------------------------------------------------------------ */
/**
* Read a line ended by CR, LF or CRLF. The default or supplied encoding is
* used to convert bytes to characters.
*
* @param c Character buffer to place the line into.
* @param off Offset into the buffer.
* @param len Maximum length of line.
* @return The length of the line or -1 for EOF.
* @exception IOException
*/
public int readLine(char[] c, int off, int len) throws IOException {
int blen = fillLine(len);
if (blen < 0)
return -1;
if (blen == 0)
return 0;
_byteBuffer.setStream(_mark, blen);
int read = 0;
while (read < len && _reader.ready()) {
int r = _reader.read(c, off + read, len - read);
if (r <= 0)
break;
read += r;
}
_mark = -1;
return read;
}
/* ------------------------------------------------------------ */
/**
* Read a line ended by CR, LF or CRLF.
*
* @param b Byte array to place the line into.
* @param off Offset into the buffer.
* @param len Maximum length of line.
* @return The length of the line or -1 for EOF.
* @exception IOException
*/
public int readLine(byte[] b, int off, int len) throws IOException {
len = fillLine(len);
if (len < 0)
return -1;
if (len == 0)
return 0;
System.arraycopy(_buf, _mark, b, off, len);
_mark = -1;
return len;
}
/* ------------------------------------------------------------ */
/**
* Read a Line ended by CR, LF or CRLF. Read a line into a shared LineBuffer
* instance. The LineBuffer is resused between calls and should not be held
* by the caller. The default or supplied encoding is used to convert bytes
* to characters.
*
* @return LineBuffer instance or null for EOF.
* @exception IOException
*/
public LineBuffer readLineBuffer() throws IOException {
return readLineBuffer(_buf.length);
}
/* ------------------------------------------------------------ */
/**
* Read a Line ended by CR, LF or CRLF. Read a line into a shared LineBuffer
* instance. The LineBuffer is resused between calls and should not be held
* by the caller. The default or supplied encoding is used to convert bytes
* to characters.
*
* @param len Maximum length of a line, or 0 for default
* @return LineBuffer instance or null for EOF.
* @exception IOException
*/
public LineBuffer readLineBuffer(int len) throws IOException {
len = fillLine(len > 0 ? len : _buf.length);
if (len < 0)
return null;
if (len == 0) {
_lineBuffer.size = 0;
return _lineBuffer;
}
_byteBuffer.setStream(_mark, len);
_lineBuffer.size = 0;
int read = 0;
while (read < len && _reader.ready()) {
int r = _reader.read(_lineBuffer.buffer, read, len - read);
if (r <= 0)
break;
read += r;
}
_lineBuffer.size = read;
_mark = -1;
return _lineBuffer;
}
/* ------------------------------------------------------------ */
public synchronized int read() throws IOException {
int b;
if (_pos >= _avail)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -