Package com.peterhi.runtime

Source Code of com.peterhi.runtime.BitStreamTest

package com.peterhi.runtime;

import static org.junit.Assert.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.junit.Before;
import org.junit.Test;

import com.peterhi.runtime.BitStream;
import com.peterhi.runtime.InsufficientBufferException;

public class BitStreamTest {
 
  private SortedMap<BigInteger, Integer> numbers;
 
  @Before
  public void setUp() {
    int[] bits = new int[] { 1, 2, 4, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128 };
   
    numbers = new TreeMap<BigInteger, Integer>();

    for (int bit : bits) {
      BigInteger ref = BigInteger.valueOf(2).pow(bit).divide(BigInteger.valueOf(2));
      BigInteger min = ref.negate();
      BigInteger max = ref.subtract(BigInteger.ONE);
      BigInteger under = min.subtract(BigInteger.ONE);
      BigInteger over = max.add(BigInteger.ONE);
      numbers.put(min, bit);
      numbers.put(max, bit);
      numbers.put(under, bit);
      numbers.put(over, bit);
    }
  }
 
  @Test
  public void testConstructorCapacity() throws Exception {
    {
      BitStream bs = new BitStream(32);
      assertEquals(0, bs.available());
      assertEquals(32, bs.bytes());
    }
   
    try {
      BitStream bs = new BitStream(-1);
      fail();
    } catch (IllegalArgumentException ex) {
    }
  }
 
  @Test
  public void testConstructorBufOffLen() throws Exception {
    {
      BitStream bs = new BitStream(new byte[32], Byte.SIZE * 16, Byte.SIZE * 16);
      assertEquals(Byte.SIZE * 16, bs.available());
      assertEquals(16, bs.bytes());
    }
   
    try {
      BitStream bs = new BitStream(null, 0, 1);
      fail();
    } catch (NullPointerException ex) {
    }
   
    try {
      BitStream bs = new BitStream(new byte[1], -1, 1);
      fail();
    } catch (IndexOutOfBoundsException ex) {
    }
   
    try {
      BitStream bs = new BitStream(new byte[1], 1, -1);
      fail();
    } catch (IndexOutOfBoundsException ex) {
    }
   
    try {
      BitStream bs = new BitStream(new byte[1], 1, Byte.SIZE);
      fail();
    } catch (IndexOutOfBoundsException ex) {
    }
  }

  @Test
  public void testAvailable() throws Exception {
    {
      BitStream bs = new BitStream(32);
      assertEquals(0, bs.available());
      assertEquals(32, bs.bytes());
    }
   
    {
      byte[] data = new byte[32];
      BitStream bs = new BitStream(data, 0, Byte.SIZE * data.length);
      assertEquals(Byte.SIZE * data.length, bs.available());
      assertEquals(data.length, bs.bytes());
    }
   
    {
      BitStream bs = new BitStream(32);
      bs.writeBit(1);
      assertEquals(1, bs.available());
      assertEquals(32, bs.bytes());
    }
  }
 
  @Test
  public void testSize() throws Exception {
    {
      BitStream bs = new BitStream(32);
      assertEquals(0, bs.available());
      assertEquals(32, bs.bytes());
    }
   
    {
      byte[] data = new byte[32];
      BitStream bs = new BitStream(data, Byte.SIZE * 16, Byte.SIZE * 16);
      assertEquals(Byte.SIZE * 16, bs.available());
      assertEquals(16, bs.bytes());
    }
   
    {
      BitStream bs = new BitStream(1);
     
      for (int i = 0; i < 9; i++) {
        bs.writeBit(1);
      }
     
      assertEquals(9, bs.available());
      assertEquals(129, bs.bytes());
    }
  }
 
