github.com/gogf/gf@v1.16.9/encoding/gbinary/gbinary_le.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gbinary
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/binary"
    12  	"fmt"
    13  	"math"
    14  )
    15  
    16  // LeEncode encodes one or multiple <values> into bytes using LittleEndian.
    17  // It uses type asserting checking the type of each value of <values> and internally
    18  // calls corresponding converting function do the bytes converting.
    19  //
    20  // It supports common variable type asserting, and finally it uses fmt.Sprintf converting
    21  // value to string and then to bytes.
    22  func LeEncode(values ...interface{}) []byte {
    23  	buf := new(bytes.Buffer)
    24  	for i := 0; i < len(values); i++ {
    25  		if values[i] == nil {
    26  			return buf.Bytes()
    27  		}
    28  
    29  		switch value := values[i].(type) {
    30  		case int:
    31  			buf.Write(LeEncodeInt(value))
    32  		case int8:
    33  			buf.Write(LeEncodeInt8(value))
    34  		case int16:
    35  			buf.Write(LeEncodeInt16(value))
    36  		case int32:
    37  			buf.Write(LeEncodeInt32(value))
    38  		case int64:
    39  			buf.Write(LeEncodeInt64(value))
    40  		case uint:
    41  			buf.Write(LeEncodeUint(value))
    42  		case uint8:
    43  			buf.Write(LeEncodeUint8(value))
    44  		case uint16:
    45  			buf.Write(LeEncodeUint16(value))
    46  		case uint32:
    47  			buf.Write(LeEncodeUint32(value))
    48  		case uint64:
    49  			buf.Write(LeEncodeUint64(value))
    50  		case bool:
    51  			buf.Write(LeEncodeBool(value))
    52  		case string:
    53  			buf.Write(LeEncodeString(value))
    54  		case []byte:
    55  			buf.Write(value)
    56  		case float32:
    57  			buf.Write(LeEncodeFloat32(value))
    58  		case float64:
    59  			buf.Write(LeEncodeFloat64(value))
    60  		default:
    61  			if err := binary.Write(buf, binary.LittleEndian, value); err != nil {
    62  				buf.Write(LeEncodeString(fmt.Sprintf("%v", value)))
    63  			}
    64  		}
    65  	}
    66  	return buf.Bytes()
    67  }
    68  
    69  // 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte);
    70  // 如果转换的二进制长度超过指定长度,那么进行截断处理
    71  func LeEncodeByLength(length int, values ...interface{}) []byte {
    72  	b := LeEncode(values...)
    73  	if len(b) < length {
    74  		b = append(b, make([]byte, length-len(b))...)
    75  	} else if len(b) > length {
    76  		b = b[0:length]
    77  	}
    78  	return b
    79  }
    80  
    81  // 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,以便确定解析的[]byte长度,
    82  // 例如:int8/16/32/64、uint8/16/32/64、float32/64等等
    83  func LeDecode(b []byte, values ...interface{}) error {
    84  	buf := bytes.NewBuffer(b)
    85  	for i := 0; i < len(values); i++ {
    86  		err := binary.Read(buf, binary.LittleEndian, values[i])
    87  		if err != nil {
    88  			return err
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  func LeEncodeString(s string) []byte {
    95  	return []byte(s)
    96  }
    97  
    98  func LeDecodeToString(b []byte) string {
    99  	return string(b)
   100  }
   101  
   102  func LeEncodeBool(b bool) []byte {
   103  	if b == true {
   104  		return []byte{1}
   105  	} else {
   106  		return []byte{0}
   107  	}
   108  }
   109  
   110  // 自动识别int类型长度,转换为[]byte
   111  func LeEncodeInt(i int) []byte {
   112  	if i <= math.MaxInt8 {
   113  		return EncodeInt8(int8(i))
   114  	} else if i <= math.MaxInt16 {
   115  		return EncodeInt16(int16(i))
   116  	} else if i <= math.MaxInt32 {
   117  		return EncodeInt32(int32(i))
   118  	} else {
   119  		return EncodeInt64(int64(i))
   120  	}
   121  }
   122  
   123  // 自动识别uint类型长度,转换为[]byte
   124  func LeEncodeUint(i uint) []byte {
   125  	if i <= math.MaxUint8 {
   126  		return EncodeUint8(uint8(i))
   127  	} else if i <= math.MaxUint16 {
   128  		return EncodeUint16(uint16(i))
   129  	} else if i <= math.MaxUint32 {
   130  		return EncodeUint32(uint32(i))
   131  	} else {
   132  		return EncodeUint64(uint64(i))
   133  	}
   134  }
   135  
   136  func LeEncodeInt8(i int8) []byte {
   137  	return []byte{byte(i)}
   138  }
   139  
   140  func LeEncodeUint8(i uint8) []byte {
   141  	return []byte{i}
   142  }
   143  
   144  func LeEncodeInt16(i int16) []byte {
   145  	b := make([]byte, 2)
   146  	binary.LittleEndian.PutUint16(b, uint16(i))
   147  	return b
   148  }
   149  
   150  func LeEncodeUint16(i uint16) []byte {
   151  	b := make([]byte, 2)
   152  	binary.LittleEndian.PutUint16(b, i)
   153  	return b
   154  }
   155  
   156  func LeEncodeInt32(i int32) []byte {
   157  	b := make([]byte, 4)
   158  	binary.LittleEndian.PutUint32(b, uint32(i))
   159  	return b
   160  }
   161  
   162  func LeEncodeUint32(i uint32) []byte {
   163  	b := make([]byte, 4)
   164  	binary.LittleEndian.PutUint32(b, i)
   165  	return b
   166  }
   167  
   168  func LeEncodeInt64(i int64) []byte {
   169  	b := make([]byte, 8)
   170  	binary.LittleEndian.PutUint64(b, uint64(i))
   171  	return b
   172  }
   173  
   174  func LeEncodeUint64(i uint64) []byte {
   175  	b := make([]byte, 8)
   176  	binary.LittleEndian.PutUint64(b, i)
   177  	return b
   178  }
   179  
   180  func LeEncodeFloat32(f float32) []byte {
   181  	bits := math.Float32bits(f)
   182  	b := make([]byte, 4)
   183  	binary.LittleEndian.PutUint32(b, bits)
   184  	return b
   185  }
   186  
   187  func LeEncodeFloat64(f float64) []byte {
   188  	bits := math.Float64bits(f)
   189  	b := make([]byte, 8)
   190  	binary.LittleEndian.PutUint64(b, bits)
   191  	return b
   192  }
   193  
   194  // 将二进制解析为int类型,根据[]byte的长度进行自动转换.
   195  // 注意内部使用的是uint*,使用int会造成位丢失。
   196  func LeDecodeToInt(b []byte) int {
   197  	if len(b) < 2 {
   198  		return int(LeDecodeToUint8(b))
   199  	} else if len(b) < 3 {
   200  		return int(LeDecodeToUint16(b))
   201  	} else if len(b) < 5 {
   202  		return int(LeDecodeToUint32(b))
   203  	} else {
   204  		return int(LeDecodeToUint64(b))
   205  	}
   206  }
   207  
   208  // 将二进制解析为uint类型,根据[]byte的长度进行自动转换
   209  func LeDecodeToUint(b []byte) uint {
   210  	if len(b) < 2 {
   211  		return uint(LeDecodeToUint8(b))
   212  	} else if len(b) < 3 {
   213  		return uint(LeDecodeToUint16(b))
   214  	} else if len(b) < 5 {
   215  		return uint(LeDecodeToUint32(b))
   216  	} else {
   217  		return uint(LeDecodeToUint64(b))
   218  	}
   219  }
   220  
   221  // 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。
   222  func LeDecodeToBool(b []byte) bool {
   223  	if len(b) == 0 {
   224  		return false
   225  	}
   226  	if bytes.Compare(b, make([]byte, len(b))) == 0 {
   227  		return false
   228  	}
   229  	return true
   230  }
   231  
   232  func LeDecodeToInt8(b []byte) int8 {
   233  	return int8(b[0])
   234  }
   235  
   236  func LeDecodeToUint8(b []byte) uint8 {
   237  	return uint8(b[0])
   238  }
   239  
   240  func LeDecodeToInt16(b []byte) int16 {
   241  	return int16(binary.LittleEndian.Uint16(LeFillUpSize(b, 2)))
   242  }
   243  
   244  func LeDecodeToUint16(b []byte) uint16 {
   245  	return binary.LittleEndian.Uint16(LeFillUpSize(b, 2))
   246  }
   247  
   248  func LeDecodeToInt32(b []byte) int32 {
   249  	return int32(binary.LittleEndian.Uint32(LeFillUpSize(b, 4)))
   250  }
   251  
   252  func LeDecodeToUint32(b []byte) uint32 {
   253  	return binary.LittleEndian.Uint32(LeFillUpSize(b, 4))
   254  }
   255  
   256  func LeDecodeToInt64(b []byte) int64 {
   257  	return int64(binary.LittleEndian.Uint64(LeFillUpSize(b, 8)))
   258  }
   259  
   260  func LeDecodeToUint64(b []byte) uint64 {
   261  	return binary.LittleEndian.Uint64(LeFillUpSize(b, 8))
   262  }
   263  
   264  func LeDecodeToFloat32(b []byte) float32 {
   265  	return math.Float32frombits(binary.LittleEndian.Uint32(LeFillUpSize(b, 4)))
   266  }
   267  
   268  func LeDecodeToFloat64(b []byte) float64 {
   269  	return math.Float64frombits(binary.LittleEndian.Uint64(LeFillUpSize(b, 8)))
   270  }
   271  
   272  // 当b位数不够时,进行高位补0。
   273  // 注意这里为了不影响原有输入参数,是采用的值复制设计。
   274  func LeFillUpSize(b []byte, l int) []byte {
   275  	if len(b) >= l {
   276  		return b[:l]
   277  	}
   278  	c := make([]byte, l)
   279  	copy(c, b)
   280  	return c
   281  }