mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 12:17:53 +08:00
109 lines
2.5 KiB
Go
109 lines
2.5 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package gconv_test
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/gogf/gf/crypto/gcrc32"
|
|
"github.com/gogf/gf/encoding/gbinary"
|
|
"github.com/gogf/gf/frame/g"
|
|
"github.com/gogf/gf/os/gtime"
|
|
"github.com/gogf/gf/test/gtest"
|
|
"github.com/gogf/gf/util/gconv"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type MyTime struct {
|
|
time.Time
|
|
}
|
|
|
|
type MyTimeSt struct {
|
|
ServiceDate MyTime
|
|
}
|
|
|
|
func (st *MyTimeSt) UnmarshalValue(v interface{}) error {
|
|
m := gconv.Map(v)
|
|
t, err := gtime.StrToTime(gconv.String(m["ServiceDate"]))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
st.ServiceDate = MyTime{t.Time}
|
|
return nil
|
|
}
|
|
|
|
func Test_Struct_UnmarshalValue1(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
st := &MyTimeSt{}
|
|
err := gconv.Struct(g.Map{"ServiceDate": "2020-10-10 12:00:01"}, st)
|
|
t.Assert(err, nil)
|
|
t.Assert(st.ServiceDate.Time.Format("2006-01-02 15:04:05"), "2020-10-10 12:00:01")
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
st := &MyTimeSt{}
|
|
err := gconv.Struct(g.Map{"ServiceDate": nil}, st)
|
|
t.AssertNE(err, nil)
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
st := &MyTimeSt{}
|
|
err := gconv.Struct(g.Map{"ServiceDate": "error"}, st)
|
|
t.AssertNE(err, nil)
|
|
})
|
|
}
|
|
|
|
type Pkg struct {
|
|
Length uint16 // Total length.
|
|
Crc32 uint32 // CRC32.
|
|
Data []byte
|
|
}
|
|
|
|
// NewPkg creates and returns a package with given data.
|
|
func NewPkg(data []byte) *Pkg {
|
|
return &Pkg{
|
|
Length: uint16(len(data) + 6),
|
|
Crc32: gcrc32.Encrypt(data),
|
|
Data: data,
|
|
}
|
|
}
|
|
|
|
// Marshal encodes the protocol struct to bytes.
|
|
func (p *Pkg) Marshal() []byte {
|
|
b := make([]byte, 6+len(p.Data))
|
|
copy(b, gbinary.EncodeUint16(p.Length))
|
|
copy(b[2:], gbinary.EncodeUint32(p.Crc32))
|
|
copy(b[6:], p.Data)
|
|
return b
|
|
}
|
|
|
|
// UnmarshalValue decodes bytes to protocol struct.
|
|
func (p *Pkg) UnmarshalValue(v interface{}) error {
|
|
b := gconv.Bytes(v)
|
|
if len(b) < 6 {
|
|
return errors.New("invalid package length")
|
|
}
|
|
p.Length = gbinary.DecodeToUint16(b[:2])
|
|
if len(b) < int(p.Length) {
|
|
return errors.New("invalid data length")
|
|
}
|
|
p.Crc32 = gbinary.DecodeToUint32(b[2:6])
|
|
p.Data = b[6:]
|
|
if gcrc32.Encrypt(p.Data) != p.Crc32 {
|
|
return errors.New("crc32 validation failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Test_Struct_UnmarshalValue2(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
var p1, p2 *Pkg
|
|
p1 = NewPkg([]byte("123"))
|
|
err := gconv.Struct(p1.Marshal(), &p2)
|
|
t.Assert(err, nil)
|
|
t.Assert(p1, p2)
|
|
})
|
|
}
|