github.com/zhongdalu/gf@v1.0.0/g/encoding/gbinary/gbinary_le.go (about)

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