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 }