2017-10-31 09:25:44 +00:00
|
|
|
package json
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
"git.loafle.net/commons_go/rpc/codec"
|
2017-10-31 09:25:44 +00:00
|
|
|
"git.loafle.net/commons_go/rpc/protocol"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2017-11-26 10:15:51 +00:00
|
|
|
// ClientResponseCodec
|
2017-10-31 09:25:44 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
2017-11-26 10:15:51 +00:00
|
|
|
// clientResponse represents a JSON-RPC response returned to a client.
|
|
|
|
type clientResponse struct {
|
|
|
|
Result *json.RawMessage `json:"result,omitempty"`
|
|
|
|
Error error `json:"error,omitempty"`
|
|
|
|
ID interface{} `json:"id,omitempty"`
|
|
|
|
}
|
2017-10-31 09:25:44 +00:00
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
// newClientResponseCodec returns a new ClientResponseCodec.
|
|
|
|
func newClientResponseCodec(raw *json.RawMessage, codec codec.Codec) (protocol.ClientResponseCodec, error) {
|
2017-10-31 09:25:44 +00:00
|
|
|
// Decode the request body and check if RPC method is valid.
|
2017-11-26 10:15:51 +00:00
|
|
|
ccr := retainClientResponseCodec()
|
|
|
|
|
|
|
|
err := json.Unmarshal(*raw, &ccr.res)
|
2017-10-31 09:25:44 +00:00
|
|
|
if err != nil {
|
2017-11-26 10:15:51 +00:00
|
|
|
releaseClientResponseCodec(ccr)
|
2017-10-31 09:25:44 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2017-11-26 10:15:51 +00:00
|
|
|
if nil == ccr.res.Result && nil == ccr.res.Error {
|
|
|
|
releaseClientResponseCodec(ccr)
|
2017-10-31 09:25:44 +00:00
|
|
|
return nil, fmt.Errorf("This is not Response")
|
|
|
|
}
|
|
|
|
|
|
|
|
return ccr, nil
|
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
// ClientResponseCodec decodes and encodes a single request.
|
|
|
|
type ClientResponseCodec struct {
|
|
|
|
res clientResponse
|
|
|
|
err error
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
func (ccr *ClientResponseCodec) ID() interface{} {
|
|
|
|
return ccr.res.ID
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
func (ccr *ClientResponseCodec) Result(result interface{}) error {
|
|
|
|
if ccr.err == nil && ccr.res.Result != nil {
|
|
|
|
if err := json.Unmarshal(*ccr.res.Result, &result); err != nil {
|
2017-11-01 09:58:16 +00:00
|
|
|
params := [1]interface{}{result}
|
2017-11-26 10:15:51 +00:00
|
|
|
if err = json.Unmarshal(*ccr.res.Result, ¶ms); err != nil {
|
2017-11-01 09:58:16 +00:00
|
|
|
ccr.err = err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ccr.err
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
func (ccr *ClientResponseCodec) Error() error {
|
|
|
|
return ccr.res.Error
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
func (ccr *ClientResponseCodec) Close() {
|
|
|
|
releaseClientResponseCodec(ccr)
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
var clientResponseCodecPool sync.Pool
|
2017-10-31 09:25:44 +00:00
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
func retainClientResponseCodec() *ClientResponseCodec {
|
|
|
|
v := clientResponseCodecPool.Get()
|
2017-10-31 09:25:44 +00:00
|
|
|
if v == nil {
|
2017-11-26 10:15:51 +00:00
|
|
|
return &ClientResponseCodec{}
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
2017-11-26 10:15:51 +00:00
|
|
|
return v.(*ClientResponseCodec)
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
func releaseClientResponseCodec(ccr *ClientResponseCodec) {
|
|
|
|
ccr.res.Result = nil
|
|
|
|
ccr.res.Error = nil
|
|
|
|
ccr.res.ID = 0
|
2017-10-31 09:25:44 +00:00
|
|
|
|
2017-11-26 10:15:51 +00:00
|
|
|
clientResponseCodecPool.Put(ccr)
|
2017-10-31 09:25:44 +00:00
|
|
|
}
|