github.com/tunabay/go-bitarray@v1.3.1/buffer_copy_test.go (about)

     1  // Copyright (c) 2021 Hirotsuna Mizuno. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be found in
     3  // the LICENSE file.
     4  
     5  package bitarray_test
     6  
     7  import (
     8  	"bytes"
     9  	"testing"
    10  
    11  	"github.com/tunabay/go-bitarray"
    12  )
    13  
    14  func TestBuffer_CopyBitsFromBytes(t *testing.T) {
    15  	// (off int, b []byte, bOff, nBits int)
    16  	buf := bitarray.NewBuffer(30)
    17  	chk := func(wantS string) {
    18  		t.Helper()
    19  		buf.V()
    20  		got := buf.BitArray()
    21  		want := bitarray.MustParse(wantS)
    22  		if !got.Equal(want) {
    23  			t.Error("unexpected:")
    24  			t.Logf(" got: %#b", got)
    25  			t.Logf("want: %#b", want)
    26  			t.Logf(" buf: %s", buf.D())
    27  		}
    28  	}
    29  	chk("0000-0000 0000-0000 0000-0000 0000-00")
    30  	buf.CopyBitsFromBytes(0, []byte{}, 0, 0)
    31  	chk("0000-0000 0000-0000 0000-0000 0000-00")
    32  	buf.CopyBitsFromBytes(0, []byte{0xA5}, 0, 4)
    33  	chk("1010-0000 0000-0000 0000-0000 0000-00")
    34  	buf.CopyBitsFromBytes(4, []byte{0xA5}, 4, 4)
    35  	chk("1010-0101 0000-0000 0000-0000 0000-00")
    36  	buf.CopyBitsFromBytes(6, []byte{0x3c}, 2, 4)
    37  	chk("1010-0111 1100-0000 0000-0000 0000-00")
    38  	buf.CopyBitsFromBytes(8, []byte{0xFA, 0xAA, 0xAF}, 4, 16)
    39  	chk("1010-0111 1010-1010 1010-1010 0000-00")
    40  	buf.CopyBitsFromBytes(12, []byte{0xF5, 0x55, 0x5F}, 4, 17)
    41  	chk("1010-0111 1010-0101 0101-0101 0101-10")
    42  	buf.CopyBitsFromBytes(18, []byte{0x00, 0x00, 0xFF, 0xF0}, 16, 12)
    43  	chk("1010-0111 1010-0101 0111-1111 1111-11")
    44  	buf.CopyBitsFromBytes(29, []byte{0xFF, 0xFF, 0xFF, 0xFE}, 31, 1)
    45  	chk("1010-0111 1010-0101 0111-1111 1111-10")
    46  	buf.CopyBitsFromBytes(15, []byte{0xFF, 0xFF, 0x7F, 0xFF}, 16, 1)
    47  	chk("1010-0111 1010-0100 0111-1111 1111-10")
    48  	buf.CopyBitsFromBytes(30, nil, 0, 0)
    49  	chk("1010-0111 1010-0100 0111-1111 1111-10")
    50  	buf.CopyBitsFromBytes(0, nil, 0, 0)
    51  	chk("1010-0111 1010-0100 0111-1111 1111-10")
    52  	buf.CopyBitsFromBytes(16, []byte{0x88, 0x88}, 0, 14)
    53  	chk("1010-0111 1010-0100 1000-1000 1000-10")
    54  
    55  	chkpanic := func(off int, b []byte, bOff, nBits int) {
    56  		defer func() {
    57  			if recover() == nil {
    58  				t.Errorf("panic expected: off=%d, ba=%#b.", off, buf)
    59  			}
    60  		}()
    61  		buf.CopyBitsFromBytes(off, b, bOff, nBits)
    62  	}
    63  	chkpanic(-1, []byte{}, 0, 0)
    64  	chkpanic(31, []byte{}, 0, 0)
    65  	chkpanic(23, []byte{0}, 0, 8)
    66  	chkpanic(24, []byte{0}, 1, 7)
    67  	chkpanic(15, []byte{0, 0}, 0, 16)
    68  	chkpanic(16, []byte{0, 0}, 1, 15)
    69  	chkpanic(17, []byte{0, 0}, 2, 14)
    70  }
    71  
    72  func TestBuffer_CopyBitsToBytes(t *testing.T) {
    73  	bs := make([]byte, 4)
    74  	buf := bitarray.NewBuffer(30)
    75  	chk := func(wantB ...byte) {
    76  		t.Helper()
    77  		if !bytes.Equal(bs, wantB) {
    78  			t.Error("unexpected:")
    79  			t.Logf(" got: %08b", bs)
    80  			t.Logf("want: %08b", wantB)
    81  			t.Logf(" buf: %#b", buf)
    82  		}
    83  	}
    84  	buf.PutBitArrayAt(0, bitarray.MustParse("1010-1111 0101-1100 1000-1000 0000-01"))
    85  	buf.CopyBitsToBytes(0, bs, 0, 0)
    86  	chk(0b_0000_0000, 0b_0000_0000, 0b_0000_0000, 0b_0000_0000)
    87  	buf.CopyBitsToBytes(0, bs, 0, 30)
    88  	chk(0b_1010_1111, 0b_0101_1100, 0b_1000_1000, 0b_0000_0100)
    89  	buf.CopyBitsToBytes(24, bs, 0, 4)
    90  	chk(0b_0000_1111, 0b_0101_1100, 0b_1000_1000, 0b_0000_0100)
    91  	buf.CopyBitsToBytes(8, bs, 4, 4)
    92  	chk(0b_0000_0101, 0b_0101_1100, 0b_1000_1000, 0b_0000_0100)
    93  	buf.CopyBitsToBytes(0, bs, 10, 18)
    94  	chk(0b_0000_0101, 0b_0110_1011, 0b_1101_0111, 0b_0010_0100)
    95  	buf.CopyBitsToBytes(0, bs, 31, 1)
    96  	chk(0b_0000_0101, 0b_0110_1011, 0b_1101_0111, 0b_0010_0101)
    97  	buf.CopyBitsToBytes(29, bs, 0, 1)
    98  	chk(0b_1000_0101, 0b_0110_1011, 0b_1101_0111, 0b_0010_0101)
    99  	buf.CopyBitsToBytes(8, bs, 0, 16)
   100  	chk(0b_0101_1100, 0b_1000_1000, 0b_1101_0111, 0b_0010_0101)
   101  	buf.CopyBitsToBytes(5, bs, 10, 2)
   102  	chk(0b_0101_1100, 0b_1011_1000, 0b_1101_0111, 0b_0010_0101)
   103  
   104  	chkpanic := func(off int, b []byte, bOff, nBits int) {
   105  		defer func() {
   106  			if recover() == nil {
   107  				t.Errorf("panic expected: off=%d, ba=%#b.", off, buf)
   108  			}
   109  		}()
   110  		buf.CopyBitsToBytes(off, b, bOff, nBits)
   111  	}
   112  	chkpanic(-1, []byte{}, 0, 0)
   113  	chkpanic(31, []byte{}, 0, 0)
   114  	chkpanic(23, []byte{0}, 0, 8)
   115  	chkpanic(24, []byte{0}, 1, 7)
   116  	chkpanic(15, []byte{0, 0}, 0, 16)
   117  	chkpanic(16, []byte{0, 0}, 1, 15)
   118  	chkpanic(17, []byte{0, 0}, 2, 14)
   119  }
   120  
   121  func TestCopyBits(t *testing.T) {
   122  	tcs := []struct {
   123  		dst, src, res string
   124  		n             int
   125  	}{
   126  		{"0", "", "0", 0},
   127  		{"1", "", "1", 0},
   128  		{"0000-0000 0", "", "0000-0000 0", 0},
   129  		{"1111-1111 1", "", "1111-1111 1", 0},
   130  		{"", "1", "", 0},
   131  		{"", "1111-1111", "", 0},
   132  		{"0", "1", "1", 1},
   133  		{"1", "0", "0", 1},
   134  		{"0", "1000-0000 0", "1", 1},
   135  		{"1", "0111-1111 1", "0", 1},
   136  		{"0000-0000", "1", "1000-0000", 1},
   137  		{"1111-1111", "0", "0111-1111", 1},
   138  		{"0000-0000", "1111-1111", "1111-1111", 8},
   139  		{"1111-1111", "0000-0000", "0000-0000", 8},
   140  		{"0000-0000", "1111-1111 0000-00", "1111-1111", 8},
   141  		{"1111-1111", "0000-0000 1111-11", "0000-0000", 8},
   142  		{"0000-0000 0000-0000 0", "1", "1000-0000 0000-0000 0", 1},
   143  		{"1111-1111 1111-1111 1", "0", "0111-1111 1111-1111 1", 1},
   144  		{"0000-0000 0000-0000 0", "1111-1111 11", "1111-1111 1100-0000 0", 10},
   145  		{"1111-1111 1111-1111 1", "0000-0000 00", "0000-0000 0011-1111 1", 10},
   146  		{"0000-0000 0000-0000 0", "1111-1010 1010-1010 1111", "1111-1010 1010-1010 1", 17},
   147  		{"1111-1111 1111-1111 1", "0000-1010 1010-1010 0000", "0000-1010 1010-1010 0", 17},
   148  	}
   149  	for _, tc := range tcs {
   150  		dstb := bitarray.MustParse(tc.dst)
   151  		srcb := bitarray.MustParse(tc.src)
   152  		want := bitarray.MustParse(tc.res)
   153  		dst := bitarray.NewBufferFromBitArray(dstb)
   154  		src := bitarray.NewBufferFromBitArray(srcb)
   155  		n := bitarray.CopyBits(dst, src)
   156  		got := dst.BitArray()
   157  		if n != tc.n {
   158  			t.Errorf("unexpected n: got %d, want %d.", n, tc.n)
   159  		}
   160  		if !got.Equal(want) {
   161  			t.Errorf("unexpected result:")
   162  			t.Logf(" got: %#b", got)
   163  			t.Logf("want: %#b", want)
   164  		}
   165  		if t.Failed() {
   166  			t.Errorf("failed: CopyBits(%q, %q)", tc.dst, tc.src)
   167  			t.FailNow()
   168  		}
   169  	}
   170  }
   171  
   172  func TestCopyBitsN(t *testing.T) {
   173  	tcs := []struct {
   174  		dst, src, res string
   175  		n, w          int
   176  	}{
   177  		{"0", "", "0", 0, 0},
   178  		{"1", "", "1", 7, 0},
   179  		{"0000-0000 0", "", "0000-0000 0", 0, 0},
   180  		{"1111-1111 1", "", "1111-1111 1", 7, 0},
   181  		{"", "1", "", 0, 0},
   182  		{"", "1111-1111", "", 7, 0},
   183  		{"0", "1", "0", 0, 0},
   184  		{"0", "1", "1", 1, 1},
   185  		{"1", "0", "0", 7, 1},
   186  		{"0", "1000-0000 0", "1", 1, 1},
   187  		{"1", "0111-1111 1", "0", 7, 1},
   188  		{"0000-0000", "1", "1000-0000", 1, 1},
   189  		{"1111-1111", "0", "0111-1111", 9, 1},
   190  		{"0000-0000", "1111-1111", "1111-0000", 4, 4},
   191  		{"0000-0000", "1111-1111", "1111-1111", 99, 8},
   192  		{"1111-1111", "0000-0000", "0000-0001", 7, 7},
   193  		{"1111-1111", "0000-0000", "0000-0000", 8, 8},
   194  		{"0000-0000", "1111-1111 0000-00", "1110-0000", 3, 3},
   195  		{"0000-0000", "1111-1111 0000-00", "1111-1111", 10, 8},
   196  		{"0000-0000", "1111-1111 0000-00", "1111-1111", 99, 8},
   197  		{"1111-1111", "0000-0000 1111-11", "0000-0001", 7, 7},
   198  		{"1111-1111", "0000-0000 1111-11", "0000-0000", 8, 8},
   199  		{"1111-1111", "0000-0000 1111-11", "0000-0000", 10, 8},
   200  		{"0000-0000 0000-0000 0", "1", "1000-0000 0000-0000 0", 16, 1},
   201  		{"1111-1111 1111-1111 1", "0", "0111-1111 1111-1111 1", 32, 1},
   202  		{"0000-0000 0000-0000 0", "1111-1111 11", "1111-1100 0000-0000 0", 6, 6},
   203  		{"0000-0000 0000-0000 0", "1111-1111 11", "1111-1111 1100-0000 0", 16, 10},
   204  		{"1111-1111 1111-1111 1", "0000-0000 00", "0111-1111 1111-1111 1", 1, 1},
   205  		{"1111-1111 1111-1111 1", "0000-0000 00", "0000-0000 0011-1111 1", 99, 10},
   206  		{"0000-0000 0000-0000 0", "1111-1010 1010-1010 1111", "1111-1010 1010-0000 0", 12, 12},
   207  		{"0000-0000 0000-0000 0", "1111-1010 1010-1010 1111", "1111-1010 1010-1010 1", 17, 17},
   208  		{"1111-1111 1111-1111 1", "0000-1010 1010-1010 0000", "0000-1010 1010-1010 0", 32, 17},
   209  	}
   210  	for _, tc := range tcs {
   211  		dstb := bitarray.MustParse(tc.dst)
   212  		srcb := bitarray.MustParse(tc.src)
   213  		want := bitarray.MustParse(tc.res)
   214  		dst := bitarray.NewBufferFromBitArray(dstb)
   215  		src := bitarray.NewBufferFromBitArray(srcb)
   216  		n := bitarray.CopyBitsN(dst, src, tc.n)
   217  		got := dst.BitArray()
   218  		if n != tc.w {
   219  			t.Errorf("unexpected n: got %d, want %d.", n, tc.w)
   220  		}
   221  		if !got.Equal(want) {
   222  			t.Errorf("unexpected result:")
   223  			t.Logf(" got: %#b", got)
   224  			t.Logf("want: %#b", want)
   225  		}
   226  		if t.Failed() {
   227  			t.Errorf("failed: CopyBitsN(%q, %q, %d)", tc.dst, tc.src, tc.n)
   228  			t.FailNow()
   229  		}
   230  	}
   231  }
   232  
   233  func TestCopyBitsPartial(t *testing.T) {
   234  	tcs := []struct {
   235  		dst, src, res string
   236  		do, so, n, w  int
   237  	}{
   238  		{"0", "", "0", 0, 0, 0, 0},
   239  		{"1", "", "1", 0, 0, 7, 0},
   240  		{"0000-0000 0", "", "0000-0000 0", 0, 0, 0, 0},
   241  		{"0000-0000 0", "", "0000-0000 0", 8, 0, 0, 0},
   242  		{"1111-1111 1", "", "1111-1111 1", 3, 0, 7, 0},
   243  		{"", "1", "", 0, 0, 0, 0},
   244  		{"", "1111-1111", "", 0, 0, 7, 0},
   245  		{"0", "1", "0", 0, 0, 0, 0},
   246  		{"0", "00100", "1", 0, 2, 1, 1},
   247  		{"1", "1110", "0", 0, 3, 7, 1},
   248  		{"0", "1000-0000 0", "1", 0, 0, 1, 1},
   249  		{"0", "0000-0000 1", "1", 0, 8, 1, 1},
   250  		{"1", "0111-1111 1", "0", 0, 0, 7, 1},
   251  		{"1", "1111-1110 1", "0", 0, 7, 7, 1},
   252  		{"0000-0000", "1", "1000-0000", 0, 0, 1, 1},
   253  		{"0000-0000", "1", "0000-1000", 4, 0, 7, 1},
   254  		{"1111-1111", "0", "0111-1111", 0, 0, 9, 1},
   255  		{"1111-1111", "0", "1111-1110", 7, 0, 9, 1},
   256  		{"0000-0000", "1111-1111", "1111-0000", 0, 0, 4, 4},
   257  		{"0000-0000", "1111-1101", "0011-0100", 2, 4, 99, 4},
   258  		{"0000-0000", "1111-1111", "1111-1111", 0, 0, 99, 8},
   259  		{"0000-0000", "1101-1111", "0000-1101", 4, 0, 99, 4},
   260  		{"1111-1111", "0000-0000", "0000-0001", 0, 0, 7, 7},
   261  		{"1111-1111", "0000-0000", "0000-0000", 0, 0, 8, 8},
   262  		{"0000-0000", "1111-1111 0000-00", "1110-0000", 0, 0, 3, 3},
   263  		{"0000-0000", "1111-1111 0000-00", "1111-1111", 0, 0, 10, 8},
   264  		{"0000-0000", "1111-1111 0000-00", "1111-1111", 0, 0, 99, 8},
   265  		{"0000-0000", "1111-1111 0001-00", "1111-0001", 0, 4, 99, 8},
   266  		{"1111-1111", "0000-0000 1111-11", "0000-0001", 0, 0, 7, 7},
   267  		{"1111-1111", "0000-0000 1111-11", "0000-0000", 0, 0, 8, 8},
   268  		{"1111-1111", "0000-0000 1111-11", "0000-0000", 0, 0, 10, 8},
   269  		{"1111-1111", "0000-0000 1100-11", "1001-1001", 1, 6, 6, 6},
   270  		{"0000-0000 0000-0000 0", "1", "1000-0000 0000-0000 0", 0, 0, 16, 1},
   271  		{"0000-0000 0000-0000 0", "1", "0000-0000 0000-0000 1", 16, 0, 99, 1},
   272  		{"1111-1111 1111-1111 1", "0", "0111-1111 1111-1111 1", 0, 0, 32, 1},
   273  		{"1111-1111 1111-1111 1", "0", "1111-1111 1111-1110 1", 15, 0, 1, 1},
   274  		{"0000-0000 0000-0000 0", "1111-1111 11", "1111-1100 0000-0000 0", 0, 0, 6, 6},
   275  		{"0000-0000 0000-0000 0", "1111-1111 11", "1111-1111 1100-0000 0", 0, 0, 16, 10},
   276  		{"1111-1111 1111-1111 1", "0000-0000 00", "0111-1111 1111-1111 1", 0, 0, 1, 1},
   277  		{"1111-1111 1111-1111 1", "0000-0000 00", "0000-0000 0011-1111 1", 0, 0, 99, 10},
   278  		{"0000-0000 0000-0000 0", "1111-1010 1010-1010 1111", "1111-1010 1010-0000 0", 0, 0, 12, 12},
   279  		{"0000-0000 0000-0000 0", "1111-1010 1010-1010 1111", "1111-1010 1010-1010 1", 0, 0, 17, 17},
   280  		{"1111-1111 1111-1111 1", "0000-1010 1010-1010 0000", "0000-1010 1010-1010 0", 0, 0, 32, 17},
   281  	}
   282  	for _, tc := range tcs {
   283  		dstb := bitarray.MustParse(tc.dst)
   284  		srcb := bitarray.MustParse(tc.src)
   285  		want := bitarray.MustParse(tc.res)
   286  		dst := bitarray.NewBufferFromBitArray(dstb)
   287  		src := bitarray.NewBufferFromBitArray(srcb)
   288  		n := bitarray.CopyBitsPartial(dst, src, tc.do, tc.so, tc.n)
   289  		got := dst.BitArray()
   290  		if n != tc.w {
   291  			t.Errorf("unexpected n: got %d, want %d.", n, tc.w)
   292  		}
   293  		if !got.Equal(want) {
   294  			t.Errorf("unexpected result:")
   295  			t.Logf(" got: %#b", got)
   296  			t.Logf("want: %#b", want)
   297  		}
   298  		if t.Failed() {
   299  			t.Errorf("failed: CopyBitsPartial(%q, %q, %d, %d, %d)", tc.dst, tc.src, tc.do, tc.so, tc.n)
   300  			t.FailNow()
   301  		}
   302  	}
   303  }