From b2f12c39dd61e6f2593eca6302dd669070353e96 Mon Sep 17 00:00:00 2001 From: Romain Lespinasse Date: Sun, 29 Oct 2017 18:52:16 +0100 Subject: [PATCH] Refactoring functions usage --- bits.go | 18 ++ bits_test.go | 78 +++++++++ byteitem.go | 50 ------ byteitem_test.go | 292 --------------------------------- byteslice.go | 162 +++++++++--------- byteslice_bigendian.go | 98 +++++------ byteslice_bigendian_test.go | 183 ++++++++------------- byteslice_littleendian.go | 97 +++++------ byteslice_littleendian_test.go | 183 ++++++++------------- byteslice_test.go | 228 +++++++++++++------------ 10 files changed, 525 insertions(+), 864 deletions(-) create mode 100644 bits.go create mode 100644 bits_test.go delete mode 100644 byteitem.go delete mode 100644 byteitem_test.go diff --git a/bits.go b/bits.go new file mode 100644 index 0000000..727ee1d --- /dev/null +++ b/bits.go @@ -0,0 +1,18 @@ +package byteslice + +const ( + maxBitsLength = 8 + maxLeastSignificantBit = 0 + maxMostSignificantBit = maxBitsLength - 1 +) + +// RBitState get the state of a specific bit of the little endian ordered data byte. +func RBitState(data byte, bit uint8) byte { + return (data >> bit & 0x01) << bit +} + +// RBitsSubset get the byte value of a subset of the little endian ordered data byte defined +// by the least significant bit and the most significant bit. +func RBitsSubset(data byte, leastSignificantBit, mostSignificantBit uint8) byte { + return data << (maxMostSignificantBit - mostSignificantBit) >> (maxMostSignificantBit + leastSignificantBit - mostSignificantBit) +} diff --git a/bits_test.go b/bits_test.go new file mode 100644 index 0000000..f68c422 --- /dev/null +++ b/bits_test.go @@ -0,0 +1,78 @@ +package byteslice + +import ( + "testing" +) + +var tcRBitState = []struct { + name string + data byte + bit uint8 + result byte +}{ + {"get low bit of high nibble", 0xf0, 4, 0x10}, + {"get low bit", 0xf0, 0, 0}, +} + +func TestRBitState(t *testing.T) { + var val byte + for _, tc := range tcRBitState { + t.Run(tc.name, func(t *testing.T) { + val = RBitState(tc.data, tc.bit) + if val != (tc.result) { + t.Errorf("RBitState(%x, %v) was %x, should be %x", + tc.data, tc.bit, + val, + tc.result) + } + }) + } +} + +func BenchmarkRBitState(b *testing.B) { + var val byte + for _, tc := range tcRBitState { + b.Run(tc.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + val = RBitState(tc.data, tc.bit) + } + }) + } +} + +var tcRBitsSubset = []struct { + name string + data byte + leastSignificantBit, mostSignificantBit uint8 + result byte +}{ + {"get bottom 3 bits", 0xf2, 0, 2, 0x02}, + {"get low bit", 0xf0, 0, 0, 0x00}, + {"lsb and msb out of order", 0xf0, 2, 0, 0x00}, +} + +func TestRBitsSubset(t *testing.T) { + var val byte + for _, tc := range tcRBitsSubset { + t.Run(tc.name, func(t *testing.T) { + val = RBitsSubset(tc.data, tc.leastSignificantBit, tc.mostSignificantBit) + if val != tc.result { + t.Errorf("RBitsSubset(%x, %v, %v) was %x, should be %x", + tc.data, tc.leastSignificantBit, tc.mostSignificantBit, + val, + tc.result) + } + }) + } +} + +func BenchmarkRBitsSubset(b *testing.B) { + var val byte + for _, tc := range tcRBitsSubset { + b.Run(tc.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + val = RBitsSubset(tc.data, tc.leastSignificantBit, tc.mostSignificantBit) + } + }) + } +} diff --git a/byteitem.go b/byteitem.go deleted file mode 100644 index dfb2a24..0000000 --- a/byteitem.go +++ /dev/null @@ -1,50 +0,0 @@ -package byteslice - -const ( - byteLength = 8 - lsb = 0 - msb = byteLength - 1 -) - -// ByteItem attaches the methods of Interface to byte -type ByteItem byte - -// ContainsBit test if a bit is contains in the data -func (data ByteItem) ContainsBit(bit uint8) bool { - return data.Contains(ByteItem(0x00).SetBit(bit)) -} - -// Contains test if some bits is contains in a data -func (data ByteItem) Contains(bits ByteItem) bool { - return data&bits == bits -} - -// SetBit change the bit of the data to 1 -func (data ByteItem) SetBit(bit uint8) ByteItem { - return data.Set(0x01 << bit) -} - -// Set affect the bits to a data -func (data ByteItem) Set(bits ByteItem) ByteItem { - return data | bits -} - -// UnsetBit change the bit of the data to 0 -func (data ByteItem) UnsetBit(bit uint8) ByteItem { - return data.Unset(0x01 << bit) -} - -// Unset unaffect the bits to a data -func (data ByteItem) Unset(bits ByteItem) ByteItem { - return data &^ bits -} - -// GetBit get the bit value from position -func (data ByteItem) GetBit(bit uint8) ByteItem { - return (data >> bit & 0x01) << bit -} - -// Subset get a byte as subset of another byte -func (data ByteItem) Subset(lsbPosition, msbPosition uint8) ByteItem { - return data << (msb - msbPosition) >> (msb + lsbPosition - msbPosition) -} diff --git a/byteitem_test.go b/byteitem_test.go deleted file mode 100644 index 53d2be9..0000000 --- a/byteitem_test.go +++ /dev/null @@ -1,292 +0,0 @@ -package byteslice - -import ( - "testing" -) - -var testcasesByteItemContainsBit = []struct { - name string - data byte - bit uint8 - result bool -}{ - {"hi in hi", 0xf0, 5, true}, - {"lo in hi", 0xf0, 2, false}, -} - -func TestByteItemContainsBit(t *testing.T) { - var val bool - for _, tc := range testcasesByteItemContainsBit { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).ContainsBit(tc.bit) - if val != tc.result { - t.Errorf("ByteItem(%x).ContainsBit(%v) was %v, should be %v", - tc.data, tc.bit, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemContainsBit(b *testing.B) { - var val bool - for _, tc := range testcasesByteItemContainsBit { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).ContainsBit(tc.bit) - } - }) - } -} - -var testcasesByteItemContainsBits = []struct { - name string - data, bits byte - result bool -}{ - {"low in hi", 0xf0, 0x05, false}, - {"hi in hi", 0xf0, 0x20, true}, - {"split", 0xf0, 0x22, false}, -} - -func TestByteItemContains(t *testing.T) { - var val bool - for _, tc := range testcasesByteItemContainsBits { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).Contains(ByteItem(tc.bits)) - if val != tc.result { - t.Errorf("ByteItem(%x).Contains(%x) was %v, should be %v", - tc.data, tc.bits, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemContains(b *testing.B) { - var val bool - for _, tc := range testcasesByteItemContainsBits { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).Contains(ByteItem(tc.bits)) - } - }) - } -} - -var testcasesByteItemSetBit = []struct { - name string - data byte - bit uint8 - result byte -}{ - {"set low bit", 0xf0, 0, 0xf1}, - {"set already-set bit", 0xf0, 5, 0xf0}, -} - -func TestByteItemSetBit(t *testing.T) { - var val ByteItem - for _, tc := range testcasesByteItemSetBit { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).SetBit(tc.bit) - if val != ByteItem(tc.result) { - t.Errorf("ByteItem(%x).SetBit(%v) was %x, should be %x", - tc.data, tc.bit, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemSetBit(b *testing.B) { - var val ByteItem - for _, tc := range testcasesByteItemSetBit { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).SetBit(tc.bit) - } - }) - } -} - -var testcasesByteItemSetBits = []struct { - name string - data, bits byte - result byte -}{ - {"set low bit", 0xf0, 0x00, 0xf0}, - {"high and low", 0xf0, 0x11, 0xf1}, -} - -func TestByteItemSet(t *testing.T) { - var val ByteItem - for _, tc := range testcasesByteItemSetBits { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).Set(ByteItem(tc.bits)) - if val != ByteItem(tc.result) { - t.Errorf("ByteItem(%x).Set(%x) was %x, should be %x", - tc.data, tc.bits, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemSet(b *testing.B) { - var val ByteItem - for _, tc := range testcasesByteItemSetBits { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).Set(ByteItem(tc.bits)) - } - }) - } -} - -var testcasesByteItemUnsetBit = []struct { - name string - data byte - bit uint8 - result byte -}{ - {"unset high bit", 0xf0, 7, 0x70}, - {"unset already-clear bit", 0xf0, 0, 0xf0}, -} - -func TestByteItemUnsetBit(t *testing.T) { - var val ByteItem - for _, tc := range testcasesByteItemUnsetBit { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).UnsetBit(tc.bit) - if val != ByteItem(tc.result) { - t.Errorf("ByteItem(%x).UnsetBit(%v) was %x, should be %x", - tc.data, tc.bit, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemUnsetBit(b *testing.B) { - var val ByteItem - for _, tc := range testcasesByteItemUnsetBit { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).UnsetBit(tc.bit) - } - }) - } -} - -var testcasesByteItemUnsetBits = []struct { - name string - data, bits byte - result byte -}{ - {"unset zero bit", 0xf0, 0x07, 0xf0}, - {"unset some bits", 0xf0, 0x11, 0xe0}, -} - -func TestByteItemUnset(t *testing.T) { - var val ByteItem - for _, tc := range testcasesByteItemUnsetBits { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).Unset(ByteItem(tc.bits)) - if val != ByteItem(tc.result) { - t.Errorf("ByteItem(%x).Unset(%x) was %x, should be %x", - tc.data, tc.bits, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemUnset(b *testing.B) { - var val ByteItem - for _, tc := range testcasesByteItemUnsetBits { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).Unset(ByteItem(tc.bits)) - } - }) - } -} - -var testcasesByteItemGetBit = []struct { - name string - data byte - bit uint8 - result byte -}{ - {"get low bit of high nibble", 0xf0, 4, 0x10}, - {"get low bit", 0xf0, 0, 0}, -} - -func TestByteItemGetBit(t *testing.T) { - var val ByteItem - for _, tc := range testcasesByteItemGetBit { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).GetBit(tc.bit) - if val != ByteItem(tc.result) { - t.Errorf("ByteItem(%x).GetBit(%v) was %x, should be %x", - tc.data, tc.bit, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemGetBit(b *testing.B) { - var val ByteItem - for _, tc := range testcasesByteItemGetBit { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).GetBit(tc.bit) - } - }) - } -} - -var testcasesByteItemSubsetBits = []struct { - name string - data byte - lsbPosition, msbPosition uint8 - result byte -}{ - {"get bottom 3 bits", 0xf2, 0, 2, 0x02}, - {"get low bit", 0xf0, 0, 0, 0x00}, - {"lsb and msb out of order", 0xf0, 2, 0, 0x00}, -} - -func TestByteItemSubset(t *testing.T) { - var val ByteItem - for _, tc := range testcasesByteItemSubsetBits { - t.Run(tc.name, func(t *testing.T) { - val = ByteItem(tc.data).Subset(tc.lsbPosition, tc.msbPosition) - if val != ByteItem(tc.result) { - t.Errorf("ByteItem(%x).Subset(%v, %v) was %x, should be %x", - tc.data, tc.lsbPosition, tc.msbPosition, - val, - tc.result) - } - }) - } -} - -func BenchmarkByteItemSubset(b *testing.B) { - var val ByteItem - for _, tc := range testcasesByteItemSubsetBits { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = ByteItem(tc.data).Subset(tc.lsbPosition, tc.msbPosition) - } - }) - } -} diff --git a/byteslice.go b/byteslice.go index 8d7a831..04077c3 100644 --- a/byteslice.go +++ b/byteslice.go @@ -5,34 +5,36 @@ import ( "math" ) -// ByteSlice attaches the methods of Interface to []byte without specific ordering -type ByteSlice []byte - -// Reverse reverse the byte slice -func (data ByteSlice) Reverse() ByteSlice { - var sliceLength = len(data) - var reversedSlice = make(ByteSlice, sliceLength) +// Reverse change the order of the byte slice. +func Reverse(data []byte) []byte { + if len(data) < 2 { + return data + } + sliceLength := len(data) + sliceHalfLength := int(math.Floor(float64(sliceLength / 2))) + reversedSlice := make([]byte, sliceLength) - for i := range data { - reversedSlice[sliceLength-i-1] = data[i] + for i := 0; i <= sliceHalfLength; i++ { + reversedSlice[i] = data[sliceLength-1-i] + reversedSlice[sliceLength-1-i] = data[i] } return reversedSlice } -// LeftShift apply left shift operation to byte array data -func (data ByteSlice) LeftShift(shift uint64) ByteSlice { +// LShift apply left shift operation to an byte slice. +func LShift(data []byte, shift uint64) []byte { if shift == 0 { return data } - var dataLength = len(data) - result := make(ByteSlice, dataLength) - if shift > byteLength { + dataLength := len(data) + result := make([]byte, dataLength) + if shift > maxBitsLength { copy(result, data[1:]) - result = ByteSlice(result).LeftShift(shift - byteLength) + result = LShift(result, shift-maxBitsLength) } else { for i := dataLength - 1; i >= 0; i-- { if i > 0 { - result[i-1] = data[i] >> (byteLength - shift) + result[i-1] = data[i] >> (maxBitsLength - shift) } result[i] = result[i] | (data[i] << shift) } @@ -40,20 +42,20 @@ func (data ByteSlice) LeftShift(shift uint64) ByteSlice { return result } -// RightShift apply right shift operation to byte array data -func (data ByteSlice) RightShift(shift uint64) ByteSlice { +// RShift apply right shift operation to an byte slice. +func RShift(data []byte, shift uint64) []byte { if shift == 0 { return data } - var dataLength = len(data) - result := make(ByteSlice, dataLength) - if shift > byteLength { - var shiftedData = append(make(ByteSlice, 1), data[:dataLength-1]...) - result = ByteSlice(shiftedData).RightShift(shift - byteLength) + dataLength := len(data) + result := make([]byte, dataLength) + if shift > maxBitsLength { + shiftedData := append(make([]byte, 1), data[:dataLength-1]...) + result = RShift(shiftedData, shift-maxBitsLength) } else { for i := 0; i < dataLength; i++ { if i < dataLength-1 { - result[i+1] = data[i] << (byteLength - shift) + result[i+1] = data[i] << (maxBitsLength - shift) } result[i] = result[i] | (data[i] >> shift) } @@ -61,88 +63,90 @@ func (data ByteSlice) RightShift(shift uint64) ByteSlice { return result } -// Mask apply AND mask to a byte array, data and mask must have the same size -func (data ByteSlice) Mask(mask ByteSlice) (ByteSlice, error) { - var dataLength = len(data) - var maskLength = len(mask) - if dataLength != maskLength { - return nil, errors.New("data and mask must have the same size") +// LPad pads the left-side of a byte slice with a filler byte. +func LPad(data []byte, length int, filler byte) []byte { + dataLength := len(data) + if length < 1 || length <= dataLength { + return data + } + result := make([]byte, length-dataLength) + for i := range result { + result[i] = filler } + result = append(result, data...) + return result +} - result := make(ByteSlice, dataLength) - for i := 0; i < dataLength; i++ { - result[i] = data[i] & mask[i] +// RPad pads the right-side of a byte slice with a filler byte. +func RPad(data []byte, length int, filler byte) []byte { + dataLength := len(data) + if length < 1 || length <= dataLength { + return data } - return result, nil + result := make([]byte, length-dataLength) + for i := range result { + result[i] = filler + } + result = append(data, result...) + return result } -// InclusiveMerge apply OR operation on two byte arrays (must have the same size) -func (data ByteSlice) InclusiveMerge(anotherData ByteSlice) (ByteSlice, error) { +// Unset apply AND operation on a byte slice with an "unset" byte slice (must have the same size). +func Unset(data, unsetData []byte) ([]byte, error) { var dataLength = len(data) - var anotherDataLength = len(anotherData) - if dataLength != anotherDataLength { - return nil, errors.New("data and anotherData must have the same size") + var unsetDataLength = len(unsetData) + if dataLength != unsetDataLength { + return nil, errors.New("data and unsetData must have the same size") } - result := make(ByteSlice, dataLength) + result := make([]byte, dataLength) for i := 0; i < dataLength; i++ { - result[i] = data[i] | anotherData[i] + result[i] = data[i] & unsetData[i] } return result, nil } -// ExclusiveMerge apply XOR operation on two byte arrays (must have the same size) -func (data ByteSlice) ExclusiveMerge(anotherData ByteSlice) (ByteSlice, error) { - var dataLength = len(data) - var anotherDataLength = len(anotherData) - if dataLength != anotherDataLength { - return nil, errors.New("data and anotherData must have the same size") +// Set apply OR operation on a byte slice with an "set" byte slice (must have the same size). +func Set(data, setData []byte) ([]byte, error) { + dataLength := len(data) + setDataLength := len(setData) + if dataLength != setDataLength { + return nil, errors.New("data and setData must have the same size") } - result := make(ByteSlice, dataLength) + result := make([]byte, dataLength) for i := 0; i < dataLength; i++ { - result[i] = data[i] ^ anotherData[i] + result[i] = data[i] | setData[i] } return result, nil } -// Not apply NOT operation to byte array -func (data ByteSlice) Not() ByteSlice { - var dataLength = len(data) - result := make(ByteSlice, dataLength) - for i := 0; i < dataLength; i++ { - result[i] = ^data[i] +// Toogle apply XOR operation on a byte slice with an "toogle" byte slice (must have the same size). +func Toogle(data, toogleData []byte) ([]byte, error) { + dataLength := len(data) + toogleDataLength := len(toogleData) + if dataLength != toogleDataLength { + return nil, errors.New("data and toogleData must have the same size") } - return result -} -func (data ByteSlice) leftPad(length int, filler byte) ByteSlice { - var dataLength = len(data) - if length < 1 || length <= dataLength { - return data - } - var result = make(ByteSlice, length-dataLength, length) - for i := range result { - result[i] = filler + result := make([]byte, dataLength) + for i := 0; i < dataLength; i++ { + result[i] = data[i] ^ toogleData[i] } - result = append(result, data...) - return result + return result, nil } -func (data ByteSlice) rightPad(length int, filler byte) ByteSlice { - var dataLength = len(data) - if length < 1 || length <= dataLength { - return data - } - var result = make(ByteSlice, length-dataLength, length) - for i := range result { - result[i] = filler +// Flip apply NOT operation to a byte slice to flip it. +func Flip(data []byte) []byte { + dataLength := len(data) + result := make([]byte, dataLength) + for i := 0; i < dataLength; i++ { + result[i] = ^data[i] } - result = append(data, result...) return result } -func computeSize(lsbPosition, msbPosition uint64) uint64 { - var byteCount = float64(msbPosition-lsbPosition) / float64(byteLength) - return uint64(math.Ceil(byteCount)) +func computeSize(leastSignificantBit, mostSignificantBit uint64) uint64 { + count := float64(mostSignificantBit-leastSignificantBit) / float64(maxBitsLength) + return uint64(math.Ceil(count)) } diff --git a/byteslice_bigendian.go b/byteslice_bigendian.go index 4853d68..c695354 100644 --- a/byteslice_bigendian.go +++ b/byteslice_bigendian.go @@ -1,86 +1,68 @@ package byteslice -// BigEndianByteSlice is a ByteSlice who are big endian ordered -type BigEndianByteSlice ByteSlice - -// Mask apply AND mask on the slice -func (data BigEndianByteSlice) Mask(mask BigEndianByteSlice) BigEndianByteSlice { +// LUnset apply AND operation on a byte slice with an "unset" byte slice using big endian order. +func LUnset(data, unsetData []byte) []byte { var dataLength = len(data) if dataLength < 1 { return data } - var maskLength = len(mask) - var operationLength = dataLength - var operationCut = dataLength - if maskLength > dataLength { - operationLength = maskLength + unsetDataLength := len(unsetData) + operationLength := dataLength + operationCut := dataLength + if unsetDataLength > dataLength { + operationLength = unsetDataLength } - result, _ := ByteSlice(ByteSlice(data).rightPad(operationLength, 0xFF)).Mask(ByteSlice(mask).rightPad(operationLength, 0xFF)) - return BigEndianByteSlice(result).newSize(operationCut) + result, _ := Unset(RPad(data, operationLength, 0xFF), RPad(unsetData, operationLength, 0xFF)) + return result[:operationCut] } -func (data BigEndianByteSlice) newSize(newSize int) BigEndianByteSlice { - return []byte(data)[:newSize] -} +// LSet apply OR operation on a byte slice with an "set" byte slice using big endian order. +func LSet(data, setData []byte) []byte { + dataLength := len(data) + setDataLength := len(setData) -// InclusiveMerge apply OR operation between this slice and another -func (data BigEndianByteSlice) InclusiveMerge(anotherData BigEndianByteSlice) BigEndianByteSlice { - var dataLength = len(data) - var anotherDataLength = len(anotherData) - - var operationLength = dataLength - if anotherDataLength > dataLength { - operationLength = anotherDataLength + operationLength := dataLength + if setDataLength > dataLength { + operationLength = setDataLength } - result, _ := ByteSlice(ByteSlice(data).rightPad(operationLength, 0x00)).InclusiveMerge(ByteSlice(anotherData).rightPad(operationLength, 0x00)) - return BigEndianByteSlice(result) + result, _ := Set(RPad(data, operationLength, 0x00), RPad(setData, operationLength, 0x00)) + return result } -// ExclusiveMerge apply XOR operation between this slice and another -func (data BigEndianByteSlice) ExclusiveMerge(anotherData BigEndianByteSlice) BigEndianByteSlice { - var dataLength = len(data) - var anotherDataLength = len(anotherData) +// LToogle apply XOR operation on a byte slice with an "toogle" byte slice using big endian order. +func LToogle(data, toogleData []byte) []byte { + dataLength := len(data) + toogleDataLength := len(toogleData) - var operationLength = dataLength - if anotherDataLength > dataLength { - operationLength = anotherDataLength + operationLength := dataLength + if toogleDataLength > dataLength { + operationLength = toogleDataLength } - result, _ := ByteSlice(ByteSlice(data).rightPad(operationLength, 0x00)).ExclusiveMerge(ByteSlice(anotherData).rightPad(operationLength, 0x00)) - - return BigEndianByteSlice(result) + result, _ := Toogle(RPad(data, operationLength, 0x00), RPad(toogleData, operationLength, 0x00)) + return result } -// Subset extract a subset of this slice -func (data BigEndianByteSlice) Subset(lsbPosition, msbPosition uint64) BigEndianByteSlice { - var maxMsb = uint64(byteLength*len(data) - 1) +// LSubset get the byte slice of a subset of the big endian ordered data byte defined +// by the least significant bit and the most significant bit. +func LSubset(data []byte, leastSignificantBit, mostSignificantBit uint64) []byte { + var maxDataMostSignificantBit = uint64(maxBitsLength*len(data) - 1) - if msbPosition <= lsbPosition || lsbPosition > maxMsb { - return make(BigEndianByteSlice, 0) + if mostSignificantBit <= leastSignificantBit || leastSignificantBit > maxDataMostSignificantBit { + return make([]byte, 0) } - if msbPosition > maxMsb { - msbPosition = maxMsb + if mostSignificantBit > maxDataMostSignificantBit { + mostSignificantBit = maxDataMostSignificantBit } - var result = ByteSlice(data).RightShift(maxMsb - msbPosition) - var correctiveShift = maxMsb - msbPosition + lsbPosition - result = ByteSlice(result).LeftShift(correctiveShift) - - var size = computeSize(lsbPosition, msbPosition) - return BigEndianByteSlice(result).trim(size) -} - -// LittleEndianSubset get a byte array as subset of another byte array when byte are in little endian -func (data BigEndianByteSlice) LittleEndianSubset(lsbPosition, msbPosition uint64) BigEndianByteSlice { - var reversedData = ByteSlice(data).Reverse() - var result = LittleEndianByteSlice(reversedData).Subset(lsbPosition, msbPosition) - return BigEndianByteSlice(ByteSlice(result).Reverse()) -} + var result = RShift(data, maxDataMostSignificantBit-mostSignificantBit) + var correctiveShift = maxDataMostSignificantBit - mostSignificantBit + leastSignificantBit + result = LShift(result, correctiveShift) -func (data BigEndianByteSlice) trim(newSize uint64) BigEndianByteSlice { - return data[:newSize] + var size = computeSize(leastSignificantBit, mostSignificantBit) + return result[:size] } diff --git a/byteslice_bigendian_test.go b/byteslice_bigendian_test.go index 30d5742..f3dd9bc 100644 --- a/byteslice_bigendian_test.go +++ b/byteslice_bigendian_test.go @@ -5,28 +5,28 @@ import ( "testing" ) -var testcasesBigEndianByteSliceMask = []struct { - name string - data []byte - mask []byte - result []byte +var tcLUnset = []struct { + name string + data []byte + unsetData []byte + result []byte }{ - {"data and mask of equal length", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x88, 0x11, 0xAA}}, - {"data shorter than mask", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB, 0x88, 0x11, 0xAA}, []byte{0x88, 0x11, 0xAA}}, - {"data longer than mask", []byte{0xAD, 0x11, 0xAB, 0x88, 0x11, 0xAA}, []byte{0xDA, 0x99, 0xBA}, []byte{0x88, 0x11, 0xAA, 0x88, 0x11, 0xAA}}, - {"empty mask on data", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, - {"mask on empty data", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{}}, - {"empty mask on empty data", []byte{}, []byte{}, []byte{}}, + {"data and unsetData of equal length", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x88, 0x11, 0xAA}}, + {"data shorter than unsetData", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB, 0x88, 0x11, 0xAA}, []byte{0x88, 0x11, 0xAA}}, + {"data longer than unsetData", []byte{0xAD, 0x11, 0xAB, 0x88, 0x11, 0xAA}, []byte{0xDA, 0x99, 0xBA}, []byte{0x88, 0x11, 0xAA, 0x88, 0x11, 0xAA}}, + {"empty unsetData on data", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, + {"unsetData on empty data", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{}}, + {"empty unsetData on empty data", []byte{}, []byte{}, []byte{}}, } -func TestBigEndianByteSliceMask(t *testing.T) { +func TestLUnset(t *testing.T) { var val []byte - for _, tc := range testcasesBigEndianByteSliceMask { + for _, tc := range tcLUnset { t.Run(tc.name, func(t *testing.T) { - val = BigEndianByteSlice(tc.data).Mask(tc.mask) + val = LUnset(tc.data, tc.unsetData) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("BigEndianByteSlice(%x).Mask(%x) was %x, should be %x", - tc.data, tc.mask, + t.Errorf("LUnset(%x, %x) was %x, should be %x", + tc.data, tc.unsetData, val, tc.result) } @@ -34,39 +34,39 @@ func TestBigEndianByteSliceMask(t *testing.T) { } } -func BenchmarkBigEndianByteSliceMask(b *testing.B) { +func BenchmarkLUnset(b *testing.B) { var val []byte - for _, tc := range testcasesBigEndianByteSliceMask { + for _, tc := range tcLUnset { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = BigEndianByteSlice(tc.data).Mask(tc.mask) + val = LUnset(tc.data, tc.unsetData) } }) } } -var testcasesBigEndianByteSliceInclusiveMerge = []struct { - name string - data []byte - anotherData []byte - result []byte +var tcLSet = []struct { + name string + data []byte + setData []byte + result []byte }{ - {"equal length arrays", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0xFF, 0x99, 0xBB}}, - {"first array longer", []byte{0xAD, 0x11, 0xAB, 0xFF, 0x99, 0xBB}, []byte{0xDA, 0x99, 0xBA}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, - {"second array longer", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB, 0xFF, 0x99, 0xBB}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, - {"first array empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, - {"second array empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, - {"empty arrays", []byte{}, []byte{}, []byte{}}, + {"equal length slices", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0xFF, 0x99, 0xBB}}, + {"data longer", []byte{0xAD, 0x11, 0xAB, 0xFF, 0x99, 0xBB}, []byte{0xDA, 0x99, 0xBA}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, + {"setData longer", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB, 0xFF, 0x99, 0xBB}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, + {"data empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, + {"setData empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, + {"empty slices", []byte{}, []byte{}, []byte{}}, } -func TestBigEndianByteSliceInclusiveMerge(t *testing.T) { +func TestLSet(t *testing.T) { var val []byte - for _, tc := range testcasesBigEndianByteSliceInclusiveMerge { + for _, tc := range tcLSet { t.Run(tc.name, func(t *testing.T) { - val = BigEndianByteSlice(tc.data).InclusiveMerge(tc.anotherData) + val = LSet(tc.data, tc.setData) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("BigEndianByteSlice(%x).InclusiveMerge(%x) was %x, should be %x", - tc.data, tc.anotherData, + t.Errorf("LSet(%x, %x) was %x, should be %x", + tc.data, tc.setData, val, tc.result) } @@ -74,39 +74,39 @@ func TestBigEndianByteSliceInclusiveMerge(t *testing.T) { } } -func BenchmarkBigEndianByteSliceInclusiveMerge(b *testing.B) { +func BenchmarkLSet(b *testing.B) { var val []byte - for _, tc := range testcasesBigEndianByteSliceInclusiveMerge { + for _, tc := range tcLSet { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = BigEndianByteSlice(tc.data).InclusiveMerge(tc.anotherData) + val = LSet(tc.data, tc.setData) } }) } } -var testcasesBigEndianByteSliceExclusiveMerge = []struct { - name string - data []byte - anotherData []byte - result []byte +var tcLToogle = []struct { + name string + data []byte + toogleData []byte + result []byte }{ - {"equal length arrays", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x77, 0x88, 0x11}}, - {"first array longer", []byte{0xAD, 0x11, 0xAB, 0x77, 0x88, 0x11}, []byte{0xDA, 0x99, 0xBA}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, - {"second array longer", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB, 0x77, 0x88, 0x11}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, - {"first array empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, - {"second array empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, - {"empty arrays", []byte{}, []byte{}, []byte{}}, + {"equal length slices", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x77, 0x88, 0x11}}, + {"data longer", []byte{0xAD, 0x11, 0xAB, 0x77, 0x88, 0x11}, []byte{0xDA, 0x99, 0xBA}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, + {"toogleData longer", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB, 0x77, 0x88, 0x11}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, + {"data empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, + {"toogleData empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, + {"empty slices", []byte{}, []byte{}, []byte{}}, } -func TestBigEndianByteSliceExclusiveMerge(t *testing.T) { +func TestLToogle(t *testing.T) { var val []byte - for _, tc := range testcasesBigEndianByteSliceExclusiveMerge { + for _, tc := range tcLToogle { t.Run(tc.name, func(t *testing.T) { - val = BigEndianByteSlice(tc.data).ExclusiveMerge(tc.anotherData) + val = LToogle(tc.data, tc.toogleData) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("BigEndianByteSlice(%x).ExclusiveMerge(%x) was %x, should be %x", - tc.data, tc.anotherData, + t.Errorf("LToogle(%x, %x) was %x, should be %x", + tc.data, tc.toogleData, val, tc.result) } @@ -114,22 +114,22 @@ func TestBigEndianByteSliceExclusiveMerge(t *testing.T) { } } -func BenchmarkBigEndianByteSliceExclusiveMerge(b *testing.B) { +func BenchmarkLToogle(b *testing.B) { var val []byte - for _, tc := range testcasesBigEndianByteSliceExclusiveMerge { + for _, tc := range tcLToogle { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = BigEndianByteSlice(tc.data).ExclusiveMerge(tc.anotherData) + val = LToogle(tc.data, tc.toogleData) } }) } } -var testcasesBigEndianByteSliceSubset = []struct { - name string - data []byte - lsbPosition, msbPosition uint64 - result []byte +var tcLSubset = []struct { + name string + data []byte + leastSignificantBit, mostSignificantBit uint64 + result []byte }{ {"extract nothing", []byte{0xDA, 0x99, 0xBA}, 0, 0, []byte{}}, {"extract nothing due to inversed positions", []byte{0xDA, 0x99, 0xBA}, 16, 8, []byte{}}, @@ -142,14 +142,14 @@ var testcasesBigEndianByteSliceSubset = []struct { {"extract all bytes with an overflow position", []byte{0xDA, 0x99, 0xBA}, 0, 100, []byte{0xDA, 0x99, 0xBA}}, } -func TestBigEndianByteSliceSubset(t *testing.T) { +func TestLSubset(t *testing.T) { var val []byte - for _, tc := range testcasesBigEndianByteSliceSubset { + for _, tc := range tcLSubset { t.Run(tc.name, func(t *testing.T) { - val = BigEndianByteSlice(tc.data).Subset(tc.lsbPosition, tc.msbPosition) + val = LSubset(tc.data, tc.leastSignificantBit, tc.mostSignificantBit) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("BigEndianByteSlice(%x).Subset(%v, %v) was %x, should be %x", - tc.data, tc.lsbPosition, tc.msbPosition, + t.Errorf("LSubset(%x, %v, %v) was %x, should be %x", + tc.data, tc.leastSignificantBit, tc.mostSignificantBit, val, tc.result) } @@ -157,55 +157,12 @@ func TestBigEndianByteSliceSubset(t *testing.T) { } } -func BenchmarkBigEndianByteSliceSubset(b *testing.B) { +func BenchmarkLSubset(b *testing.B) { var val []byte - for _, tc := range testcasesBigEndianByteSliceSubset { + for _, tc := range tcLSubset { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = BigEndianByteSlice(tc.data).Subset(tc.lsbPosition, tc.msbPosition) - } - }) - } -} - -var testcasesBigEndianByteSliceLittleEndianSubset = []struct { - name string - data []byte - lsbPosition, msbPosition uint64 - result []byte -}{ - {"extract nothing", []byte{0xDA, 0x99, 0xBA}, 0, 0, []byte{}}, - {"extract nothing due to inversed positions", []byte{0xDA, 0x99, 0xBA}, 16, 8, []byte{}}, - {"extract nothing due to wrong positions", []byte{0xDA, 0x99, 0xBA}, 100, 101, []byte{}}, - {"extract only in one byte", []byte{0xBA, 0x99, 0xDA}, 5, 7, []byte{0x05}}, - {"extract one byte over two bytes", []byte{0xBA, 0x99, 0xDA}, 7, 8, []byte{0x03}}, - {"extract two bytes over three bytes", []byte{0xBA, 0x99, 0xDA}, 6, 17, []byte{0x66, 0x0A}}, - {"extract three bytes over three bytes", []byte{0xBA, 0x99, 0xDA}, 1, 22, []byte{0xDD, 0x4C, 0x2D}}, - {"extract all bytes", []byte{0xDA, 0x99, 0xBA}, 0, 23, []byte{0xDA, 0x99, 0xBA}}, - {"extract all bytes with an overflow position", []byte{0xDA, 0x99, 0xBA}, 0, 100, []byte{0xDA, 0x99, 0xBA}}, -} - -func TestBigEndianByteSliceLittleEndianSubset(t *testing.T) { - var val []byte - for _, tc := range testcasesBigEndianByteSliceLittleEndianSubset { - t.Run(tc.name, func(t *testing.T) { - val = BigEndianByteSlice(tc.data).LittleEndianSubset(tc.lsbPosition, tc.msbPosition) - if !reflect.DeepEqual(val, tc.result) { - t.Errorf("BigEndianByteSlice(%x).LittleEndianSubset(%v, %v) was %x, should be %x", - tc.data, tc.lsbPosition, tc.msbPosition, - val, - tc.result) - } - }) - } -} - -func BenchmarkBigEndianByteSliceLittleEndianSubset(b *testing.B) { - var val []byte - for _, tc := range testcasesBigEndianByteSliceLittleEndianSubset { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = BigEndianByteSlice(tc.data).LittleEndianSubset(tc.lsbPosition, tc.msbPosition) + val = LSubset(tc.data, tc.leastSignificantBit, tc.mostSignificantBit) } }) } diff --git a/byteslice_littleendian.go b/byteslice_littleendian.go index b0db0e0..5f22004 100644 --- a/byteslice_littleendian.go +++ b/byteslice_littleendian.go @@ -1,86 +1,69 @@ package byteslice -// LittleEndianByteSlice is a ByteSlice who are little endian ordered -type LittleEndianByteSlice ByteSlice - -// Mask apply AND mask to a byte array -func (data LittleEndianByteSlice) Mask(mask LittleEndianByteSlice) LittleEndianByteSlice { +// RUnset apply AND operation on a byte slice with an "unset" byte slice using little endian order. +func RUnset(data, unsetData []byte) []byte { var dataLength = len(data) if dataLength < 1 { return data } - var maskLength = len(mask) - var operationLength = dataLength - var operationCut = 0 - if maskLength > dataLength { - operationLength = maskLength + unsetDataLength := len(unsetData) + operationLength := dataLength + operationCut := 0 + if unsetDataLength > dataLength { + operationLength = unsetDataLength operationCut = operationLength - dataLength } - result, _ := ByteSlice(ByteSlice(data).leftPad(operationLength, 0xFF)).Mask(ByteSlice(mask).leftPad(operationLength, 0xFF)) - return LittleEndianByteSlice(result).newSize(operationCut) + result, _ := Unset(LPad(data, operationLength, 0xFF), LPad(unsetData, operationLength, 0xFF)) + return result[operationCut:] } -func (data LittleEndianByteSlice) newSize(newSize int) LittleEndianByteSlice { - return []byte(data)[newSize:] -} +// RSet apply OR operation on a byte slice with an "set" byte slice using little endian order. +func RSet(data, setData []byte) []byte { + dataLength := len(data) + setDataLength := len(setData) -// InclusiveMerge apply OR operation on two byte arrays -func (data LittleEndianByteSlice) InclusiveMerge(anotherData LittleEndianByteSlice) LittleEndianByteSlice { - var dataLength = len(data) - var anotherDataLength = len(anotherData) - - var operationLength = dataLength - if anotherDataLength > dataLength { - operationLength = anotherDataLength + operationLength := dataLength + if setDataLength > dataLength { + operationLength = setDataLength } - result, _ := ByteSlice(ByteSlice(data).leftPad(operationLength, 0x00)).InclusiveMerge(ByteSlice(anotherData).leftPad(operationLength, 0x00)) - return LittleEndianByteSlice(result) + result, _ := Set(LPad(data, operationLength, 0x00), LPad(setData, operationLength, 0x00)) + return result } -// ExclusiveMerge apply XOR operation on two byte arrays -func (data LittleEndianByteSlice) ExclusiveMerge(anotherData LittleEndianByteSlice) LittleEndianByteSlice { - var dataLength = len(data) - var anotherDataLength = len(anotherData) +// RToogle apply XOR operation on a byte slice with an "toogle" byte slice using little endian order. +func RToogle(data, toogleData []byte) []byte { + dataLength := len(data) + toogleDataLength := len(toogleData) - var operationLength = dataLength - if anotherDataLength > dataLength { - operationLength = anotherDataLength + operationLength := dataLength + if toogleDataLength > dataLength { + operationLength = toogleDataLength } - result, _ := ByteSlice(ByteSlice(data).leftPad(operationLength, 0x00)).ExclusiveMerge(ByteSlice(anotherData).leftPad(operationLength, 0x00)) - return LittleEndianByteSlice(result) + result, _ := Toogle(LPad(data, operationLength, 0x00), LPad(toogleData, operationLength, 0x00)) + return result } -// Subset get a byte array as subset of another byte array -func (data LittleEndianByteSlice) Subset(lsbPosition, msbPosition uint64) LittleEndianByteSlice { - var maxMsb = uint64(byteLength*len(data) - 1) +// RSubset get the byte slice of a subset of the little endian ordered data byte defined +// by the least significant bit and the most significant bit. +func RSubset(data []byte, leastSignificantBit, mostSignificantBit uint64) []byte { + var maxDataMostSignificantBit = uint64(maxBitsLength*len(data) - 1) - if msbPosition <= lsbPosition || lsbPosition > maxMsb { - return make(LittleEndianByteSlice, 0) + if mostSignificantBit <= leastSignificantBit || leastSignificantBit > maxDataMostSignificantBit { + return make([]byte, 0) } - if msbPosition > maxMsb { - msbPosition = maxMsb + if mostSignificantBit > maxDataMostSignificantBit { + mostSignificantBit = maxDataMostSignificantBit } - var result = ByteSlice(data).LeftShift(maxMsb - msbPosition) - var correctiveShift = maxMsb - msbPosition + lsbPosition - result = ByteSlice(result).RightShift(correctiveShift) - - var size = computeSize(lsbPosition, msbPosition) - return LittleEndianByteSlice(result).trim(size) -} - -// BigEndianSubset get a byte array as subset of another byte array when byte are in big endian -func (data LittleEndianByteSlice) BigEndianSubset(lsbPosition, msbPosition uint64) LittleEndianByteSlice { - var reversedData = ByteSlice(data).Reverse() - var result = BigEndianByteSlice(reversedData).Subset(lsbPosition, msbPosition) - return LittleEndianByteSlice(ByteSlice(result).Reverse()) -} + var result = LShift(data, maxDataMostSignificantBit-mostSignificantBit) + var correctiveShift = maxDataMostSignificantBit - mostSignificantBit + leastSignificantBit + result = RShift(result, correctiveShift) -func (data LittleEndianByteSlice) trim(newSize uint64) LittleEndianByteSlice { - return data[uint64(len(data))-newSize:] + var size = computeSize(leastSignificantBit, mostSignificantBit) + return result[uint64(len(result))-size:] } diff --git a/byteslice_littleendian_test.go b/byteslice_littleendian_test.go index 410b093..41eab16 100644 --- a/byteslice_littleendian_test.go +++ b/byteslice_littleendian_test.go @@ -5,28 +5,28 @@ import ( "testing" ) -var testcasesLittleEndianByteSliceMask = []struct { - name string - data []byte - mask []byte - result []byte +var tcRUnset = []struct { + name string + data []byte + unsetData []byte + result []byte }{ - {"data and mask of equal length", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x88, 0x11, 0xAA}}, - {"data shorter than mask", []byte{0xDA, 0x99, 0xBA}, []byte{0x88, 0x11, 0xAA, 0xAD, 0x11, 0xAB}, []byte{0x88, 0x11, 0xAA}}, - {"data longer than mask", []byte{0x88, 0x11, 0xAA, 0xAD, 0x11, 0xAB}, []byte{0xDA, 0x99, 0xBA}, []byte{0x88, 0x11, 0xAA, 0x88, 0x11, 0xAA}}, - {"empty mask on data", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, - {"mask on empty data", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{}}, - {"empty mask on empty data", []byte{}, []byte{}, []byte{}}, + {"data and unsetData of equal length", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x88, 0x11, 0xAA}}, + {"data shorter than unsetData", []byte{0xDA, 0x99, 0xBA}, []byte{0x88, 0x11, 0xAA, 0xAD, 0x11, 0xAB}, []byte{0x88, 0x11, 0xAA}}, + {"data longer than unsetData", []byte{0x88, 0x11, 0xAA, 0xAD, 0x11, 0xAB}, []byte{0xDA, 0x99, 0xBA}, []byte{0x88, 0x11, 0xAA, 0x88, 0x11, 0xAA}}, + {"empty unsetData on data", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, + {"unsetData on empty data", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{}}, + {"empty unsetData on empty data", []byte{}, []byte{}, []byte{}}, } -func TestLittleEndianByteSliceMask(t *testing.T) { +func TestRUnset(t *testing.T) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceMask { + for _, tc := range tcRUnset { t.Run(tc.name, func(t *testing.T) { - val = LittleEndianByteSlice(tc.data).Mask(tc.mask) + val = RUnset(tc.data, tc.unsetData) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("LittleEndianByteSlice(%x).Mask(%x) was %x, should be %x", - tc.data, tc.mask, + t.Errorf("RUnset(%x, %x) was %x, should be %x", + tc.data, tc.unsetData, val, tc.result) } @@ -34,39 +34,39 @@ func TestLittleEndianByteSliceMask(t *testing.T) { } } -func BenchmarkLittleEndianByteSliceMask(b *testing.B) { +func BenchmarkRUnset(b *testing.B) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceMask { + for _, tc := range tcRUnset { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = LittleEndianByteSlice(tc.data).Mask(tc.mask) + val = RUnset(tc.data, tc.unsetData) } }) } } -var testcasesLittleEndianByteSliceInclusiveMerge = []struct { - name string - data []byte - anotherData []byte - result []byte +var tcRSet = []struct { + name string + data []byte + setData []byte + result []byte }{ - {"equal length arrays", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0xFF, 0x99, 0xBB}}, - {"first array longer", []byte{0xFF, 0x99, 0xBB, 0xAD, 0x11, 0xAB}, []byte{0xDA, 0x99, 0xBA}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, - {"second array longer", []byte{0xDA, 0x99, 0xBA}, []byte{0xFF, 0x99, 0xBB, 0xAD, 0x11, 0xAB}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, - {"first array empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, - {"second array empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, - {"empty arrays", []byte{}, []byte{}, []byte{}}, + {"equal length slices", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0xFF, 0x99, 0xBB}}, + {"data longer", []byte{0xFF, 0x99, 0xBB, 0xAD, 0x11, 0xAB}, []byte{0xDA, 0x99, 0xBA}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, + {"setData longer", []byte{0xDA, 0x99, 0xBA}, []byte{0xFF, 0x99, 0xBB, 0xAD, 0x11, 0xAB}, []byte{0xFF, 0x99, 0xBB, 0xFF, 0x99, 0xBB}}, + {"data empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, + {"setData empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, + {"empty slices", []byte{}, []byte{}, []byte{}}, } -func TestLittleEndianByteSliceInclusiveMerge(t *testing.T) { +func TestRSet(t *testing.T) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceInclusiveMerge { + for _, tc := range tcRSet { t.Run(tc.name, func(t *testing.T) { - val = LittleEndianByteSlice(tc.data).InclusiveMerge(tc.anotherData) + val = RSet(tc.data, tc.setData) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("LittleEndianByteSlice(%x).InclusiveMerge(%x) was %x, should be %x", - tc.data, tc.anotherData, + t.Errorf("RSet(%x, %x) was %x, should be %x", + tc.data, tc.setData, val, tc.result) } @@ -74,39 +74,39 @@ func TestLittleEndianByteSliceInclusiveMerge(t *testing.T) { } } -func BenchmarkLittleEndianByteSliceInclusiveMerge(b *testing.B) { +func BenchmarkRSet(b *testing.B) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceInclusiveMerge { + for _, tc := range tcRSet { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = LittleEndianByteSlice(tc.data).InclusiveMerge(tc.anotherData) + val = RSet(tc.data, tc.setData) } }) } } -var testcasesLittleEndianByteSliceExclusiveMerge = []struct { - name string - data []byte - anotherData []byte - result []byte +var tcRToogle = []struct { + name string + data []byte + toogleData []byte + result []byte }{ - {"equal length arrays", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x77, 0x88, 0x11}}, - {"first array longer", []byte{0x77, 0x88, 0x11, 0xAD, 0x11, 0xAB}, []byte{0xDA, 0x99, 0xBA}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, - {"second array longer", []byte{0xDA, 0x99, 0xBA}, []byte{0x77, 0x88, 0x11, 0xAD, 0x11, 0xAB}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, - {"first array empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, - {"second array empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, - {"empty arrays", []byte{}, []byte{}, []byte{}}, + {"equal length slices", []byte{0xDA, 0x99, 0xBA}, []byte{0xAD, 0x11, 0xAB}, []byte{0x77, 0x88, 0x11}}, + {"data longer", []byte{0x77, 0x88, 0x11, 0xAD, 0x11, 0xAB}, []byte{0xDA, 0x99, 0xBA}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, + {"toogleData longer", []byte{0xDA, 0x99, 0xBA}, []byte{0x77, 0x88, 0x11, 0xAD, 0x11, 0xAB}, []byte{0x77, 0x88, 0x11, 0x77, 0x88, 0x11}}, + {"data empty", []byte{}, []byte{0xAD, 0x11, 0xAB}, []byte{0xAD, 0x11, 0xAB}}, + {"toogleData empty", []byte{0xDA, 0x99, 0xBA}, []byte{}, []byte{0xDA, 0x99, 0xBA}}, + {"empty slices", []byte{}, []byte{}, []byte{}}, } -func TestLittleEndianByteSliceExclusiveMerge(t *testing.T) { +func TestRToogle(t *testing.T) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceExclusiveMerge { + for _, tc := range tcRToogle { t.Run(tc.name, func(t *testing.T) { - val = LittleEndianByteSlice(tc.data).ExclusiveMerge(tc.anotherData) + val = RToogle(tc.data, tc.toogleData) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("LittleEndianByteSlice(%x).ExclusiveMerge(%x) was %x, should be %x", - tc.data, tc.anotherData, + t.Errorf("RToogle(%x, %x) was %x, should be %x", + tc.data, tc.toogleData, val, tc.result) } @@ -114,22 +114,22 @@ func TestLittleEndianByteSliceExclusiveMerge(t *testing.T) { } } -func BenchmarkLittleEndianByteSliceExclusiveMerge(b *testing.B) { +func BenchmarkRToogle(b *testing.B) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceExclusiveMerge { + for _, tc := range tcRToogle { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = LittleEndianByteSlice(tc.data).ExclusiveMerge(tc.anotherData) + val = RToogle(tc.data, tc.toogleData) } }) } } -var testcasesLittleEndianByteSliceSubset = []struct { - name string - data []byte - lsbPosition, msbPosition uint64 - result []byte +var tcRSubset = []struct { + name string + data []byte + leastSignificantBit, mostSignificantBit uint64 + result []byte }{ {"extract nothing", []byte{0xDA, 0x99, 0xBA}, 0, 0, []byte{}}, {"extract nothing due to inversed positions", []byte{0xDA, 0x99, 0xBA}, 16, 8, []byte{}}, @@ -142,14 +142,14 @@ var testcasesLittleEndianByteSliceSubset = []struct { {"extract all bytes with an overflow position", []byte{0xDA, 0x99, 0xBA}, 0, 100, []byte{0xDA, 0x99, 0xBA}}, } -func TestLittleEndianByteSliceSubset(t *testing.T) { +func TestRSubset(t *testing.T) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceSubset { + for _, tc := range tcRSubset { t.Run(tc.name, func(t *testing.T) { - val = LittleEndianByteSlice(tc.data).Subset(tc.lsbPosition, tc.msbPosition) + val = RSubset(tc.data, tc.leastSignificantBit, tc.mostSignificantBit) if !reflect.DeepEqual(val, tc.result) { - t.Errorf("LittleEndianByteSlice(%x).Subset(%v, %v) was %x, should be %x", - tc.data, tc.lsbPosition, tc.msbPosition, + t.Errorf("RSubset(%x, %v, %v) was %x, should be %x", + tc.data, tc.leastSignificantBit, tc.mostSignificantBit, val, tc.result) } @@ -157,55 +157,12 @@ func TestLittleEndianByteSliceSubset(t *testing.T) { } } -func BenchmarkLittleEndianByteSliceSubset(b *testing.B) { +func BenchmarkRSubset(b *testing.B) { var val []byte - for _, tc := range testcasesLittleEndianByteSliceSubset { + for _, tc := range tcRSubset { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = LittleEndianByteSlice(tc.data).Subset(tc.lsbPosition, tc.msbPosition) - } - }) - } -} - -var testcasesLittleEndianByteSliceBigEndianSubset = []struct { - name string - data []byte - lsbPosition, msbPosition uint64 - result []byte -}{ - {"extract nothing", []byte{0xDA, 0x99, 0xBA}, 0, 0, []byte{}}, - {"extract nothing due to inversed positions", []byte{0xDA, 0x99, 0xBA}, 16, 8, []byte{}}, - {"extract nothing due to wrong positions", []byte{0xDA, 0x99, 0xBA}, 100, 101, []byte{}}, - {"extract only in one byte", []byte{0xDA, 0x99, 0xBA}, 5, 7, []byte{0x40}}, - {"extract one byte over two bytes", []byte{0xDA, 0x99, 0xBA}, 7, 8, []byte{0x40}}, - {"extract two bytes over three bytes", []byte{0xBA, 0x99, 0xDA}, 6, 17, []byte{0x60, 0xA6}}, - {"extract three bytes over three bytes", []byte{0xBA, 0x99, 0xDA}, 1, 22, []byte{0x74, 0x33, 0xB5}}, - {"extract all bytes", []byte{0xDA, 0x99, 0xBA}, 0, 23, []byte{0xDA, 0x99, 0xBA}}, - {"extract all bytes with an overflow position", []byte{0xDA, 0x99, 0xBA}, 0, 100, []byte{0xDA, 0x99, 0xBA}}, -} - -func TestLittleEndianByteSliceBigEndianSubset(t *testing.T) { - var val []byte - for _, tc := range testcasesLittleEndianByteSliceBigEndianSubset { - t.Run(tc.name, func(t *testing.T) { - val = LittleEndianByteSlice(tc.data).BigEndianSubset(tc.lsbPosition, tc.msbPosition) - if !reflect.DeepEqual(val, tc.result) { - t.Errorf("LittleEndianByteSlice(%x).BigEndianSubset(%v, %v) was %x, should be %x", - tc.data, tc.lsbPosition, tc.msbPosition, - val, - tc.result) - } - }) - } -} - -func BenchmarkLittleEndianByteSliceBigEndianSubset(b *testing.B) { - var val []byte - for _, tc := range testcasesLittleEndianByteSliceBigEndianSubset { - b.Run(tc.name, func(b *testing.B) { - for i := 0; i < b.N; i++ { - val = LittleEndianByteSlice(tc.data).BigEndianSubset(tc.lsbPosition, tc.msbPosition) + val = RSubset(tc.data, tc.leastSignificantBit, tc.mostSignificantBit) } }) } diff --git a/byteslice_test.go b/byteslice_test.go index e3c8bd5..ee763d1 100644 --- a/byteslice_test.go +++ b/byteslice_test.go @@ -5,20 +5,44 @@ import ( "testing" ) -func TestByteSliceReverse(t *testing.T) { - data := []byte{0x01, 0x10} - result := []byte{0x10, 0x01} - - val := ByteSlice(data).Reverse() - if !reflect.DeepEqual(val, ByteSlice(result)) { - t.Errorf("ByteSlice(%x).Reverse() was %x, should be %x", - data, - val, - result) +var tcReverse = []struct { + name string + data []byte + result []byte +}{ + {"empty byte slice", []byte{}, []byte{}}, + {"one element byte slice", []byte{0x01}, []byte{0x01}}, + {"even length byte slice", []byte{0x01, 0x10}, []byte{0x10, 0x01}}, + {"odd length byte slice", []byte{0x01, 0xFF, 0x10}, []byte{0x10, 0xFF, 0x01}}, +} + +func TestReverse(t *testing.T) { + var val []byte + for _, tc := range tcReverse { + t.Run(tc.name, func(t *testing.T) { + val = Reverse(tc.data) + if !reflect.DeepEqual(val, tc.result) { + t.Errorf("Reverse(%x) was %x, should be %x", + tc.data, + val, + tc.result) + } + }) + } +} + +func BenchmarkReverse(b *testing.B) { + var val []byte + for _, tc := range tcReverse { + b.Run(tc.name, func(b *testing.B) { + for i := 0; i < b.N; i++ { + val = Reverse(tc.data) + } + }) } } -var testcasesByteSliceLeftShift = []struct { +var tcLShift = []struct { name string data []byte shift uint64 @@ -31,13 +55,13 @@ var testcasesByteSliceLeftShift = []struct { {"overflow shift to the left", []byte{0xDA, 0x99, 0xBA}, 24, []byte{0x00, 0x00, 0x00}}, } -func TestByteSliceLeftShift(t *testing.T) { - var val ByteSlice - for _, tc := range testcasesByteSliceLeftShift { +func TestLShift(t *testing.T) { + var val []byte + for _, tc := range tcLShift { t.Run(tc.name, func(t *testing.T) { - val = ByteSlice(tc.data).LeftShift(tc.shift) - if !reflect.DeepEqual(val, ByteSlice(tc.result)) { - t.Errorf("LeftShift(%x, %v) was %x, should be %x", + val = LShift(tc.data, tc.shift) + if !reflect.DeepEqual(val, tc.result) { + t.Errorf("LShift(%x, %v) was %x, should be %x", tc.data, tc.shift, val, tc.result) @@ -46,18 +70,18 @@ func TestByteSliceLeftShift(t *testing.T) { } } -func BenchmarkByteSliceLeftShift(b *testing.B) { - var val ByteSlice - for _, tc := range testcasesByteSliceLeftShift { +func BenchmarkLShift(b *testing.B) { + var val []byte + for _, tc := range tcLShift { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = ByteSlice(tc.data).LeftShift(tc.shift) + val = LShift(tc.data, tc.shift) } }) } } -var testcasesByteSliceRightShift = []struct { +var tcRShift = []struct { name string data []byte shift uint64 @@ -70,13 +94,13 @@ var testcasesByteSliceRightShift = []struct { {"overflow shift to the right", []byte{0xDA, 0x99, 0xBA}, 24, []byte{0x00, 0x00, 0x00}}, } -func TestByteSliceRightShift(t *testing.T) { - var val ByteSlice - for _, tc := range testcasesByteSliceRightShift { +func TestRShift(t *testing.T) { + var val []byte + for _, tc := range tcRShift { t.Run(tc.name, func(t *testing.T) { - val = ByteSlice(tc.data).RightShift(tc.shift) - if !reflect.DeepEqual(val, ByteSlice(tc.result)) { - t.Errorf("RightShift(%x, %v) was %x, should be %x", + val = RShift(tc.data, tc.shift) + if !reflect.DeepEqual(val, tc.result) { + t.Errorf("RShift(%x, %v) was %x, should be %x", tc.data, tc.shift, val, tc.result) @@ -85,55 +109,39 @@ func TestByteSliceRightShift(t *testing.T) { } } -func BenchmarkByteSliceRightShift(b *testing.B) { - var val ByteSlice - for _, tc := range testcasesByteSliceRightShift { +func BenchmarkRShift(b *testing.B) { + var val []byte + for _, tc := range tcRShift { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = ByteSlice(tc.data).RightShift(tc.shift) + val = RShift(tc.data, tc.shift) } }) } } -func TestByteSliceMaskError(t *testing.T) { - val, err := ByteSlice([]byte{0x00, 0x00}).Mask(ByteSlice([]byte{0x00})) - if err == nil || val != nil { - t.Errorf("Mask with two byte arrays of different size needs to return an error and no value") - } -} - -func TestByteSliceInclusiveMergeError(t *testing.T) { - val, err := ByteSlice([]byte{0x00, 0x00}).InclusiveMerge(ByteSlice([]byte{0x00})) - if err == nil || val != nil { - t.Errorf("InclusiveMerge with two byte arrays of different size needs to return an error and no value") - } -} - -func TestByteSliceExclusiveMergeError(t *testing.T) { - val, err := ByteSlice([]byte{0x00, 0x00}).ExclusiveMerge(ByteSlice([]byte{0x00})) - if err == nil || val != nil { - t.Errorf("ExclusiveMerge with two byte arrays of different size needs to return an error and no value") - } -} - -var testcasesByteSliceNot = []struct { +var tcLPad = []struct { name string data []byte + length int + filler byte result []byte }{ - {"not empty array", []byte{0xDA, 0x99, 0xBA}, []byte{0x25, 0x66, 0x45}}, - {"empty array", []byte{}, []byte{}}, + {"lpad to two elements on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0x00, 0xDA}}, + {"lpad to two elements with a filler on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0x00, 0xDA}}, + {"lpad to two elements on an empty array", []byte{}, 2, 0x11, []byte{0x11, 0x11}}, + {"lpad to one element on an larger array", []byte{0xDA, 0x99, 0xBA}, 1, 0x11, []byte{0xDA, 0x99, 0xBA}}, + {"lpad to negative element size change nothing", []byte{0xDA}, -1, 0x11, []byte{0xDA}}, } -func TestByteSliceNot(t *testing.T) { - var val ByteSlice - for _, tc := range testcasesByteSliceNot { +func TestLPad(t *testing.T) { + var val []byte + for _, tc := range tcLPad { t.Run(tc.name, func(t *testing.T) { - val = ByteSlice(tc.data).Not() - if !reflect.DeepEqual(val, ByteSlice(tc.result)) { - t.Errorf("Not(%x) was %x, should be %x", - tc.data, + val = LPad(tc.data, tc.length, tc.filler) + if !reflect.DeepEqual(val, tc.result) { + t.Errorf("LPad(%x, %v, %v) was %x, should be %x", + tc.data, tc.length, tc.filler, val, tc.result) } @@ -141,38 +149,38 @@ func TestByteSliceNot(t *testing.T) { } } -func BenchmarkByteSliceNot(b *testing.B) { - var val ByteSlice - for _, tc := range testcasesByteSliceNot { +func BenchmarkLPad(b *testing.B) { + var val []byte + for _, tc := range tcLPad { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = ByteSlice(tc.data).Not() + val = LPad(tc.data, tc.length, tc.filler) } }) } } -var testcasesByteSliceLeftPad = []struct { +var tcRPad = []struct { name string data []byte length int filler byte result []byte }{ - {"lpad to two elements on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0x00, 0xDA}}, - {"lpad to two elements with a filler on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0x00, 0xDA}}, - {"lpad to two elements on an empty array", []byte{}, 2, 0x11, []byte{0x11, 0x11}}, - {"lpad to one element on an larger array", []byte{0xDA, 0x99, 0xBA}, 1, 0x11, []byte{0xDA, 0x99, 0xBA}}, - {"lpad to negative element size change nothing", []byte{0xDA}, -1, 0x11, []byte{0xDA}}, + {"rpad to two elements on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0xDA, 0x00}}, + {"lpad to two elements with a filler on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0xDA, 0x00}}, + {"rpad to two elements on an empty array", []byte{}, 2, 0x11, []byte{0x11, 0x11}}, + {"rpad to one element on an larger array", []byte{0xDA, 0x99, 0xBA}, 1, 0x11, []byte{0xDA, 0x99, 0xBA}}, + {"rpad to negative element size change nothing", []byte{0xDA}, -1, 0x00, []byte{0xDA}}, } -func TestByteSliceLeftPad(t *testing.T) { - var val ByteSlice - for _, tc := range testcasesByteSliceLeftPad { +func TestRPad(t *testing.T) { + var val []byte + for _, tc := range tcRPad { t.Run(tc.name, func(t *testing.T) { - val = ByteSlice(tc.data).leftPad(tc.length, tc.filler) - if !reflect.DeepEqual(val, ByteSlice(tc.result)) { - t.Errorf("ByteSlice(%x).leftPad(%v, %v) was %x, should be %x", + val = RPad(tc.data, tc.length, tc.filler) + if !reflect.DeepEqual(val, tc.result) { + t.Errorf("RPad(%x, %v, %v) was %x, should be %x", tc.data, tc.length, tc.filler, val, tc.result) @@ -181,39 +189,55 @@ func TestByteSliceLeftPad(t *testing.T) { } } -func BenchmarkByteSliceLeftPad(b *testing.B) { - var val ByteSlice - for _, tc := range testcasesByteSliceLeftPad { +func BenchmarkRPad(b *testing.B) { + var val []byte + for _, tc := range tcRPad { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = ByteSlice(tc.data).leftPad(tc.length, tc.filler) + val = RPad(tc.data, tc.length, tc.filler) } }) } } -var testcasesByteSliceRightPad = []struct { +func TestUnsetError(t *testing.T) { + val, err := Unset([]byte{0x00, 0x00}, []byte{0x00}) + if err == nil || val != nil { + t.Errorf("Unset with two byte slices of different size needs to return an error and no value") + } +} + +func TestSetError(t *testing.T) { + val, err := Set([]byte{0x00, 0x00}, []byte{0x00}) + if err == nil || val != nil { + t.Errorf("Set with two byte slices of different size needs to return an error and no value") + } +} + +func TestToogleError(t *testing.T) { + val, err := Toogle([]byte{0x00, 0x00}, []byte{0x00}) + if err == nil || val != nil { + t.Errorf("Toogle with two byte slices of different size needs to return an error and no value") + } +} + +var tcFlip = []struct { name string data []byte - length int - filler byte result []byte }{ - {"rpad to two elements on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0xDA, 0x00}}, - {"lpad to two elements with a filler on an smaller array", []byte{0xDA}, 2, 0x00, []byte{0xDA, 0x00}}, - {"rpad to two elements on an empty array", []byte{}, 2, 0x11, []byte{0x11, 0x11}}, - {"rpad to one element on an larger array", []byte{0xDA, 0x99, 0xBA}, 1, 0x11, []byte{0xDA, 0x99, 0xBA}}, - {"rpad to negative element size change nothing", []byte{0xDA}, -1, 0x00, []byte{0xDA}}, + {"not empty array", []byte{0xDA, 0x99, 0xBA}, []byte{0x25, 0x66, 0x45}}, + {"empty array", []byte{}, []byte{}}, } -func TestByteSliceRightPad(t *testing.T) { - var val ByteSlice - for _, tc := range testcasesByteSliceRightPad { +func TestFlip(t *testing.T) { + var val []byte + for _, tc := range tcFlip { t.Run(tc.name, func(t *testing.T) { - val = ByteSlice(tc.data).rightPad(tc.length, tc.filler) - if !reflect.DeepEqual(val, ByteSlice(tc.result)) { - t.Errorf("ByteSlice(%x).rightPad(%v, %v) was %x, should be %x", - tc.data, tc.length, tc.filler, + val = Flip(tc.data) + if !reflect.DeepEqual(val, tc.result) { + t.Errorf("Flip(%x) was %x, should be %x", + tc.data, val, tc.result) } @@ -221,12 +245,12 @@ func TestByteSliceRightPad(t *testing.T) { } } -func BenchmarkByteSliceRightPad(b *testing.B) { - var val ByteSlice - for _, tc := range testcasesByteSliceRightPad { +func BenchmarkFlip(b *testing.B) { + var val []byte + for _, tc := range tcFlip { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - val = ByteSlice(tc.data).rightPad(tc.length, tc.filler) + val = Flip(tc.data) } }) }