github.com/zhongdalu/gf@v1.0.0/g/encoding/gbinary/gbinary_le.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). 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/zhongdalu/gf. 6 7 package gbinary 8 9 import ( 10 "bytes" 11 "encoding/binary" 12 "fmt" 13 "math" 14 ) 15 16 // 针对基本类型进行二进制打包,支持的基本数据类型包括: 17 // int/8/16/32/64、uint/8/16/32/64、float32/64、bool、string、[]byte。 18 // 其他未知类型使用 fmt.Sprintf("%v", value) 转换为字符串之后处理。 19 func LeEncode(values ...interface{}) []byte { 20 buf := new(bytes.Buffer) 21 for i := 0; i < len(values); i++ { 22 if values[i] == nil { 23 return buf.Bytes() 24 } 25 26 switch value := values[i].(type) { 27 case int: 28 buf.Write(LeEncodeInt(value)) 29 case int8: 30 buf.Write(LeEncodeInt8(value)) 31 case int16: 32 buf.Write(LeEncodeInt16(value)) 33 case int32: 34 buf.Write(LeEncodeInt32(value)) 35 case int64: 36 buf.Write(LeEncodeInt64(value)) 37 case uint: 38 buf.Write(LeEncodeUint(value)) 39 case uint8: 40 buf.Write(LeEncodeUint8(value)) 41 case uint16: 42 buf.Write(LeEncodeUint16(value)) 43 case uint32: 44 buf.Write(LeEncodeUint32(value)) 45 case uint64: 46 buf.Write(LeEncodeUint64(value)) 47 case bool: 48 buf.Write(LeEncodeBool(value)) 49 case string: 50 buf.Write(LeEncodeString(value)) 51 case []byte: 52 buf.Write(value) 53 case float32: 54 buf.Write(LeEncodeFloat32(value)) 55 case float64: 56 buf.Write(LeEncodeFloat64(value)) 57 default: 58 if err := binary.Write(buf, binary.LittleEndian, value); err != nil { 59 buf.Write(LeEncodeString(fmt.Sprintf("%v", value))) 60 } 61 } 62 } 63 return buf.Bytes() 64 } 65 66 // 将变量转换为二进制[]byte,并指定固定的[]byte长度返回,长度单位为字节(byte); 67 // 如果转换的二进制长度超过指定长度,那么进行截断处理 68 func LeEncodeByLength(length int, values ...interface{}) []byte { 69 b := LeEncode(values...) 70 if len(b) < length { 71 b = append(b, make([]byte, length-len(b))...) 72 } else if len(b) > length { 73 b = b[0:length] 74 } 75 return b 76 } 77 78 // 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,以便确定解析的[]byte长度, 79 // 例如:int8/16/32/64、uint8/16/32/64、float32/64等等 80 func LeDecode(b []byte, values ...interface{}) error { 81 buf := bytes.NewBuffer(b) 82 for i := 0; i < len(values); i++ { 83 err := binary.Read(buf, binary.LittleEndian, values[i]) 84 if err != nil { 85 return err 86 } 87 } 88 return nil 89 } 90 91 func LeEncodeString(s string) []byte { 92 return []byte(s) 93 } 94 95 func LeDecodeToString(b []byte) string { 96 return string(b) 97 } 98 99 func LeEncodeBool(b bool) []byte { 100 if b == true { 101 return []byte{1} 102 } else { 103 return []byte{0} 104 } 105 } 106 107 // 自动识别int类型长度,转换为[]byte 108 func LeEncodeInt(i int) []byte { 109 if i <= math.MaxInt8 { 110 return EncodeInt8(int8(i)) 111 } else if i <= math.MaxInt16 { 112 return EncodeInt16(int16(i)) 113 } else if i <= math.MaxInt32 { 114 return EncodeInt32(int32(i)) 115 } else { 116 return EncodeInt64(int64(i)) 117 } 118 } 119 120 // 自动识别uint类型长度,转换为[]byte 121 func LeEncodeUint(i uint) []byte { 122 if i <= math.MaxUint8 { 123 return EncodeUint8(uint8(i)) 124 } else if i <= math.MaxUint16 { 125 return EncodeUint16(uint16(i)) 126 } else if i <= math.MaxUint32 { 127 return EncodeUint32(uint32(i)) 128 } else { 129 return EncodeUint64(uint64(i)) 130 } 131 } 132 133 func LeEncodeInt8(i int8) []byte { 134 return []byte{byte(i)} 135 } 136 137 func LeEncodeUint8(i uint8) []byte { 138 return []byte{byte(i)} 139 } 140 141 func LeEncodeInt16(i int16) []byte { 142 b := make([]byte, 2) 143 binary.LittleEndian.PutUint16(b, uint16(i)) 144 return b 145 } 146 147 func LeEncodeUint16(i uint16) []byte { 148 b := make([]byte, 2) 149 binary.LittleEndian.PutUint16(b, i) 150 return b 151 } 152 153 func LeEncodeInt32(i int32) []byte { 154 b := make([]byte, 4) 155 binary.LittleEndian.PutUint32(b, uint32(i)) 156 return b 157 } 158 159 func LeEncodeUint32(i uint32) []byte { 160 b := make([]byte, 4) 161 binary.LittleEndian.PutUint32(b, i) 162 return b 163 } 164 165 func LeEncodeInt64(i int64) []byte { 166 b := make([]byte, 8) 167 binary.LittleEndian.PutUint64(b, uint64(i)) 168 return b 169 } 170 171 func LeEncodeUint64(i uint64) []byte { 172 b := make([]byte, 8) 173 binary.LittleEndian.PutUint64(b, i) 174 return b 175 } 176 177 func LeEncodeFloat32(f float32) []byte { 178 bits := math.Float32bits(f) 179 b := make([]byte, 4) 180 binary.LittleEndian.PutUint32(b, bits) 181 return b 182 } 183 184 func LeEncodeFloat64(f float64) []byte { 185 bits := math.Float64bits(f) 186 b := make([]byte, 8) 187 binary.LittleEndian.PutUint64(b, bits) 188 return b 189 } 190 191 // 将二进制解析为int类型,根据[]byte的长度进行自动转换. 192 // 注意内部使用的是uint*,使用int会造成位丢失。 193 func LeDecodeToInt(b []byte) int { 194 if len(b) < 2 { 195 return int(LeDecodeToUint8(b)) 196 } else if len(b) < 3 { 197 return int(LeDecodeToUint16(b)) 198 } else if len(b) < 5 { 199 return int(LeDecodeToUint32(b)) 200 } else { 201 return int(LeDecodeToUint64(b)) 202 } 203 } 204 205 // 将二进制解析为uint类型,根据[]byte的长度进行自动转换 206 func LeDecodeToUint(b []byte) uint { 207 if len(b) < 2 { 208 return uint(LeDecodeToUint8(b)) 209 } else if len(b) < 3 { 210 return uint(LeDecodeToUint16(b)) 211 } else if len(b) < 5 { 212 return uint(LeDecodeToUint32(b)) 213 } else { 214 return uint(LeDecodeToUint64(b)) 215 } 216 } 217 218 // 将二进制解析为bool类型,识别标准是判断二进制中数值是否都为0,或者为空。 219 func LeDecodeToBool(b []byte) bool { 220 if len(b) == 0 { 221 return false 222 } 223 if bytes.Compare(b, make([]byte, len(b))) == 0 { 224 return false 225 } 226 return true 227 } 228 229 func LeDecodeToInt8(b []byte) int8 { 230 return int8(b[0]) 231 } 232 233 func LeDecodeToUint8(b []byte) uint8 { 234 return uint8(b[0]) 235 } 236 237 func LeDecodeToInt16(b []byte) int16 { 238 return int16(binary.LittleEndian.Uint16(LeFillUpSize(b, 2))) 239 } 240 241 func LeDecodeToUint16(b []byte) uint16 { 242 return binary.LittleEndian.Uint16(LeFillUpSize(b, 2)) 243 } 244 245 func LeDecodeToInt32(b []byte) int32 { 246 return int32(binary.LittleEndian.Uint32(LeFillUpSize(b, 4))) 247 } 248 249 func LeDecodeToUint32(b []byte) uint32 { 250 return binary.LittleEndian.Uint32(LeFillUpSize(b, 4)) 251 } 252 253 func LeDecodeToInt64(b []byte) int64 { 254 return int64(binary.LittleEndian.Uint64(LeFillUpSize(b, 8))) 255 } 256 257 func LeDecodeToUint64(b []byte) uint64 { 258 return binary.LittleEndian.Uint64(LeFillUpSize(b, 8)) 259 } 260 261 func LeDecodeToFloat32(b []byte) float32 { 262 return math.Float32frombits(binary.LittleEndian.Uint32(LeFillUpSize(b, 4))) 263 } 264 265 func LeDecodeToFloat64(b []byte) float64 { 266 return math.Float64frombits(binary.LittleEndian.Uint64(LeFillUpSize(b, 8))) 267 } 268 269 // 当b位数不够时,进行高位补0。 270 // 注意这里为了不影响原有输入参数,是采用的值复制设计。 271 func LeFillUpSize(b []byte, l int) []byte { 272 if len(b) >= l { 273 return b[:l] 274 } 275 c := make([]byte, l) 276 copy(c, b) 277 return c 278 }