  @Test
  public void testReadBit() throws Exception {
    {
      byte[] data = new byte[] { (byte )170, (byte )85 };
      BitStream bs = new BitStream(data, 0, Byte.SIZE * data.length);
     
      for (int i = 0; i < Byte.SIZE; i++) {
        int bit = bs.readBit();
       
        if (i % 2 == 0) {
          assertEquals(0, bit);
        } else {
          assertEquals(1, bit);
        }
      }
     
      for (int i = 0; i < Byte.SIZE; i++) {
        int bit = bs.readBit();
       
        if (i % 2 == 0) {
          assertEquals(1, bit);
        } else {
          assertEquals(0, bit);
        }
      }
     
      assertEquals(0, bs.available());
      assertEquals(2, bs.bytes());
    }
   
    {
      BitStream bs = new BitStream(32);
      assertEquals(0, bs.available());
      assertEquals(32, bs.bytes());
      assertEquals(-1, bs.readBit());
    }
  }
 
  @Test
  public void testWriteBit() throws Exception {
    {
      BitStream bs = new BitStream(1);
     
      for (int i = 0; i < 10; i++) {
        bs.writeBit(i % 2);
      }
     
      assertEquals(10, bs.available());
      assertEquals(129, bs.bytes());
     
      for (int i = 0; i < 10; i++) {
        assertEquals(i % 2, bs.readBit());
      }
     
      assertEquals(0, bs.available());
      assertEquals(129, bs.bytes());
      assertEquals(-1, bs.readBit());
    }
  }
 
  @Test
  public void testReadBits() throws Exception {
    {
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      DataOutputStream dos = new DataOutputStream(baos);
      int bytesWritten = 0;
     
      for (Map.Entry<BigInteger, Integer> entry : numbers.entrySet()) {
        BigInteger number = entry.getKey();
        Integer size = entry.getValue();
       
        if (size == Byte.SIZE) {
          dos.writeByte(number.byteValue());
          bytesWritten += Byte.SIZE / 8;
        } else if (size == Short.SIZE) {
          dos.writeShort(number.shortValue());
          bytesWritten += Short.SIZE / 8;
        } else if (size == Integer.SIZE) {
          dos.writeInt(number.intValue());
          bytesWritten += Integer.SIZE / 8;
        } else if (size == Long.SIZE) {
          dos.writeLong(number.longValue());
          bytesWritten += Long.SIZE / 8;
        }
      }
     
      byte[] data = baos.toByteArray();
      BitStream bs = new BitStream(data, 0, Byte.SIZE * data.length);
     
      for (Map.Entry<BigInteger, Integer> entry : numbers.entrySet()) {
        BigInteger number = entry.getKey();
        Integer size = entry.getValue();
       
        if (size == Byte.SIZE) {
          assertEquals(number.byteValue(), bs.readBits(size, true).byteValue());
        } else if (size == Short.SIZE) {
          assertEquals(number.shortValue(), bs.readBits(size, true).shortValue());
        } else if (size == Integer.SIZE) {
          assertEquals(number.intValue(), bs.readBits(size, true).intValue());
        } else if (size == Long.SIZE) {
          assertEquals(number.longValue(), bs.readBits(size, true).longValue());
        }
      }
     
      assertEquals(0, bs.available());
      assertEquals(bytesWritten, bs.bytes());
    }
   
    try {
      BitStream bs = new BitStream(32);
      bs.readBits(-1, true);
      fail();
    } catch (IllegalArgumentException ex) {
    }
   
    try {
      BitStream bs = new BitStream(32);
      bs.readBits(1, true);
      fail();
    } catch (EOFException ex) {
    }
   
    try {
      BitStream bs = new BitStream(32);
      bs.writeBit(1);
      bs.readBits(2, true);
      fail();
    } catch (InsufficientBufferException ex) {
    }
  }
 
