github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/longbits/bit_reader_test.go (about)

     1  // Copyright 2020 Insolar Network Ltd.
     2  // All rights reserved.
     3  // This material is licensed under the Insolar License version 1.0,
     4  // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md.
     5  
     6  package longbits
     7  
     8  import (
     9  	"bytes"
    10  	"io"
    11  	"math/bits"
    12  	"testing"
    13  
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  var testSample = []byte{0xF4, 0x7F, 0x15, 0x01, 0x02, 0xFD, 0xFF, 0xFF}
    18  
    19  func copyBits(bytes []byte) []byte {
    20  	return append([]byte(nil), bytes...)
    21  }
    22  
    23  func reverseBits(bytes []byte) []byte {
    24  	r := make([]byte, len(bytes))
    25  	for i, v := range bytes {
    26  		r[i] = bits.Reverse8(v)
    27  	}
    28  	return r
    29  }
    30  
    31  func Test_BitReader_ReadByte(t *testing.T) {
    32  	bytes := copyBits(testSample)
    33  	br := NewBitArrayReader(LSB, bytes)
    34  	for _, b := range bytes {
    35  		require.False(t, br.IsArrayDepleted())
    36  		vb, err := br.ReadByte()
    37  		require.NoError(t, err)
    38  		require.Equal(t, b, vb)
    39  	}
    40  	require.True(t, br.IsArrayDepleted())
    41  
    42  	br = NewBitArrayReader(MSB, reverseBits(bytes))
    43  	for _, b := range bytes {
    44  		require.False(t, br.IsArrayDepleted())
    45  		vb, err := br.ReadByte()
    46  		require.NoError(t, err)
    47  		require.Equal(t, b, vb)
    48  	}
    49  	require.True(t, br.IsArrayDepleted())
    50  }
    51  
    52  func Test_BitStrReader_ReadByte(t *testing.T) {
    53  	bytes := copyBits(testSample)
    54  	br := NewBitStrReader(LSB, CopyBytes(bytes))
    55  	for _, b := range bytes {
    56  		require.False(t, br.IsArrayDepleted())
    57  		vb, err := br.ReadByte()
    58  		require.NoError(t, err)
    59  		require.Equal(t, b, vb)
    60  	}
    61  	require.True(t, br.IsArrayDepleted())
    62  
    63  	br = NewBitStrReader(MSB, CopyBytes(reverseBits(bytes)))
    64  	for _, b := range bytes {
    65  		require.False(t, br.IsArrayDepleted())
    66  		vb, err := br.ReadByte()
    67  		require.NoError(t, err)
    68  		require.Equal(t, b, vb)
    69  	}
    70  	require.True(t, br.IsArrayDepleted())
    71  }
    72  
    73  type testReader struct {
    74  	internal interface {
    75  		ReadBit() (int, error)
    76  		ReadByte() (byte, error)
    77  		ReadSubByte(bitLen uint8) (byte, error)
    78  	}
    79  }
    80  
    81  func (v testReader) ReadBit() int {
    82  	if r, err := v.internal.ReadBit(); err != nil {
    83  		panic(err)
    84  	} else {
    85  		return r
    86  	}
    87  }
    88  
    89  func (v testReader) ReadByte() byte {
    90  	if r, err := v.internal.ReadByte(); err != nil {
    91  		panic(err)
    92  	} else {
    93  		return r
    94  	}
    95  }
    96  
    97  func (v testReader) ReadSubByte(bitLen uint8) byte {
    98  	if r, err := v.internal.ReadSubByte(bitLen); err != nil {
    99  		panic(err)
   100  	} else {
   101  		return r
   102  	}
   103  }
   104  
   105  type arrayReader interface {
   106  	AlignOffset() uint8
   107  	IsArrayDepleted() bool
   108  }
   109  
   110  func (v testReader) IsArray() bool {
   111  	_, ok := v.internal.(arrayReader)
   112  	return ok
   113  }
   114  
   115  func (v testReader) testAlignOffset(t *testing.T, ofs uint8) {
   116  	if ar, ok := v.internal.(arrayReader); ok {
   117  		require.Equal(t, ofs, ar.AlignOffset())
   118  	}
   119  }
   120  
   121  func (v testReader) testArrayDepleted(t *testing.T, isDepleted bool) {
   122  	if ar, ok := v.internal.(arrayReader); ok {
   123  		if isDepleted {
   124  			require.True(t, ar.IsArrayDepleted())
   125  		} else {
   126  			require.False(t, ar.IsArrayDepleted())
   127  		}
   128  	}
   129  }
   130  
   131  func testBitReaderRead(t *testing.T, br testReader) {
   132  	br.testAlignOffset(t, 0)
   133  	require.Equal(t, 0, br.ReadBit())
   134  	br.testAlignOffset(t, 1)
   135  	require.Equal(t, 0, br.ReadBit())
   136  	br.testAlignOffset(t, 2)
   137  	require.Equal(t, 1, br.ReadBit())
   138  	br.testAlignOffset(t, 3)
   139  	require.Equal(t, 0, br.ReadBit())
   140  	br.testAlignOffset(t, 4)
   141  	require.Equal(t, 1, br.ReadBit())
   142  	br.testAlignOffset(t, 5)
   143  
   144  	require.Equal(t, byte(0xFF), br.ReadByte())
   145  	br.testAlignOffset(t, 5)
   146  	require.Equal(t, byte(0xAB), br.ReadByte())
   147  	br.testAlignOffset(t, 5)
   148  
   149  	require.Equal(t, 0, br.ReadBit())
   150  	br.testAlignOffset(t, 6)
   151  	require.Equal(t, 0, br.ReadBit())
   152  	br.testAlignOffset(t, 7)
   153  	require.Equal(t, 0, br.ReadBit())
   154  	br.testAlignOffset(t, 0)
   155  
   156  	require.Equal(t, byte(0x01), br.ReadByte())
   157  	require.Equal(t, byte(0x02), br.ReadByte())
   158  
   159  	require.Equal(t, byte(0xFD), br.ReadByte())
   160  	require.Equal(t, byte(0xFF), br.ReadByte())
   161  	require.Equal(t, byte(0xFF), br.ReadByte())
   162  
   163  	br.testArrayDepleted(t, true)
   164  	br.testAlignOffset(t, 0)
   165  }
   166  
   167  func testBitReaderReadSubByte(t *testing.T, br testReader) {
   168  	require.Equal(t, byte(0), br.ReadSubByte(0))
   169  	br.testAlignOffset(t, 0)
   170  
   171  	require.Equal(t, byte(0), br.ReadSubByte(1))
   172  	br.testAlignOffset(t, 1)
   173  
   174  	require.Equal(t, byte(2), br.ReadSubByte(2))
   175  	br.testAlignOffset(t, 3)
   176  
   177  	require.Equal(t, byte(0x7E), br.ReadSubByte(7))
   178  	br.testAlignOffset(t, 2)
   179  
   180  	require.Equal(t, byte(0x1F), br.ReadSubByte(6))
   181  	br.testAlignOffset(t, 0)
   182  
   183  	require.Equal(t, byte(0x15), br.ReadSubByte(7))
   184  
   185  	require.Equal(t, byte(0x02), br.ReadSubByte(7))
   186  	require.Equal(t, byte(0x08), br.ReadSubByte(7))
   187  	require.Equal(t, byte(0x68), br.ReadSubByte(7))
   188  	require.Equal(t, byte(0x7F), br.ReadSubByte(7))
   189  	require.Equal(t, byte(0x7F), br.ReadSubByte(7))
   190  	require.Equal(t, byte(0x3F), br.ReadSubByte(6))
   191  
   192  	br.testAlignOffset(t, 0)
   193  	br.testArrayDepleted(t, true)
   194  }
   195  
   196  func newByteReader(b []byte) io.ByteReader {
   197  	return bytes.NewReader(b)
   198  }
   199  
   200  func Test_BitReader_FirstLow_Read(t *testing.T) {
   201  	bytes := copyBits(testSample)
   202  	testBitReaderRead(t, testReader{NewBitIoReader(LSB, newByteReader(bytes))})
   203  	testBitReaderRead(t, testReader{NewBitArrayReader(LSB, bytes)})
   204  	testBitReaderRead(t, testReader{NewBitStrReader(LSB, CopyBytes(bytes))})
   205  	testBitReaderReadSubByte(t, testReader{NewBitIoReader(LSB, newByteReader(bytes))})
   206  	testBitReaderReadSubByte(t, testReader{NewBitArrayReader(LSB, bytes)})
   207  	testBitReaderReadSubByte(t, testReader{NewBitStrReader(LSB, CopyBytes(bytes))})
   208  }
   209  
   210  func testBitReaderReadSubByteCycle(t *testing.T, br testReader) {
   211  	for i := byte(0); i < 8; i++ {
   212  		require.Equal(t, i, br.ReadSubByte(3))
   213  	}
   214  }
   215  
   216  func Test_BitReader_FirstHigh_SubByte(t *testing.T) {
   217  	bytes := reverseBits([]byte{0x88, 0xC6, 0xFA})
   218  	testBitReaderReadSubByteCycle(t, testReader{NewBitIoReader(MSB, newByteReader(bytes))})
   219  	testBitReaderReadSubByteCycle(t, testReader{NewBitArrayReader(MSB, bytes)})
   220  	testBitReaderReadSubByteCycle(t, testReader{NewBitStrReader(MSB, CopyBytes(bytes))})
   221  }
   222  
   223  func Test_BitReader_FirstLow_SubByte(t *testing.T) {
   224  	bytes := []byte{0x88, 0xC6, 0xFA}
   225  	testBitReaderReadSubByteCycle(t, testReader{NewBitIoReader(LSB, newByteReader(bytes))})
   226  	testBitReaderReadSubByteCycle(t, testReader{NewBitArrayReader(LSB, bytes)})
   227  	testBitReaderReadSubByteCycle(t, testReader{NewBitStrReader(LSB, CopyBytes(bytes))})
   228  }