All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.java.textilej.util.LocationTrackingReader Maven / Gradle / Ivy

The newest version!
package net.java.textilej.util;

import java.io.IOException;
import java.io.Reader;


public class LocationTrackingReader extends Reader {
	private Reader delegate;

	private int offset = -1;
	private int lineOffset = -1;
	private int lineNumber = -1;
	
	private char[] buf;
	private int bufOffset = 0;
	private int bufLength = 0;
	
	public LocationTrackingReader(Reader delegate) {
		this(delegate,2048);
	}
	
	public LocationTrackingReader(Reader delegate,int bufferSize) {
		this.delegate = delegate;
		buf = new char[bufferSize];
	}

	@Override
	public void close() throws IOException {
		delegate.close();
	}

	@Override
	public int read(char[] cbuf, int off, int len) throws IOException {
		if (bufLength > 0) {
			int length = Math.min(len, bufLength);
			System.arraycopy(buf, bufOffset, cbuf, off, length);
			bufLength -=length;
			bufOffset += length;
			if (bufLength == 0) {
				bufOffset = 0;
			}
			offset += length;
			return length;
		} else {
			int read = delegate.read(cbuf,off,len);
			if (read != -1) {
				offset += read;
			}
			return read;
		}
	}
	
	@Override
	public int read() throws IOException {
		if (bufLength > 0) {
			int c = buf[bufOffset];
			bufLength -= 1;
			bufOffset += 1;
			if (bufLength == 0) {
				bufOffset = 0;
			}
			offset += 1;
			return c;
		} else {
			int read = delegate.read();
			if (read != -1) {
				++offset;
			}
			return read;
		}
	}

	/**
	 * Read a line of text, omitting the line delimiters.
	 * 
	 * @return the text or null if the end of input has been reached
	 * 
	 * @see #getLineOffset()
	 */
	public String readLine() throws IOException {
		lineOffset = offset+1;
		
		int lineBufOffset = bufOffset;
		int c = -1;
		for (int x = lineBufOffset;;++x) {
			if (x >= (bufOffset+bufLength)) {
				if (bufOffset > 0 && bufLength > 0) {
					System.arraycopy(buf, bufOffset, buf, 0, bufLength);
					x -= bufOffset;
					bufOffset = 0;
					lineBufOffset = 0;
				}
				if (bufOffset+bufLength >= buf.length) {
					// expand the buffer
					char[] newBuf = new char[buf.length*2];
					if (bufLength > 0) {
						System.arraycopy(buf, bufOffset, newBuf, 0,bufLength);
					}
					x -= bufOffset;
					bufOffset = 0;
					lineBufOffset = 0;
					buf = newBuf;
				}
				int emptyOffset = bufOffset+bufLength;
				int read = delegate.read(buf, emptyOffset, buf.length-emptyOffset);
				if (read > 0) {
					bufLength += read;
				} else {
					// end of input
					break;
				}
			}
			if (x >= (bufOffset+bufLength)) {
				// end of input
				break;
			}
			int nc = buf[x];
			if (nc == '\n') {
				// eol
				int length = x-lineBufOffset+1;
				bufOffset += length;
				bufLength -= length;
				offset += length;
				
				int stringLength = c=='\r'?length-2:length-1;
				++lineNumber;
				return new String(buf,lineBufOffset,stringLength);
			} else if (c == '\r') {
				int length = x-lineBufOffset;
				bufOffset += length;
				bufLength -= length;
				offset += length;
				int stringLength = length-1;
				++lineNumber;
				return new String(buf,lineBufOffset,stringLength);
			}
			c = nc;
		}
		if (bufLength > 0) {
			String line = new String(buf,bufOffset,c=='\r'?bufLength -1:bufLength);
			bufOffset = 0;
			offset += bufLength;
			bufLength = 0;
			++lineNumber;
			return line;
		} else {
			++lineNumber;
			return null;
		}
	}
	
	/**
	 * Get the character offset of the last character read.
	 */
	public int getOffset() {
		return offset;
	}

	/**
	 * Get the character offset of the first character of the last line read. The result of calling this method is only
	 * meaningful immediately after having called {@link #readLine()}.
	 * 
	 * @see #readLine()
	 */
	public int getLineOffset() {
		return lineOffset;
	}

	/**
	 * get the 0-based line number of the last line read. The result of calling this method is only
	 * meaningful immediately after having called {@link #readLine()}.
	 * 
	 * @see #readLine()
	 */
	public int getLineNumber() {
		return lineNumber;
	}
	
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy