mirror of
https://github.com/clearml/go-nvlib
synced 2025-04-16 13:32:44 +00:00
Add pkg/bytes as a direct port from mig-parted/internal/bytes
Signed-off-by: Kevin Klues <kklues@nvidia.com>
This commit is contained in:
parent
e43d82971c
commit
98d311e418
87
pkg/bytes/bytes.go
Normal file
87
pkg/bytes/bytes.go
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package bytes
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type Raw interface {
|
||||
Raw() *[]byte
|
||||
}
|
||||
|
||||
type Reader interface {
|
||||
Read8(pos int) uint8
|
||||
Read16(pos int) uint16
|
||||
Read32(pos int) uint32
|
||||
Read64(pos int) uint64
|
||||
Len() int
|
||||
}
|
||||
|
||||
type Writer interface {
|
||||
Write8(pos int, value uint8)
|
||||
Write16(pos int, value uint16)
|
||||
Write32(pos int, value uint32)
|
||||
Write64(pos int, value uint64)
|
||||
Len() int
|
||||
}
|
||||
|
||||
type Bytes interface {
|
||||
Raw
|
||||
Reader
|
||||
Writer
|
||||
Slice(offset int, size int) Bytes
|
||||
LittleEndian() Bytes
|
||||
BigEndian() Bytes
|
||||
}
|
||||
|
||||
var nativeByteOrder binary.ByteOrder
|
||||
|
||||
func init() {
|
||||
buf := [2]byte{}
|
||||
*(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0x00FF)
|
||||
|
||||
switch buf {
|
||||
case [2]byte{0xFF, 0x00}:
|
||||
nativeByteOrder = binary.LittleEndian
|
||||
case [2]byte{0x00, 0xFF}:
|
||||
nativeByteOrder = binary.BigEndian
|
||||
default:
|
||||
panic("Unable to infer byte order")
|
||||
}
|
||||
}
|
||||
|
||||
func New(data *[]byte) Bytes {
|
||||
return (*native)(data)
|
||||
}
|
||||
|
||||
func NewLittleEndian(data *[]byte) Bytes {
|
||||
if nativeByteOrder == binary.LittleEndian {
|
||||
return (*native)(data)
|
||||
} else {
|
||||
return (*swapbo)(data)
|
||||
}
|
||||
}
|
||||
|
||||
func NewBigEndian(data *[]byte) Bytes {
|
||||
if nativeByteOrder == binary.BigEndian {
|
||||
return (*native)(data)
|
||||
} else {
|
||||
return (*swapbo)(data)
|
||||
}
|
||||
}
|
178
pkg/bytes/bytes_test.go
Normal file
178
pkg/bytes/bytes_test.go
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package bytes
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
source := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
bytes := New(&source)
|
||||
require.IsType(t, (*native)(&source), bytes)
|
||||
|
||||
bytes = NewLittleEndian(&source)
|
||||
if nativeByteOrder == binary.LittleEndian {
|
||||
require.IsType(t, (*native)(&source), bytes)
|
||||
} else {
|
||||
require.IsType(t, (*swapbo)(&source), bytes)
|
||||
|
||||
}
|
||||
|
||||
bytes = NewBigEndian(&source)
|
||||
if nativeByteOrder == binary.BigEndian {
|
||||
require.IsType(t, (*native)(&source), bytes)
|
||||
} else {
|
||||
require.IsType(t, (*swapbo)(&source), bytes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRead(t *testing.T) {
|
||||
source := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
type testCase struct {
|
||||
Description string
|
||||
New func(*[]byte) Bytes
|
||||
ByteOrder binary.ByteOrder
|
||||
Offset int
|
||||
}
|
||||
testCases := func() []testCase {
|
||||
var testCases []testCase
|
||||
for i := 0; i < len(source)/2; i++ {
|
||||
tc1 := testCase{
|
||||
fmt.Sprintf("LittleEndian offset: %v", i),
|
||||
NewLittleEndian,
|
||||
binary.LittleEndian,
|
||||
i,
|
||||
}
|
||||
|
||||
tc2 := testCase{
|
||||
fmt.Sprintf("BigEndian offset: %v", i),
|
||||
NewBigEndian,
|
||||
binary.BigEndian,
|
||||
i,
|
||||
}
|
||||
|
||||
testCases = append(testCases, tc1, tc2)
|
||||
}
|
||||
return testCases
|
||||
}()
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Description, func(t *testing.T) {
|
||||
bytes := tc.New(&source)
|
||||
|
||||
r8 := bytes.Read8(tc.Offset)
|
||||
require.Equal(t, r8, source[tc.Offset])
|
||||
|
||||
r16 := bytes.Read16(tc.Offset)
|
||||
require.Equal(t, r16, tc.ByteOrder.Uint16(source[tc.Offset:tc.Offset+2]))
|
||||
|
||||
r32 := bytes.Read32(tc.Offset)
|
||||
require.Equal(t, r32, tc.ByteOrder.Uint32(source[tc.Offset:tc.Offset+4]))
|
||||
|
||||
r64 := bytes.Read64(tc.Offset)
|
||||
require.Equal(t, r64, tc.ByteOrder.Uint64(source[tc.Offset:tc.Offset+8]))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrite(t *testing.T) {
|
||||
source := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||
|
||||
type testCase struct {
|
||||
Description string
|
||||
New func(*[]byte) Bytes
|
||||
ByteOrder binary.ByteOrder
|
||||
Offset int
|
||||
}
|
||||
testCases := func() []testCase {
|
||||
var testCases []testCase
|
||||
for i := 0; i < len(source)/2; i++ {
|
||||
tc1 := testCase{
|
||||
fmt.Sprintf("LittleEndian offset: %v", i),
|
||||
NewLittleEndian,
|
||||
binary.LittleEndian,
|
||||
i,
|
||||
}
|
||||
|
||||
tc2 := testCase{
|
||||
fmt.Sprintf("BigEndian offset: %v", i),
|
||||
NewBigEndian,
|
||||
binary.BigEndian,
|
||||
i,
|
||||
}
|
||||
|
||||
testCases = append(testCases, tc1, tc2)
|
||||
}
|
||||
return testCases
|
||||
}()
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Description, func(t *testing.T) {
|
||||
bytes := tc.New(&source)
|
||||
|
||||
r8 := bytes.Read8(tc.Offset)
|
||||
require.Equal(t, r8, source[tc.Offset])
|
||||
bytes.Write8(tc.Offset, (1<<8)-1)
|
||||
r8 = bytes.Read8(tc.Offset)
|
||||
require.Equal(t, r8, uint8((1<<8)-1))
|
||||
require.Equal(t, r8, source[tc.Offset])
|
||||
bytes.Write8(tc.Offset, uint8(tc.Offset))
|
||||
|
||||
r16 := bytes.Read16(tc.Offset)
|
||||
require.Equal(t, r16, tc.ByteOrder.Uint16(source[tc.Offset:tc.Offset+2]))
|
||||
bytes.Write16(tc.Offset, (1<<16)-1)
|
||||
r16 = bytes.Read16(tc.Offset)
|
||||
require.Equal(t, r16, uint16((1<<16)-1))
|
||||
require.Equal(t, r16, tc.ByteOrder.Uint16(source[tc.Offset:tc.Offset+2]))
|
||||
bytes.Write8(tc.Offset+0, uint8(tc.Offset+0))
|
||||
bytes.Write8(tc.Offset+1, uint8(tc.Offset+1))
|
||||
|
||||
r32 := bytes.Read32(tc.Offset)
|
||||
require.Equal(t, r32, tc.ByteOrder.Uint32(source[tc.Offset:tc.Offset+4]))
|
||||
bytes.Write32(tc.Offset, (1<<32)-1)
|
||||
r32 = bytes.Read32(tc.Offset)
|
||||
require.Equal(t, r32, uint32((1<<32)-1))
|
||||
require.Equal(t, r32, tc.ByteOrder.Uint32(source[tc.Offset:tc.Offset+4]))
|
||||
bytes.Write8(tc.Offset+0, uint8(tc.Offset+0))
|
||||
bytes.Write8(tc.Offset+1, uint8(tc.Offset+1))
|
||||
bytes.Write8(tc.Offset+2, uint8(tc.Offset+2))
|
||||
bytes.Write8(tc.Offset+3, uint8(tc.Offset+3))
|
||||
|
||||
r64 := bytes.Read64(tc.Offset)
|
||||
require.Equal(t, r64, tc.ByteOrder.Uint64(source[tc.Offset:tc.Offset+8]))
|
||||
bytes.Write64(tc.Offset, (1<<64)-1)
|
||||
r64 = bytes.Read64(tc.Offset)
|
||||
require.Equal(t, r64, uint64((1<<64)-1))
|
||||
require.Equal(t, r64, tc.ByteOrder.Uint64(source[tc.Offset:tc.Offset+8]))
|
||||
bytes.Write8(tc.Offset+0, uint8(tc.Offset+0))
|
||||
bytes.Write8(tc.Offset+1, uint8(tc.Offset+1))
|
||||
bytes.Write8(tc.Offset+2, uint8(tc.Offset+2))
|
||||
bytes.Write8(tc.Offset+3, uint8(tc.Offset+3))
|
||||
bytes.Write8(tc.Offset+4, uint8(tc.Offset+4))
|
||||
bytes.Write8(tc.Offset+5, uint8(tc.Offset+5))
|
||||
bytes.Write8(tc.Offset+6, uint8(tc.Offset+6))
|
||||
bytes.Write8(tc.Offset+7, uint8(tc.Offset+7))
|
||||
})
|
||||
}
|
||||
}
|
78
pkg/bytes/native.go
Normal file
78
pkg/bytes/native.go
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package bytes
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type native []byte
|
||||
|
||||
var _ Bytes = (*native)(nil)
|
||||
|
||||
func (b *native) Read8(pos int) uint8 {
|
||||
return (*b)[pos]
|
||||
}
|
||||
|
||||
func (b *native) Read16(pos int) uint16 {
|
||||
return *(*uint16)(unsafe.Pointer(&((*b)[pos])))
|
||||
}
|
||||
|
||||
func (b *native) Read32(pos int) uint32 {
|
||||
return *(*uint32)(unsafe.Pointer(&((*b)[pos])))
|
||||
}
|
||||
|
||||
func (b *native) Read64(pos int) uint64 {
|
||||
return *(*uint64)(unsafe.Pointer(&((*b)[pos])))
|
||||
}
|
||||
|
||||
func (b *native) Write8(pos int, value uint8) {
|
||||
(*b)[pos] = value
|
||||
}
|
||||
|
||||
func (b *native) Write16(pos int, value uint16) {
|
||||
*(*uint16)(unsafe.Pointer(&((*b)[pos]))) = value
|
||||
}
|
||||
|
||||
func (b *native) Write32(pos int, value uint32) {
|
||||
*(*uint32)(unsafe.Pointer(&((*b)[pos]))) = value
|
||||
}
|
||||
|
||||
func (b *native) Write64(pos int, value uint64) {
|
||||
*(*uint64)(unsafe.Pointer(&((*b)[pos]))) = value
|
||||
}
|
||||
|
||||
func (b *native) Slice(offset int, size int) Bytes {
|
||||
nb := (*b)[offset : offset+size]
|
||||
return &nb
|
||||
}
|
||||
|
||||
func (b *native) LittleEndian() Bytes {
|
||||
return NewLittleEndian((*[]byte)(b))
|
||||
}
|
||||
|
||||
func (b *native) BigEndian() Bytes {
|
||||
return NewBigEndian((*[]byte)(b))
|
||||
}
|
||||
|
||||
func (b *native) Raw() *[]byte {
|
||||
return (*[]byte)(b)
|
||||
}
|
||||
|
||||
func (b *native) Len() int {
|
||||
return len(*b)
|
||||
}
|
112
pkg/bytes/swapbo.go
Normal file
112
pkg/bytes/swapbo.go
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package bytes
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type swapbo []byte
|
||||
|
||||
var _ Bytes = (*swapbo)(nil)
|
||||
|
||||
func (b *swapbo) Read8(pos int) uint8 {
|
||||
return (*b)[pos]
|
||||
}
|
||||
|
||||
func (b *swapbo) Read16(pos int) uint16 {
|
||||
buf := [2]byte{}
|
||||
buf[0] = (*b)[pos+1]
|
||||
buf[1] = (*b)[pos+0]
|
||||
return *(*uint16)(unsafe.Pointer(&buf[0]))
|
||||
}
|
||||
|
||||
func (b *swapbo) Read32(pos int) uint32 {
|
||||
buf := [4]byte{}
|
||||
buf[0] = (*b)[pos+3]
|
||||
buf[1] = (*b)[pos+2]
|
||||
buf[2] = (*b)[pos+1]
|
||||
buf[3] = (*b)[pos+0]
|
||||
return *(*uint32)(unsafe.Pointer(&buf[0]))
|
||||
}
|
||||
|
||||
func (b *swapbo) Read64(pos int) uint64 {
|
||||
buf := [8]byte{}
|
||||
buf[0] = (*b)[pos+7]
|
||||
buf[1] = (*b)[pos+6]
|
||||
buf[2] = (*b)[pos+5]
|
||||
buf[3] = (*b)[pos+4]
|
||||
buf[4] = (*b)[pos+3]
|
||||
buf[5] = (*b)[pos+2]
|
||||
buf[6] = (*b)[pos+1]
|
||||
buf[7] = (*b)[pos+0]
|
||||
return *(*uint64)(unsafe.Pointer(&buf[0]))
|
||||
}
|
||||
|
||||
func (b *swapbo) Write8(pos int, value uint8) {
|
||||
(*b)[pos] = value
|
||||
}
|
||||
|
||||
func (b *swapbo) Write16(pos int, value uint16) {
|
||||
buf := [2]byte{}
|
||||
*(*uint16)(unsafe.Pointer(&buf[0])) = value
|
||||
(*b)[pos+0] = buf[1]
|
||||
(*b)[pos+1] = buf[0]
|
||||
}
|
||||
|
||||
func (b *swapbo) Write32(pos int, value uint32) {
|
||||
buf := [4]byte{}
|
||||
*(*uint32)(unsafe.Pointer(&buf[0])) = value
|
||||
(*b)[pos+0] = buf[3]
|
||||
(*b)[pos+1] = buf[2]
|
||||
(*b)[pos+2] = buf[1]
|
||||
(*b)[pos+3] = buf[0]
|
||||
}
|
||||
|
||||
func (b *swapbo) Write64(pos int, value uint64) {
|
||||
buf := [8]byte{}
|
||||
*(*uint64)(unsafe.Pointer(&buf[0])) = value
|
||||
(*b)[pos+0] = buf[7]
|
||||
(*b)[pos+1] = buf[6]
|
||||
(*b)[pos+2] = buf[5]
|
||||
(*b)[pos+3] = buf[4]
|
||||
(*b)[pos+4] = buf[3]
|
||||
(*b)[pos+5] = buf[2]
|
||||
(*b)[pos+6] = buf[1]
|
||||
(*b)[pos+7] = buf[0]
|
||||
}
|
||||
|
||||
func (b *swapbo) Slice(offset int, size int) Bytes {
|
||||
nb := (*b)[offset : offset+size]
|
||||
return &nb
|
||||
}
|
||||
|
||||
func (b *swapbo) LittleEndian() Bytes {
|
||||
return NewLittleEndian((*[]byte)(b))
|
||||
}
|
||||
|
||||
func (b *swapbo) BigEndian() Bytes {
|
||||
return NewBigEndian((*[]byte)(b))
|
||||
}
|
||||
|
||||
func (b *swapbo) Raw() *[]byte {
|
||||
return (*[]byte)(b)
|
||||
}
|
||||
|
||||
func (b *swapbo) Len() int {
|
||||
return len(*b)
|
||||
}
|
Loading…
Reference in New Issue
Block a user