Skip to content

Commit 4d247aa

Browse files
committed
feat(draft-02): implement draft-02, resolve #60,#61,#62,#63
1 parent 4318488 commit 4d247aa

File tree

15 files changed

+1202
-31
lines changed

15 files changed

+1202
-31
lines changed

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright 2019~2020 北京熹乐科技有限公司 CELLA
189+
Copyright 2019~2020 CELLA, Inc.
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.
@@ -198,4 +198,4 @@
198198
distributed under the License is distributed on an "AS IS" BASIS,
199199
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200200
See the License for the specific language governing permissions and
201-
limitations under the License.
201+
limitations under the License.

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ vet:
1414
lint:
1515
$(GOLINT) $(GOFILES)
1616

17-
test:
17+
v1test:
1818
$(GO) test -v ./...
1919

2020
cover:
21-
$(GO) test -coverprofile=prof.out && $(GO) tool cover -html=prof.out && rm prof.out
21+
$(GO) test github.com/yomorun/y3-codec-golang/pkg -coverprofile=prof.out && $(GO) tool cover -html=prof.out && rm prof.out
22+
23+
test:
24+
$(GO) test -v api.go api_test.go stream_api.go stream_api_test.go
25+
26+
test-spec:
27+
$(GO) test -v github.com/yomorun/y3-codec-golang/pkg/spec

