// Path: src/main/java/uk/elementarysoftware/quickcsv/api/ByteArraySource.java
// public static class ByteArrayChunk extends ReusableChunk {
//     public static final ByteArrayChunk EMPTY = new ByteArrayChunk(new byte[0], 0, false, (b) -> {});
//         
//     private final byte[] data;
//     private final int length;
//     private final boolean isLast;
// 
//     /**
//      * @param data - underlying content
//      * @param length - content length
//      * @param isLast - is this chunk of is last
//      * @param onFree - callback that will be called when data from this chunk has been fully consumed.
//      */
//     public ByteArrayChunk(byte[] data, int length, boolean isLast, Consumer<byte[]> onFree) {
//         super(() -> onFree.accept(data));
//         this.data = data;
//         this.length = length;
//         this.isLast = isLast;
//     }
// 
//     public byte[] getData() {
//         return data;
//     }
// 
//     public int getLength() {
//         return length;
//     }
// 
//     public boolean isLast() {
//         return isLast;
//     }
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/Field.java
// public interface Field {
// 
//     public ByteBuffer raw();
// 
//     public String asString();
//     
//     public double asDouble();
//     public byte asByte();
//     public char asChar();
//     public short asShort();
//     public int asInt();
//     public long asLong();
//     
//     public Integer asBoxedInt();
//     public Double asBoxedDouble();
// 
//     public boolean isEmpty();
// 
//     public Field clone();
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/functional/Pair.java
// public class Pair<F, S> {
//     
//     public final F first;
//     public final S second;
// 
//     /**
//      * Constructor for a Pair.
//      *
//      * @param first the first object in the Pair
//      * @param second the second object in the pair
//      */
//     public Pair(F first, S second) {
//         this.first = first;
//         this.second = second;
//     }
// 
//     /**
//      * Checks the two objects for equality by delegating to their respective
//      * {@link Object#equals(Object)} methods.
//      *
//      * @param o the {@link Pair} to which this one is to be checked for equality
//      * @return true if the underlying objects of the Pair are both considered
//      *         equal
//      */
//     @Override
//     public boolean equals(Object o) {
//         if (!(o instanceof Pair)) {
//             return false;
//         }
//         Pair<?, ?> p = (Pair<?, ?>) o;
//         return Objects.equals(p.first, first) && Objects.equals(p.second, second);
//     }
// 
//     /**
//      * Compute a hash code using the hash codes of the underlying objects
//      *
//      * @return a hashcode of the Pair
//      */
//     @Override
//     public int hashCode() {
//         return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
//     }
//     
//     @Override
//     public String toString() {
//         return first+"="+second;
//     }
// 
//     /**
//      * Convenience method for creating an appropriately typed pair.
//      * @param a the first object in the Pair
//      * @param b the second object in the pair
//      * @param <A> type of left element
//      * @param <B> type of right element
//      * @return a Pair that is templatized with the types of a and b
//      */
//     public static <A, B> Pair <A, B> of(A a, B b) {
//         return new Pair<A, B>(a, b);
//     }
// }


import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import uk.elementarysoftware.quickcsv.api.ByteArraySource.ByteArrayChunk;
import uk.elementarysoftware.quickcsv.api.Field;
import uk.elementarysoftware.quickcsv.functional.Pair;
package uk.elementarysoftware.quickcsv.parser;





public class ByteSliceTest {
    
    private static final String FIELDS22 = "field11,field12\nfield21,field22";
    private static final String FIELDS33 = "field11,field12,field13\nfield21,field22,field23\nfield31,field32,field33";
    private static final String QUOTED = "'field11','field12'\n'field21','field22'\n";
    
