public int readLine( final byte[] array, final int off, final int len, final EnumSet<LineTerminator> terminators ) throws IOException { ByteArrays.ensureOffsetLength( array ,off, len ); if ( len == 0 ) return 0; if ( noMoreCharacters() ) return -1; int i, k = 0, remaining = len, read = 0; for(;;) { for( i = 0; i < avail && i < remaining && ( k = buffer[ pos + i ] ) != '\n' && k != '\r' ; i++ ); System.arraycopy( buffer, pos, array, off + read, i ); pos += i; avail -= i; read += i; remaining -= i; if ( remaining == 0 ) { readBytes += read; return read; }  if ( avail > 0 ) { if ( k == '\n' ) { pos++; avail--; if ( terminators.contains( LineTerminator.LF ) ) { readBytes += read + 1; return read; } else { array[ off + read++ ] = '\n'; remaining--; } } else if ( k == '\r' ) { pos++; avail--;  if ( terminators.contains( LineTerminator.CR_LF ) ) { if ( avail > 0 ) { if ( buffer[ pos ] == '\n' ) { pos ++; avail--; readBytes += read + 2; return read; } } else { if ( noMoreCharacters() ) {   if ( ! terminators.contains( LineTerminator.CR ) ) { array[ off + read++ ] = '\r'; remaining--; readBytes += read; } else readBytes += read + 1;  return read; } if ( buffer[ 0 ] == '\n' ) {  pos++; avail--; readBytes += read + 2; return read; } } }  if ( terminators.contains( LineTerminator.CR ) ) { readBytes += read + 1; return read; }  array[ off + read++ ] = '\r'; remaining--; } } else if ( noMoreCharacters() ) { readBytes += read; return read; } }
public int readLine( final byte[] array ) throws IOException { return readLine( array, 0, array.length, ALL_TERMINATORS );
	public int readLine( final byte[] array, final int off, final int len, final EnumSet<LineTerminator> terminators ) throws IOException {		ByteArrays.ensureOffsetLength( array ,off, len );		if ( len == 0 ) return 0; // 0-length reads always return 0		if ( noMoreCharacters() ) return -1;		int i, k = 0, remaining = len, read = 0; // The number of bytes still to be read		for(;;) {			for( i = 0; i < avail && i < remaining && ( k = buffer[ pos + i ] ) != '\n' && k != '\r' ; i++ );			System.arraycopy( buffer, pos, array, off + read, i );			pos += i; 			avail -= i;			read += i;			remaining -= i;			if ( remaining == 0 ) {				readBytes += read;				return read; // We did not stop because of a terminator			}						if ( avail > 0 ) { // We met a terminator				if ( k == '\n' ) { // LF first					pos++;					avail--;					if ( terminators.contains( LineTerminator.LF ) ) {						readBytes += read + 1;						return read;					}					else {						array[ off + read++ ] = '\n';						remaining--;					}				}				else if ( k == '\r' ) { // CR first					pos++;					avail--;										if ( terminators.contains( LineTerminator.CR_LF ) ) {						if ( avail > 0 ) {							if ( buffer[ pos ] == '\n' ) { // CR/LF with LF already in the buffer.								pos ++;								avail--;								readBytes += read + 2;								return read;							}						}						else { // We must search for the LF.							if ( noMoreCharacters() ) {								// Not found a matching LF because of end of file, will return CR in buffer if not a terminator								if ( ! terminators.contains( LineTerminator.CR ) ) {									array[ off + read++ ] = '\r';									remaining--;									readBytes += read;								}								else readBytes += read + 1;																return read;							}							if ( buffer[ 0 ] == '\n' ) {								// Found matching LF, won't return terminators in the buffer								pos++;								avail--;								readBytes += read + 2;								return read;							}						}					}										if ( terminators.contains( LineTerminator.CR ) ) {						readBytes += read + 1;						return read;					}										array[ off + read++ ] = '\r';					remaining--;				}			}			else if ( noMoreCharacters() ) {				readBytes += read;				return read;			}		}	}