rpc/protocol/json/client_notify.go
crusader 5cad5b126d ing
2017-11-01 17:13:23 +09:00

93 lines
2.3 KiB
Go

package json
import (
"encoding/json"
"fmt"
"sync"
"git.loafle.net/commons_go/rpc/protocol"
)
// ----------------------------------------------------------------------------
// ClientCodecNotify
// ----------------------------------------------------------------------------
// newCodecRequest returns a new ClientCodecNotify.
func newClientCodecNotify(raw json.RawMessage) (protocol.ClientCodecNotify, error) {
// Decode the request body and check if RPC method is valid.
ccn := retainClientCodecNotify()
err := json.Unmarshal(raw, &ccn.notify)
if err != nil {
releaseClientCodecNotify(ccn)
return nil, err
}
if "" == ccn.notify.Method {
releaseClientCodecNotify(ccn)
return nil, fmt.Errorf("This is not ClientNotify")
}
if ccn.notify.Version != Version {
ccn.err = &Error{
Code: E_INVALID_REQ,
Message: "jsonrpc must be " + Version,
Data: ccn.notify,
}
}
return ccn, nil
}
// ClientCodecNotify decodes and encodes a single notification.
type ClientCodecNotify struct {
notify clientNotify
err error
}
func (ccn *ClientCodecNotify) Method() string {
return ccn.notify.Method
}
func (ccn *ClientCodecNotify) ReadParams(args interface{}) error {
if ccn.err == nil && ccn.notify.Params != nil {
// Note: if scr.request.Params is nil it's not an error, it's an optional member.
// JSON params structured object. Unmarshal to the args object.
if err := json.Unmarshal(*ccn.notify.Params, args); err != nil {
// Clearly JSON params is not a structured object,
// fallback and attempt an unmarshal with JSON params as
// array value and RPC params is struct. Unmarshal into
// array containing the request struct.
params := [1]interface{}{args}
if err = json.Unmarshal(*ccn.notify.Params, &params); err != nil {
ccn.err = &Error{
Code: E_INVALID_REQ,
Message: err.Error(),
Data: ccn.notify.Params,
}
}
}
}
return ccn.err
}
func (ccn *ClientCodecNotify) Complete() {
releaseClientCodecNotify(ccn)
}
var clientCodecNotifyPool sync.Pool
func retainClientCodecNotify() *ClientCodecNotify {
v := clientCodecNotifyPool.Get()
if v == nil {
return &ClientCodecNotify{}
}
return v.(*ClientCodecNotify)
}
func releaseClientCodecNotify(ccn *ClientCodecNotify) {
ccn.notify.Version = ""
ccn.notify.Method = ""
ccn.notify.Params = nil
clientCodecNotifyPool.Put(ccn)
}