github.com/wangyougui/gf/v2@v2.6.5/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/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  // LeEncode encodes one or multiple `values` into bytes using LittleEndian.
    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 LeEncode(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  		switch value := values[i].(type) {
    33  		case int:
    34  			buf.Write(LeEncodeInt(value))
    35  		case int8:
    36  			buf.Write(LeEncodeInt8(value))
    37  		case int16:
    38  			buf.Write(LeEncodeInt16(value))
    39  		case int32:
    40  			buf.Write(LeEncodeInt32(value))
    41  		case int64:
    42  			buf.Write(LeEncodeInt64(value))
    43  		case uint:
    44  			buf.Write(LeEncodeUint(value))
    45  		case uint8:
    46  			buf.Write(LeEncodeUint8(value))
    47  		case uint16:
    48  			buf.Write(LeEncodeUint16(value))
    49  		case uint32:
    50  			buf.Write(LeEncodeUint32(value))
    51  		case uint64:
    52  			buf.Write(LeEncodeUint64(value))
    53  		case bool:
    54  			buf.Write(LeEncodeBool(value))
    55  		case string:
    56  			buf.Write(LeEncodeString(value))
    57  		case []byte:
    58  			buf.Write(value)
    59  		case float32:
    60  			buf.Write(LeEncodeFloat32(value))
    61  		case float64:
    62  			buf.Write(LeEncodeFloat64(value))
    63  
    64  		default:
    65  			if err := binary.Write(buf, binary.LittleEndian, value); err != nil {
    66  				intlog.Errorf(context.TODO(), `%+v`, err)
    67  				buf.Write(LeEncodeString(fmt.Sprintf("%v", value)))
    68  			}
    69  		}
    70  	}
    71  	return buf.Bytes()
    72  }
    73  
    74  func LeEncodeByLength(length int, values ...interface{}) []byte {
    75  	b := LeEncode(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 LeDecode(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.LittleEndian, values[i]); err != nil {
    91  			err = gerror.Wrap(err, `binary.Read failed`)
    92  			return err
    93  		}
    94  	}
    95  	return nil
    96  }
    97  
    98  func LeEncodeString(s string) []byte {
    99  	return []byte(s)
   100  }
   101  
   102  func LeDecodeToString(b []byte) string {
   103  	return string(b)
   104  }
   105  
   106  func LeEncodeBool(b bool) []byte {
   107  	if b {
   108  		return []byte{1}
   109  	} else {
   110  		return []byte{0}
   111  	}
   112  }
   113  
   114  func LeEncodeInt(i int) []byte {
   115  	if i <= math.MaxInt8 {
   116  		return EncodeInt8(int8(i))
   117  	} else if i <= math.MaxInt16 {
   118  		return EncodeInt16(int16(i))
   119  	} else if i <= math.MaxInt32 {
   120  		return EncodeInt32(int32(i))
   121  	} else {
   122  		return EncodeInt64(int64(i))
   123  	}
   124  }
   125  
   126  func LeEncodeUint(i uint) []byte {
   127  	if i <= math.MaxUint8 {
   128  		return EncodeUint8(uint8(i))
   129  	} else if i <= math.MaxUint16 {
   130  		return EncodeUint16(uint16(i))
   131  	} else if i <= math.MaxUint32 {
   132  		return EncodeUint32(uint32(i))
   133  	} else {
   134  		return EncodeUint64(uint64(i))
   135  	}
   136  }
   137  
   138  func LeEncodeInt8(i int8) []byte {
   139  	return []byte{byte(i)}
   140  }
   141  
   142  func LeEncodeUint8(i uint8) []byte {
   143  	return []byte{i}
   144  }
   145  
   146  func LeEncodeInt16(i int16) []byte {
   147  	b := make([]byte, 2)
   148  	binary.LittleEndian.PutUint16(b, uint16(i))
   149  	return b
   150  }
   151  
   152  func LeEncodeUint16(i uint16) []byte {
   153  	b := make([]byte, 2)
   154  	binary.LittleEndian.PutUint16(b, i)
   155  	return b
   156  }
   157  
   158  func LeEncodeInt32(i int32) []byte {
   159  	b := make([]byte, 4)
   160  	binary.LittleEndian.PutUint32(b, uint32(i))
   161  	return b
   162  }
   163  
   164  func LeEncodeUint32(i uint32) []byte {
   165  	b := make([]byte, 4)
   166  	binary.LittleEndian.PutUint32(b, i)
   167  	return b
   168  }
   169  
   170  func LeEncodeInt64(i int64) []byte {
   171  	b := make([]byte, 8)
   172  	binary.LittleEndian.PutUint64(b, uint64(i))
   173  	return b
   174  }
   175  
   176  func LeEncodeUint64(i uint64) []byte {
   177  	b := make([]byte, 8)
   178  	binary.LittleEndian.PutUint64(b, i)
   179  	return b
   180  }
   181  
   182  func LeEncodeFloat32(f float32) []byte {
   183  	bits := math.Float32bits(f)
   184  	b := make([]byte, 4)
   185  	binary.LittleEndian.PutUint32(b, bits)
   186  	return b
   187  }
   188  
   189  func LeEncodeFloat64(f float64) []byte {
   190  	bits := math.Float64bits(f)
   191  	b := make([]byte, 8)
   192  	binary.LittleEndian.PutUint64(b, bits)
   193  	return b
   194  }
   195  
   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  func LeDecodeToUint(b []byte) uint {
   209  	if len(b) < 2 {
   210  		return uint(LeDecodeToUint8(b))
   211  	} else if len(b) < 3 {
   212  		return uint(LeDecodeToUint16(b))
   213  	} else if len(b) < 5 {
   214  		return uint(LeDecodeToUint32(b))
   215  	} else {
   216  		return uint(LeDecodeToUint64(b))
   217  	}
   218  }
   219  
   220  func LeDecodeToBool(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 LeDecodeToInt8(b []byte) int8 {
   231  	if len(b) == 0 {
   232  		panic(`empty slice given`)
   233  	}
   234  	return int8(b[0])
   235  }
   236  
   237  func LeDecodeToUint8(b []byte) uint8 {
   238  	if len(b) == 0 {
   239  		panic(`empty slice given`)
   240  	}
   241  	return b[0]
   242  }
   243  
   244  func LeDecodeToInt16(b []byte) int16 {
   245  	return int16(binary.LittleEndian.Uint16(LeFillUpSize(b, 2)))
   246  }
   247  
   248  func LeDecodeToUint16(b []byte) uint16 {
   249  	return binary.LittleEndian.Uint16(LeFillUpSize(b, 2))
   250  }
   251  
   252  func LeDecodeToInt32(b []byte) int32 {
   253  	return int32(binary.LittleEndian.Uint32(LeFillUpSize(b, 4)))
   254  }
   255  
   256  func LeDecodeToUint32(b []byte) uint32 {
   257  	return binary.LittleEndian.Uint32(LeFillUpSize(b, 4))
   258  }
   259  
   260  func LeDecodeToInt64(b []byte) int64 {
   261  	return int64(binary.LittleEndian.Uint64(LeFillUpSize(b, 8)))
   262  }
   263  
   264  func LeDecodeToUint64(b []byte) uint64 {
   265  	return binary.LittleEndian.Uint64(LeFillUpSize(b, 8))
   266  }
   267  
   268  func LeDecodeToFloat32(b []byte) float32 {
   269  	return math.Float32frombits(binary.LittleEndian.Uint32(LeFillUpSize(b, 4)))
   270  }
   271  
   272  func LeDecodeToFloat64(b []byte) float64 {
   273  	return math.Float64frombits(binary.LittleEndian.Uint64(LeFillUpSize(b, 8)))
   274  }
   275  
   276  // LeFillUpSize fills up the bytes `b` to given length `l` using LittleEndian.
   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 LeFillUpSize(b []byte, l int) []byte {
   281  	if len(b) >= l {
   282  		return b[:l]
   283  	}
   284  	c := make([]byte, l)
   285  	copy(c, b)
   286  	return c
   287  }