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 }