github.com/gogf/gf@v1.16.9/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/gogf/gf. 6 7 package gbinary 8 9 import ( 10 "bytes" 11 "encoding/binary" 12 "fmt" 13 "math" 14 ) 15 16 // LeEncode encodes one or multiple <values> into bytes using LittleEndian. 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 LeEncode(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(LeEncodeInt(value)) 32 case int8: 33 buf.Write(LeEncodeInt8(value)) 34 case int16: 35 buf.Write(LeEncodeInt16(value)) 36 case int32: 37 buf.Write(LeEncodeInt32(value)) 38 case int64: 39 buf.Write(LeEncodeInt64(value)) 40 case uint: 41 buf.Write(LeEncodeUint(value)) 42 case uint8: 43 buf.Write(LeEncodeUint8(value)) 44 case uint16: 45 buf.Write(LeEncodeUint16(value)) 46 case uint32: 47 buf.Write(LeEncodeUint32(value)) 48 case uint64: 49 buf.Write(LeEncodeUint64(value)) 50 case bool: 51 buf.Write(LeEncodeBool(value)) 52 case string: 53 buf.Write(LeEncodeString(value)) 54 case []byte: 55 buf.Write(value) 56 case float32: 57 buf.Write(LeEncodeFloat32(value)) 58 case float64: 59 buf.Write(LeEncodeFloat64(value)) 60 default: 61 if err := binary.Write(buf, binary.LittleEndian, value); err != nil { 62 buf.Write(LeEncodeString(fmt.Sprintf("%v", value))) 63 } 64 } 65 } 66 return buf.Bytes() 67 } 68 69 // 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte); 70 // 如果转换的二进制长度超过指定长度,那么进行截断处理 71 func LeEncodeByLength(length int, values ...interface{}) []byte { 72 b := LeEncode(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 LeDecode(b []byte, values ...interface{}) error { 84 buf := bytes.NewBuffer(b) 85 for i := 0; i < len(values); i++ { 86 err := binary.Read(buf, binary.LittleEndian, values[i]) 87 if err != nil { 88 return err 89 } 90 } 91 return nil 92 } 93 94 func LeEncodeString(s string) []byte { 95 return []byte(s) 96 } 97 98 func LeDecodeToString(b []byte) string { 99 return string(b) 100 } 101 102 func LeEncodeBool(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 LeEncodeInt(i int) []byte { 112 if i <= math.MaxInt8 { 113 return EncodeInt8(int8(i)) 114 } else if i <= math.MaxInt16 { 115 return EncodeInt16(int16(i)) 116 } else if i <= math.MaxInt32 { 117 return EncodeInt32(int32(i)) 118 } else { 119 return EncodeInt64(int64(i)) 120 } 121 } 122 123 // 自动识别uint类型长度,转换为[]byte 124 func LeEncodeUint(i uint) []byte { 125 if i <= math.MaxUint8 { 126 return EncodeUint8(uint8(i)) 127 } else if i <= math.MaxUint16 { 128 return EncodeUint16(uint16(i)) 129 } else if i <= math.MaxUint32 { 130 return EncodeUint32(uint32(i)) 131 } else { 132 return EncodeUint64(uint64(i)) 133 } 134 } 135 136 func LeEncodeInt8(i int8) []byte { 137 return []byte{byte(i)} 138 } 139 140 func LeEncodeUint8(i uint8) []byte { 141 return []byte{i} 142 } 143 144 func LeEncodeInt16(i int16) []byte { 145 b := make([]byte, 2) 146 binary.LittleEndian.PutUint16(b, uint16(i)) 147 return b 148 } 149 150 func LeEncodeUint16(i uint16) []byte { 151 b := make([]byte, 2) 152 binary.LittleEndian.PutUint16(b, i) 153 return b 154 } 155 156 func LeEncodeInt32(i int32) []byte { 157 b := make([]byte, 4) 158 binary.LittleEndian.PutUint32(b, uint32(i)) 159 return b 160 } 161 162 func LeEncodeUint32(i uint32) []byte { 163 b := make([]byte, 4) 164 binary.LittleEndian.PutUint32(b, i) 165 return b 166 } 167 168 func LeEncodeInt64(i int64) []byte { 169 b := make([]byte, 8) 170 binary.LittleEndian.PutUint64(b, uint64(i)) 171 return b 172 } 173 174 func LeEncodeUint64(i uint64) []byte { 175 b := make([]byte, 8) 176 binary.LittleEndian.PutUint64(b, i) 177 return b 178 } 179 180 func LeEncodeFloat32(f float32) []byte { 181 bits := math.Float32bits(f) 182 b := make([]byte, 4) 183 binary.LittleEndian.PutUint32(b, bits) 184 return b 185 } 186 187 func LeEncodeFloat64(f float64) []byte { 188 bits := math.Float64bits(f) 189 b := make([]byte, 8) 190 binary.LittleEndian.PutUint64(b, bits) 191 return b 192 } 193 194 // 将二进制解析为int类型,根据[]byte的长度进行自动转换. 195 // 注意内部使用的是uint*,使用int会造成位丢失。 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 // 将二进制解析为uint类型,根据[]byte的长度进行自动转换 209 func LeDecodeToUint(b []byte) uint { 210 if len(b) < 2 { 211 return uint(LeDecodeToUint8(b)) 212 } else if len(b) < 3 { 213 return uint(LeDecodeToUint16(b)) 214 } else if len(b) < 5 { 215 return uint(LeDecodeToUint32(b)) 216 } else { 217 return uint(LeDecodeToUint64(b)) 218 } 219 } 220 221 // 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。 222 func LeDecodeToBool(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 LeDecodeToInt8(b []byte) int8 { 233 return int8(b[0]) 234 } 235 236 func LeDecodeToUint8(b []byte) uint8 { 237 return uint8(b[0]) 238 } 239 240 func LeDecodeToInt16(b []byte) int16 { 241 return int16(binary.LittleEndian.Uint16(LeFillUpSize(b, 2))) 242 } 243 244 func LeDecodeToUint16(b []byte) uint16 { 245 return binary.LittleEndian.Uint16(LeFillUpSize(b, 2)) 246 } 247 248 func LeDecodeToInt32(b []byte) int32 { 249 return int32(binary.LittleEndian.Uint32(LeFillUpSize(b, 4))) 250 } 251 252 func LeDecodeToUint32(b []byte) uint32 { 253 return binary.LittleEndian.Uint32(LeFillUpSize(b, 4)) 254 } 255 256 func LeDecodeToInt64(b []byte) int64 { 257 return int64(binary.LittleEndian.Uint64(LeFillUpSize(b, 8))) 258 } 259 260 func LeDecodeToUint64(b []byte) uint64 { 261 return binary.LittleEndian.Uint64(LeFillUpSize(b, 8)) 262 } 263 264 func LeDecodeToFloat32(b []byte) float32 { 265 return math.Float32frombits(binary.LittleEndian.Uint32(LeFillUpSize(b, 4))) 266 } 267 268 func LeDecodeToFloat64(b []byte) float64 { 269 return math.Float64frombits(binary.LittleEndian.Uint64(LeFillUpSize(b, 8))) 270 } 271 272 // 当b位数不够时,进行高位补0。 273 // 注意这里为了不影响原有输入参数,是采用的值复制设计。 274 func LeFillUpSize(b []byte, l int) []byte { 275 if len(b) >= l { 276 return b[:l] 277 } 278 c := make([]byte, l) 279 copy(c, b) 280 return c 281 }