github.com/virtao/GoTypeBytes@v0.0.0-20140410081032-5927a98cc663/typeBytes.go (about)

     1  package typeBytes
     2  
     3  import (
     4  	"github.com/virtao/GoEndian"
     5  	"unsafe"
     6  )
     7  
     8  const (
     9  	INT_SIZE       int = int(unsafe.Sizeof(0))
    10  	UINT_SIZE      int = int(unsafe.Sizeof(uint(0)))
    11  	FLOAT32_SIZE   int = 4
    12  	FLOAT64_SIZE   int = 8
    13  	DEFAULT_ENDIAN int = 0
    14  	BIG_ENDIAN     int = 1
    15  	LITTLE_ENDIAN  int = 2
    16  )
    17  
    18  func IntToBytes(n int) (ret []byte) {
    19  	return xToBytes(unsafe.Pointer(&n), INT_SIZE)
    20  }
    21  
    22  func BytesToInt(n []byte) (ret int) {
    23  	p := bytesToX(n, INT_SIZE)
    24  	ret = *((*int)(p))
    25  	return ret
    26  }
    27  
    28  func UintToBytes(n uint) (ret []byte) {
    29  	return xToBytes(unsafe.Pointer(&n), UINT_SIZE)
    30  }
    31  
    32  func BytesToUint(n []byte) (ret uint) {
    33  	p := bytesToX(n, UINT_SIZE)
    34  	ret = *((*uint)(p))
    35  	return ret
    36  }
    37  
    38  func Float32ToBytes(n float32) (ret []byte) {
    39  	return xToBytes(unsafe.Pointer(&n), FLOAT32_SIZE)
    40  }
    41  
    42  func BytesToFloat32(n []byte) (ret float32) {
    43  	p := bytesToX(n, INT_SIZE)
    44  	ret = *((*float32)(p))
    45  	return ret
    46  }
    47  
    48  func Float64ToBytes(n float64) (ret []byte) {
    49  	return xToBytes(unsafe.Pointer(&n), FLOAT64_SIZE)
    50  }
    51  
    52  func BytesToFloat64(n []byte) (ret float64) {
    53  	p := bytesToX(n, FLOAT64_SIZE)
    54  	ret = *((*float64)(p))
    55  	return ret
    56  }
    57  
    58  //np = 原始数据地址,size = 原始数据长度
    59  func xToBytes(np unsafe.Pointer, size int) (ret []byte) {
    60  	ret = make([]byte, size)
    61  	for i := 0; i < size; i++ {
    62  		ret[i] = *((*byte)(unsafe.Pointer((uintptr(np) + uintptr(i)))))
    63  	}
    64  
    65  	return ret
    66  }
    67  
    68  //n = 原始数据,size = 目标数据长度
    69  func bytesToX(n []byte, size int) (ret unsafe.Pointer) {
    70  	ns := len(n)
    71  	bytes := make([]byte, size)
    72  	if ns > size { //数组长度太大,截取前size个字节
    73  		copy(bytes, n[:size])
    74  	} else { //数组长度太小,根据大小端字节序保存,对于小端存储,原始字节顺序必须确定与小端存储顺序一致(高地址存低位,或者数组的高元素编号存低位数)
    75  		if endian.IsBigEndian() {
    76  			copy(bytes[size-ns:], n)
    77  		} else {
    78  			copy(bytes[:ns], n)
    79  		}
    80  	}
    81  
    82  	ret = getSliceArrayPointer(unsafe.Pointer(&bytes))
    83  	return ret
    84  }
    85  
    86  func getSliceArrayPointer(p unsafe.Pointer) (ret unsafe.Pointer) {
    87  	return unsafe.Pointer(*(*uintptr)(p))
    88  }
    89  
    90  func Int16ToBytes(n int16) (ret []byte) {
    91  	return Uint16ToBytes(uint16(n))
    92  }
    93  func BytesToInt16(buf []byte) (ret int16) {
    94  	return int16(BytesToUint16(buf))
    95  }
    96  func Uint16ToBytes(n uint16) (ret []byte) {
    97  	ret = make([]byte, 2)
    98  	endian.Endian.PutUint16(ret, n)
    99  	return ret
   100  }
   101  func BytesToUint16(buf []byte) (ret uint16) {
   102  	return endian.Endian.Uint16(buf)
   103  }
   104  
   105  func Int32ToBytes(n int32) (ret []byte) {
   106  	return Uint32ToBytes(uint32(n))
   107  }
   108  func BytesToInt32(buf []byte) (ret int32) {
   109  	return int32(BytesToUint32(buf))
   110  }
   111  func Uint32ToBytes(n uint32) (ret []byte) {
   112  	ret = make([]byte, 4)
   113  	endian.Endian.PutUint32(ret, n)
   114  	return ret
   115  }
   116  func BytesToUint32(buf []byte) (ret uint32) {
   117  	return endian.Endian.Uint32(buf)
   118  }
   119  
   120  func Int64ToBytes(n int64) (ret []byte) {
   121  	return Uint64ToBytes(uint64(n))
   122  }
   123  func BytesToInt64(buf []byte) (ret int64) {
   124  	return int64(BytesToUint64(buf))
   125  }
   126  func Uint64ToBytes(n uint64) (ret []byte) {
   127  	ret = make([]byte, 8)
   128  	endian.Endian.PutUint64(ret, n)
   129  	return ret
   130  }
   131  func BytesToUint64(buf []byte) (ret uint64) {
   132  	return endian.Endian.Uint64(buf)
   133  }
   134  
   135  //将字节数组前后反转,用于大小端转换
   136  func BytesReverse(data []byte) {
   137  	for i, j := 0, len(data)-1; i < j; i, j = i+1, j-1 {
   138  		data[i], data[j] = data[j], data[i]
   139  	}
   140  }
   141  
   142  //将默认字节序改为大端序,如果机器默认为大端序则没有变化。注意,会修改原数组的值
   143  func DefaultToBigEndian(data []byte) (ret []byte) {
   144  	if endian.IsLittleEndian() {
   145  		BytesReverse(data)
   146  	}
   147  	return data
   148  }
   149  
   150  //将默认字节序改为小端序,如果机器默认为小端序则没有变化,注意,会修改原数组的值
   151  func DefaultToLittleEndian(data []byte) (ret []byte) {
   152  	if endian.IsBigEndian() {
   153  		BytesReverse(data)
   154  	}
   155  	return data
   156  }