view src/test/java/org/msgpack/io/TestLinkedBufferInput.java @ 0:cb825acd883a

first commit
author sugi
date Sat, 18 Oct 2014 15:06:15 +0900
parents
children
line wrap: on
line source

package org.msgpack.io;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;

import java.nio.ByteBuffer;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;

import org.junit.Test;


public class TestLinkedBufferInput {
    @Test
    public void testReadByte() throws IOException {
        byte[] src = new byte[8];
        src[0] = (byte)1;
        src[2] = (byte)1;
        src[4] = (byte)1;
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);
        LinkedBufferInput b2 = new LinkedBufferInput(8);
        b2.feed(src);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        assertEndOfBuffer(b2);
    }

    @Test
    public void testFeedByteArrayCopy() throws IOException {
        byte[] small = new byte[8];
        small[0] = (byte)1;
        small[2] = (byte)1;
        small[4] = (byte)1;

        byte[] large = new byte[16];
        large[0] = (byte)1;
        large[3] = (byte)1;
        large[6] = (byte)1;
        large[10] = (byte)1;

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        LinkedBufferInput b2 = new LinkedBufferInput(11);

        for(int i=0; i < 3; i++) {
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(small);
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(large);
            }
        }

        byte[] src = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        assertEndOfBuffer(b2);
    }

    @Test
    public void testFeedByteArrayReference() throws IOException {
        byte[] small = new byte[8];
        small[0] = (byte)1;
        small[2] = (byte)1;
        small[4] = (byte)1;

        byte[] large = new byte[16];
        large[0] = (byte)1;
        large[3] = (byte)1;
        large[6] = (byte)1;
        large[10] = (byte)1;

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        LinkedBufferInput b2 = new LinkedBufferInput(11);

        for(int i=0; i < 3; i++) {
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(small, true);
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(large, true);
            }
        }

        byte[] src = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        assertEndOfBuffer(b2);
    }

    @Test
    public void testFeedByteArrayCopyReference() throws IOException {
        byte[] small = new byte[8];
        small[0] = (byte)1;
        small[2] = (byte)1;
        small[4] = (byte)1;

        byte[] large = new byte[16];
        large[0] = (byte)1;
        large[3] = (byte)1;
        large[6] = (byte)1;
        large[10] = (byte)1;

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        LinkedBufferInput b2 = new LinkedBufferInput(11);

        for(int i=0; i < 3; i++) {
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(small);
            }
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(small, true);
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(large);
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(large, true);
            }
        }

        byte[] src = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        try {
            b2.readByte();
            fail();
        } catch(EndOfBufferException eof) {
        }
    }

    @Test
    public void testGetPrimitives() throws IOException {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        DataOutputStream o = new DataOutputStream(bo);
        o.writeByte((byte)2);
        o.writeShort((short)2);
        o.writeInt(2);
        o.writeLong(2L);
        o.writeFloat(1.1f);
        o.writeDouble(1.1);
        byte[] src = bo.toByteArray();

        LinkedBufferInput b = new LinkedBufferInput(1024);

        for(int i=0; i < 2; i++) {
            b.feed(src);

            assertEquals((byte)2, b.getByte());
            assertEquals((byte)2, b.getByte());
            b.advance();
            assertEquals((short)2, b.getShort());
            assertEquals((short)2, b.getShort());
            b.advance();
            assertEquals(2, b.getInt());
            assertEquals(2, b.getInt());
            b.advance();
            assertEquals(2L, b.getLong());
            assertEquals(2L, b.getLong());
            b.advance();
            assertEquals(1.1f, b.getFloat(), 0.000001f);
            assertEquals(1.1f, b.getFloat(), 0.000001f);
            b.advance();
            assertEquals(1.1, b.getDouble(), 0.000001);
            assertEquals(1.1, b.getDouble(), 0.000001);
            b.advance();
        }
    }

    @Test
    public void testGetPrimitivesChunks() throws IOException {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        DataOutputStream o = new DataOutputStream(bo);
        o.writeByte((byte)2);
        o.writeShort((short)2);
        o.writeInt(2);
        o.writeLong(2L);
        o.writeFloat(1.1f);
        o.writeDouble(1.1);
        byte[] src = bo.toByteArray();

        LinkedBufferInput b = new LinkedBufferInput(1024);

        for(int i=0; i < 2; i++) {
            int p = 0;

            b.feed(src, p++, 1, true);
            assertEquals((byte)2, b.getByte());
            assertEquals((byte)2, b.getByte());
            b.advance();

            for(int j=0; j < 2; j++) {
                try {
                    b.getShort();
                    fail();
                } catch(EndOfBufferException eof) {
                }
                b.feed(src, p++, 1, true);
            }
            assertEquals((short)2, b.getShort());
            assertEquals((short)2, b.getShort());
            b.advance();

            for(int j=0; j < 4; j++) {
                try {
                    b.getInt();
                    fail();
                } catch(EndOfBufferException eof) {
                }
                b.feed(src, p++, 1, true);
            }
            assertEquals(2, b.getInt());
            assertEquals(2, b.getInt());
            b.advance();

            for(int j=0; j < 8; j++) {
                try {
                    b.getLong();
                    fail();
                } catch(EndOfBufferException eof) {
                }
                b.feed(src, p++, 1, true);
            }
            assertEquals(2L, b.getLong());
            assertEquals(2L, b.getLong());
            b.advance();

            for(int j=0; j < 4; j++) {
                try {
                    b.getFloat();
                    fail();
                } catch(EndOfBufferException eof) {
                }
                b.feed(src, p++, 1, true);
            }
            assertEquals(1.1f, b.getFloat(), 0.000001f);
            assertEquals(1.1f, b.getFloat(), 0.000001f);
            b.advance();

            for(int j=0; j < 8; j++) {
                try {
                    b.getDouble();
                    fail();
                } catch(EndOfBufferException eof) {
                }
                b.feed(src, p++, 1, true);
            }
            assertEquals(1.1, b.getDouble(), 0.000001);
            assertEquals(1.1, b.getDouble(), 0.000001);
            b.advance();
        }
    }


    @Test
    public void testFeedByteBufferCopy() throws IOException {
        byte[] small = new byte[8];
        small[0] = (byte)1;
        small[2] = (byte)1;
        small[4] = (byte)1;

        byte[] large = new byte[16];
        large[0] = (byte)1;
        large[3] = (byte)1;
        large[6] = (byte)1;
        large[10] = (byte)1;

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        LinkedBufferInput b2 = new LinkedBufferInput(11);

        for(int i=0; i < 3; i++) {
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(ByteBuffer.wrap(small));
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(ByteBuffer.wrap(large));
            }
        }

        byte[] src = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        assertEndOfBuffer(b2);
    }

    @Test
    public void testFeedByteBufferReference() throws IOException {
        byte[] small = new byte[8];
        small[0] = (byte)1;
        small[2] = (byte)1;
        small[4] = (byte)1;

        byte[] large = new byte[16];
        large[0] = (byte)1;
        large[3] = (byte)1;
        large[6] = (byte)1;
        large[10] = (byte)1;

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        LinkedBufferInput b2 = new LinkedBufferInput(11);

        for(int i=0; i < 3; i++) {
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(ByteBuffer.wrap(small), true);
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(ByteBuffer.wrap(large), true);
            }
        }

        byte[] src = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        assertEndOfBuffer(b2);
    }

    @Test
    public void testFeedByteBufferCopyReference() throws IOException {
        byte[] small = new byte[8];
        small[0] = (byte)1;
        small[2] = (byte)1;
        small[4] = (byte)1;

        byte[] large = new byte[16];
        large[0] = (byte)1;
        large[3] = (byte)1;
        large[6] = (byte)1;
        large[10] = (byte)1;

        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        LinkedBufferInput b2 = new LinkedBufferInput(11);

        for(int i=0; i < 3; i++) {
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(ByteBuffer.wrap(small));
            }
            for(int j=0; j < 7; j++) {
                bout.write(small);
                b2.feed(ByteBuffer.wrap(small), true);
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(ByteBuffer.wrap(large));
            }
            for(int j=0; j < 4; j++) {
                bout.write(large);
                b2.feed(ByteBuffer.wrap(large), true);
            }
        }

        byte[] src = bout.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(src);
        DataInputStream b1 = new DataInputStream(bin);

        for(int i=0; i < src.length; i++) {
            assertEquals(b1.readByte(), b2.readByte());
        }

        assertEndOfBuffer(b2);
    }

    @Test
    public void testClear() throws IOException {
        byte[] src = new byte[8];

        LinkedBufferInput b = new LinkedBufferInput(11);

        for(int i=0; i < 2; i++) {
            try {
                b.readByte();
                fail();
            } catch(EndOfBufferException eof) {
            }

            b.feed(src);

            b.clear();

            assertEndOfBuffer(b);

            b.feed(src);

            for(int j=0; j < src.length; j++) {
                b.readByte();
            }

            b.clear();
        }
    }

    @Test
    public void testClearRecycle() throws IOException {
        byte[] data = new byte[8];
        data[0] = (byte)1;
        data[2] = (byte)1;
        data[4] = (byte)1;

        LinkedBufferInput b = new LinkedBufferInput(16);

        b.feed(data);
        assertEquals(1, b.link.size());
        assertEquals(8, b.writable);
        b.clear();
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);

        b.feed(data);
        b.feed(data);
        assertEquals(1, b.link.size());
        assertEquals(0, b.writable);
        b.clear();
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
    }

    @Test
    public void testCopyReferencedBuffer() throws IOException {
        byte[] data = new byte[16];
        data[0] = (byte)4;
        data[3] = (byte)5;
        data[6] = (byte)6;
        data[10] = (byte)7;

        LinkedBufferInput b = new LinkedBufferInput(32);
        int n;
        byte[] buf = new byte[16];

        b.feed(data, true);
        b.feed(data, true);
        b.feed(data, true);
        assertEquals(3, b.link.size());
        assertEquals(-1, b.writable);

        b.copyReferencedBuffer();
        assertEquals(1, b.link.size());
        assertEquals(0, b.writable);

        n = b.read(buf, 0, 16);
        assertEquals(n, 16);
        assertArrayEquals(data, buf);

        n = b.read(buf, 0, 16);
        assertEquals(n, 16);
        assertArrayEquals(data, buf);

        n = b.read(buf, 0, 16);
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
    }

    @Test
    public void testCopyReferencedBufferOptimized() throws IOException {
        byte[] data = new byte[16];
        data[0] = (byte)4;
        data[3] = (byte)5;
        data[6] = (byte)6;
        data[10] = (byte)7;

        LinkedBufferInput b = new LinkedBufferInput(32);
        int n;
        byte[] buf = new byte[16];

        b.feed(data, true);
        b.feed(data, true);
        b.feed(data);  // buffer allocated
        assertEquals(3, b.link.size());
        assertEquals(16, b.writable);

        b.copyReferencedBuffer();
        assertEquals(2, b.link.size());
        assertEquals(16, b.writable);

        n = b.read(buf, 0, 16);
        assertEquals(n, 16);
        assertArrayEquals(data, buf);

        n = b.read(buf, 0, 16);
        assertEquals(n, 16);
        assertArrayEquals(data, buf);

        n = b.read(buf, 0, 16);
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
    }

    @Test
    public void testBufferRecycleByteArray() throws IOException {
        byte[] data = new byte[16];
        data[0] = (byte)4;
        data[3] = (byte)5;
        data[6] = (byte)6;
        data[10] = (byte)7;

        LinkedBufferInput b = new LinkedBufferInput(32);
        int n;
        byte[] buf = new byte[16];

        b.feed(data);  // feed 1; buffer allocated; remains 32-16 = 16 bytes
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
        ByteBuffer allocated = b.link.peekLast();

        b.feed(data);  // feed 2; remains 16-16 = 0 bytes
        assertEquals(1, b.link.size());
        assertEquals(0, b.writable);
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume 16 bytes 1
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());
        assertEquals(0, b.writable);  // no writable
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume 16 bytes 2; comsume all buffer; recycled
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEndOfBuffer(b);
        assertEquals(1, b.link.size());
        assertEquals(32, b.writable);  // recycled
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(data);  // feed 1; remains 32-16 = 16 bytes
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
        assertEquals(true, allocated == b.link.peekLast());

        b.clear();  // clear; recycled
        assertEndOfBuffer(b);
        assertEquals(1, b.link.size());
        assertEquals(32, b.writable);  // recycled
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(data, true);  // feed reference 1;
        assertEquals(2, b.link.size());  // leaves last writable buffer
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(data, true);  // feed reference 2;
        assertEquals(3, b.link.size());  // leaves last writable buffer
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume first link 1
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(2, b.link.size());  // first link is removed
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume first link 2
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());  // first link is removed
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(data);  // feed 1; remains 32-16 = 16 bytes;
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(data, true);  // feed reference 2; writable buffer is hidden
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(2, b.link.size());
        assertEquals(-1, b.writable);  // now not writable
        assertEquals(true, allocated != b.link.peekLast());
        assertEquals(true, allocated == b.link.peekFirst());

        n = b.read(buf, 0, 16);  // consume data 1
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());  // recycled buffer is removed
        assertEquals(-1, b.writable);
        assertEquals(true, allocated != b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume data 2
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEndOfBuffer(b);
        assertEquals(0, b.link.size());
        assertEquals(-1, b.writable);
    }

    // copied from testBufferRecycleByteArray
    @Test
    public void testBufferRecycleByteBuffer() throws IOException {
        byte[] data = new byte[16];
        data[0] = (byte)4;
        data[3] = (byte)5;
        data[6] = (byte)6;
        data[10] = (byte)7;

        ByteBuffer bb = ByteBuffer.wrap(data);

        LinkedBufferInput b = new LinkedBufferInput(32);
        int n;
        byte[] buf = new byte[16];

        b.feed(bb.duplicate());  // feed 1; buffer allocated; remains 32-16 = 16 bytes
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
        ByteBuffer allocated = b.link.peekLast();

        b.feed(bb.duplicate());  // feed 2; remains 16-16 = 0 bytes
        assertEquals(1, b.link.size());
        assertEquals(0, b.writable);
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume 16 bytes 1
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());
        assertEquals(0, b.writable);  // no writable
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume 16 bytes 2; comsume all buffer; recycled
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEndOfBuffer(b);
        assertEquals(1, b.link.size());
        assertEquals(32, b.writable);  // recycled
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(bb.duplicate());  // feed 1; remains 32-16 = 16 bytes
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
        assertEquals(true, allocated == b.link.peekLast());

        b.clear();  // clear; recycled
        assertEndOfBuffer(b);
        assertEquals(1, b.link.size());
        assertEquals(32, b.writable);  // recycled
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(bb.duplicate(), true);  // feed reference 1;
        assertEquals(2, b.link.size());  // leaves last writable buffer
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(bb.duplicate(), true);  // feed reference 2;
        assertEquals(3, b.link.size());  // leaves last writable buffer
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume first link 1
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(2, b.link.size());  // first link is removed
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume first link 2
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());  // first link is removed
        assertEquals(32, b.writable);    // which remains 32 bytes
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(bb.duplicate());  // feed 1; remains 32-16 = 16 bytes;
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());
        assertEquals(16, b.writable);
        assertEquals(true, allocated == b.link.peekLast());

        b.feed(bb.duplicate(), true);  // feed reference 2; writable buffer is hidden
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(2, b.link.size());
        assertEquals(-1, b.writable);  // now not writable
        assertEquals(true, allocated != b.link.peekLast());
        assertEquals(true, allocated == b.link.peekFirst());

        n = b.read(buf, 0, 16);  // consume data 1
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEquals(1, b.link.size());  // recycled buffer is removed
        assertEquals(-1, b.writable);
        assertEquals(true, allocated != b.link.peekLast());

        n = b.read(buf, 0, 16);  // consume data 2
        assertEquals(n, 16);
        assertArrayEquals(data, buf);
        assertEndOfBuffer(b);
        assertEquals(0, b.link.size());
        assertEquals(-1, b.writable);
    }

    private void assertEndOfBuffer(LinkedBufferInput b) throws IOException {
        try {
            b.readByte();
            fail();
        } catch(EndOfBufferException eof) {
        }
    }
}