98 lines
2.1 KiB
Go
98 lines
2.1 KiB
Go
|
package json
|
||
|
|
||
|
import (
|
||
|
"encoding/base64"
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"git.bvbej.com/bvbej/base-golang/pkg/websocket/codec"
|
||
|
)
|
||
|
|
||
|
type jsonCodec struct{}
|
||
|
|
||
|
type jsonReq struct {
|
||
|
Router string `json:"router"`
|
||
|
Data []byte `json:"data"`
|
||
|
Error string `json:"error,omitempty"`
|
||
|
}
|
||
|
|
||
|
type jsonAck struct {
|
||
|
Router string `json:"router"`
|
||
|
Data string `json:"data"`
|
||
|
Error string `json:"error,omitempty"`
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
codec.RegisterCodec("json_codec", new(jsonCodec))
|
||
|
}
|
||
|
|
||
|
func (*jsonCodec) Marshal(router string, dataPtr any, retErr error) ([]byte, error) {
|
||
|
if router == "" {
|
||
|
return nil, fmt.Errorf("marshal: router is empty")
|
||
|
}
|
||
|
|
||
|
if dataPtr == nil && retErr == nil {
|
||
|
return nil, fmt.Errorf("marshal data in package is nil. router:%s dt:%T", router, dataPtr)
|
||
|
}
|
||
|
|
||
|
ack := &jsonAck{
|
||
|
Router: router,
|
||
|
}
|
||
|
|
||
|
if dataPtr != nil {
|
||
|
data, err := json.Marshal(dataPtr)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("marshal json marshal failed. routerr:%s dt:%T err:%v", router, dataPtr, err)
|
||
|
}
|
||
|
ack.Data = base64.StdEncoding.EncodeToString(data)
|
||
|
}
|
||
|
|
||
|
if retErr != nil {
|
||
|
ack.Error = retErr.Error()
|
||
|
}
|
||
|
|
||
|
ackByte, err := json.Marshal(ack)
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("marshal json marshal failed. routerr:%s dt:%T err:%v", router, dataPtr, err)
|
||
|
}
|
||
|
return ackByte, nil
|
||
|
}
|
||
|
|
||
|
func (*jsonCodec) Unmarshal(msg []byte) (int, *codec.MsgPack, error) {
|
||
|
var i = len(msg)
|
||
|
|
||
|
req := &jsonReq{}
|
||
|
err := json.Unmarshal(msg, req)
|
||
|
if err != nil {
|
||
|
return i, nil, errors.New("unmarshal split message id failed")
|
||
|
}
|
||
|
|
||
|
var router = req.Router
|
||
|
msgPack := &codec.MsgPack{Router: router}
|
||
|
dt := codec.GetMessage(router)
|
||
|
if dt == nil {
|
||
|
return i, nil, fmt.Errorf("unmarshal message not registed. router:%s", router)
|
||
|
}
|
||
|
|
||
|
if req.Data != nil {
|
||
|
err = json.Unmarshal(req.Data, dt)
|
||
|
if err != nil {
|
||
|
return i, nil, fmt.Errorf("unmarshal json unmarshal failed. dt:%T msg:%s err:%v", dt, string(msg), err)
|
||
|
}
|
||
|
}
|
||
|
msgPack.DataPtr = dt
|
||
|
if req.Error != "" {
|
||
|
msgPack.Err = errors.New(req.Error)
|
||
|
}
|
||
|
|
||
|
return i, msgPack, nil
|
||
|
}
|
||
|
|
||
|
func (*jsonCodec) ToString(data any) string {
|
||
|
ab, err := json.Marshal(data)
|
||
|
if err != nil {
|
||
|
return fmt.Sprintf("invalid type %T", data)
|
||
|
}
|
||
|
return string(ab)
|
||
|
}
|