README.md

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ See [YoMo Codec SPEC](https://github.com/yomorun/yomo-codec)
1717

1818
## Test
1919

20-
`go test ./...`
20+
`make test`
2121

2222
## Use
2323

@@ -27,6 +27,8 @@ See [YoMo Codec SPEC](https://github.com/yomorun/yomo-codec)
2727

2828
### Encode examples
2929

30+
Encode Key-Value type `{ID: 3}` to Y3:
31+
3032
```go
3133
package main
3234

@@ -36,34 +38,47 @@ import (
3638
)
3739

3840
func main() {
39-
// if we want to repesent `var obj = &foo{ID: -1, bar: &bar{Name: "C"}}`
40-
// in YoMo-Codec:
41+
// Key:ID = Tag:0x01
42+
buffer, _ = y3.EncodeInt(0x01, 3)
43+
44+
// get whole buf
45+
fmt.Printf("res=%#v", buffer) // res=[]byte{0x01, 0x01, 0x03}
46+
}
47+
```
4148

42-
// 0x81 -> node
43-
var foo = y3.NewNodePacketEncoder(0x01)
49+
if we want to repesent JSON `foo: {ID: -1, Name: "C"}` in Y3:
4450

45-
// 0x02 -> foo.ID=-11
46-
var yp1 = y3.NewPrimitivePacketEncoder(0x02)
47-
yp1.SetInt32Value(-1)
48-
foo.AddPrimitivePacket(yp1)
51+
```go
52+
package main
4953

50-
// 0x83 -> &bar{}
51-
var bar = y3.NewNodePacketEncoder(0x03)
54+
import (
55+
"fmt"
56+
y3 "github.com/yomorun/y3-codec-golang"
57+
)
5258

53-
// 0x04 -> bar.Name="C"
54-
var yp2 = y3.NewPrimitivePacketEncoder(0x04)
55-
yp2.SetStringValue("C")
56-
bar.AddPrimitivePacket(yp2)
59+
func main() {
60+
// Key:ID 0x01 -> -1
61+
var id, _ = y3.NewPacket(0x01)
62+
id.SetInt32(-1)
5763

58-
// -> foo.bar=&bar
59-
foo.AddNodePacket(bar)
60-
61-
fmt.Printf("res=%#v", foo.Encode()) // res=[]byte{0x81, 0x08, 0x02, 0x01, 0x7F, 0x83, 0x03, 0x04, 0x01, 0x43}
64+
// Key:Name 0x02 -> "C"
65+
var name, _ = y3.NewPacket(0x02)
66+
name.SetString("C")
67+
68+
// parent node
69+
var foo, _ = y3.NewPacket(0x10)
70+
foo.AddNode(id)
71+
foo.AddNode(name)
72+
73+
// get whole buf
74+
fmt.Printf("res=%#v", foo.Encode()) // res=[]byte{0x10, 0x06, 0x01, 0x01, 0x7F, 0x02, 0x01, 0x43}
6275
}
6376
```
6477

6578
### Decode examples 1: decode a primitive packet
6679

80+
Decode `[0x0A, 0x01, 0x7F]` as Int type
81+
6782
```go
6883
package main
6984

@@ -75,13 +90,13 @@ import (
7590
func main() {
7691
fmt.Println(">> Parsing [0x0A, 0x01, 0x7F], which like Key-Value format = 0x0A: 127")
7792
buf := []byte{0x0A, 0x01, 0x7F}
78-
res, _, err := y3.DecodePrimitivePacket(buf)
79-
v1, err := res.ToUInt32()
93+
res, _, err := y3.DecodePacket(buf)
94+
val, err := res.ToInt32()
8095
if err != nil {
8196
panic(err)
8297
}
8398

84-
fmt.Printf("Tag Key=[%#X], Value=%v\n", res.SeqID(), v1)
99+
fmt.Printf("Tag Key=[%#X], Value=%v\n", res.Tag, val)
85100
}
86101
```
87102

@@ -130,3 +145,9 @@ More examples in `/examples/`
130145

131146
## License
132147
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fyomorun%2Fy3-codec-golang.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fyomorun%2Fy3-codec-golang?ref=badge_large)
148+
149+
## CLA
150+
151+
[Sign CLA](https://cla-assistant.io/yomorun/y3-codec-golang)
152+
153+
[![CLA assistant](https://cla-assistant.io/readme/badge/yomorun/y3-codec-golang)](https://cla-assistant.io/yomorun/y3-codec-golang)

api.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package y3
2+
3+
import (
4+
"errors"
5+
6+
"github.com/yomorun/y3-codec-golang/pkg/spec"
7+
)
8+
9+
// EncodeBool encode bool type data
10+
func EncodeBool(tag int, v bool) ([]byte, error) {
11+
p, err := spec.NewPacket(uint64(tag))
12+
if err != nil {
13+
return nil, err
14+
}
15+
p.SetBool(v)
16+
return p.Encode()
17+
}
18+
19+
// EncodeUInt encode uint type data
20+
func EncodeUInt(tag int, v uint) ([]byte, error) {
21+
p, err := spec.NewPacket(uint64(tag))
22+
if err != nil {
23+
return nil, err
24+
}
25+
p.SetUInt32(uint32(v))
26+
return p.Encode()
27+
}
28+
29+
// EncodeInt encode int type data
30+
func EncodeInt(tag int, v int) ([]byte, error) {
31+
p, err := spec.NewPacket(uint64(tag))
32+
if err != nil {
33+
return nil, err
34+
}
35+
p.SetInt32(v)
36+
return p.Encode()
37+
}
38+
39+
// EncodeUInt64 encode uint64 type data
40+
func EncodeUInt64(tag int, v uint64) ([]byte, error) {
41+
p, err := spec.NewPacket(uint64(tag))
42+
if err != nil {
43+
return nil, err
44+
}
45+
p.SetUInt64(v)
46+
return p.Encode()
47+
}
48+
49+
// EncodeInt64 encode int type data
50+
func EncodeInt64(tag int, v int64) ([]byte, error) {
51+
p, err := spec.NewPacket(uint64(tag))
52+
if err != nil {
53+
return nil, err
54+
}
55+
p.SetInt64(v)
56+
return p.Encode()
57+
}
58+
59+
// EncodeFloat32 encode float32 type data
60+
func EncodeFloat32(tag int, v float32) ([]byte, error) {
61+
p, err := spec.NewPacket(uint64(tag))
62+
if err != nil {
63+
return nil, err
64+
}
65+
p.SetFloat32(v)
66+
return p.Encode()
67+
}
68+
69+
// EncodeFloat64 encode float64 type data
70+
func EncodeFloat64(tag int, v float64) ([]byte, error) {
71+
p, err := spec.NewPacket(uint64(tag))
72+
if err != nil {
73+
return nil, err
74+
}
75+
p.SetFloat64(v)
76+
return p.Encode()
77+
}
78+
79+
// EncodeString encode UTF-8 string data
80+
func EncodeString(tag int, v string) ([]byte, error) {
81+
p, err := spec.NewPacket(uint64(tag))
82+
if err != nil {
83+
return nil, err
84+
}
85+
p.SetUTF8String(v)
86+
return p.Encode()
87+
}
88+
89+
// EncodeBytes encode raw bytes
90+
func EncodeBytes(tag int, v []byte) ([]byte, error) {
91+
p, err := spec.NewPacket(uint64(tag))
92+
if err != nil {
93+
return nil, err
94+
}
95+
p.PutBytes(v)
96+
return p.Encode()
97+
}
98+
99+
// Marshal TODO wip
100+
func Marshal(tag int, obj interface{}) ([]byte, error) {
101+
panic(errors.New("NotImplementedError"))
102+
}

api_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package y3
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestD2EncodeUInt32(t *testing.T) {
8+
testD2EncodeUInt32(t, 0x03, 6, []byte{0x03, 0x01, 0x06})
9+
testD2EncodeUInt32(t, 0x06, 127, []byte{0x06, 0x02, 0x80, 0x7F})
10+
}
11+
12+
func TestD2EncodeInt32(t *testing.T) {
13+
testD2EncodeInt(t, 0x03, -1, []byte{0x03, 0x01, 0x7F})
14+
testD2EncodeInt(t, 0x06, -65, []byte{0x06, 0x02, 0xFF, 0x3F})
15+
testD2EncodeInt(t, 0x09, 255, []byte{0x09, 0x02, 0x81, 0x7F})
16+
}
17+
18+
func TestD2EncodeUInt64(t *testing.T) {
19+
testD2EncodeUInt64(t, 0x03, 0, []byte{0x03, 0x01, 0x00})
20+
testD2EncodeUInt64(t, 0x06, 1, []byte{0x06, 0x01, 0x01})
21+
testD2EncodeUInt64(t, 0x09, 18446744073709551615, []byte{0x09, 0x01, 0x7F})
22+
}
23+
24+
func TestD2EncodeInt64(t *testing.T) {
25+
testD2EncodeInt64(t, 0x03, 0, []byte{0x03, 0x01, 0x00})
26+
testD2EncodeInt64(t, 0x06, 1, []byte{0x06, 0x01, 0x01})
27+
testD2EncodeInt64(t, 0x09, -1, []byte{0x09, 0x01, 0x7F})
28+
}
29+
30+
func TestD2EncodeFloat32(t *testing.T) {
31+
testD2EncodeFloat32(t, 0x03, -2, []byte{0x03, 0x01, 0xC0})
32+
testD2EncodeFloat32(t, 0x06, 0.25, []byte{0x06, 0x02, 0x3E, 0x80})
33+
testD2EncodeFloat32(t, 0x09, 68.123, []byte{0x09, 0x04, 0x42, 0x88, 0x3E, 0xFA})
34+
}
35+
36+
func TestD2EncodeFloat64(t *testing.T) {
37+
testD2EncodeFloat64(t, 0x03, 23, []byte{0x03, 0x02, 0x40, 0x37})
38+
testD2EncodeFloat64(t, 0x06, 2, []byte{0x06, 0x01, 0x40})
39+
testD2EncodeFloat64(t, 0x09, 0.01171875, []byte{0x09, 0x02, 0x3F, 0x88})
40+
}
41+
42+
func TestD2EncodeString(t *testing.T) {
43+
p, _ := EncodeString(0x01, "C")
44+
compareTwoBytes(t, p, []byte{0x01, 0x01, 0x43})
45+
p, _ = EncodeString(0x01, "CC")
46+
compareTwoBytes(t, p, []byte{0x01, 0x02, 0x43, 0x43})
47+
p, _ = EncodeString(0x01, "Yona")
48+
compareTwoBytes(t, p, []byte{0x01, 0x04, 0x59, 0x6F, 0x6E, 0x61})
49+
p, _ = EncodeString(0x01, "https://yomo.run")
50+
compareTwoBytes(t, p, []byte{0x01, 0x10, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x79, 0x6F, 0x6D, 0x6F, 0x2E, 0x72, 0x75, 0x6E})
51+
}
52+
53+
func TestD2EncodeBytes(t *testing.T) {
54+
p, _ := EncodeBytes(0x01, []byte{0x03, 0x06, 0x09, 0x0C, 0x0F})
55+
compareTwoBytes(t, p, []byte{0x01, 0x05, 0x03, 0x06, 0x09, 0x0C, 0x0F})
56+
}
57+
58+
func TestD2EncodeBool(t *testing.T) {
59+
p, _ := EncodeBool(0x01, true)
60+
compareTwoBytes(t, p, []byte{0x01, 0x01, 0x01})
61+
p, _ = EncodeBool(0x01, false)
62+
compareTwoBytes(t, p, []byte{0x01, 0x01, 0x00})
63+
}
64+
65+
func testD2EncodeUInt32(t *testing.T, tag int, val uint, expected []byte) {
66+
p, _ := EncodeUInt(tag, val)
67+
compareTwoBytes(t, p, expected)
68+
}
69+
70+
func testD2EncodeInt(t *testing.T, tag int, val int, expected []byte) {
71+
p, _ := EncodeInt(tag, val)
72+
compareTwoBytes(t, p, expected)
73+
}
74+
75+
func testD2EncodeUInt64(t *testing.T, tag int, val uint64, expected []byte) {
76+
p, _ := EncodeUInt64(tag, val)
77+
compareTwoBytes(t, p, expected)
78+
}
79+
80+
func testD2EncodeInt64(t *testing.T, tag int, val int64, expected []byte) {
81+
p, _ := EncodeInt64(tag, val)
82+
compareTwoBytes(t, p, expected)
83+
}
84+
85+
func testD2EncodeFloat32(t *testing.T, tag int, val float32, expected []byte) {
86+
p, _ := EncodeFloat32(tag, val)
87+
compareTwoBytes(t, p, expected)
88+
}
89+
90+
func testD2EncodeFloat64(t *testing.T, tag int, val float64, expected []byte) {
91+
p, _ := EncodeFloat64(tag, val)
92+
compareTwoBytes(t, p, expected)
93+
}
94+
95+
func compareTwoBytes(t *testing.T, result []byte, expected []byte) {
96+
for i, p := range result {
97+
if p != expected[i] {
98+
t.Errorf("\nexpected:[% X]\n actual:[% X]\n", expected, result)
99+
break
100+
}
101+
}
102+
}

pkg/encoding/nvarint.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func sizeOfNVarInt(value int64, width int) int {
7878
const unit = 8 // bit width of encoding unit
7979

8080
var lead = value >> (width - 1)
81-
for size := width / unit - 1; size > 0; size-- {
81+
for size := width/unit - 1; size > 0; size-- {
8282
var lookAhead = value >> (size*unit - 1)
8383
if lookAhead != lead {
8484
return size + 1

pkg/encoding/pvarint.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func (codec *VarCodec) decodePVarInt(buffer []byte, value *int64) error {
123123
return ErrBufferInsufficient
124124
}
125125

126-
const unit = 7 // bit width of encoding unit
126+
const unit = 7 // bit width of encoding unit
127127
if codec.Size == 0 { // initialize sign bit
128128
const flag = 8 - unit // bit width for non-encoding bits
129129
*value = int64(int8(buffer[codec.Ptr]) << flag >> unit)
@@ -135,7 +135,7 @@ func (codec *VarCodec) decodePVarInt(buffer []byte, value *int64) error {
135135
codec.Ptr++
136136

137137
codec.Size++
138-
*value = (*value << unit) | int64(mask & part)
138+
*value = (*value << unit) | int64(mask&part)
139139

140140
if part >= 0 { // it's the last byte
141141
return nil

pkg/encoding/varfloat.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func sizeOfVarFloat(bits uint64, width int) int {
4747
const mask = uint64(0xFF) // mask of encoding unit
4848

4949
for s := 0; width > 1; s += unit {
50-
if bits & (mask << s) != 0 {
50+
if bits&(mask<<s) != 0 {
5151
return width
5252
}
5353
width--
@@ -68,7 +68,7 @@ func (codec *VarCodec) encodeVarFloat(buffer []byte, bits uint64, width int) err
6868
return ErrBufferInsufficient
6969
}
7070
codec.Size--
71-
buffer[codec.Ptr] = byte(bits >> ((codec.Size & mask + gap) * unit))
71+
buffer[codec.Ptr] = byte(bits >> ((codec.Size&mask + gap) * unit))
7272
codec.Ptr++
7373
}
7474

0 commit comments

Comments
 (0)