mirror of
https://gitee.com/johng/gf
synced 2026-06-06 16:21:40 +08:00
gbinary示例
This commit is contained in:
@ -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])
|
||||
}
|
||||
|
||||
@ -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))))
|
||||
|
||||
30
geg/encoding/gbinary/bits1.go
Normal file
30
geg/encoding/gbinary/bits1.go
Normal 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)
|
||||
}
|
||||
30
geg/encoding/gbinary/bits2.go
Normal file
30
geg/encoding/gbinary/bits2.go
Normal 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]))
|
||||
}
|
||||
Reference in New Issue
Block a user