github.com/wangyougui/gf/v2@v2.6.5/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/wangyougui/gf.
     6  
     7  package gbinary
     8  
     9  import (
    10  	"bytes"
    11  	"context"
    12  	"encoding/binary"
    13  	"fmt"
    14  	"math"
    15  
    16  	"github.com/wangyougui/gf/v2/errors/gerror"
    17  	"github.com/wangyougui/gf/v2/internal/intlog"
    18  )
    19  
    20  // BeEncode encodes one or multiple `values` into bytes using BigEndian.
    21  // It uses type asserting checking the type of each value of `values` and internally
    22  // calls corresponding converting function do the bytes converting.
    23  //
    24  // It supports common variable type asserting, and finally it uses fmt.Sprintf converting
    25  // value to string and then to bytes.
    26  func BeEncode(values ...interface{}) []byte {
    27  	buf := new(bytes.Buffer)
    28  	for i := 0; i < len(values); i++ {
    29  		if values[i] == nil {
    30  			return buf.Bytes()
    31  		}
    32  
    33  		switch value := values[i].(type) {
    34  		case int:
    35  			buf.Write(BeEncodeInt(value))
    36  		case int8:
    37  			buf.Write(BeEncodeInt8(value))
    38  		case int16:
    39  			buf.Write(BeEncodeInt16(value))
    40  		case int32:
    41  			buf.Write(BeEncodeInt32(value))
    42  		case int64:
    43  			buf.Write(BeEncodeInt64(value))
    44  		case uint:
    45  			buf.Write(BeEncodeUint(value))
    46  		case uint8:
    47  			buf.Write(BeEncodeUint8(value))
    48  		case uint16:
    49  			buf.Write(BeEncodeUint16(value))
    50  		case uint32:
    51  			buf.Write(BeEncodeUint32(value))
    52  		case uint64:
    53  			buf.Write(BeEncodeUint64(value))
    54  		case bool:
    55  			buf.Write(BeEncodeBool(value))
    56  		case string:
    57  			buf.Write(BeEncodeString(value))
    58  		case []byte:
    59  			buf.Write(value)
    60  		case float32:
    61  			buf.Write(BeEncodeFloat32(value))
    62  		case float64:
    63  			buf.Write(BeEncodeFloat64(value))
    64  		default:
    65  			if err := binary.Write(buf, binary.BigEndian, value); err != nil {
    66  				intlog.Errorf(context.TODO(), `%+v`, err)
    67  				buf.Write(BeEncodeString(fmt.Sprintf("%v", value)))
    68  			}
    69  		}
    70  	}
    71  	return buf.Bytes()
    72  }
    73  
    74  func BeEncodeByLength(length int, values ...interface{}) []byte {
    75  	b := BeEncode(values...)
    76  	if len(b) < length {
    77  		b = append(b, make([]byte, length-len(b))...)
    78  	} else if len(b) > length {
    79  		b = b[0:length]
    80  	}
    81  	return b
    82  }
    83  
    84  func BeDecode(b []byte, values ...interface{}) error {
    85  	var (
    86  		err error
    87  		buf = bytes.NewBuffer(b)
    88  	)
    89  	for i := 0; i < len(values); i++ {
    90  		if err = binary.Read(buf, binary.BigEndian, values[i]); err != nil {
    91  			err = gerror.Wrap(err, `binary.Read failed`)
    92  			return err
    93  		}
    94  	}
    95  	return nil
    96  }
    97  
    98  func BeEncodeString(s string) []byte {
    99  	return []byte(s)
   100  }
   101  
   102  func BeDecodeToString(b []byte) string {
   103  	return string(b)
   104  }
   105  
   106  func BeEncodeBool(b bool) []byte {
   107  	if b {
   108  		return []byte{1}
   109  	} else {
   110  		return []byte{0}
   111  	}
   112  }
   113  
   114  func BeEncodeInt(i int) []byte {
   115  	if i <= math.MaxInt8 {
   116  		return BeEncodeInt8(int8(i))
   117  	} else if i <= math.MaxInt16 {
   118  		return BeEncodeInt16(int16(i))
   119  	} else if i <= math.MaxInt32 {
   120  		return BeEncodeInt32(int32(i))
   121  	} else {
   122  		return BeEncodeInt64(int64(i))
   123  	}
   124  }
   125  
   126  func BeEncodeUint(i uint) []byte {
   127  	if i <= math.MaxUint8 {
   128  		return BeEncodeUint8(uint8(i))
   129  	} else if i <= math.MaxUint16 {
   130  		return BeEncodeUint16(uint16(i))
   131  	} else if i <= math.MaxUint32 {
   132  		return BeEncodeUint32(uint32(i))
   133  	} else {
   134  		return BeEncodeUint64(uint64(i))
   135  	}
   136  }
   137  
   138  func BeEncodeInt8(i int8) []byte {
   139  	return []byte{byte(i)}
   140  }
   141  
   142  func BeEncodeUint8(i uint8) []byte {
   143  	return []byte{i}
   144  }
   145  
   146  func BeEncodeInt16(i int16) []byte {
   147  	b := make([]byte, 2)
   148  	binary.BigEndian.PutUint16(b, uint16(i))
   149  	return b
   150  }
   151  
   152  func BeEncodeUint16(i uint16) []byte {
   153  	b := make([]byte, 2)
   154  	binary.BigEndian.PutUint16(b, i)
   155  	return b
   156  }
   157  
   158  func BeEncodeInt32(i int32) []byte {
   159  	b := make([]byte, 4)
   160  	binary.BigEndian.PutUint32(b, uint32(i))
   161  	return b
   162  }
   163  
   164  func BeEncodeUint32(i uint32) []byte {
   165  	b := make([]byte, 4)
   166  	binary.BigEndian.PutUint32(b, i)
   167  	return b
   168  }
   169  
   170  func BeEncodeInt64(i int64) []byte {
   171  	b := make([]byte, 8)
   172  	binary.BigEndian.PutUint64(b, uint64(i))
   173  	return b
   174  }
   175  
   176  func BeEncodeUint64(i uint64) []byte {
   177  	b := make([]byte, 8)
   178  	binary.BigEndian.PutUint64(b, i)
   179  	return b
   180  }
   181  
   182  func BeEncodeFloat32(f float32) []byte {
   183  	bits := math.Float32bits(f)
   184  	b := make([]byte, 4)
   185  	binary.BigEndian.PutUint32(b, bits)
   186  	return b
   187  }
   188  
   189  func BeEncodeFloat64(f float64) []byte {
   190  	bits := math.Float64bits(f)
   191  	b := make([]byte, 8)
   192  	binary.BigEndian.PutUint64(b, bits)
   193  	return b
   194  }
   195  
   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  func BeDecodeToUint(b []byte) uint {
   209  	if len(b) < 2 {
   210  		return uint(BeDecodeToUint8(b))
   211  	} else if len(b) < 3 {
   212  		return uint(BeDecodeToUint16(b))
   213  	} else if len(b) < 5 {
   214  		return uint(BeDecodeToUint32(b))
   215  	} else {
   216  		return uint(BeDecodeToUint64(b))
   217  	}
   218  }
   219  
   220  func BeDecodeToBool(b []byte) bool {
   221  	if len(b) == 0 {
   222  		return false
   223  	}
   224  	if bytes.Equal(b, make([]byte, len(b))) {
   225  		return false
   226  	}
   227  	return true
   228  }
   229  
   230  func BeDecodeToInt8(b []byte) int8 {
   231  	if len(b) == 0 {
   232  		panic(`empty slice given`)
   233  	}
   234  	return int8(b[0])
   235  }
   236  
   237  func BeDecodeToUint8(b []byte) uint8 {
   238  	if len(b) == 0 {
   239  		panic(`empty slice given`)
   240  	}
   241  	return b[0]
   242  }
   243  
   244  func BeDecodeToInt16(b []byte) int16 {
   245  	return int16(binary.BigEndian.Uint16(BeFillUpSize(b, 2)))
   246  }
   247  
   248  func BeDecodeToUint16(b []byte) uint16 {
   249  	return binary.BigEndian.Uint16(BeFillUpSize(b, 2))
   250  }
   251  
   252  func BeDecodeToInt32(b []byte) int32 {
   253  	return int32(binary.BigEndian.Uint32(BeFillUpSize(b, 4)))
   254  }
   255  
   256  func BeDecodeToUint32(b []byte) uint32 {
   257  	return binary.BigEndian.Uint32(BeFillUpSize(b, 4))
   258  }
   259  
   260  func BeDecodeToInt64(b []byte) int64 {
   261  	return int64(binary.BigEndian.Uint64(BeFillUpSize(b, 8)))
   262  }
   263  
   264  func BeDecodeToUint64(b []byte) uint64 {
   265  	return binary.BigEndian.Uint64(BeFillUpSize(b, 8))
   266  }
   267  
   268  func BeDecodeToFloat32(b []byte) float32 {
   269  	return math.Float32frombits(binary.BigEndian.Uint32(BeFillUpSize(b, 4)))
   270  }
   271  
   272  func BeDecodeToFloat64(b []byte) float64 {
   273  	return math.Float64frombits(binary.BigEndian.Uint64(BeFillUpSize(b, 8)))
   274  }
   275  
   276  // BeFillUpSize fills up the bytes `b` to given length `l` using big BigEndian.
   277  //
   278  // Note that it creates a new bytes slice by copying the original one to avoid changing
   279  // the original parameter bytes.
   280  func BeFillUpSize(b []byte, l int) []byte {
   281  	if len(b) >= l {
   282  		return b[:l]
   283  	}
   284  	c := make([]byte, l)
   285  	copy(c[l-len(b):], b)
   286  	return c
   287  }