/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved. <a>http://www.crunii.com</a>
 */
package com.crunii.micro.common.file;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.util.concurrent.CountDownLatch;

/**
 * @author 田平 create 2017年9月5日上午10:39:08
 */
public class RangeReader implements Runnable {

	private int lineSize = 0;// 文件行数，空行不算行数
	private int bufferSize = 1024;
	private String charset = "UTF-8";// 源文件字符集
	private MappedByteBuffer mb;
	private LineHandler handler;
	private CountDownLatch doneSignal;

	public RangeReader(LineHandler handler, MappedByteBuffer mb, CountDownLatch doneSignal) {
		this.handler = handler;
		this.mb = mb;
		this.doneSignal = doneSignal;
	}

	public RangeReader(LineHandler handler, MappedByteBuffer mb, String charset, CountDownLatch doneSignal) {
		this.handler = handler;
		this.mb = mb;
		this.charset = charset;
		this.doneSignal = doneSignal;
	}

	public RangeReader(LineHandler handler, MappedByteBuffer mb, int bufferSize, String charset, CountDownLatch doneSignal) {
		this.handler = handler;
		this.mb = mb;
		this.bufferSize = bufferSize;
		this.charset = charset;
		this.doneSignal = doneSignal;
	}

	public void run() {
		ByteArrayOutputStream bos = null;
		String line = null;
		try {
			bos = new ByteArrayOutputStream(bufferSize);
			byte[] readBuff = new byte[bufferSize];
			int start = 0;
			int readLength = bufferSize;
			while (mb.hasRemaining()) {
				if (start + readLength < mb.limit()) {
					readLength = bufferSize;
				} else {
					readLength = mb.limit() - start;
				}
				mb.get(readBuff, 0, readLength);
				for (int i = 0; i < readLength; i++) {
					byte tp = readBuff[i];
					if (Range.checkLineChar(tp)) {
						if (bos.size() > 0) {
							line = new String(bos.toByteArray(), charset);
							lineSize++;
							handler.lineString(line);
							bos.reset();
						}
					} else {
						bos.write(tp);
					}
				}
				start = start + readLength;
			}
			if (bos.size() > 0) {
				line = new String(bos.toByteArray(), charset);
				lineSize++;
				handler.lineString(line);
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			doneSignal.countDown();
			if (mb != null) {
				mb.clear();
			}
			if (bos != null) {
				try {
					bos.close();
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
		}
	}

	/**
	 * @return the lineSize
	 */
	public int getLineSize() {
		return lineSize;
	}

	/**
	 * @param lineSize the lineSize to set
	 */
	public void setLineSize(int lineSize) {
		this.lineSize = lineSize;
	}

	/**
	 * @return the bufferSize
	 */
	public int getBufferSize() {
		return bufferSize;
	}

	/**
	 * @param bufferSize the bufferSize to set
	 */
	public void setBufferSize(int bufferSize) {
		this.bufferSize = bufferSize;
	}

	/**
	 * @return the charset
	 */
	public String getCharset() {
		return charset;
	}

	/**
	 * @param charset the charset to set
	 */
	public void setCharset(String charset) {
		this.charset = charset;
	}

	/**
	 * @return the handler
	 */
	public LineHandler getHandler() {
		return handler;
	}

	/**
	 * @param handler the handler to set
	 */
	public void setHandler(LineHandler handler) {
		this.handler = handler;
	}

}