  @Test
  public void testWriteBits() throws Exception {
    {
      BitStream bs = new BitStream(60);
     
      for (Map.Entry<BigInteger, Integer> entry : numbers.entrySet()) {
        BigInteger number = entry.getKey();
        Integer size = entry.getValue();

        if (size == Byte.SIZE || size == Short.SIZE || size == Integer.SIZE || size == Long.SIZE) {
          bs.writeBits(number, size);
        }
      }

      assertEquals(Byte.SIZE * 60, bs.available());
      assertEquals(60, bs.bytes());
     
      byte[] data = bs.toByteArray();
      DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
     
      for (Map.Entry<BigInteger, Integer> entry : numbers.entrySet()) {
        BigInteger number = entry.getKey();
        Integer size = entry.getValue();
       
        if (size == Byte.SIZE) {
          assertEquals(number.byteValue(), dis.readByte());
        } else if (size == Short.SIZE) {
          assertEquals(number.shortValue(), dis.readShort());
        } else if (size == Integer.SIZE) {
          assertEquals(number.intValue(), dis.readInt());
        } else if (size == Long.SIZE) {
          assertEquals(number.longValue(), dis.readLong());
        }
      }
    }
   
    try {
      BitStream bs = new BitStream(32);
      bs.writeBits(null, 0);
      fail();
    } catch (NullPointerException ex) {
    }
   
    try {
      BitStream bs = new BitStream(32);
      bs.writeBits(BigInteger.ONE, -1);
      fail();
    } catch (IllegalArgumentException ex) {
    }
  }
 
  @Test
  public void testReadAndWriteArbitraryBits() throws Exception {
    // ceil(1095 * 4 / 8)
    BitStream bsw = new BitStream(548);
    int bitsWritten = 0;
   
    for (Map.Entry<BigInteger, Integer> entry : numbers.entrySet()) {
      BigInteger number = entry.getKey();
      Integer size = entry.getValue();
      bsw.writeBits(number, size);
      bitsWritten += size;
    }
   
    assertEquals(bitsWritten, bsw.available());
    assertEquals(548, bsw.bytes());
   
    byte[] data = bsw.toByteArray();
    BitStream bsr = new BitStream(data, 0, bitsWritten);
   
    for (Map.Entry<BigInteger, Integer> entry : numbers.entrySet()) {
      BigInteger number = entry.getKey();
      Integer size = entry.getValue();
     
      BigInteger value = bsr.readBits(size, true);
      BigInteger mask = BigInteger.ZERO;
     
      for (int i = 0; i < size; i++) {
        mask = mask.or(BigInteger.ONE.shiftLeft(i));
      }
     
      assertEquals(number.and(mask), value.and(mask));
    }
   
    assertEquals(0, bsr.available());
    assertEquals(548, bsr.bytes());
  }
 
  @Test
  public void testReadMarks() throws Exception {
    BitStream bs = new BitStream(new byte[] { 1, 2 }, 0, Byte.SIZE * 2);
    assertEquals(1, bs.readBits(8, true).byteValue());
    bs.setReadMark();
    assertEquals(2, bs.readBits(8, true).byteValue());
    assertEquals(-1, bs.readBit());
    bs.goToReadMark();
    assertEquals(2, bs.readBits(8, true).byteValue());
    assertEquals(-1, bs.readBit());
    bs.clearReadMark();
    assertEquals(-1, bs.readBit());
    assertEquals(0, bs.available());
    assertEquals(2, bs.bytes());
    bs.goToReadFromBeginning();
    assertEquals(1, bs.readBits(8, true).byteValue());
    assertEquals(2, bs.readBits(8, true).byteValue());
  }
 
  @Test
  public void testWriteMarks() throws Exception {
    BitStream bs = new BitStream(2);
    bs.writeBits(BigInteger.ONE, 8);
    bs.setWriteMark();
    bs.writeBits(BigInteger.TEN, 8);
    assertEquals(Byte.SIZE * 2, bs.available());
    assertEquals(2, bs.bytes());
    byte[] data = bs.toByteArray();
    assertEquals(2, data.length);
    assertEquals(1, data[0]);
    assertEquals(10, data[1]);
    bs.goToWriteMark();
    bs.writeBits(BigInteger.ZERO, 8);
    assertEquals(Byte.SIZE * 2, bs.available());
    assertEquals(2, bs.bytes());
    data = bs.toByteArray();
    assertEquals(2, data.length);
    assertEquals(1, data[0]);
    assertEquals(0, data[1]);
    bs.clearWriteMark();
    bs.writeBits(BigInteger.TEN, 8);
    data = bs.toByteArray();
    assertEquals(3, data.length);
    assertEquals(Byte.SIZE * 3, bs.available());
    assertEquals(130, bs.bytes());
    bs.goToWriteFromBeginning();
    bs.writeBits(BigInteger.ZERO, 8);
    bs.writeBits(BigInteger.ZERO, 8);
    data = bs.toByteArray();
    assertEquals(0, data[0]);
    assertEquals(0, data[1]);
  }
 
