gitee.com/quant1x/num@v0.3.2/binary/bytes.go (about)

     1  package binary
     2  
     3  import (
     4  	"gitee.com/quant1x/num/kind"
     5  	"math"
     6  	"unsafe"
     7  	_ "unsafe"
     8  )
     9  
    10  //go:linkname Repeat bytes.Repeat
    11  func Repeat(b []byte, count int) []byte
    12  
    13  // ToBytes x的内存空间直接转成字节切片
    14  func ToBytes[E kind.BaseType](x E) []byte {
    15  	return v0ToBytes(x)
    16  }
    17  
    18  // TODO: 内存操作demo
    19  func f64ToBytes(x float64) []byte {
    20  	ptr := unsafe.Pointer(&x)
    21  	b := (*[8]byte)(ptr)[:]
    22  	return b
    23  }
    24  
    25  // 性能和v1ToBytes_nocopy接近
    26  func v0ToBytes[E kind.BaseType](x E) []byte {
    27  	ptr := unsafe.Pointer(&x)
    28  	switch v := any(x).(type) {
    29  	case bool, int8, uint8: // bool, byte, int8, uint8
    30  		return (*[1]byte)(ptr)[:]
    31  	case int16, uint16: // int16, uint16, word(windows)
    32  		return (*[2]byte)(ptr)[:]
    33  	case int32, uint32, float32: // int32, uint32, float32, rune(int32), dword(windows)
    34  		return (*[4]byte)(ptr)[:]
    35  	case int64, uint64, int, uintptr, float64, complex64: // int64, uint64, int, uintptr, float64, complex64
    36  		return (*[8]byte)(ptr)[:]
    37  	case complex128: // complex128
    38  		return (*[16]byte)(ptr)[:]
    39  	case string: // string
    40  		// unsafe.SizeOf("") == 16, 需要单独处理, 不能按照类型的SizeOf返回值类处理
    41  		return unsafe.Slice(unsafe.StringData(v), len(v))
    42  	}
    43  	//panic(fmt.Errorf("unsupported type: %T", x))
    44  	panic("unsupported type")
    45  }
    46  
    47  // 性能和v1ToBytes_nocopy接近
    48  // 存在bug, unsafe.SizeOf("") == 16
    49  func v0ToBytes1[E kind.BaseType](x E) []byte {
    50  	size := int(unsafe.Sizeof(x))
    51  	ptr := unsafe.Pointer(&x)
    52  	switch size {
    53  	case 1: // bool, byte, int8, uint8
    54  		return (*[1]byte)(ptr)[:]
    55  	case 2: // int16, uint16, word
    56  		return (*[2]byte)(ptr)[:]
    57  	case 4: // int32, uint32, dword, float32
    58  		return (*[4]byte)(ptr)[:]
    59  	case 8: // int64, uint64, int, uintptr, flot64, complex64
    60  		return (*[8]byte)(ptr)[:]
    61  	case 16: // complex128 string
    62  		return (*[16]byte)(ptr)[:]
    63  	default:
    64  	}
    65  	//panic(fmt.Errorf("unsupported type: %T", x))
    66  	panic("unsupported type")
    67  }
    68  
    69  func v1ToBytes_copy[T kind.BaseType](x T) []byte {
    70  	size := int(unsafe.Sizeof(x))
    71  	var v SliceHeader
    72  	v.Len = size
    73  	v.Cap = size
    74  	v.Data = uintptr(unsafe.Pointer(&x))
    75  	d := *(*[]byte)(unsafe.Pointer(&v))
    76  	// TODO: 下面可能是delve的bug
    77  	// 在GoLand调试时, 如果不进行copy, 那么后续操作中内存一定会被覆盖
    78  	data := make([]byte, size)
    79  	copy(data[:size], d[:size])
    80  	return data
    81  }
    82  
    83  func v1ToBytes_nocopy[T kind.BaseType](x T) []byte {
    84  	size := int(unsafe.Sizeof(x))
    85  	ptr := unsafe.Pointer(&x)
    86  	var v SliceHeader
    87  	v.Len = size
    88  	v.Cap = size
    89  	v.Data = uintptr(ptr)
    90  	d := *(*[]byte)(unsafe.Pointer(&v))
    91  	return d
    92  }
    93  
    94  func v2ToBytes[T kind.BaseType](x T) []byte {
    95  	b := make([]byte, unsafe.Sizeof(x))
    96  	endian := defaultByteOrder()
    97  	switch v := any(x).(type) {
    98  	case float64:
    99  		u64 := math.Float64bits(v)
   100  		endian.PutUint64(b, u64)
   101  	}
   102  	return b
   103  }
   104  
   105  func v3ToBytes[E kind.BaseType](x E) []byte {
   106  	size := unsafe.Sizeof(x)
   107  	ptr := unsafe.Pointer(&x)
   108  	b := (*[1]byte)(ptr)[:]
   109  	return unsafe.Slice(&b[0], size)
   110  }
   111  
   112  // ToSlice 内存空间字节数组直接转成泛型切片
   113  func ToSlice[T kind.BaseType](data []byte, n int) []T {
   114  	if n < 1 {
   115  		return []T{}
   116  	}
   117  	return v1ToSlice[T](data, n)
   118  }
   119  
   120  func v0ToSlice[T kind.BaseType](data []byte, n int) []T {
   121  	ptr := unsafe.Pointer(&data[0])
   122  	b := (*[1]T)(ptr)[:]
   123  	return unsafe.Slice(&b[0], n)
   124  }
   125  
   126  func v1ToSlice[T kind.BaseType](data []byte, n int) []T {
   127  	var v SliceHeader
   128  	v.Len = n
   129  	v.Cap = n
   130  	v.Data = uintptr(unsafe.Pointer(&data[0]))
   131  	return *(*[]T)(unsafe.Pointer(&v))
   132  }