Awesome
đ VERSION: draft-02
âŗī¸ STATE: WIP
đ¨đŗ įŽäŊä¸æ đŦđ§ English
Y3
Y3 is the golang implementation of Y3 Codec, which describe a fast and low CPU binding data encoder/decoder focus on edge computing and streaming processing.
See the explainer for more info, more about the ways to combine with YoMo.
Y3 Codec
See Y3 Codec SPEC
Test
go test ./...
Use
go get -u github.com/yomorun/y3-codec-golang
Examples
Encode examples
package main
import (
"fmt"
y3 "github.com/yomorun/y3-codec-golang"
)
func main() {
// if we want to repesent `var obj = &foo{ID: -1, bar: &bar{Name: "C"}}`
// in Y3-Codec:
// 0x81 -> node
var foo = y3.NewNodePacketEncoder(0x01)
// 0x02 -> foo.ID=-11
var yp1 = y3.NewPrimitivePacketEncoder(0x02)
yp1.SetInt32Value(-1)
foo.AddPrimitivePacket(yp1)
// 0x83 -> &bar{}
var bar = y3.NewNodePacketEncoder(0x03)
// 0x04 -> bar.Name="C"
var yp2 = y3.NewPrimitivePacketEncoder(0x04)
yp2.SetStringValue("C")
bar.AddPrimitivePacket(yp2)
// -> foo.bar=&bar
foo.AddNodePacket(bar)
fmt.Printf("res=%#v", foo.Encode()) // res=[]byte{0x81, 0x08, 0x02, 0x01, 0x7F, 0x83, 0x03, 0x04, 0x01, 0x43}
}
Decode examples 1: decode a primitive packet
package main
import (
"fmt"
y3 "github.com/yomorun/y3-codec-golang"
)
func main() {
fmt.Println(">> Parsing [0x0A, 0x01, 0x7F], which like Key-Value format = 0x0A: 127")
buf := []byte{0x0A, 0x01, 0x7F}
res, _, err := y3.DecodePrimitivePacket(buf)
v1, err := res.ToUInt32()
if err != nil {
panic(err)
}
fmt.Printf("Tag Key=[%#X], Value=%v\n", res.SeqID(), v1)
}
Decode examples 2: decode a node packet
package main
import (
"fmt"
y3 "github.com/yomorun/y3-codec-golang"
)
func main() {
fmt.Println(">> Parsing [0x84, 0x06, 0x0A, 0x01, 0x7F, 0x0B, 0x01, 0x43] EQUALS JSON= 0x84: { 0x0A: -1, 0x0B: 'C' }")
buf := []byte{0x84, 0x06, 0x0A, 0x01, 0x7F, 0x0B, 0x01, 0x43}
res, _, err := y3.DecodeNodePacket(buf)
v1 := res.PrimitivePackets[0]
p1, err := v1.ToInt32()
if err != nil {
panic(err)
}
fmt.Printf("Tag Key=[%#X.%#X], Value=%v\n", res.SeqID(), v1.SeqID(), p1)
v2 := res.PrimitivePackets[1]
p2, err := v2.ToUTF8String()
if err != nil {
panic(err)
}
fmt.Printf("Tag Key=[%#X.%#X], Value=%v\n", res.SeqID(), v2.SeqID(), p2)
}
More examples in /examples/
Types
Y3 implements the YoMo Codec protocol and supports the following Golang data types and provides Hight-Level wrappers.
<details> <summary>int32</summary>// encode
var data int32 = 123
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetInt32Value(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToInt32()
fmt.Printf("val=%d", val)
</details>
<details>
<summary>uint32</summary>
var data uint32 = 123
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetUInt32Value(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToUInt32()
fmt.Printf("val=%d", val)
</details>
<details>
<summary>int64</summary>
// encode
var data int64 = 123
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetInt64Value(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToInt64()
fmt.Printf("val=%d", val)
</details>
<details>
<summary>uint64</summary>
// encode
var data uint64 = 123
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetUInt64Value(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToUInt64()
fmt.Printf("val=%d", val)
</details>
<details>
<summary>float32</summary>
// encode
var data float32 = 1.23
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetFloat32Value(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToFloat32()
fmt.Printf("val=%f", val)
</details>
<details>
<summary>float64</summary>
// encode
var data float64 = 1.23
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetFloat64Value(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToFloat64()
fmt.Printf("val=%f", val)
</details>
<details>
<summary>bool</summary>
// encode
var data bool = true
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetBoolValue(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToBool()
fmt.Printf("val=%v", val)
</details>
<details>
<summary>string</summary>
// encode
var data string = "abc"
var prim = y3.NewPrimitivePacketEncoder(0x01)
prim.SetStringValue(data)
buf := prim.Encode()
// decode
res, _, _, _ := y3.DecodePrimitivePacket(buf)
val, _ := res.ToUTF8String()
fmt.Printf("val=%s", val)
</details>
<details>
<summary>int32 slice</summary>
// encode
data := []int32{123, 456}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToInt64Slice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetInt32Value(int32(v.(int64)))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]int32, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToInt32()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>uint32 slice</summary>
// encode
data := []uint32{123, 456}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToUInt64Slice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetUInt32Value(uint32(v.(uint64)))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]uint32, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToUInt32()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>int64 slice</summary>
// encode
data := []int64{123, 456}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToInt64Slice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetInt64Value(v.(int64))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]int64, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToInt64()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>uint64 slice</summary>
data := []uint64{123, 456}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToUInt64Slice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetUInt64Value(v.(uint64))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]uint64, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToUInt64()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>float32 slice</summary>
// encode
data := []float32{1.23, 4.56}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToUFloat64Slice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetFloat32Value(float32(v.(float64)))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]float32, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToFloat32()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>float64 slice</summary>
// encode
data := []float64{1.23, 4.56}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToUFloat64Slice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetFloat64Value(v.(float64))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]float64, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToFloat64()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>bool slice</summary>
// encode
data := []bool{true, false}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToBoolSlice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetBoolValue(v.(bool))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]bool, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToBool()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>string slice</summary>
// encode
data := []string{"abc", "def"}
var node = y3.NewNodeSlicePacketEncoder(0x10)
if out, ok := utils.ToStringSlice(data); ok {
for _, v := range out {
var item = y3.NewPrimitivePacketEncoder(0x00)
item.SetStringValue(fmt.Sprintf("%v", v))
node.AddPrimitivePacket(item)
}
}
buf := node.Encode()
// decode
packet, _, _ := y3.DecodeNodePacket(buf)
result := make([]string, 0)
for _, p := range packet.PrimitivePackets {
v, _ := p.ToUTF8String()
result = append(result, v)
}
fmt.Printf("result=%v", result)
</details>
<details>
<summary>complex types</summary>
// encode
var node = y3.NewNodePacketEncoder(0x01)
node.AddPrimitivePacket(func() *y3.PrimitivePacketEncoder {
var prim1 = y3.NewPrimitivePacketEncoder(0x10)
prim1.SetFloat32Value(40.5)
return prim1
}())
node.AddPrimitivePacket(func() *y3.PrimitivePacketEncoder {
var prim1 = y3.NewPrimitivePacketEncoder(0x11)
prim1.SetInt64Value(time.Now().Unix())
return prim1
}())
buf := node.Encode()
// decode
res, _, _ := y3.DecodeNodePacket(buf)
for _, v := range res.PrimitivePackets {
if v.SeqID() == 0x10 {
fmt.Printf("0x10=%f\n", func() float32 {
val, _ := v.ToFloat32()
return val
}())
}
if v.SeqID() == 0x11 {
fmt.Printf("0x11=%d\n", func() int64 {
val, _ := v.ToInt64()
return val
}())
}
}
</details>
<details>
<summary>complex slice types</summary>
// encode
var node = y3.NewNodeSlicePacketEncoder(0x01)
for i := 0; i < 2; i++ {
item := y3.NewNodePacketEncoder(0x00)
item.AddPrimitivePacket(func() *y3.PrimitivePacketEncoder {
var prim1 = y3.NewPrimitivePacketEncoder(0x10)
prim1.SetFloat32Value(40.5)
return prim1
}())
item.AddPrimitivePacket(func() *y3.PrimitivePacketEncoder {
var prim1 = y3.NewPrimitivePacketEncoder(0x11)
prim1.SetInt64Value(time.Now().Unix())
return prim1
}())
node.AddNodePacket(item)
}
buf := node.Encode()
// decode
res, _, _ := y3.DecodeNodePacket(buf)
for _, v := range res.NodePackets {
if res.SeqID() != 0x01 {
continue
}
for _, vv := range v.PrimitivePackets {
if vv.SeqID() == 0x10 {
fmt.Printf("0x10=%f\n", func() float32 {
val, _ := vv.ToFloat32()
return val
}())
}
if vv.SeqID() == 0x11 {
fmt.Printf("0x11=%d\n", func() int64 {
val, _ := vv.ToInt64()
return val
}())
}
}
}
</details>
Contributors
<a href="https://github.com/figroc"><img src="https://avatars1.githubusercontent.com/u/2026460?v=3" title="figroc" width="80" height="80"></a>