gbinary示例

This commit is contained in:
John
2018-01-18 12:02:56 +08:00
parent 83664d0032
commit 4911fd58eb
4 changed files with 171 additions and 14 deletions

View File

@ -16,11 +16,20 @@ import (
// 二进制位(0|1)
type Bit uint8
// 整形二进制打包,注意参数必须为字长确定的类型:int8/16/32/64、uint8/16/32/64
// 针对基本类型进行二进制打包,支持的基本数据类型包括:int/8/16/32/64、uint/8/16/32/64、float32/64、bool、string、[]byte
func Encode(vs ...interface{}) ([]byte, error) {
buf := new(bytes.Buffer)
for i := 0; i < len(vs); i++ {
err := binary.Write(buf, binary.LittleEndian, vs[i])
var err error = nil
switch vs[i].(type) {
case int: buf.Write(EncodeInt(vs[i].(int)))
case uint: buf.Write(EncodeUint(vs[i].(uint)))
case bool: buf.Write(EncodeBool(vs[i].(bool)))
case string: buf.Write(EncodeString(vs[i].(string)))
case []byte: buf.Write(vs[i].([]byte))
default:
err = binary.Write(buf, binary.LittleEndian, vs[i])
}
if err != nil {
return nil, err
}
@ -28,7 +37,8 @@ func Encode(vs ...interface{}) ([]byte, error) {
return buf.Bytes(), nil
}
// 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,字长确定的类型int8/16/32/64、uint8/16/32/64
// 整形二进制解包,注意第二个及其后参数为字长确定的整形变量的指针地址,以便确定解析的[]byte长度
// 例如int8/16/32/64、uint8/16/32/64、float32/64等等
func Decode(b []byte, vs ...interface{}) error {
buf := bytes.NewBuffer(b)
for i := 0; i < len(vs); i++ {
@ -48,6 +58,40 @@ func DecodeToString(b []byte) string {
return string(b)
}
func EncodeBool(b bool) []byte {
if b == true {
return []byte{1}
} else {
return []byte{0}
}
}
// 自动识别int类型长度转换为[]byte
func EncodeInt(i int) []byte {
if i <= math.MaxInt8 {
return EncodeInt8(int8(i))
} else if i <= math.MaxInt16 {
return EncodeInt16(int16(i))
} else if i <= math.MaxInt32 {
return EncodeInt32(int32(i))
} else {
return EncodeInt64(int64(i))
}
}
// 自动识别uint类型长度转换为[]byte
func EncodeUint(i uint) []byte {
if i <= math.MaxUint8 {
return EncodeUint8(uint8(i))
} else if i <= math.MaxUint16 {
return EncodeUint16(uint16(i))
} else if i <= math.MaxUint32 {
return EncodeUint32(uint32(i))
} else {
return EncodeUint64(uint64(i))
}
}
func EncodeInt8(i int8) []byte {
return []byte{byte(i)}
}
@ -116,6 +160,43 @@ func fillUpSize(b []byte, l int) []byte {
return c
}
// 将二进制解析为int类型根据[]byte的长度进行自动转换
func DecodeToInt(b []byte) int {
if len(b) < 2 {
return int(DecodeToInt8(b))
} else if len(b) < 3 {
return int(DecodeToInt16(b))
} else if len(b) < 5 {
return int(DecodeToInt32(b))
} else {
return int(DecodeToInt64(b))
}
}
// 将二进制解析为uint类型根据[]byte的长度进行自动转换
func DecodeToUint(b []byte) uint {
if len(b) < 2 {
return uint(DecodeToUint8(b))
} else if len(b) < 3 {
return uint(DecodeToUint16(b))
} else if len(b) < 5 {
return uint(DecodeToUint32(b))
} else {
return uint(DecodeToUint64(b))
}
}
// 将二进制解析为bool类型识别标准是判断二进制中数值是否都为0或者为空
func DecodeToBool(b []byte) bool {
if len(b) == 0 {
return false
}
if bytes.Compare(b, make([]byte, len(b))) == 0 {
return false
}
return true
}
func DecodeToInt8(b []byte) int8 {
return int8(b[0])
}

View File

@ -1,33 +1,49 @@
package main
import (
"gitee.com/johng/gf/g/encoding/gbinary"
"gitee.com/johng/gf/g/os/glog"
"fmt"
"gitee.com/johng/gf/g/os/glog"
"gitee.com/johng/gf/g/encoding/gbinary"
)
func main() {
// 使用gbinary.Encoded对整形二进制打包注意参数必须为字长确定的类型int8/16/32/64、uint8/16/32/64
if buffer, err := gbinary.Encode(int32(18), int64(24)); err != nil {
// 使用gbinary.Encoded对基本数据类型进行二进制打包
if buffer, err := gbinary.Encode(18, 300, 1.01); err != nil {
glog.Error(err)
} else {
fmt.Println(buffer)
}
// 使用gbinary.Decode对整形二进制解包注意第二个及其后参数为字长确定的整形变量的指针地址字长确定的类型int8/16/32/64、uint8/16/32/64
if buffer, err := gbinary.Encode(int32(18), int64(24)); err != nil {
// 使用gbinary.Decode对整形二进制解包注意第二个及其后参数为字长确定的整形变量的指针地址字长确定的类型
// 例如int8/16/32/64、uint8/16/32/64、float32/64
// 这里的1.01默认为float64类型(64位系统下)
if buffer, err := gbinary.Encode(18, 300, 1.01); err != nil {
glog.Error(err)
} else {
var i1 int32
var i2 int64
if err := gbinary.Decode(buffer, &i1, &i2); err != nil {
var i1 int8
var i2 int16
var f3 float64
if err := gbinary.Decode(buffer, &i1, &i2, &f3); err != nil {
glog.Error(err)
} else {
fmt.Println(i1, i2)
fmt.Println(i1, i2, f3)
}
}
// 编码/解析 int自动识别变量长度
fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(1)))
fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(300)))
fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(70000)))
fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(2000000000)))
fmt.Println(gbinary.DecodeToInt(gbinary.EncodeInt(500000000000)))
// 编码/解析 uint自动识别变量长度
fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(1)))
fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(300)))
fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(70000)))
fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(2000000000)))
fmt.Println(gbinary.DecodeToUint(gbinary.EncodeUint(500000000000)))
// 编码/解析 int8/16/32/64
fmt.Println(gbinary.DecodeToInt8(gbinary.EncodeInt8(int8(100))))
fmt.Println(gbinary.DecodeToInt16(gbinary.EncodeInt16(int16(100))))