    @Test
    public void testSplitOnLastLineEnd() {
        String content = "line1\nline2\nlastline";
        ByteSlice slice = sliceFor(content.getBytes());
        assertEquals(content, slice.toString());
        Pair<ByteSlice, ByteSlice> sliced = slice.splitOnLastLineEnd();
        assertEquals("line1\nline2\n", sliced.first.toString());
        assertEquals("lastline", sliced.second.toString());
    }
    
    
    @Test
    public void testSplitOnLastLineEndWithSkip() {
        String content = "line1\nline2\nlastline";
        ByteSlice slice = sliceFor(content.getBytes());
        slice.nextLine();
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/ByteArraySource.java
// public static class ByteArrayChunk extends ReusableChunk {
//     public static final ByteArrayChunk EMPTY = new ByteArrayChunk(new byte[0], 0, false, (b) -> {});
//         
//     private final byte[] data;
//     private final int length;
//     private final boolean isLast;
// 
//     /**
//      * @param data - underlying content
//      * @param length - content length
//      * @param isLast - is this chunk of is last
//      * @param onFree - callback that will be called when data from this chunk has been fully consumed.
//      */
//     public ByteArrayChunk(byte[] data, int length, boolean isLast, Consumer<byte[]> onFree) {
//         super(() -> onFree.accept(data));
//         this.data = data;
//         this.length = length;
//         this.isLast = isLast;
//     }
// 
//     public byte[] getData() {
//         return data;
//     }
// 
//     public int getLength() {
//         return length;
//     }
// 
//     public boolean isLast() {
//         return isLast;
//     }
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/api/Field.java
// public interface Field {
// 
//     public ByteBuffer raw();
// 
//     public String asString();
//     
//     public double asDouble();
//     public byte asByte();
//     public char asChar();
//     public short asShort();
//     public int asInt();
//     public long asLong();
//     
//     public Integer asBoxedInt();
//     public Double asBoxedDouble();
// 
//     public boolean isEmpty();
// 
//     public Field clone();
// }
// 
// Path: src/main/java/uk/elementarysoftware/quickcsv/functional/Pair.java
// public class Pair<F, S> {
//     
//     public final F first;
//     public final S second;
// 
//     /**
//      * Constructor for a Pair.
//      *
//      * @param first the first object in the Pair
//      * @param second the second object in the pair
//      */
//     public Pair(F first, S second) {
//         this.first = first;
//         this.second = second;
//     }
// 
//     /**
//      * Checks the two objects for equality by delegating to their respective
//      * {@link Object#equals(Object)} methods.
//      *
//      * @param o the {@link Pair} to which this one is to be checked for equality
//      * @return true if the underlying objects of the Pair are both considered
//      *         equal
//      */
//     @Override
//     public boolean equals(Object o) {
//         if (!(o instanceof Pair)) {
//             return false;
//         }
//         Pair<?, ?> p = (Pair<?, ?>) o;
//         return Objects.equals(p.first, first) && Objects.equals(p.second, second);
//     }
// 
//     /**
//      * Compute a hash code using the hash codes of the underlying objects
//      *
//      * @return a hashcode of the Pair
//      */
//     @Override
//     public int hashCode() {
//         return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
//     }
//     
//     @Override
//     public String toString() {
//         return first+"="+second;
//     }
// 
//     /**
//      * Convenience method for creating an appropriately typed pair.
//      * @param a the first object in the Pair
//      * @param b the second object in the pair
//      * @param <A> type of left element
//      * @param <B> type of right element
//      * @return a Pair that is templatized with the types of a and b
//      */
//     public static <A, B> Pair <A, B> of(A a, B b) {
//         return new Pair<A, B>(a, b);
//     }
// }


// Path: src/test/java/uk/elementarysoftware/quickcsv/parser/ByteSliceTest.java
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import uk.elementarysoftware.quickcsv.api.ByteArraySource.ByteArrayChunk;
import uk.elementarysoftware.quickcsv.api.Field;
import uk.elementarysoftware.quickcsv.functional.Pair;

package uk.elementarysoftware.quickcsv.parser;





public class ByteSliceTest {
    
    private static final String FIELDS22 = "field11,field12\nfield21,field22";
    private static final String FIELDS33 = "field11,field12,field13\nfield21,field22,field23\nfield31,field32,field33";
    private static final String QUOTED = "'field11','field12'\n'field21','field22'\n";
    
    @Test
    public void testSplitOnLastLineEnd() {
        String content = "line1\nline2\nlastline";
        ByteSlice slice = sliceFor(content.getBytes());
        assertEquals(content, slice.toString());
        Pair<ByteSlice, ByteSlice> sliced = slice.splitOnLastLineEnd();
        assertEquals("line1\nline2\n", sliced.first.toString());
        assertEquals("lastline", sliced.second.toString());
    }
    
    
    @Test
    public void testSplitOnLastLineEndWithSkip() {
        String content = "line1\nline2\nlastline";
        ByteSlice slice = sliceFor(content.getBytes());
        slice.nextLine();
        Pair<ByteSlice, ByteSlice> sliced = slice.splitOnLastLineEnd();