package org.simpleflatmapper.csv.parser;

import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;

public final class ReaderCharBuffer extends CharBuffer {

	private final int maxBufferSize;
	private final Reader reader;
	private int resizeThreshold;

	public ReaderCharBuffer(final int bufferSize, int maxBufferLength, Reader reader) {
		super(new char[bufferSize], 0);
		this.maxBufferSize = maxBufferLength;
		this.reader = reader;
		this.resizeThreshold = (buffer.length >> 2) * 3;
	}

	@Override
	public final boolean next() throws IOException {
		// shift buffer consumer data
		int effectiveMark = Math.min(bufferSize, mark);
		int newSize = bufferSize - effectiveMark;
		char[] lbuffer = this.buffer;
		System.arraycopy(lbuffer, effectiveMark, lbuffer, 0, newSize);
		bufferSize = newSize;
		mark = 0;

		if (newSize > resizeThreshold) {
			int newBufferSize = Math.min(maxBufferSize, lbuffer.length << 1);
			if (newBufferSize <= newSize) {
				throw new BufferOverflowException("The content in the csv cell exceed the maxSizeBuffer " + maxBufferSize + ", see CsvParser.DSL.maxSizeBuffer(int) to change the default value");
			}			// double buffer size
			lbuffer = Arrays.copyOf(lbuffer, newBufferSize);
			this.buffer = lbuffer;
			// 3/4
			resizeThreshold = (newBufferSize >> 2) * 3;
		}

		int l = reader.read(lbuffer, newSize, lbuffer.length - newSize);
		bufferSize += Math.max(0, l);
		return l > 0;
	}

}

@@ -247,27 +247,26 @@
 ate 
-int resizeThreshold
+final int readSize
 ;%0A%0A%09
@@ -299,22 +299,20 @@
 nal int 
-buffer
+read
 Size, in
@@ -368,23 +368,82 @@
 har%5B
-bufferSize%5D, 0)
+readSize %3C 4096 ? readSize : readSize * 2%5D, 0);%0A%09%09this.readSize = readSize
 ;%0A%09%09
@@ -508,59 +508,8 @@
 er;%0A
-%09%09this.resizeThreshold = (buffer.length %3E%3E 2) * 3;%0A
 %09%7D%0A%0A
@@ -601,16 +601,56 @@
 er data%0A
+%09%09int currentSize = this.bufferSize;%0A%09%09%0A
 %09%09int ef
@@ -672,22 +672,23 @@
 ath.min(
-buffer
+current
 Size, ma
@@ -708,22 +708,23 @@
 wSize = 
-buffer
+current
 Size - e
@@ -737,16 +737,40 @@
 veMark;%0A
+%09%09%0A%09%09// shift left over%0A
 %09%09char%5B%5D
@@ -864,113 +864,338 @@
 ;%0A%09%09
-bufferSize = newSize;%0A%09%09mark = 0;%0A%0A%09%09if (newSize %3E resizeThreshold) %7B%0A%09%09%09int newBufferSize = Math.min(max
+mark = 0;%0A%0A%09%09int bufferLength = lbuffer.length;%0A%09%09%0A%09%09int availableSpace = bufferLength - newSize;%0A%09%0A%09%09int effectiveReadSize = readSize;%0A%09%09%0A%09%09// make sure we can read readSize%0A%09%09if (availableSpace %3C effectiveReadSize) %7B%0A%09%09%09int newBufferSize = bufferLength * 2;%0A%09%09%09%0A%09%09%09if (newBufferSize %3C bufferLength + effectiveReadSize) %7B%0A%09%09%09%09new
 Buff
@@ -1204,31 +1204,138 @@
 Size
-, l
+ =  
 buffer
-.l
+L
 ength 
-%3C%3C 1);
++ effectiveReadSize;%0A%09%09%09%7D%0A%09%09%09%0A%09%09%09if (newBufferSize %3E maxBufferSize) %7B%0A%09%09%09%09newBufferSize = maxBufferSize;%0A%09%09%09%7D%0A%09%09%09
 %0A%09%09%09
@@ -1557,32 +1557,16 @@
 %09%09%09%7D
+%0A
 %09%09%09
-// double buffer size
+%0A%09%09%09
 %0A%09%09%09
@@ -1647,136 +1647,268 @@
 %0A%09%09%09
-// 3/4%0A%09%09%09resizeThreshold = (newBufferSize %3E%3E 2) * 3;%0A%09%09%7D%0A%0A%09%09int l = reader.read(lbuffer, newSize, lbuffer.length - newSize);%0A%09%09
+%0A%09%09%09if (effectiveReadSize %3E bufferLength - newSize) %7B%0A%09%09%09%09effectiveReadSize = bufferLength - newSize;%0A%09%09%09%7D%0A%09%09%7D%0A%0A%09%09int l = reader.read(lbuffer, newSize, effectiveReadSize);%0A%09%09%0A%09%09if (l %3E= 0) %7B%0A%09%09%09this.bufferSize = newSize + l;%0A%09%09%09return true;%0A%09%09%7D else %7B%0A%09%09%09this.
 buff
@@ -1918,27 +1918,20 @@
 ize 
-+
 = 
-Math.max(0, l)
+newSize
 ;%0A
+%09
 %09%09re
@@ -1939,14 +1939,18 @@
 urn 
-l %3E 0;
+false;%0A%09%09%7D
 %0A%09%7D%0A

align reads