View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g/encoding/gbinary"
)
func main() {
// 传感器状态0:已下线, 1:开启, 2:关闭, 3:待机
count := 100
status := 1
// 编码
bits := make([]gbinary.Bit, 0)
for i := 0; i < count; i++ {
bits = gbinary.EncodeBits(bits, uint(status), 2)
}
buffer := gbinary.EncodeBitsToBytes(bits)
fmt.Println("buffer length:", len(buffer))
// 解码
alivecount := 0
sensorbits := gbinary.DecodeBytesToBits(buffer)
for i := 0; i < len(sensorbits); i += 2 {
if gbinary.DecodeBits(sensorbits[i:i+2]) == 1 {
alivecount++
}
}
fmt.Println("alived sensor:", alivecount)
}

View File

@ -0,0 +1,30 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g/encoding/gbinary"
)
func main() {
// Meta元数据文件数据结构[键名哈希64(64bit,8byte) 键名长度(8bit,1byte) 键值长度(24bit,3byte) 数据文件偏移量(40bit,5byte)](变长)
hash := 521369841259754125
klen := 12
vlen := 35535
offset := 80000000
// 编码
bits := make([]gbinary.Bit, 0)
bits = gbinary.EncodeBits(bits, uint(hash), 64)
bits = gbinary.EncodeBits(bits, uint(klen), 8)
bits = gbinary.EncodeBits(bits, uint(vlen), 24)
bits = gbinary.EncodeBits(bits, uint(offset), 40)
buffer := gbinary.EncodeBitsToBytes(bits)
fmt.Println("meta length:", len(buffer))
// 解码
metabits := gbinary.DecodeBytesToBits(buffer)
fmt.Println("hash :", gbinary.DecodeBits(metabits[0 : 64]))
fmt.Println("klen :", gbinary.DecodeBits(metabits[64 : 72]))
fmt.Println("vlen :", gbinary.DecodeBits(metabits[72 : 96]))
fmt.Println("offset:", gbinary.DecodeBits(metabits[96 : 136]))
}