  @Test
  public void testAlignWrite() throws Exception {
    BitStream bs = new BitStream(2);
    bs.writeBit(1);
    bs.alignWrite();
    bs.writeBit(1);
    byte[] data = bs.toByteArray();
    assertEquals(1, data[0]);
    assertEquals(1, data[1]);
    assertEquals(9, bs.available());
    assertEquals(2, bs.bytes());
  }
 
  @Test
  public void testAlignRead() throws Exception {
    BitStream bs = new BitStream(new byte[] { 1, 1 }, 0, Byte.SIZE * 2);
    assertEquals(1, bs.readBit());
    bs.alignRead();
    assertEquals(1, bs.readBit());
    assertEquals(7, bs.available());
    assertEquals(2, bs.bytes());
  }
 
  @Test
  public void testToByteArray() throws Exception {
    BitStream bs = new BitStream(2);
    bs.writeBits(BigInteger.valueOf(255), 8);
    bs.writeBits(BigInteger.valueOf(255), 8);
    byte[] data = bs.toByteArray();
    assertEquals(-1, data[0]);
    assertEquals(-1, data[1]);
    bs.readBits(4, true);
    data = bs.toByteArray();
    assertEquals(-1, data[0]);
    assertEquals(15, data[1]);
    assertEquals(12, bs.available());
    assertEquals(2, bs.bytes());
  }
 
  @Test
  public void testClear() throws Exception {
    BitStream bs = new BitStream(2);
    bs.writeBit(1);
    bs.alignRead();
    bs.writeBit(0);
    bs.writeBit(1);
    assertEquals(1, bs.readBit());
    bs.clear();
    assertEquals(-1, bs.readBit());
    assertEquals(0, bs.available());
    assertEquals(2, bs.bytes());
    bs.writeBit(1);
    byte[] data = bs.toByteArray();
    assertEquals(1, data[0]);
    assertEquals(1, bs.available());
    assertEquals(2, bs.bytes());
  }
 
  @Test
  public void testSkipWrite() throws Exception {
    BitStream bs0 = new BitStream(1);
    bs0.writeBit(1);
    bs0.alignWrite();
    bs0.writeBit(1);
    BitStream bs1 = new BitStream(1);
    bs1.writeBit(1);
    bs1.skipWrite(7);
    bs1.writeBit(1);
    byte[] data = new byte[] { 1, 1 };
    assertArrayEquals(data, bs0.toByteArray());
    assertArrayEquals(data, bs1.toByteArray());
   
    try {
      bs0.skipWrite(-1);
      fail();
    } catch (IllegalArgumentException ex) {
    }
  }
 
  @Test
  public void testSkipRead() throws Exception {
    byte[] data = new byte[] { 1, 1 };
    BitStream bs0 = new BitStream(data, 0, Byte.SIZE * data.length);
    BitStream bs1 = new BitStream(data, 0, Byte.SIZE * data.length);
    assertEquals(1, bs0.readBit());
    assertEquals(1, bs1.readBit());
    bs0.alignRead();
    bs1.skipRead(7);
    assertEquals(1, bs0.readBit());
    assertEquals(1, bs1.readBit());
    assertEquals(7, bs0.available());
    assertEquals(7, bs1.available());

    assertEquals(7, bs0.skipRead(7));
    assertEquals(0, bs0.available());
    assertEquals(0, bs0.skipRead(7));
   
    try {
      bs0.skipRead(-1);
      fail();
    } catch (IllegalArgumentException ex) {
    }
  }
}
TOP

Related Classes of com.peterhi.runtime.BitStreamTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.