github.com/gogf/gf@v1.16.9/encoding/gbinary/gbinary_be.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  // BeEncode encodes one or multiple <values> into bytes using BigEndian.
    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 BeEncode(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(BeEncodeInt(value))
    32  		case int8:
    33  			buf.Write(BeEncodeInt8(value))
    34  		case int16:
    35  			buf.Write(BeEncodeInt16(value))
    36  		case int32:
    37  			buf.Write(BeEncodeInt32(value))
    38  		case int64:
    39  			buf.Write(BeEncodeInt64(value))
    40  		case uint:
    41  			buf.Write(BeEncodeUint(value))
    42  		case uint8:
    43  			buf.Write(BeEncodeUint8(value))
    44  		case uint16:
    45  			buf.Write(BeEncodeUint16(value))
    46  		case uint32:
    47  			buf.Write(BeEncodeUint32(value))
    48  		case uint64:
    49  			buf.Write(BeEncodeUint64(value))
    50  		case bool:
    51  			buf.Write(BeEncodeBool(value))
    52  		case string:
    53  			buf.Write(BeEncodeString(value))
    54  		case []byte:
    55  			buf.Write(value)
    56  		case float32:
    57  			buf.Write(BeEncodeFloat32(value))
    58  		case float64:
    59  			buf.Write(BeEncodeFloat64(value))
    60  		default:
    61  			if err := binary.Write(buf, binary.BigEndian, value); err != nil {
    62  				buf.Write(BeEncodeString(fmt.Sprintf("%v", value)))
    63  			}
    64  		}
    65  	}
    66  	return buf.Bytes()
    67  }
    68  
    69  // 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte);
    70  // 如果转换的二进制长度超过指定长度,那么进行截断处理
    71  func BeEncodeByLength(length int, values ...interface{}) []byte {
    72  	b := BeEncode(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 BeDecode(b []byte, values ...interface{}) error {
    84  	buf := bytes.NewBuffer(b)
    85  	for i := 0; i < len(values); i++ {
    86  		err := binary.Read(buf, binary.BigEndian, values[i])
    87  		if err != nil {
    88  			return err
    89  		}
    90  	}
    91  	return nil
    92  }
    93  
    94  func BeEncodeString(s string) []byte {
    95  	return []byte(s)
    96  }
    97  
    98  func BeDecodeToString(b []byte) string {
    99  	return string(b)
   100  }
   101  
   102  func BeEncodeBool(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 BeEncodeInt(i int) []byte {
   112  	if i <= math.MaxInt8 {
   113  		return BeEncodeInt8(int8(i))
   114  	} else if i <= math.MaxInt16 {
   115  		return BeEncodeInt16(int16(i))
   116  	} else if i <= math.MaxInt32 {
   117  		return BeEncodeInt32(int32(i))
   118  	} else {
   119  		return BeEncodeInt64(int64(i))
   120  	}
   121  }
   122  
   123  // 自动识别uint类型长度,转换为[]byte
   124  func BeEncodeUint(i uint) []byte {
   125  	if i <= math.MaxUint8 {
   126  		return BeEncodeUint8(uint8(i))
   127  	} else if i <= math.MaxUint16 {
   128  		return BeEncodeUint16(uint16(i))
   129  	} else if i <= math.MaxUint32 {
   130  		return BeEncodeUint32(uint32(i))
   131  	} else {
   132  		return BeEncodeUint64(uint64(i))
   133  	}
   134  }
   135  
   136  func BeEncodeInt8(i int8) []byte {
   137  	return []byte{byte(i)}
   138  }
   139  
   140  func BeEncodeUint8(i uint8) []byte {
   141  	return []byte{i}
   142  }
   143  
   144  func BeEncodeInt16(i int16) []byte {
   145  	b := make([]byte, 2)
   146  	binary.BigEndian.PutUint16(b, uint16(i))
   147  	return b
   148  }
   149  
   150  func BeEncodeUint16(i uint16) []byte {
   151  	b := make([]byte, 2)
   152  	binary.BigEndian.PutUint16(b, i)
   153  	return b
   154  }
   155  
   156  func BeEncodeInt32(i int32) []byte {
   157  	b := make([]byte, 4)
   158  	binary.BigEndian.PutUint32(b, uint32(i))
   159  	return b
   160  }
   161  
   162  func BeEncodeUint32(i uint32) []byte {
   163  	b := make([]byte, 4)
   164  	binary.BigEndian.PutUint32(b, i)
   165  	return b
   166  }
   167  
   168  func BeEncodeInt64(i int64) []byte {
   169  	b := make([]byte, 8)
   170  	binary.BigEndian.PutUint64(b, uint64(i))
   171  	return b
   172  }
   173  
   174  func BeEncodeUint64(i uint64) []byte {
   175  	b := make([]byte, 8)
   176  	binary.BigEndian.PutUint64(b, i)
   177  	return b
   178  }
   179  
   180  func BeEncodeFloat32(f float32) []byte {
   181  	bits := math.Float32bits(f)
   182  	b := make([]byte, 4)
   183  	binary.BigEndian.PutUint32(b, bits)
   184  	return b
   185  }
   186  
   187  func BeEncodeFloat64(f float64) []byte {
   188  	bits := math.Float64bits(f)
   189  	b := make([]byte, 8)
   190  	binary.BigEndian.PutUint64(b, bits)
   191  	return b
   192  }
   193  
   194  // 将二进制解析为int类型,根据[]byte的长度进行自动转换.
   195  // 注意内部使用的是uint*,使用int会造成位丢失。
   196  func BeDecodeToInt(b []byte) int {
   197  	if len(b) < 2 {
   198  		return int(BeDecodeToUint8(b))
   199  	} else if len(b) < 3 {
   200  		return int(BeDecodeToUint16(b))
   201  	} else if len(b) < 5 {
   202  		return int(BeDecodeToUint32(b))
   203  	} else {
   204  		return int(BeDecodeToUint64(b))
   205  	}
   206  }
   207  
   208  // 将二进制解析为uint类型,根据[]byte的长度进行自动转换
   209  func BeDecodeToUint(b []byte) uint {
   210  	if len(b) < 2 {
   211  		return uint(BeDecodeToUint8(b))
   212  	} else if len(b) < 3 {
   213  		return uint(BeDecodeToUint16(b))
   214  	} else if len(b) < 5 {
   215  		return uint(BeDecodeToUint32(b))
   216  	} else {
   217  		return uint(BeDecodeToUint64(b))
   218  	}
   219  }
   220  
   221  // 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。
   222  func BeDecodeToBool(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 BeDecodeToInt8(b []byte) int8 {
   233  	return int8(b[0])
   234  }
   235  
   236  func BeDecodeToUint8(b []byte) uint8 {
   237  	return uint8(b[0])
   238  }
   239  
   240  func BeDecodeToInt16(b []byte) int16 {
   241  	return int16(binary.BigEndian.Uint16(BeFillUpSize(b, 2)))
   242  }
   243  
   244  func BeDecodeToUint16(b []byte) uint16 {
   245  	return binary.BigEndian.Uint16(BeFillUpSize(b, 2))
   246  }
   247  
   248  func BeDecodeToInt32(b []byte) int32 {
   249  	return int32(binary.BigEndian.Uint32(BeFillUpSize(b, 4)))
   250  }
   251  
   252  func BeDecodeToUint32(b []byte) uint32 {
   253  	return binary.BigEndian.Uint32(BeFillUpSize(b, 4))
   254  }
   255  
   256  func BeDecodeToInt64(b []byte) int64 {
   257  	return int64(binary.BigEndian.Uint64(BeFillUpSize(b, 8)))
   258  }
   259  
   260  func BeDecodeToUint64(b []byte) uint64 {
   261  	return binary.BigEndian.Uint64(BeFillUpSize(b, 8))
   262  }
   263  
   264  func BeDecodeToFloat32(b []byte) float32 {
   265  	return math.Float32frombits(binary.BigEndian.Uint32(BeFillUpSize(b, 4)))
   266  }
   267  
   268  func BeDecodeToFloat64(b []byte) float64 {
   269  	return math.Float64frombits(binary.BigEndian.Uint64(BeFillUpSize(b, 8)))
   270  }
   271  
   272  // BeFillUpSize fills up the bytes <b> to given length <l> using big BigEndian.
   273  //
   274  // Note that it creates a new bytes slice by copying the original one to avoid changing
   275  // the original parameter bytes.
   276  func BeFillUpSize(b []byte, l int) []byte {
   277  	if len(b) >= l {
   278  		return b[:l]
   279  	}
   280  	c := make([]byte, l)
   281  	copy(c[l-len(b):], b)
   282  	return c
   283  }