Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* The MIT License
*
* Copyright (c) 2009 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package htsjdk.samtools.util;
import htsjdk.samtools.SAMException;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
/**
* Line-oriented InputStream reader that uses one buffer for disk buffering and line-termination-finding,
* in order to improve performance.
*
* Implementation detail: All public methods must leave the input buffer in a non-empty state, unless at EOF.
*
* @author [email protected]
*/
public class FastLineReader implements Closeable {
private InputStream in;
private byte[] fileBuffer = new byte[512000];
// Next byte to read in fileBuffer
private int nextByte = 0;
// Number of bytes in fileBuffer
private int numBytes = 0;
private boolean atEof;
public FastLineReader(final InputStream in) {
this.in = in;
ensureBufferNotEmpty();
}
/**
* @return true if input is exhausted
*/
public boolean eof() {
return atEof;
}
/**
* @return peeks at the next byte in the stream and returns true if it is CR or LF. Returns false if EOF or
* next byte is not CR or LF.
*/
public boolean atEoln() {
return ensureBufferNotEmpty() && (fileBuffer[nextByte] == '\n' || fileBuffer[nextByte] == '\r');
}
/**
* Advance over any EOLN chars (CR or LF)
* @return true if saw one or more CR or LFs
*/
public boolean skipNewlines() {
boolean sawEoln = false;
while (atEoln()) {
sawEoln = true;
++nextByte;
}
return sawEoln;
}
@Override
public void close() {
CloserUtil.close(in);
in = null;
fileBuffer = null;
}
/**
* @return Next byte from the input. Do not call if at EOF.
*/
public byte getByte() {
final byte ret = peekByte();
++nextByte;
ensureBufferNotEmpty();
return ret;
}
/**
* @return Next byte from the input, without advancing over that byte. Do not call if at EOF.
*/
public byte peekByte() {
if (eof()) {
throw new IllegalStateException("Cannot getByte() if EOF.");
}
return fileBuffer[nextByte];
}
/**
* Read from input until input is exhausted, EOLN is seen, or output buffer is filled
* @param outputBuffer where to put bytes read
* @param startOutputIndex where to start putting bytes read
* @return number of bytes read
*/
public int readToEndOfOutputBufferOrEoln(final byte[] outputBuffer, final int startOutputIndex) {
boolean sawNewline;
int totalGrabbed = 0;
do {
if (!ensureBufferNotEmpty()) {
break;
}
final int startInputIndex = nextByte;
sawNewline = advanceToEobOrEoln();
int lengthOfChunk = nextByte - startInputIndex;
// Roll back if went past the amount that can be stored in the output buffer.
// Assumption is that lines are relatively short so this won't happen very often.
if (lengthOfChunk > outputBuffer.length - (startOutputIndex + totalGrabbed)) {
lengthOfChunk = outputBuffer.length - (startOutputIndex + totalGrabbed);
nextByte = startInputIndex + lengthOfChunk;
}
System.arraycopy(fileBuffer, startInputIndex, outputBuffer, startOutputIndex + totalGrabbed, lengthOfChunk);
totalGrabbed += lengthOfChunk;
} while (!sawNewline && totalGrabbed < outputBuffer.length - startOutputIndex);
ensureBufferNotEmpty();
return totalGrabbed;
}
/**
* Advance nextByte to end of currently-buffered input or to line terminator
* @return true if saw a line terminator
*/
private boolean advanceToEobOrEoln() {
while (nextByte < numBytes) {
if (atEoln()) {
return true;
}
++nextByte;
}
return false;
}
/**
* Ensure that fileBuffer has at least one byte available in it. Potentially wipes out
* what is in fileBuffer so everything from fileBuffer[0..nextByte] should already have been pulled out.
* @return false if EOF, else true
*/
private boolean ensureBufferNotEmpty() {
try {
if (nextByte < numBytes) {
return true;
}
nextByte = 0;
numBytes = in.read(fileBuffer);
atEof = (numBytes < 1);
return !atEof;
} catch (IOException e) {
throw new SAMException("Exception reading InputStream", e);
}
}
}